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