xref: /titanic_52/usr/src/lib/nsswitch/ldap/common/getexecattr.c (revision 7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fe)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <secdb.h>
30 #include <exec_attr.h>
31 #include "ldap_common.h"
32 
33 
34 /* exec_attr attributes filters */
35 #define	ISWILD(x)		(x == NULL) ? "*" : x
36 #define	_EXEC_NAME		"cn"
37 #define	_EXEC_POLICY		"SolarisKernelSecurityPolicy"
38 #define	_EXEC_TYPE		"SolarisProfileType"
39 #define	_EXEC_RES1		"SolarisAttrRes1"
40 #define	_EXEC_RES2		"SolarisAttrRes2"
41 #define	_EXEC_ID		"SolarisProfileId"
42 #define	_EXEC_ATTRS		"SolarisAttrKeyValue"
43 #define	_EXEC_GETEXECNAME	"(&(objectClass=SolarisExecAttr)(cn=%s)"\
44 				"(SolarisKernelSecurityPolicy=%s)"\
45 				"(SolarisProfileType=%s))"
46 #define	_EXEC_GETEXECNAME_SSD	"(&(%%s)(cn=%s)"\
47 				"(SolarisKernelSecurityPolicy=%s)"\
48 				"(SolarisProfileType=%s))"
49 #define	_EXEC_GETEXECID		"(&(objectClass=SolarisExecAttr)"\
50 				"(SolarisProfileId=%s)"\
51 				"(SolarisKernelSecurityPolicy=%s)"\
52 				"(SolarisProfileType=%s))"
53 #define	_EXEC_GETEXECID_SSD	"(&(%%s)"\
54 				"(SolarisProfileId=%s)"\
55 				"(SolarisKernelSecurityPolicy=%s)"\
56 				"(SolarisProfileType=%s))"
57 #define	_EXEC_GETEXECNAMEID	"(&(objectClass=SolarisExecAttr)(cn=%s)"\
58 				"(SolarisProfileId=%s)"\
59 				"(SolarisKernelSecurityPolicy=%s)"\
60 				"(SolarisProfileType=%s))"
61 #define	_EXEC_GETEXECNAMEID_SSD	"(&(%%s)(cn=%s)"\
62 				"(SolarisProfileId=%s)"\
63 				"(SolarisKernelSecurityPolicy=%s)"\
64 				"(SolarisProfileType=%s))"
65 
66 
67 /* from libnsl */
68 extern int _doexeclist(nss_XbyY_args_t *);
69 extern char *_exec_wild_id(char *, const char *);
70 extern void _exec_cleanup(nss_status_t, nss_XbyY_args_t *);
71 
72 
73 static const char *exec_attrs[] = {
74 	_EXEC_NAME,
75 	_EXEC_POLICY,
76 	_EXEC_TYPE,
77 	_EXEC_RES1,
78 	_EXEC_RES2,
79 	_EXEC_ID,
80 	_EXEC_ATTRS,
81 	(char *)NULL
82 };
83 
84 
85 #ifdef	DEBUG
86 static void
87 _print_execstr(execstr_t *exec)
88 {
89 
90 	(void) fprintf(stdout, "      exec-name: [%s]\n", exec->name);
91 	if (exec->policy != (char *)NULL) {
92 		(void) fprintf(stdout, "      policy: [%s]\n", exec->policy);
93 	}
94 	if (exec->type != (char *)NULL) {
95 		(void) fprintf(stdout, "      type: [%s]\n", exec->type);
96 	}
97 	if (exec->res1 != (char *)NULL) {
98 		(void) fprintf(stdout, "      res1: [%s]\n", exec->res1);
99 	}
100 	if (exec->res2 != (char *)NULL) {
101 		(void) fprintf(stdout, "      res2: [%s]\n", exec->res2);
102 	}
103 	if (exec->id != (char *)NULL) {
104 		(void) fprintf(stdout, "      id: [%s]\n", exec->id);
105 	}
106 	if (exec->attr != (char *)NULL) {
107 		(void) fprintf(stdout, "      attr: [%s]\n", exec->attr);
108 	}
109 	if (exec->next != (execstr_t *)NULL) {
110 		(void) fprintf(stdout, "      next: [%s]\n", exec->next->name);
111 		(void) fprintf(stdout, "\n");
112 		_print_execstr(exec->next);
113 	}
114 }
115 #endif	/* DEBUG */
116 
117 
118 static int
119 _exec_ldap_exec2ent(ns_ldap_entry_t *entry, nss_XbyY_args_t *argp)
120 {
121 
122 	int			i;
123 	unsigned long		len = 0L;
124 	int			buflen = (int)0;
125 	char			*nullstring = (char *)NULL;
126 	char			*buffer = (char *)NULL;
127 	char			*ceiling = (char *)NULL;
128 	execstr_t		*exec = (execstr_t *)NULL;
129 	ns_ldap_attr_t		*attrptr;
130 
131 	buffer = argp->buf.buffer;
132 	buflen = (size_t)argp->buf.buflen;
133 	(void) memset(argp->buf.buffer, 0, buflen);
134 	exec = (execstr_t *)(argp->buf.result);
135 	ceiling = buffer + buflen;
136 	exec->name = (char *)NULL;
137 	exec->policy = (char *)NULL;
138 	exec->type = (char *)NULL;
139 	exec->res1 = (char *)NULL;
140 	exec->res2 = (char *)NULL;
141 	exec->id = (char *)NULL;
142 	exec->attr = (char *)NULL;
143 
144 	for (i = 0; i < entry->attr_count; i++) {
145 		attrptr = entry->attr_pair[i];
146 		if (attrptr == NULL) {
147 			return ((int)NSS_STR_PARSE_PARSE);
148 		}
149 		if (strcasecmp(attrptr->attrname, _EXEC_NAME) == 0) {
150 			if ((attrptr->attrvalue[0] == NULL) ||
151 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
152 				return ((int)NSS_STR_PARSE_PARSE);
153 			}
154 			exec->name = buffer;
155 			buffer += len + 1;
156 			if (buffer >= ceiling) {
157 				return ((int)NSS_STR_PARSE_ERANGE);
158 			}
159 			(void) strcpy(exec->name, attrptr->attrvalue[0]);
160 			continue;
161 		}
162 		if (strcasecmp(attrptr->attrname, _EXEC_POLICY) == 0) {
163 			if ((attrptr->attrvalue[0] == NULL) ||
164 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
165 				exec->policy = nullstring;
166 			} else {
167 				exec->policy = buffer;
168 				buffer += len + 1;
169 				if (buffer >= ceiling) {
170 					return ((int)NSS_STR_PARSE_ERANGE);
171 				}
172 				(void) strcpy(exec->policy,
173 				    attrptr->attrvalue[0]);
174 			}
175 			continue;
176 		}
177 		if (strcasecmp(attrptr->attrname, _EXEC_TYPE) == 0) {
178 			if ((attrptr->attrvalue[0] == NULL) ||
179 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
180 				exec->type = nullstring;
181 			} else {
182 				exec->type = buffer;
183 				buffer += len + 1;
184 				if (buffer >= ceiling) {
185 					return ((int)NSS_STR_PARSE_ERANGE);
186 				}
187 				(void) strcpy(exec->type,
188 				    attrptr->attrvalue[0]);
189 			}
190 			continue;
191 		}
192 		if (strcasecmp(attrptr->attrname, _EXEC_RES1) == 0) {
193 			if ((attrptr->attrvalue[0] == NULL) ||
194 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
195 				exec->res1 = nullstring;
196 			} else {
197 				exec->res1 = buffer;
198 				buffer += len + 1;
199 				if (buffer >= ceiling) {
200 					return ((int)NSS_STR_PARSE_ERANGE);
201 				}
202 				(void) strcpy(exec->res1,
203 				    attrptr->attrvalue[0]);
204 			}
205 			continue;
206 		}
207 		if (strcasecmp(attrptr->attrname, _EXEC_RES2) == 0) {
208 			if ((attrptr->attrvalue[0] == NULL) ||
209 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
210 				exec->res2 = nullstring;
211 			} else {
212 				exec->res2 = buffer;
213 				buffer += len + 1;
214 				if (buffer >= ceiling) {
215 					return ((int)NSS_STR_PARSE_ERANGE);
216 				}
217 				(void) strcpy(exec->res2,
218 				    attrptr->attrvalue[0]);
219 			}
220 			continue;
221 		}
222 		if (strcasecmp(attrptr->attrname, _EXEC_ID) == 0) {
223 			if ((attrptr->attrvalue[0] == NULL) ||
224 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
225 				exec->id = nullstring;
226 			} else {
227 				exec->id = buffer;
228 				buffer += len + 1;
229 				if (buffer >= ceiling) {
230 					return ((int)NSS_STR_PARSE_ERANGE);
231 				}
232 				(void) strcpy(exec->id, attrptr->attrvalue[0]);
233 			}
234 			continue;
235 		}
236 		if (strcasecmp(attrptr->attrname, _EXEC_ATTRS) == 0) {
237 			if ((attrptr->attrvalue[0] == NULL) ||
238 			    (len = strlen(attrptr->attrvalue[0])) < 1) {
239 				exec->attr = nullstring;
240 			} else {
241 				exec->attr = buffer;
242 				buffer += len + 1;
243 				if (buffer >= ceiling) {
244 					return ((int)NSS_STR_PARSE_ERANGE);
245 				}
246 				(void) strcpy(exec->attr,
247 				    attrptr->attrvalue[0]);
248 			}
249 			continue;
250 		}
251 	}
252 
253 	exec->next = (execstr_t *)NULL;
254 
255 #ifdef	DEBUG
256 	(void) fprintf(stdout, "\n[getexecattr.c: _exec_ldap_exec2ent]\n");
257 	_print_execstr(exec);
258 #endif	/* DEBUG */
259 
260 	return ((int)NSS_STR_PARSE_SUCCESS);
261 }
262 
263 
264 /*
265  * place the results from ldap object structure into argp->buf.result
266  * returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE}
267  */
268 static int
269 _nss_ldap_exec2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp)
270 {
271 	int			status = (int)NSS_STR_PARSE_SUCCESS;
272 	ns_ldap_entry_t		*entry;
273 	ns_ldap_result_t	*result = be->result;
274 
275 	if (!argp->buf.result) {
276 		status = (int)NSS_STR_PARSE_ERANGE;
277 		goto result_exec2ent;
278 	}
279 
280 	for (entry = result->entry; entry != NULL; entry = entry->next) {
281 		status = _exec_ldap_exec2ent(entry, argp);
282 		if (status != NSS_STR_PARSE_SUCCESS) {
283 			goto result_exec2ent;
284 		}
285 	}
286 
287 result_exec2ent:
288 	(void) __ns_ldap_freeResult(&be->result);
289 	return (status);
290 }
291 
292 
293 static nss_status_t
294 _exec_process_val(ldap_backend_ptr be, nss_XbyY_args_t *argp)
295 {
296 	int 			status;
297 	nss_status_t		nss_stat = NSS_UNAVAIL;
298 	ns_ldap_attr_t		*attrptr;
299 	ns_ldap_entry_t		*entry;
300 	ns_ldap_result_t	*result = be->result;
301 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
302 
303 #ifdef	DEBUG
304 	(void) fprintf(stdout, "\n[getexecattr.c: _exec_process_val]\n");
305 #endif	/* DEBUG */
306 
307 	argp->returnval = NULL;
308 	attrptr = getattr(result, 0);
309 	if (attrptr == NULL) {
310 		(void) __ns_ldap_freeResult(&be->result);
311 		return (nss_stat);
312 	}
313 	for (entry = result->entry; entry != NULL; entry = entry->next) {
314 		status = _exec_ldap_exec2ent(entry, argp);
315 		switch (status) {
316 		case NSS_STR_PARSE_SUCCESS:
317 			argp->returnval = argp->buf.result;
318 			nss_stat = NSS_SUCCESS;
319 			if (_priv_exec->search_flag == GET_ALL) {
320 				if (_doexeclist(argp) == 0) {
321 					nss_stat = NSS_UNAVAIL;
322 				}
323 			}
324 			break;
325 		case NSS_STR_PARSE_ERANGE:
326 			argp->erange = 1;
327 			nss_stat = NSS_NOTFOUND;
328 			break;
329 		case NSS_STR_PARSE_PARSE:
330 			nss_stat = NSS_NOTFOUND;
331 			break;
332 		default:
333 			nss_stat = NSS_UNAVAIL;
334 			break;
335 		}
336 
337 		if ((_priv_exec->search_flag == GET_ONE) ||
338 		    (nss_stat != NSS_SUCCESS)) {
339 			break;
340 		}
341 	}
342 
343 	return (nss_stat);
344 }
345 
346 
347 /*
348  * Check if we have either an exact match or a wild-card entry for that id.
349  */
350 static nss_status_t
351 get_wild(ldap_backend_ptr be, nss_XbyY_args_t *argp, int getby_flag)
352 {
353 	char		*dup_id = NULL;
354 	char		*wild_id;
355 	char		searchfilter[SEARCHFILTERLEN];
356 	char		userdata[SEARCHFILTERLEN];
357 	char		name[SEARCHFILTERLEN];
358 	char		id[SEARCHFILTERLEN];
359 	int		ret;
360 	nss_status_t	nss_stat = NSS_NOTFOUND;
361 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
362 	const char	*policy = _priv_exec->policy;
363 	const char	*type = _priv_exec->type;
364 
365 	if (strpbrk(policy, "*()\\") != NULL ||
366 	    type != NULL && strpbrk(type, "*()\\") != NULL)
367 		return ((nss_status_t)NSS_NOTFOUND);
368 
369 	if (_priv_exec->id != NULL)
370 		dup_id = strdup(_priv_exec->id);
371 
372 	switch (getby_flag) {
373 	case NSS_DBOP_EXECATTR_BYNAMEID:
374 		if (_ldap_filter_name(name, _priv_exec->name,
375 		    sizeof (name)) != 0)
376 			goto go_out;
377 		break;
378 	}
379 
380 	wild_id = dup_id;
381 	do {
382 		if (wild_id != NULL) {
383 			if (_ldap_filter_name(id, wild_id, sizeof (id)) != 0)
384 				goto go_out;
385 		} else
386 			(void) strlcpy(id, "*", sizeof (id));
387 
388 		switch (getby_flag) {
389 		case NSS_DBOP_EXECATTR_BYID:
390 			ret = snprintf(searchfilter, sizeof (searchfilter),
391 			    _EXEC_GETEXECID, id, policy, ISWILD(type));
392 			if (ret >= sizeof (searchfilter) || ret < 0)
393 				goto go_out;
394 			ret = snprintf(userdata, sizeof (userdata),
395 			    _EXEC_GETEXECID_SSD, id, policy, ISWILD(type));
396 			if (ret >= sizeof (userdata) || ret < 0)
397 				goto go_out;
398 			break;
399 
400 		case NSS_DBOP_EXECATTR_BYNAMEID:
401 			ret = snprintf(searchfilter, sizeof (searchfilter),
402 			    _EXEC_GETEXECNAMEID, name, id,
403 			    policy, ISWILD(type));
404 			if (ret >= sizeof (searchfilter) || ret < 0)
405 				goto go_out;
406 			ret = snprintf(userdata, sizeof (userdata),
407 			    _EXEC_GETEXECNAMEID_SSD, name, id,
408 			    policy, ISWILD(type));
409 			if (ret >= sizeof (userdata) || ret < 0)
410 				goto go_out;
411 			break;
412 
413 		default:
414 			goto go_out;
415 		}
416 		nss_stat = _nss_ldap_nocb_lookup(be, argp, _EXECATTR,
417 		    searchfilter, NULL, _merge_SSD_filter, userdata);
418 		if (nss_stat == NSS_SUCCESS)
419 			break;
420 	} while ((wild_id = _exec_wild_id(wild_id, type)) != NULL);
421 
422 go_out:
423 	free(dup_id);
424 
425 	return (nss_stat);
426 }
427 
428 static nss_status_t
429 getbynam(ldap_backend_ptr be, void *a)
430 {
431 	char		searchfilter[SEARCHFILTERLEN];
432 	char		userdata[SEARCHFILTERLEN];
433 	char		name[SEARCHFILTERLEN];
434 	int		ret;
435 	nss_status_t	nss_stat;
436 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
437 	_priv_execattr	*_priv_exec = (_priv_execattr *)(argp->key.attrp);
438 	const char	*policy = _priv_exec->policy;
439 	const char	*type = _priv_exec->type;
440 
441 #ifdef	DEBUG
442 	(void) fprintf(stdout, "\n[getexecattr.c: getbyname]\n");
443 #endif	/* DEBUG */
444 
445 	if (strpbrk(policy, "*()\\") != NULL ||
446 	    type != NULL && strpbrk(type, "*()\\") != NULL ||
447 	    _ldap_filter_name(name, _priv_exec->name, sizeof (name)) != 0)
448 		return ((nss_status_t)NSS_NOTFOUND);
449 	ret = snprintf(searchfilter, sizeof (searchfilter),
450 	    _EXEC_GETEXECNAME, name, policy, ISWILD(type));
451 	if (ret >= sizeof (searchfilter) || ret < 0)
452 		return ((nss_status_t)NSS_NOTFOUND);
453 	ret = snprintf(userdata, sizeof (userdata),
454 	    _EXEC_GETEXECNAME_SSD, name, policy, ISWILD(type));
455 	if (ret >= sizeof (userdata) || ret < 0)
456 		return ((nss_status_t)NSS_NOTFOUND);
457 
458 	nss_stat = _nss_ldap_nocb_lookup(be, argp, _EXECATTR,
459 	    searchfilter, NULL, _merge_SSD_filter, userdata);
460 
461 	if (nss_stat == NSS_SUCCESS)
462 		nss_stat = _exec_process_val(be, argp);
463 
464 	_exec_cleanup(nss_stat, argp);
465 
466 	return (nss_stat);
467 }
468 
469 
470 static nss_status_t
471 getbyid(ldap_backend_ptr be, void *a)
472 {
473 	nss_status_t	nss_stat;
474 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
475 
476 #ifdef	DEBUG
477 	(void) fprintf(stdout, "\n[getexecattr.c: getbyid]\n");
478 #endif	/* DEBUG */
479 
480 	nss_stat = get_wild(be, argp, NSS_DBOP_EXECATTR_BYID);
481 
482 	if (nss_stat == NSS_SUCCESS)
483 		nss_stat = _exec_process_val(be, argp);
484 
485 	_exec_cleanup(nss_stat, argp);
486 
487 	return (nss_stat);
488 }
489 
490 
491 static nss_status_t
492 getbynameid(ldap_backend_ptr be, void *a)
493 {
494 	nss_status_t	nss_stat;
495 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
496 
497 #ifdef	DEBUG
498 	(void) fprintf(stdout, "\n[getexecattr.c: getbynameid]\n");
499 #endif	/* DEBUG */
500 
501 	nss_stat = get_wild(be, argp, NSS_DBOP_EXECATTR_BYNAMEID);
502 
503 	if (nss_stat == NSS_SUCCESS)
504 		nss_stat = _exec_process_val(be, argp);
505 
506 	_exec_cleanup(nss_stat, argp);
507 
508 	return (nss_stat);
509 }
510 
511 
512 static ldap_backend_op_t execattr_ops[] = {
513 	_nss_ldap_destr,
514 	_nss_ldap_endent,
515 	_nss_ldap_setent,
516 	_nss_ldap_getent,
517 	getbynam,
518 	getbyid,
519 	getbynameid
520 };
521 
522 
523 /*ARGSUSED0*/
524 nss_backend_t *
525 _nss_ldap_exec_attr_constr(const char *dummy1,
526     const char *dummy2,
527     const char *dummy3,
528     const char *dummy4,
529     const char *dummy5,
530     const char *dummy6,
531     const char *dummy7)
532 {
533 #ifdef	DEBUG
534 	(void) fprintf(stdout,
535 	    "\n[getexecattr.c: _nss_ldap_exec_attr_constr]\n");
536 #endif
537 	return ((nss_backend_t *)_nss_ldap_constr(execattr_ops,
538 		sizeof (execattr_ops)/sizeof (execattr_ops[0]), _EXECATTR,
539 		exec_attrs, _nss_ldap_exec2ent));
540 }
541