1/* $NetBSD: rbac.c,v 1.2 2021/08/14 16:14:53 christos Exp $ */ 2 3/* rbac.c - RBAC main file */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2013-2021 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18/* ACKNOWLEDGEMENTS: 19 */ 20 21#include <sys/cdefs.h> 22__RCSID("$NetBSD: rbac.c,v 1.2 2021/08/14 16:14:53 christos Exp $"); 23 24#include "portable.h" 25 26#include <stdio.h> 27 28#include <ac/string.h> 29 30#include "slap.h" 31#include "slap-config.h" 32#include "lutil.h" 33 34#include "rbac.h" 35 36#define RBAC_REQ 1 37 38static slap_overinst rbac; 39 40static struct berval slap_EXOP_CREATE_SESSION = 41 BER_BVC(LDAP_RBAC_EXOP_CREATE_SESSION); 42static struct berval slap_EXOP_CHECK_ACCESS = 43 BER_BVC(LDAP_RBAC_EXOP_CHECK_ACCESS); 44static struct berval slap_EXOP_ADD_ACTIVE_ROLE = 45 BER_BVC(LDAP_RBAC_EXOP_ADD_ACTIVE_ROLE); 46static struct berval slap_EXOP_DROP_ACTIVE_ROLE = 47 BER_BVC(LDAP_RBAC_EXOP_DROP_ACTIVE_ROLE); 48static struct berval slap_EXOP_DELETE_SESSION = 49 BER_BVC(LDAP_RBAC_EXOP_DELETE_SESSION); 50static struct berval slap_EXOP_SESSION_ROLES = 51 BER_BVC(LDAP_RBAC_EXOP_SESSION_ROLES); 52 53rbac_tenant_t rbac_tenants = { 54 { 55 .schema = &slap_rbac_jts_schema, 56 }, 57 NULL 58}; 59 60static ConfigDriver rbac_cf_gen; 61 62static ConfigTable rbaccfg[] = { 63 { "rbac-default-users-base-dn", "usersDN", 2, 2, 0, 64 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_USERS_BASE_DN, 65 rbac_cf_gen, 66 "(OLcfgCtAt:7.1 NAME 'olcRBACDefaultUsersBaseDn' " 67 "DESC 'default Base DN for RBAC users ' " 68 "SYNTAX OMsDirectoryString " 69 "SINGLE-VALUE )", 70 NULL, NULL 71 }, 72 { "rbac-default-roles-base-dn", "rolesDN", 2, 2, 0, 73 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_ROLES_BASE_DN, 74 rbac_cf_gen, 75 "(OLcfgCtAt:7.2 NAME 'olcRBACDefaultRolesBaseDn' " 76 "DESC 'default base DN for RBAC roles ' " 77 "SYNTAX OMsDirectoryString " 78 "SINGLE-VALUE )", 79 NULL, NULL 80 }, 81 { "rbac-default-permissions-base-dn", "permissionsDN", 2, 2, 0, 82 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_PERMISSIONS_BASE_DN, 83 rbac_cf_gen, 84 "(OLcfgCtAt:7.3 NAME 'olcRBACDefaultPermissionsBaseDn' " 85 "DESC 'default base DN for RBAC permissions ' " 86 "SYNTAX OMsDirectoryString " 87 "SINGLE-VALUE )", 88 NULL, NULL 89 }, 90 { "rbac-default-sessions-base-dn", "sessionsDN", 2, 2, 0, 91 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_SESSIONS_BASE_DN, 92 rbac_cf_gen, 93 "(OLcfgCtAt:7.4 NAME 'olcRBACDefaultSessionsBaseDn' " 94 "DESC 'default base DN for RBAC permissions ' " 95 "SYNTAX OMsDirectoryString " 96 "SINGLE-VALUE )", 97 NULL, NULL 98 }, 99 { "rbac-admin", "adminDN", 2, 2, 0, 100 ARG_MAGIC|ARG_DN|RBAC_ADMIN_DN, 101 rbac_cf_gen, 102 "(OLcfgCtAt:7.5 NAME 'olcRBACAdminDn' " 103 "DESC 'default admin DN for RBAC repository ' " 104 "SYNTAX OMsDirectoryString " 105 "SINGLE-VALUE )", 106 NULL, NULL 107 }, 108 { "rbac-pwd", "adminPwd", 2, 2, 0, 109 ARG_MAGIC|RBAC_ADMIN_PWD, 110 rbac_cf_gen, 111 "(OLcfgCtAt:7.6 NAME 'olcRBACAdminPwd' " 112 "DESC 'default admin pwd for RBAC repository ' " 113 "SYNTAX OMsDirectoryString " 114 "SINGLE-VALUE )", 115 NULL, NULL 116 }, 117 { "rbac-session-admin", "sessionAdminDN", 2, 2, 0, 118 ARG_MAGIC|ARG_DN|RBAC_SESSION_ADMIN_DN, 119 rbac_cf_gen, 120 "(OLcfgCtAt:7.7 NAME 'olcRBACSessionAdminDn' " 121 "DESC 'admin DN for RBAC session repository ' " 122 "SYNTAX OMsDirectoryString " 123 "SINGLE-VALUE )", 124 NULL, NULL 125 }, 126 { "rbac-session-admin-pwd", "sessionAdminPwd", 2, 2, 0, 127 ARG_MAGIC|RBAC_SESSION_ADMIN_PWD, 128 rbac_cf_gen, 129 "(OLcfgCtAt:7.8 NAME 'olcRBACSessionAdminPwd' " 130 "DESC 'admin pwd for RBAC session repository ' " 131 "SYNTAX OMsDirectoryString SINGLE-VALUE )", 132 NULL, NULL 133 }, 134 { "tenant", "tenant", 2, 2, 0, 135 ARG_MAGIC|ARG_DN|RBAC_TENANT, 136 rbac_cf_gen, "(OLcfgCtAt:7.9 NAME 'olcRBACTenant' " 137 "DESC 'RBAC tenant ' " 138 "SYNTAX OMsDirectoryString " 139 "SINGLE-VALUE )", 140 NULL, NULL 141 }, 142 { "rbac-default-audit-base-dn", "auditDN", 2, 2, 0, 143 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_AUDIT_BASE_DN, 144 rbac_cf_gen, 145 "(OLcfgCtAt:7.10 NAME 'olcRBACDefaultAuditBaseDn' " 146 "DESC 'default base DN for RBAC audit records ' " 147 "SYNTAX OMsDirectoryString " 148 "SINGLE-VALUE )", 149 NULL, NULL 150 }, 151 { "rbac-default-tenant-id", "tenantId", 2, 2, 0, 152 ARG_MAGIC|RBAC_DEFAULT_TENANT_ID, 153 rbac_cf_gen, 154 "(OLcfgCtAt:7.11 NAME 'olcRBACDefaultTenantId' " 155 "DESC 'default tenant id' " 156 "SYNTAX OMsDirectoryString " 157 "SINGLE-VALUE )", 158 NULL, NULL 159 }, 160 161 { NULL, NULL, 0, 0, 0, ARG_IGNORED } 162}; 163 164static ConfigOCs rbac_ocs[] = { 165 { "( OLcfgCtOc:7.1 " 166 "NAME 'olcRBACConfig' " 167 "DESC 'RBAC configuration' " 168 "SUP olcOverlayConfig " 169 "MAY ( olcRBACDefaultUsersBaseDn $ olcRBACDefaultRolesBaseDn $ " 170 "olcRBACDefaultPermissionsBaseDn $ olcRBACDefaultSessionsBaseDn $ " 171 "olcRBACAdminDn $ olcRBACAdminPwd $ olcRBACSessionAdminDn $ " 172 "olcRBACSessionAdminPwd) )", 173 Cft_Overlay, rbaccfg }, 174 175 { NULL, 0, NULL } 176}; 177 178static slap_verbmasks rbac_keys[] = { 179 { BER_BVC("default_users_base_dn"), RBAC_DEFAULT_USERS_BASE_DN }, 180 { BER_BVC("default_roles_base_dn"), RBAC_DEFAULT_ROLES_BASE_DN }, 181 { BER_BVC("default_permissions_base_dn"), 182 RBAC_DEFAULT_PERMISSIONS_BASE_DN }, 183 { BER_BVC("tenant"), RBAC_TENANT }, 184 185 { BER_BVNULL, 0 } 186}; 187 188static slap_verbmasks rbac_tenant_keys[] = { 189 { BER_BVC("id"), RBAC_TENANT_ID }, 190 { BER_BVC("users_base_dn"), RBAC_USERS_BASE_DN }, 191 { BER_BVC("roles_base_dn"), RBAC_ROLES_BASE_DN }, 192 { BER_BVC("permissions_base_dn"), RBAC_PERMISSIONS_BASE_DN }, 193 194 { BER_BVNULL, 0 } 195}; 196 197static void 198rbac_tenant_parse( char *tenent_info, tenant_info_t *tenants ) 199{ 200 return; 201} 202 203static int 204rbac_cf_gen( ConfigArgs *c ) 205{ 206 slap_overinst *on = (slap_overinst *)c->bi; 207 rbac_tenant_t *ri = &rbac_tenants; 208 int rc = 0; 209 210 if ( c->op == SLAP_CONFIG_EMIT ) { 211 switch ( c->type ) { 212 case RBAC_DEFAULT_USERS_BASE_DN: 213 value_add_one( &c->rvalue_vals, &ri->tenant_info.users_basedn ); 214 break; 215 case RBAC_DEFAULT_ROLES_BASE_DN: 216 value_add_one( &c->rvalue_vals, &ri->tenant_info.roles_basedn ); 217 break; 218 case RBAC_DEFAULT_PERMISSIONS_BASE_DN: 219 value_add_one( 220 &c->rvalue_vals, &ri->tenant_info.permissions_basedn ); 221 break; 222 case RBAC_DEFAULT_SESSIONS_BASE_DN: 223 value_add_one( 224 &c->rvalue_vals, &ri->tenant_info.sessions_basedn ); 225 break; 226 case RBAC_DEFAULT_AUDIT_BASE_DN: 227 value_add_one( &c->rvalue_vals, &ri->tenant_info.audit_basedn ); 228 break; 229 case RBAC_ADMIN_DN: 230 value_add_one( &c->rvalue_vals, &ri->tenant_info.admin ); 231 break; 232 case RBAC_ADMIN_PWD: 233 value_add_one( &c->rvalue_vals, &ri->tenant_info.pwd ); 234 break; 235 case RBAC_SESSION_ADMIN_DN: 236 value_add_one( 237 &c->rvalue_vals, &ri->tenant_info.session_admin ); 238 break; 239 case RBAC_DEFAULT_TENANT_ID: 240 value_add_one( &c->rvalue_vals, &ri->tenant_info.tid ); 241 break; 242 default: 243 break; 244 } 245 return rc; 246 } else if ( c->op == LDAP_MOD_DELETE ) { 247 /* FIXME */ 248 return 1; 249 } 250 switch ( c->type ) { 251 case RBAC_DEFAULT_USERS_BASE_DN: { 252 struct berval dn = BER_BVNULL; 253 ber_str2bv( c->argv[1], 0, 0, &dn ); 254 rc = dnNormalize( 255 0, NULL, NULL, &dn, &ri->tenant_info.users_basedn, NULL ); 256 break; 257 } 258 case RBAC_DEFAULT_ROLES_BASE_DN: { 259 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.roles_basedn ); 260 break; 261 } 262 case RBAC_DEFAULT_PERMISSIONS_BASE_DN: { 263 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.permissions_basedn ); 264 break; 265 } 266 case RBAC_DEFAULT_SESSIONS_BASE_DN: { 267 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.sessions_basedn ); 268 break; 269 } 270 case RBAC_DEFAULT_AUDIT_BASE_DN: { 271 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.audit_basedn ); 272 break; 273 } 274 case RBAC_ADMIN_DN: { 275 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.admin ); 276 break; 277 } 278 case RBAC_ADMIN_PWD: { 279 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.pwd ); 280 break; 281 } 282 case RBAC_SESSION_ADMIN_DN: { 283 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.session_admin ); 284 break; 285 } 286 case RBAC_SESSION_ADMIN_PWD: { 287 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.session_admin_pwd ); 288 break; 289 } 290 case RBAC_DEFAULT_TENANT_ID: { 291 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.tid ); 292 break; 293 } 294 case RBAC_TENANT: { 295 rbac_tenant_parse( c->argv[1], &ri->tenant_info ); 296 break; 297 } 298 default: 299 break; 300 } 301 302 return rc; 303} 304 305/* 306 * rbac configuration 307 */ 308 309tenant_info_t * 310rbac_tid2tenant( struct berval *tid ) 311{ 312 /* return the only tenant for now */ 313 return &rbac_tenants.tenant_info; 314} 315 316//{ BER_BVC(LDAP_RBAC_EXOP_SESSION_ROLES), rbac_session_roles }, 317 318static int 319slap_parse_rbac_session_roles( 320 struct berval *in, 321 rbac_req_t **reqpp, 322 const char **text, 323 void *ctx ) 324{ 325 int rc = LDAP_SUCCESS; 326 struct berval reqdata = BER_BVNULL; 327 rbac_req_t *reqp = NULL; 328 BerElementBuffer berbuf; 329 BerElement *ber = (BerElement *)&berbuf; 330 ber_tag_t tag; 331 ber_len_t len = -1; 332 333 *text = NULL; 334 335 if ( in == NULL || in->bv_len == 0 ) { 336 *text = "empty request data field in rbac_session_roles exop"; 337 return LDAP_PROTOCOL_ERROR; 338 } 339 340 reqp = rbac_alloc_req( RBAC_REQ_SESSION_ROLES ); 341 342 if ( !reqp ) { 343 *text = "unable to allocate memory for rbac_session_roles exop"; 344 return LDAP_PROTOCOL_ERROR; 345 } 346 347 ber_dupbv_x( &reqdata, in, ctx ); 348 349 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ 350 ber_init2( ber, &reqdata, 0 ); 351 352 tag = ber_scanf( ber, "{" /*}*/ ); 353 354 if ( tag == LBER_ERROR ) { 355 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: " 356 "decoding error.\n" ); 357 goto decoding_error; 358 } 359 360 tag = ber_peek_tag( ber, &len ); 361 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID_SESS ) { 362 struct berval uid; 363 tag = ber_scanf( ber, "m", &uid ); 364 if ( tag == LBER_ERROR ) { 365 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: " 366 "user id parse failed.\n" ); 367 goto decoding_error; 368 } 369 ber_dupbv_x( &reqp->uid, &uid, ctx ); 370 tag = ber_peek_tag( ber, &len ); 371 } 372 373 //tag = ber_peek_tag( ber, &len ); 374 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ) { 375 struct berval sessid; 376 tag = ber_scanf( ber, "m", &sessid ); 377 if ( tag == LBER_ERROR ) { 378 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: " 379 "session id parse failed.\n" ); 380 goto decoding_error; 381 } 382 ber_dupbv_x( &reqp->sessid, &sessid, ctx ); 383 tag = ber_peek_tag( ber, &len ); 384 } 385 386 if ( tag != LBER_DEFAULT || len != 0 ) { 387decoding_error:; 388 389 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: " 390 "decoding error, len=%ld\n", 391 (long)len ); 392 rc = LDAP_PROTOCOL_ERROR; 393 *text = "data decoding error"; 394 } 395 396 if ( rc == LDAP_SUCCESS ) { 397 *reqpp = reqp; 398 } else { 399 rbac_free_req( reqp ); 400 *reqpp = NULL; 401 } 402 403 if ( !BER_BVISNULL( &reqdata ) ) { 404 ber_memfree_x( reqdata.bv_val, ctx ); 405 } 406 407 return rc; 408} 409 410static int 411rbac_session_roles( Operation *op, SlapReply *rs ) 412{ 413 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 414 const struct berval rbac_op = BER_BVC("SessionRoles"); 415 rbac_req_t *reqp = NULL; 416 rbac_session_t *sessp; 417 int rc; 418 419 rs->sr_err = slap_parse_rbac_session_roles( 420 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 421 422 assert( rs->sr_err == LDAP_SUCCESS ); 423 424 /* get the session using the session id */ 425 sessp = rbac_session_byid( op, reqp ); 426 if ( !sessp ) { 427 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: " 428 "session not found\n" ); 429 rc = LDAP_UNWILLING_TO_PERFORM; 430 goto done; 431 } 432 433 /* checking whether the session is owned by the user */ 434 if ( !rbac_is_session_owner( sessp, reqp ) ) { 435 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: " 436 "session not owned by user\n" ); 437 rc = LDAP_UNWILLING_TO_PERFORM; 438 goto done; 439 } 440 441 rc = rbac_int_delete_session( op, sessp ); 442 if ( rc != LDAP_SUCCESS ) { 443 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: " 444 "unable to delete session\n" ); 445 rc = LDAP_UNWILLING_TO_PERFORM; 446 goto done; 447 } 448 449 /* 450 * If we wanted to... 451 * load these roles into a response with a sequence nested within a 452 * sequence: (No, we're not actually doing this here.) 453 * 0x30 LL ber_printf( ber, "{" ); 454 * 0x04 L1 455 * 0x04 L2 a b c d 456 * 0x04 L3 e f g h 457 * 0x04 L4 i j k l 458 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL ); 459 * close it ber_printf( ber, "t{W}", LDAP_TAG_EXOP_RBAC_ROLES, roles ); 460 */ 461 462 /* 463 * Instead we are... 464 * loading these roles into the response within a sequence: (Yes, we are doing this here.) 465 * 0x30 LL ber_printf( ber, "{" ); 466 * 0x04 L1 a b c d 467 * 0x04 L2 e f g h 468 * 0x04 L3 i j k l 469 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL ); 470 * close it ber_printf( ber, "tW", LDAP_TAG_EXOP_RBAC_ROLES, roles ); 471 */ 472 BerElementBuffer berbuf; 473 BerElement *ber = (BerElement *)&berbuf; 474 ber_init_w_nullc( ber, LBER_USE_DER ); 475 BerVarray roles = NULL; 476 if ( sessp->roles ) { 477 struct berval tmpbv; 478 // open the sequence: 479 ber_printf( ber, "{" /*}*/ ); 480 //char *role; 481 int i = 0; 482 //BerVarray roles = NULL; 483 for ( i = 0; !BER_BVISNULL( &sessp->roles[i] ); i++ ) { 484 tmpbv.bv_val = sessp->roles[i].bv_val; 485 tmpbv.bv_len = sessp->roles[i].bv_len; 486 // add role name: 487 ber_bvarray_add_x( &roles, &tmpbv, NULL ); 488 489 //LBER_F( int ) 490 //ber_bvecadd_x LDAP_P(( struct berval ***bvec, 491 // struct berval *bv, void *ctx )); 492 493 // first attempt at sequence within a sequence... 494 // open another sequence: 495 /* 496 ber_printf( ber, "{" } ); 497 // add role name (again): 498 ber_bvarray_add_x(&roles, &tmpbv, NULL); 499 // close the nested sequence: 500 ber_printf( ber, { "}" ); 501*/ 502 // end 2nd sequence 503 } 504 /* 505 * This is how we add several octet strings at one time. An array of struct berval's is supplied. 506 * The array is terminated by a struct berval with a NULL bv_val. 507 * Note that a construct like '{W}' is required to get an actual SEQUENCE OF octet strings. 508 * But here we are using 'tW' which allows passing a collection of octets w/out a nesting within a sequence. 509 */ 510 ber_printf( ber, "tW", 511 LDAP_TAG_EXOP_RBAC_ROLES, roles); 512 513 // TODO: determine why free on roles array causes a seg fault: 514 //ber_bvarray_free_x(roles, NULL); 515 516 // close the sequence: 517 ber_printf( ber, /*{*/ "N}" ); 518 } 519 520 if ( rc < 0 ) { 521 rs->sr_err = LDAP_OTHER; 522 rs->sr_text = "internal error"; 523 } else { 524 (void)ber_flatten( ber, &rs->sr_rspdata ); 525 rs->sr_err = LDAP_SUCCESS; 526 } 527 ber_free_buf( ber ); 528 // END LOAD ROLES INTO RESPONSE 529 530done:; 531 rs->sr_err = rc; 532 533 // always put the OID in the response: 534 rs->sr_rspoid = ch_strdup( slap_EXOP_SESSION_ROLES.bv_val ); 535 536 /* generate audit log */ 537 rbac_audit( 538 op, SessionRoles, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 539 rbac_free_session( sessp ); 540 rbac_free_req( reqp ); 541 return rs->sr_err; 542} 543 544static int 545rbac_session_rolesx( Operation *op, SlapReply *rs ) 546{ 547 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 548 const struct berval rbac_op = BER_BVC("SessionRoles"); 549 rbac_session_t *sessp = NULL; 550 rbac_req_t *reqp = NULL; 551 int rc; 552 553 rs->sr_err = slap_parse_rbac_session_roles( 554 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 555 556 assert( rs->sr_err == LDAP_SUCCESS ); 557 558 /* get the session using the session id */ 559 sessp = rbac_session_byid( op, reqp ); 560 if ( !sessp ) { 561 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: " 562 "session not found\n" ); 563 rc = LDAP_UNWILLING_TO_PERFORM; 564 goto done; 565 } 566 567 /* checking whether the session is owned by the user */ 568 if ( !rbac_is_session_owner( sessp, reqp ) ) { 569 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: " 570 "session not owned by user\n" ); 571 rc = LDAP_UNWILLING_TO_PERFORM; 572 goto done; 573 } 574 575 rc = rbac_int_delete_session( op, sessp ); 576 if ( rc != LDAP_SUCCESS ) { 577 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: " 578 "unable to delete session\n" ); 579 rc = LDAP_UNWILLING_TO_PERFORM; 580 goto done; 581 } 582 583 /* 584 * If we wanted to... 585 * load these roles into a response with a sequence nested within a 586 * sequence: (No, we're not actually doing this here.) 587 * 0x30 LL ber_printf( ber, "{" ); 588 * 0x04 L1 589 * 0x04 L2 a b c d 590 * 0x04 L3 e f g h 591 * 0x04 L4 i j k l 592 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL ); 593 * close it ber_printf( ber, "t{W}", LDAP_TAG_EXOP_RBAC_ROLES, roles ); 594 */ 595 596 /* 597 * Instead we are... 598 * loading these roles into the response within a sequence: (Yes, we are doing this here.) 599 * 0x30 LL ber_printf( ber, "{" ); 600 * 0x04 L1 a b c d 601 * 0x04 L2 e f g h 602 * 0x04 L3 i j k l 603 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL ); 604 * close it ber_printf( ber, "tW", LDAP_TAG_EXOP_RBAC_ROLES, roles ); 605 */ 606 BerElementBuffer berbuf; 607 BerElement *ber = (BerElement *)&berbuf; 608 ber_init_w_nullc( ber, LBER_USE_DER ); 609 BerVarray roles = NULL; 610 if ( sessp->roles ) { 611 struct berval tmpbv; 612 // open the sequence: 613 ber_printf( ber, "{" /*}*/ ); 614 //char *role; 615 int i = 0; 616 //BerVarray roles = NULL; 617 for ( i = 0; !BER_BVISNULL( &sessp->roles[i] ); i++ ) { 618 tmpbv.bv_val = sessp->roles[i].bv_val; 619 tmpbv.bv_len = sessp->roles[i].bv_len; 620 // add role name: 621 ber_bvarray_add_x( &roles, &tmpbv, NULL ); 622 623 // first attempt at sequence within a sequence... 624 // open another sequence: 625 /* 626 ber_printf( ber, "{" } ); 627 // add role name (again): 628 ber_bvarray_add_x(&roles, &tmpbv, NULL); 629 // close the nested sequence: 630 ber_printf( ber, { "}" ); 631*/ 632 // end 2nd sequence 633 } 634 /* 635 * This is how we add several octet strings at one time. An array of struct berval's is supplied. 636 * The array is terminated by a struct berval with a NULL bv_val. 637 * Note that a construct like '{W}' is required to get an actual SEQUENCE OF octet strings. 638 * But here we are using 'tW' which allows passing a collection of octets w/out a nesting within a sequence. 639 */ 640 ber_printf( ber, "tW", 641 LDAP_TAG_EXOP_RBAC_ROLES, roles); 642 643 // TODO: determine why free on roles array causes a seg fault: 644 //ber_bvarray_free_x(roles, NULL); 645 646 // close the sequence: 647 ber_printf( ber, /*{*/ "N}" ); 648 } 649 650 if ( rc < 0 ) { 651 rs->sr_err = LDAP_OTHER; 652 rs->sr_text = "internal error"; 653 } else { 654 (void)ber_flatten( ber, &rs->sr_rspdata ); 655 rs->sr_err = LDAP_SUCCESS; 656 } 657 ber_free_buf( ber ); 658 // END LOAD ROLES INTO RESPONSE 659 660done:; 661 rs->sr_err = rc; 662 663 // always put the OID in the response: 664 rs->sr_rspoid = ch_strdup( slap_EXOP_SESSION_ROLES.bv_val ); 665 666 /* generate audit log */ 667 rbac_audit( 668 op, SessionRoles, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 669 rbac_free_session( sessp ); 670 rbac_free_req( reqp ); 671 return rs->sr_err; 672} 673 674/* 675 * slap_parse_rbac_create_session 676 */ 677static int 678slap_parse_rbac_create_session( 679 struct berval *in, 680 rbac_req_t **reqpp, 681 const char **text, 682 void *ctx ) 683{ 684 int rc = LDAP_SUCCESS; 685 struct berval reqdata = BER_BVNULL; 686 rbac_req_t *reqp = NULL; 687 BerElementBuffer berbuf; 688 BerElement *ber = (BerElement *)&berbuf; 689 ber_tag_t tag; 690 ber_len_t len = -1; 691 692 *text = NULL; 693 694 if ( in == NULL || in->bv_len == 0 ) { 695 *text = "empty request data field in rbac_create_session exop"; 696 return LDAP_PROTOCOL_ERROR; 697 } 698 699 reqp = rbac_alloc_req( RBAC_REQ_CREATE_SESSION ); 700 701 if ( !reqp ) { 702 *text = "unable to allocate memory for bac_create_session exop"; 703 return LDAP_PROTOCOL_ERROR; 704 } 705 706 ber_dupbv_x( &reqdata, in, ctx ); 707 708 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ 709 ber_init2( ber, &reqdata, 0 ); 710 711 tag = ber_scanf( ber, "{" /*}*/ ); 712 713 if ( tag == LBER_ERROR ) { 714 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 715 "decoding error.\n" ); 716 goto decoding_error; 717 } 718 719 // Order: 1. sessionId, 2. tenantId, 3. userId, 4. password and 5. roles 720 /* must-have */ 721 tag = ber_peek_tag( ber, &len ); 722 723 // 1. SESSIONID 724 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID ) { 725 struct berval bv; 726 tag = ber_scanf( ber, "m", &bv ); 727 if ( tag == LBER_ERROR ) { 728 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 729 "session id parse failed.\n" ); 730 goto decoding_error; 731 } 732 ber_dupbv_x( &reqp->sessid, &bv, ctx ); 733 tag = ber_peek_tag( ber, &len ); 734 } 735 736 // 2. TENANT ID 737 if ( tag == LDAP_TAG_EXOP_RBAC_TENANT_ID ) { 738 struct berval bv; 739 tag = ber_scanf( ber, "m", &bv ); 740 if ( tag == LBER_ERROR ) { 741 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 742 "tenant id parse failed.\n" ); 743 goto decoding_error; 744 } 745 ber_dupbv_x( &reqp->tenantid, &bv, ctx ); 746 tag = ber_peek_tag( ber, &len ); 747 } 748 749 // 3. USERID 750 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID ) { 751 struct berval bv; 752 tag = ber_scanf( ber, "m", &bv ); 753 if ( tag == LBER_ERROR ) { 754 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 755 "user id parse failed.\n" ); 756 goto decoding_error; 757 } 758 ber_dupbv_x( &reqp->uid, &bv, ctx ); 759 tag = ber_peek_tag( ber, &len ); 760 } 761 762 // 4. PASSWORD 763 if ( tag == LDAP_TAG_EXOP_RBAC_AUTHTOK ) { 764 struct berval bv; 765 tag = ber_scanf( ber, "m", &bv); 766 if ( tag == LBER_ERROR ) { 767 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 768 "authtok parse failed.\n" ); 769 goto decoding_error; 770 } 771 ber_dupbv_x( &reqp->authtok, &bv, ctx ); 772 tag = ber_peek_tag( ber, &len ); 773 } 774 775 // 5. ROLES 776 if ( tag == LDAP_TAG_EXOP_RBAC_ACTIVE_ROLE ) { 777 tag = ber_scanf( ber, "W", &reqp->roles); 778 if ( tag == LBER_ERROR ) { 779 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 780 "role parse failed.\n" ); 781 goto decoding_error; 782 } 783 tag = ber_peek_tag( ber, &len ); 784 } 785 786 if ( tag != LBER_DEFAULT || len != 0 ) { 787decoding_error:; 788 789 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 790 "decoding error, len=%ld\n", 791 (long)len ); 792 rc = LDAP_PROTOCOL_ERROR; 793 *text = "data decoding error"; 794 } 795 796 if ( rc == LDAP_SUCCESS ) { 797 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_create_session: " 798 "SUCCESS\n" ); 799 800 *reqpp = reqp; 801 } else { 802 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_create_session: " 803 "NO SUCCESS RC=%d\n", rc ); 804 805 rbac_free_req( reqp ); 806 *reqpp = NULL; 807 } 808 809 if ( !BER_BVISNULL( &reqdata ) ) { 810 ber_memfree_x( reqdata.bv_val, ctx ); 811 } 812 813 return rc; 814} 815 816/* 817 * rbac_create_session: 818 * 1. authenticate user 819 * 2. evaluate pwd policy 820 * 3. create session 821 */ 822static int 823rbac_create_session( Operation *op, SlapReply *rs ) 824{ 825 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 826 struct berval rbac_op = BER_BVC("CreateSession"); 827 BerElementBuffer berbuf; 828 BerElement *ber = (BerElement *)&berbuf; 829 int rc = LDAP_SUCCESS; 830 rbac_session_t *sessp = NULL; 831 rbac_user_t *userp = NULL; 832 rbac_req_t *reqp = NULL; 833 834 rs->sr_err = slap_parse_rbac_create_session( 835 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 836 837 assert( rs->sr_err == LDAP_SUCCESS ); 838 839 /* read user entry */ 840 userp = rbac_read_user( op, reqp ); 841 if ( !userp ) { 842 Debug( LDAP_DEBUG_ANY, "rbac_create_session: " 843 "unable to read user entry\n" ); 844 rs->sr_err = LDAP_NO_SUCH_OBJECT; 845 rs->sr_text = "rbac_create_session: unable to read user entry"; 846 goto done; 847 } 848 849 if ( !BER_BVISNULL( &userp->password ) ) { 850 /* if request is with pwd, authenticate the user */ 851 rc = rbac_authenticate_user( op, userp ); 852 if ( rc != LDAP_SUCCESS ) { 853 Debug( LDAP_DEBUG_ANY, "rbac_create_session: " 854 "rbac_authenticate_user failed!\n" ); 855 rs->sr_err = LDAP_INVALID_CREDENTIALS; 856 rs->sr_text = "rbac_create_session: invalid credential"; 857 goto done; 858 } 859 /* 860 rbac_user_t *ui = op->o_callback->sc_private; 861 int pVal = ui->authz; 862 printf("password reset val=%d", pVal ); 863*/ 864 865 } else { 866 /* no pwd is provided, check whether the requesting session */ 867 /* id has the access privilege to create a session on behalf */ 868 /* of the user */ 869 rc = rbac_create_session_acl_check( &reqp->sessid, userp ); 870 if ( rc != LDAP_SUCCESS ) { 871 Debug( LDAP_DEBUG_ANY, "rbac_create_session: " 872 "rbac_authenticate_user failed!\n" ); 873 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 874 rs->sr_text = "rbac_create_session: session permission denied"; 875 goto done; 876 } 877 } 878 879 /* check user temporal constraint */ 880 rc = rbac_user_temporal_constraint( userp ); 881 if ( rc != LDAP_SUCCESS ) { 882 Debug( LDAP_DEBUG_ANY, "rbac_create_session: " 883 "rbac_user_temporal_constraint() failed!\n" ); 884 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 885 rs->sr_text = "rbac_create_session: temporal constraint violation"; 886 goto done; 887 } 888 889 sessp = rbac_alloc_session(); 890 if ( !sessp ) { 891 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 892 rs->sr_text = "rbac_create_session: unable to allocate session"; 893 goto done; 894 } 895 896 rc = activate_session_roles( sessp, reqp, userp ); 897 if ( rc != LDAP_SUCCESS ) { 898 Debug( LDAP_DEBUG_ANY, "rbac_create_session: " 899 "failed to activate roles to session!\n" ); 900 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 901 rs->sr_text = 902 "rbac_create_session: failed to activate roles into session"; 903 goto done; 904 } 905 906 /* store uid and tenant id in session */ 907 ber_dupbv( &sessp->userdn, &userp->dn ); 908 ber_dupbv( &sessp->uid, &reqp->uid ); 909 ber_dupbv( &sessp->tenantid, &reqp->tenantid ); 910 911 /* register RBAC session */ 912 rc = rbac_register_session( op, rs, sessp ); 913 if ( rc != LDAP_SUCCESS ) { 914 goto done; 915 } 916 917 ber_init_w_nullc( ber, LBER_USE_DER ); 918 rc = ber_printf( ber, "{tO}", LDAP_TAG_EXOP_RBAC_SESSION_ID, 919 &sessp->sessid ); 920 if ( rc < 0 ) { 921 rs->sr_err = LDAP_OTHER; 922 rs->sr_text = "internal error"; 923 } else { 924 (void)ber_flatten( ber, &rs->sr_rspdata ); 925 rs->sr_rspoid = ch_strdup( slap_EXOP_CREATE_SESSION.bv_val ); 926 rs->sr_err = LDAP_SUCCESS; 927 } 928 929 ber_free_buf( ber ); 930 931done:; 932 933 // always put the OID in the response: 934 rs->sr_rspoid = ch_strdup( slap_EXOP_CREATE_SESSION.bv_val ); 935 /* generate audit log */ 936 rbac_audit( 937 op, CreateSession, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 938 939 rbac_free_req( reqp ); 940 rbac_free_session( sessp ); 941 942 //if (rs->sr_err != LDAP_SUCCESS) { 943 //send_ldap_result( op, rs ); 944 //} 945 946 return rs->sr_err; 947} 948 949/* 950 * slap_parse_rbac_check_access 951 */ 952static int 953slap_parse_rbac_check_access( 954 struct berval *in, 955 rbac_req_t **reqpp, 956 const char **text, 957 void *ctx ) 958{ 959 int rc = LDAP_SUCCESS; 960 struct berval reqdata = BER_BVNULL; 961 rbac_req_t *reqp = NULL; 962 BerElementBuffer berbuf; 963 BerElement *ber = (BerElement *)&berbuf; 964 ber_tag_t tag; 965 ber_len_t len; 966 967 *text = NULL; 968 reqp = rbac_alloc_req( RBAC_REQ_CHECK_ACCESS ); 969 970 if ( !reqp ) { 971 *text = "unable to allocate memory for slap_parse_rbac_check_access"; 972 return LDAP_PROTOCOL_ERROR; 973 } 974 975 if ( in == NULL || in->bv_len == 0 ) { 976 *text = "empty request data field in rbac_check_access exop"; 977 return LDAP_PROTOCOL_ERROR; 978 } 979 980 ber_dupbv_x( &reqdata, in, ctx ); 981 982 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ 983 ber_init2( ber, &reqdata, 0 ); 984 985 tag = ber_scanf( ber, "{" /*}*/ ); 986 987 if ( tag == LBER_ERROR ) { 988 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 989 "decoding error.\n" ); 990 goto decoding_error; 991 } 992 993 // sessionId is required: 994 tag = ber_peek_tag( ber, &len ); 995 if ( tag != LDAP_TAG_EXOP_RBAC_SESSION_ID ) { 996 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 997 "decoding error.\n" ); 998 goto decoding_error; 999 } else { 1000 struct berval bv; 1001 tag = ber_scanf( ber, "m", &bv ); 1002 if ( tag == LBER_ERROR ) { 1003 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1004 "session id parse failed.\n" ); 1005 goto decoding_error; 1006 } 1007 ber_dupbv_x( &reqp->sessid, &bv, ctx ); 1008 tag = ber_peek_tag( ber, &len ); 1009 } 1010 1011 // operationName is required: 1012 if ( tag != LDAP_TAG_EXOP_RBAC_OPNAME ) { 1013 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1014 "decoding error.\n" ); 1015 goto decoding_error; 1016 } else { 1017 struct berval bv; 1018 tag = ber_scanf( ber, "m", &bv ); 1019 if ( tag == LBER_ERROR ) { 1020 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1021 "opname parse failed.\n" ); 1022 goto decoding_error; 1023 } 1024 ber_dupbv_x( &reqp->opname, &bv, ctx ); 1025 tag = ber_peek_tag( ber, &len ); 1026 } 1027 1028 // objectName is required: 1029 if ( tag != LDAP_TAG_EXOP_RBAC_OBJNAME ) { 1030 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1031 "decoding error.\n" ); 1032 goto decoding_error; 1033 } else { 1034 struct berval bv; 1035 tag = ber_scanf( ber, "m", &bv ); 1036 if ( tag == LBER_ERROR ) { 1037 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1038 "objname parse failed.\n" ); 1039 goto decoding_error; 1040 } 1041 ber_dupbv_x( &reqp->objname, &bv, ctx ); 1042 tag = ber_peek_tag( ber, &len ); 1043 } 1044 1045 // objectId is optional: 1046 if ( tag == LDAP_TAG_EXOP_RBAC_OBJID ) { 1047 struct berval bv; 1048 tag = ber_scanf( ber, "m", &bv ); 1049 if ( tag == LBER_ERROR ) { 1050 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1051 "objid parse failed.\n" ); 1052 goto decoding_error; 1053 } 1054 ber_dupbv_x( &reqp->objid, &bv, ctx ); 1055 tag = ber_peek_tag( ber, &len ); 1056 } 1057 1058 if ( tag != LBER_DEFAULT || len != 0 ) { 1059decoding_error:; 1060 1061 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: " 1062 "decoding error, len=%ld\n", 1063 (long)len ); 1064 rc = LDAP_PROTOCOL_ERROR; 1065 *text = "data decoding error"; 1066 } 1067 1068 if ( rc == LDAP_SUCCESS ) { 1069 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_check_access: " 1070 "SUCCESS\n" ); 1071 *reqpp = reqp; 1072 } else { 1073 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_check_access: " 1074 "FAIL\n" ); 1075 rbac_free_req( reqp ); 1076 } 1077 1078 if ( !BER_BVISNULL( &reqdata ) ) { 1079 ber_memfree_x( reqdata.bv_val, ctx ); 1080 } 1081 1082 return rc; 1083} 1084 1085// checkAcess F (ALL) 1086static int 1087rbac_check_access( Operation *op, SlapReply *rs ) 1088{ 1089 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1090 rbac_session_t *sessp = NULL; 1091 rbac_permission_t *permp = NULL; 1092 rbac_constraint_t *cp = NULL; 1093 rbac_req_t *reqp = NULL; 1094 const struct berval rbac_op = BER_BVC("CheckAccess"); 1095 int rc = LDAP_SUCCESS; 1096 int found = 0; 1097 1098 rs->sr_err = slap_parse_rbac_check_access( 1099 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 1100 1101 assert( rs->sr_err == LDAP_SUCCESS ); 1102 1103 BER_BVZERO( &op->o_req_dn ); 1104 BER_BVZERO( &op->o_req_ndn ); 1105 1106 /* get the session using the session id */ 1107 sessp = rbac_session_byid( op, reqp ); 1108 if ( !sessp ) { 1109 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1110 "session not found\n" ); 1111 rc = LDAP_UNWILLING_TO_PERFORM; 1112 goto done; 1113 } 1114 1115 /* read the permission using objectName and OpName */ 1116 permp = rbac_read_permission( op, reqp ); 1117 if ( !permp ) { 1118 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1119 "permission not found\n" ); 1120 rc = LDAP_UNWILLING_TO_PERFORM; 1121 goto done; 1122 } 1123 1124 // Convert the user-role constraint data from BerVarray to rbac_constraint_t format 1125 cp = rbac_user_role_constraints( sessp->role_constraints ); 1126 1127 // Now do the actual rbac checkAccess: 1128 rc = rbac_check_session_permission( sessp, permp, cp ); 1129 1130 if ( rc != LDAP_SUCCESS ) { 1131 Debug( LDAP_DEBUG_ANY, "rbac_check_user_permission: " 1132 "failed\n" ); 1133 rc = LDAP_UNWILLING_TO_PERFORM; 1134 goto done; 1135 } 1136 1137done: 1138 1139 rs->sr_err = rc; 1140 // always put the OID in the response: 1141 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val ); 1142 1143 /* generate audit log */ 1144 rbac_audit( op, CheckAccess, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 1145 1146 rbac_free_permission( permp ); 1147 rbac_free_req( reqp ); 1148 rbac_free_session( sessp ); 1149 rbac_free_constraints( cp ); 1150 1151 return rs->sr_err; 1152} 1153 1154// checkAcess A loop back 1155static int 1156rbac_check_accessA( Operation *op, SlapReply *rs ) 1157{ 1158 int rc = LDAP_SUCCESS; 1159 1160 //rs->sr_err = slap_parse_rbac_check_access(op->ore_reqdata, 1161 // &reqp, &rs->sr_text, NULL); 1162 1163 // always put the OID in the response: 1164 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val ); 1165 rs->sr_err = rc; 1166 1167 return rc; 1168} 1169 1170// checkAcess B parse 1171static int 1172rbac_check_accessB( Operation *op, SlapReply *rs ) 1173{ 1174 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1175 rbac_req_t *reqp = NULL; 1176 const struct berval rbac_op = BER_BVC("CheckAccess"); 1177 int rc = LDAP_SUCCESS; 1178 1179 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" ); 1180 1181 rs->sr_err = slap_parse_rbac_check_access( 1182 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 1183 1184 assert( rs->sr_err == LDAP_SUCCESS ); 1185 1186 BER_BVZERO( &op->o_req_dn ); 1187 BER_BVZERO( &op->o_req_ndn ); 1188 1189 // always put the OID in the response: 1190 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val ); 1191 rs->sr_err = rc; 1192 1193 rbac_free_req( reqp ); 1194 1195 return rc; 1196} 1197 1198// checkAcess C - parse request & read session record 1199static int 1200rbac_check_accessC( Operation *op, SlapReply *rs ) 1201{ 1202 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1203 rbac_session_t *sessp = NULL; 1204 rbac_req_t *reqp = NULL; 1205 const struct berval rbac_op = BER_BVC("CheckAccess"); 1206 int rc = LDAP_SUCCESS; 1207 1208 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" ); 1209 1210 rs->sr_err = slap_parse_rbac_check_access( 1211 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 1212 1213 assert( rs->sr_err == LDAP_SUCCESS ); 1214 1215 BER_BVZERO( &op->o_req_dn ); 1216 BER_BVZERO( &op->o_req_ndn ); 1217 1218 /* get the session using the session id */ 1219 sessp = rbac_session_byid( op, reqp ); 1220 if ( !sessp ) { 1221 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1222 "session not found\n" ); 1223 rc = LDAP_UNWILLING_TO_PERFORM; 1224 goto done; 1225 } 1226 1227done: 1228 1229 // always put the OID in the response: 1230 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val ); 1231 rs->sr_err = rc; 1232 1233 rbac_free_req( reqp ); 1234 rbac_free_session( sessp ); 1235 return rc; 1236} 1237 1238// checkAcess D, parse, read perm 1239static int 1240rbac_check_accessD( Operation *op, SlapReply *rs ) 1241{ 1242 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1243 rbac_permission_t *permp = NULL; 1244 rbac_req_t *reqp = NULL; 1245 const struct berval rbac_op = BER_BVC("CheckAccess"); 1246 int rc = LDAP_SUCCESS; 1247 1248 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" ); 1249 1250 rs->sr_err = slap_parse_rbac_check_access( 1251 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 1252 1253 assert( rs->sr_err == LDAP_SUCCESS ); 1254 1255 BER_BVZERO( &op->o_req_dn ); 1256 BER_BVZERO( &op->o_req_ndn ); 1257 1258 /* get the session using the session id */ 1259 /* 1260 sessp = rbac_session_byid(op, reqp); 1261 if ( !sessp ) { 1262 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1263 "session not found\n" ); 1264 rc = LDAP_UNWILLING_TO_PERFORM; 1265 goto done; 1266 } 1267*/ 1268 1269 /* read the permission using objectName and OpName */ 1270 permp = rbac_read_permission( op, reqp ); 1271 if ( !permp ) { 1272 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1273 "permission not found\n" ); 1274 rc = LDAP_UNWILLING_TO_PERFORM; 1275 goto done; 1276 } 1277 1278done: 1279 1280 // always put the OID in the response: 1281 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val ); 1282 rs->sr_err = rc; 1283 1284 rbac_free_permission( permp ); 1285 rbac_free_req( reqp ); 1286 1287 return rc; 1288} 1289 1290// checkAcess E everything but the audit insert 1291static int 1292rbac_check_accessE( Operation *op, SlapReply *rs ) 1293{ 1294 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1295 rbac_session_t *sessp = NULL; 1296 rbac_permission_t *permp = NULL; 1297 rbac_constraint_t *cp = NULL; 1298 rbac_req_t *reqp = NULL; 1299 const struct berval rbac_op = BER_BVC("CheckAccess"); 1300 int rc = LDAP_SUCCESS; 1301 1302 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" ); 1303 1304 rs->sr_err = slap_parse_rbac_check_access( 1305 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 1306 1307 assert( rs->sr_err == LDAP_SUCCESS ); 1308 1309 BER_BVZERO( &op->o_req_dn ); 1310 BER_BVZERO( &op->o_req_ndn ); 1311 1312 /* get the session using the session id */ 1313 sessp = rbac_session_byid( op, reqp ); 1314 if ( !sessp ) { 1315 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1316 "session not found\n" ); 1317 rc = LDAP_UNWILLING_TO_PERFORM; 1318 goto done; 1319 } 1320 1321 /* read the permission using objectName and OpName */ 1322 permp = rbac_read_permission( op, reqp ); 1323 if ( !permp ) { 1324 Debug( LDAP_DEBUG_ANY, "rbac_check_access: " 1325 "permission not found\n" ); 1326 rc = LDAP_UNWILLING_TO_PERFORM; 1327 goto done; 1328 } 1329 1330 // Convert the user-role constraint data from BerVarray to rbac_constraint_t format 1331 cp = rbac_user_role_constraints( sessp->role_constraints ); 1332 1333 // Now do the actual rbac checkAccess: 1334 rc = rbac_check_session_permission( sessp, permp, cp ); 1335 1336 if ( rc != LDAP_SUCCESS ) { 1337 Debug( LDAP_DEBUG_ANY, "rbac_check_user_permission: " 1338 "failed\n" ); 1339 rc = LDAP_UNWILLING_TO_PERFORM; 1340 goto done; 1341 } 1342 1343done: 1344 1345 rs->sr_err = rc; 1346 // always put the OID in the response: 1347 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val ); 1348 1349 /* generate audit log */ 1350 //rbac_audit(op, CheckAccess, sessp, reqp, rs->sr_err, 1351 // (char *) rs->sr_text); 1352 1353 rbac_free_permission( permp ); 1354 rbac_free_req( reqp ); 1355 rbac_free_session( sessp ); 1356 rbac_free_constraints( cp ); 1357 1358 return rs->sr_err; 1359} 1360 1361/* check whether role exists and role assigned to the user */ 1362static int 1363rbac_check_user_role( 1364 rbac_req_t *reqp, 1365 rbac_session_t *sessp, 1366 rbac_user_t *userp ) 1367{ 1368 int rc = 0; 1369 int i; 1370 1371 //assert(!BER_BVISEMPTY(&reqp->roles[0])); 1372 assert( !BER_BVISEMPTY( &reqp->role ) ); 1373 1374 for ( i = 0; !BER_BVISNULL( &userp->roles[i] ); i++ ) { 1375 //if (!ber_bvstrcasecmp(&userp->roles[i], &reqp->roles[0])) { 1376 if ( !ber_bvstrcasecmp( &userp->roles[i], &reqp->role ) ) { 1377 rc = 1; /* found the match */ 1378 goto done; 1379 } 1380 } 1381 1382done:; 1383 1384 return rc; 1385} 1386 1387/* check whether role exists and role assigned to the session */ 1388static int 1389rbac_check_session_role( rbac_req_t *reqp, rbac_session_t *sessp ) 1390{ 1391 int rc = 0; 1392 int i; 1393 1394 for ( i = 0; !BER_BVISNULL( &sessp->roles[i] ); i++ ) { 1395 //if (!ber_bvstrcasecmp(&sessp->roles[i], &reqp->roles[0])) { 1396 if ( !ber_bvstrcasecmp( &sessp->roles[i], &reqp->role ) ) { 1397 rc = 1; /* found the match */ 1398 goto done; 1399 } 1400 } 1401 1402done:; 1403 1404 return rc; 1405} 1406 1407/* make sure user is the owner of the session */ 1408static int 1409rbac_check_user_session( rbac_session_t *sessp, rbac_req_t *reqp ) 1410{ 1411 int rc = 0; 1412 1413 if ( BER_BVISNULL( &sessp->uid ) || BER_BVISNULL( &reqp->uid ) || 1414 sessp->uid.bv_len != reqp->uid.bv_len ) { 1415 goto done; 1416 } 1417 1418 if ( !strncasecmp( 1419 sessp->uid.bv_val, reqp->uid.bv_val, reqp->uid.bv_len ) ) { 1420 rc = 1; 1421 goto done; 1422 } 1423 1424done:; 1425 1426 return rc; 1427} 1428 1429/* 1430 * slap_parse_rbac_active_role 1431 */ 1432static int 1433slap_parse_rbac_active_role( 1434 struct berval *in, 1435 int add_or_drop_role, 1436 rbac_req_t **reqpp, 1437 const char **text, 1438 void *ctx ) 1439{ 1440 int rc = LDAP_SUCCESS; 1441 struct berval reqdata = BER_BVNULL; 1442 rbac_req_t *reqp = NULL; 1443 BerElementBuffer berbuf; 1444 BerElement *ber = (BerElement *)&berbuf; 1445 ber_tag_t tag; 1446 ber_len_t len = -1; 1447 1448 *text = NULL; 1449 1450 if ( in == NULL || in->bv_len == 0 ) { 1451 *text = "empty request data field in rbac_create_session exop"; 1452 return LDAP_PROTOCOL_ERROR; 1453 } 1454 1455 reqp = rbac_alloc_req( add_or_drop_role ); 1456 1457 if ( !reqp ) { 1458 *text = "unable to allocate memory for rbac_add_drop_active_role exop"; 1459 return LDAP_PROTOCOL_ERROR; 1460 } 1461 1462 ber_dupbv_x( &reqdata, in, ctx ); 1463 1464 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ 1465 ber_init2( ber, &reqdata, 0 ); 1466 1467 tag = ber_scanf( ber, "{" /*}*/ ); 1468 1469 if ( tag == LBER_ERROR ) { 1470 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_active_role: " 1471 "decoding error.\n" ); 1472 goto decoding_error; 1473 } 1474 1475 tag = ber_peek_tag( ber, &len ); 1476 //if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID ) { 1477 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID_SESS ) { 1478 struct berval bv; 1479 tag = ber_scanf( ber, "m", &bv ); 1480 if ( tag == LBER_ERROR ) { 1481 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_active_role: " 1482 "user id parse failed.\n" ); 1483 goto decoding_error; 1484 } 1485 ber_dupbv( &reqp->uid, &bv ); 1486 tag = ber_peek_tag( ber, &len ); 1487 } 1488 1489 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ) { 1490 struct berval bv; 1491 tag = ber_scanf( ber, "m", &bv ); 1492 if ( tag == LBER_ERROR ) { 1493 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_active_role: " 1494 "session id parse failed.\n" ); 1495 goto decoding_error; 1496 } 1497 ber_dupbv( &reqp->sessid, &bv ); 1498 tag = ber_peek_tag( ber, &len ); 1499 } 1500 1501 if ( tag == LDAP_TAG_EXOP_RBAC_ROLE_NM_SESS ) { 1502 struct berval bv; 1503 tag = ber_scanf( ber, "m", &bv ); 1504 //tag = ber_scanf( ber, "W", &reqp->roles); 1505 //tag = ber_scanf( ber, "m", &reqp->roles); 1506 //tag = ber_scanf( ber, "m", &reqp->roles[0]); 1507 if ( tag == LBER_ERROR ) { 1508 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 1509 "role parse failed.\n" ); 1510 goto decoding_error; 1511 } 1512 ber_dupbv( &reqp->role, &bv ); 1513 //ber_dupbv(&reqp->roles[0], &bv); 1514 tag = ber_peek_tag( ber, &len ); 1515 } 1516 1517 if ( tag != LBER_DEFAULT || len != 0 ) { 1518decoding_error:; 1519 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: " 1520 "decoding error, len=%ld\n", 1521 (long)len ); 1522 rc = LDAP_PROTOCOL_ERROR; 1523 *text = "data decoding error"; 1524 } 1525 1526 if ( rc == LDAP_SUCCESS ) { 1527 *reqpp = reqp; 1528 } else { 1529 rbac_free_req( reqp ); 1530 *reqpp = NULL; 1531 } 1532 1533 if ( !BER_BVISNULL( &reqdata ) ) { 1534 ber_memfree_x( reqdata.bv_val, ctx ); 1535 } 1536 1537 return rc; 1538} 1539 1540static int 1541rbac_add_active_role( Operation *op, SlapReply *rs ) 1542{ 1543 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1544 struct berval rbac_op = BER_BVC("AddActiveRole"); 1545 rbac_req_t *reqp = NULL; 1546 rbac_user_t *userp = NULL; 1547 rbac_session_t *sessp; 1548 int rc = LDAP_SUCCESS; 1549 1550 rs->sr_err = slap_parse_rbac_active_role( op->ore_reqdata, 1551 RBAC_REQ_ADD_ACTIVE_ROLE, &reqp, &rs->sr_text, NULL ); 1552 1553 assert( rs->sr_err == LDAP_SUCCESS ); 1554 1555 /* get the session using the session id */ 1556 sessp = rbac_session_byid( op, reqp ); 1557 if ( !sessp ) { 1558 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: " 1559 "session not found\n" ); 1560 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1561 rs->sr_text = "rbac_add_active_role: session not found"; 1562 goto done; 1563 } 1564 1565 /* read user entry */ 1566 userp = rbac_read_user( op, reqp ); 1567 if ( !userp ) { 1568 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: " 1569 "unable to read user entry\n" ); 1570 rs->sr_err = LDAP_NO_SUCH_OBJECT; 1571 rs->sr_text = "rbac_add_active_role: unable to read user entry"; 1572 goto done; 1573 } 1574 1575 /* make sure role exists and role assigned to the user */ 1576 if ( !rbac_check_user_role( reqp, sessp, userp ) ) { 1577 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: " 1578 "role not assigned to the user\n" ); 1579 rs->sr_err = LDAP_NO_SUCH_OBJECT; 1580 rs->sr_text = "rbac_add_active_role: role not assigned to the user"; 1581 goto done; 1582 } 1583 1584 /* make sure user is the owner of the session */ 1585 if ( !rbac_check_user_session( sessp, reqp ) ) { 1586 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: " 1587 "user not owner of session\n" ); 1588 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1589 rs->sr_text = "rbac_add_active_role: user not owner of the session"; 1590 goto done; 1591 } 1592 1593 /* add the role to the session */ 1594 rc = rbac_session_add_role( op, sessp, reqp ); 1595 if ( rc != LDAP_SUCCESS ) { 1596 rs->sr_err = rc; 1597 if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) { 1598 rs->sr_text = 1599 "rbac_add_active_role: role already activated in session"; 1600 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: " 1601 "role already activated in session\n" ); 1602 } else { 1603 rs->sr_text = "rbac_add_active_role: unable to add role to session"; 1604 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: " 1605 "unable to add role to session\n" ); 1606 } 1607 goto done; 1608 } 1609 1610done: 1611 1612 // always put the OID in the response: 1613 rs->sr_rspoid = ch_strdup( slap_EXOP_ADD_ACTIVE_ROLE.bv_val ); 1614 1615 /* generate audit log */ 1616 rbac_audit( 1617 op, AddActiveRole, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 1618 1619 rbac_free_session( sessp ); 1620 rbac_free_user( userp ); 1621 rbac_free_req( reqp ); 1622 1623 return rs->sr_err; 1624} 1625 1626static int 1627rbac_drop_active_role( Operation *op, SlapReply *rs ) 1628{ 1629 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1630 const struct berval rbac_op = BER_BVC("DropActiveRole"); 1631 rbac_session_t *sessp; 1632 rbac_req_t *reqp = NULL; 1633 int rc = LDAP_SUCCESS; 1634 1635 rs->sr_err = slap_parse_rbac_active_role( op->ore_reqdata, 1636 RBAC_REQ_DROP_ACTIVE_ROLE, &reqp, &rs->sr_text, NULL ); 1637 1638 assert( rs->sr_err == LDAP_SUCCESS ); 1639 1640 /* get the session using the session id */ 1641 sessp = rbac_session_byid( op, reqp ); 1642 if ( !sessp ) { 1643 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: " 1644 "session not found\n" ); 1645 rc = LDAP_UNWILLING_TO_PERFORM; 1646 goto done; 1647 } 1648 1649 if ( BER_BVISNULL( &reqp->role ) || !sessp->roles || 1650 BER_BVISNULL( &sessp->roles[0] ) ) { 1651 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: " 1652 "unavailable role\n" ); 1653 rc = LDAP_UNWILLING_TO_PERFORM; 1654 goto done; 1655 } 1656 1657 /* make sure role exists and role assigned to the user */ 1658 if ( !rbac_check_session_role( reqp, sessp ) ) { 1659 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: " 1660 "role not assigned to session\n" ); 1661 rc = LDAP_UNWILLING_TO_PERFORM; 1662 goto done; 1663 } 1664 1665 /* make sure user is the owner of the session */ 1666 if ( !rbac_check_user_session( sessp, reqp ) ) { 1667 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: " 1668 "user not owner of session\n" ); 1669 rc = LDAP_UNWILLING_TO_PERFORM; 1670 rs->sr_text = "rbac_drop_active_role: user not owner of the session"; 1671 goto done; 1672 } 1673 1674 /* drop the role to the session */ 1675 rc = rbac_session_drop_role( op, sessp, reqp ); 1676 if ( rc != LDAP_SUCCESS ) { 1677 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: " 1678 "unable to drop active role from session\n" ); 1679 rc = LDAP_UNWILLING_TO_PERFORM; 1680 rs->sr_text = "rbac_drop_active_role: unable to drop role from session"; 1681 goto done; 1682 } 1683 1684done: 1685 rs->sr_err = rc; 1686 1687 // always put the OID in the response: 1688 rs->sr_rspoid = ch_strdup( slap_EXOP_DROP_ACTIVE_ROLE.bv_val ); 1689 1690 /* generate audit log */ 1691 rbac_audit( 1692 op, DropActiveRole, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 1693 1694 rbac_free_session( sessp ); 1695 rbac_free_req( reqp ); 1696 1697 return rs->sr_err; 1698} 1699 1700/* 1701 * slap_parse_rbac_delete_session 1702 */ 1703static int 1704slap_parse_rbac_delete_session( 1705 struct berval *in, 1706 rbac_req_t **reqpp, 1707 const char **text, 1708 void *ctx ) 1709{ 1710 int rc = LDAP_SUCCESS; 1711 struct berval reqdata = BER_BVNULL; 1712 rbac_req_t *reqp = NULL; 1713 BerElementBuffer berbuf; 1714 BerElement *ber = (BerElement *)&berbuf; 1715 ber_tag_t tag; 1716 ber_len_t len = -1; 1717 1718 *text = NULL; 1719 1720 if ( in == NULL || in->bv_len == 0 ) { 1721 *text = "empty request data field in rbac_delete_session exop"; 1722 return LDAP_PROTOCOL_ERROR; 1723 } 1724 1725 reqp = rbac_alloc_req( RBAC_REQ_DELETE_SESSION ); 1726 1727 if ( !reqp ) { 1728 *text = "unable to allocate memory for rbac_delete_session exop"; 1729 return LDAP_PROTOCOL_ERROR; 1730 } 1731 1732 ber_dupbv_x( &reqdata, in, ctx ); 1733 1734 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ 1735 ber_init2( ber, &reqdata, 0 ); 1736 1737 tag = ber_scanf( ber, "{" /*}*/ ); 1738 1739 if ( tag == LBER_ERROR ) { 1740 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: " 1741 "decoding error.\n" ); 1742 goto decoding_error; 1743 } 1744 1745 tag = ber_peek_tag( ber, &len ); 1746 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID_SESS ) { 1747 struct berval uid; 1748 tag = ber_scanf( ber, "m", &uid ); 1749 if ( tag == LBER_ERROR ) { 1750 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: " 1751 "user id parse failed.\n" ); 1752 goto decoding_error; 1753 } 1754 ber_dupbv_x( &reqp->uid, &uid, ctx ); 1755 tag = ber_peek_tag( ber, &len ); 1756 } 1757 1758 //tag = ber_peek_tag( ber, &len ); 1759 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ) { 1760 struct berval sessid; 1761 tag = ber_scanf( ber, "m", &sessid ); 1762 if ( tag == LBER_ERROR ) { 1763 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: " 1764 "session id parse failed.\n" ); 1765 goto decoding_error; 1766 } 1767 ber_dupbv_x( &reqp->sessid, &sessid, ctx ); 1768 tag = ber_peek_tag( ber, &len ); 1769 } 1770 1771 if ( tag != LBER_DEFAULT || len != 0 ) { 1772decoding_error:; 1773 1774 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: " 1775 "decoding error, len=%ld\n", 1776 (long)len ); 1777 rc = LDAP_PROTOCOL_ERROR; 1778 *text = "data decoding error"; 1779 } 1780 1781 if ( rc == LDAP_SUCCESS ) { 1782 *reqpp = reqp; 1783 } else { 1784 rbac_free_req( reqp ); 1785 *reqpp = NULL; 1786 } 1787 1788 if ( !BER_BVISNULL( &reqdata ) ) { 1789 ber_memfree_x( reqdata.bv_val, ctx ); 1790 } 1791 1792 return rc; 1793} 1794 1795static int 1796rbac_delete_session( Operation *op, SlapReply *rs ) 1797{ 1798 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1799 const struct berval rbac_op = BER_BVC("DeleteSession"); 1800 rbac_session_t *sessp = NULL; 1801 rbac_req_t *reqp = NULL; 1802 int rc; 1803 1804 rs->sr_err = slap_parse_rbac_delete_session( 1805 op->ore_reqdata, &reqp, &rs->sr_text, NULL ); 1806 1807 assert( rs->sr_err == LDAP_SUCCESS ); 1808 1809 /* get the session using the session id */ 1810 sessp = rbac_session_byid( op, reqp ); 1811 if ( !sessp ) { 1812 Debug( LDAP_DEBUG_ANY, "rbac_delete_session: " 1813 "session not found\n" ); 1814 rc = LDAP_UNWILLING_TO_PERFORM; 1815 goto done; 1816 } 1817 1818 /* checking whether the session is owned by the user */ 1819 if ( !rbac_is_session_owner( sessp, reqp ) ) { 1820 Debug( LDAP_DEBUG_ANY, "rbac_delete_session: " 1821 "session not owned by user\n" ); 1822 rc = LDAP_UNWILLING_TO_PERFORM; 1823 goto done; 1824 } 1825 1826 rc = rbac_int_delete_session( op, sessp ); 1827 if ( rc != LDAP_SUCCESS ) { 1828 Debug( LDAP_DEBUG_ANY, "rbac_int_delete_session: " 1829 "unable to delete session\n" ); 1830 rc = LDAP_UNWILLING_TO_PERFORM; 1831 goto done; 1832 } 1833 1834done:; 1835 1836 rs->sr_err = rc; 1837 1838 // always put the OID in the response: 1839 rs->sr_rspoid = ch_strdup( slap_EXOP_DELETE_SESSION.bv_val ); 1840 1841 /* generate audit log */ 1842 rbac_audit( 1843 op, DeleteSession, sessp, reqp, rs->sr_err, (char *)rs->sr_text ); 1844 1845 rbac_free_session( sessp ); 1846 rbac_free_req( reqp ); 1847 1848 return rs->sr_err; 1849} 1850 1851/* returns the permissions associated with a session */ 1852static int 1853rbac_session_permissions( Operation *op, SlapReply *rs, rbac_req_t *reqp ) 1854{ 1855 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1856 const struct berval rbac_op = BER_BVC("SessionPermissions"); 1857 rbac_session_t *sessp; 1858 1859 sessp = rbac_session_byid( op, reqp ); 1860 if ( !sessp ) { 1861 Debug( LDAP_DEBUG_ANY, "rbac_session_permissions: " 1862 "session id not found\n" ); 1863 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1864 goto done; 1865 } 1866 1867 rs->sr_err = rbac_int_session_permissions( op, rs, reqp, sessp ); 1868 if ( rs->sr_err != LDAP_SUCCESS ) { 1869 Debug( LDAP_DEBUG_ANY, "rbac_session_permissions: " 1870 "permissions not found\n" ); 1871 goto done; 1872 } 1873 1874done:; 1875 return rs->sr_err; 1876} 1877 1878/* extract session permission info from op */ 1879int 1880rbac_search_parse_session_permissions_req( 1881 Operation *op, 1882 rbac_req_t **reqpp, 1883 const char **text, 1884 void *ctx ) 1885{ 1886 int rc = LDAP_SUCCESS; 1887 struct berval *sessid = NULL; 1888 rbac_req_t *reqp = NULL; 1889 *text = NULL; 1890 struct berval rbac_session_id = BER_BVC("sessionID"); 1891 struct berval rbac_session_permissions_attr = 1892 BER_BVC("sessionPermissions"); 1893 AttributeDescription *ad = NULL; 1894 Filter *f; 1895 1896 /* check simple assertion (sessionID=<session id>) */ 1897 f = op->ors_filter; 1898 ad = f->f_ava->aa_desc; 1899 if ( !ad || ber_bvstrcasecmp( &rbac_session_id, &ad->ad_cname ) ) { 1900 goto done; 1901 } 1902 sessid = &f->f_ava->aa_value; 1903 1904 if ( !rbac_is_valid_session_id( sessid ) ) { 1905 Debug( LDAP_DEBUG_ANY, "rbac_search_parse_session_permissions_req: " 1906 "invalid session id\n" ); 1907 rc = LDAP_UNWILLING_TO_PERFORM; 1908 goto done; 1909 } 1910 1911 /* check requested attr */ 1912 1913 if ( !op->oq_search.rs_attrs || 1914 BER_BVISNULL( &op->oq_search.rs_attrs[0].an_name ) || 1915 ber_bvstrcasecmp( &op->oq_search.rs_attrs[0].an_name, 1916 &rbac_session_permissions_attr ) || 1917 !BER_BVISNULL( &op->oq_search.rs_attrs[1].an_name ) ) { 1918 Debug( LDAP_DEBUG_ANY, "rbac_search_parse_session_permissions_req: " 1919 "only sessionPermissions allowed\n" ); 1920 rc = LDAP_UNWILLING_TO_PERFORM; 1921 goto done; 1922 } 1923 1924 reqp = rbac_alloc_req( RBAC_REQ_SESSION_PERMISSIONS ); 1925 if ( !reqp ) { 1926 *text = "unable to allocate memory for rbac_session_permissions req"; 1927 rc = LDAP_UNWILLING_TO_PERFORM; 1928 goto done; 1929 } 1930 1931 /* retrieve session id from search filter */ 1932 ber_dupbv_x( &reqp->sessid, sessid, ctx ); 1933 1934done:; 1935 1936 if ( rc == LDAP_SUCCESS ) { 1937 *reqpp = reqp; 1938 } else { 1939 rbac_free_req( reqp ); 1940 *reqpp = NULL; 1941 } 1942 1943 return rc; 1944} 1945 1946static int 1947rbac_search( Operation *op, SlapReply *rs ) 1948{ 1949 Debug( LDAP_DEBUG_ANY, "rbac_search entry\n" ); 1950 1951 return SLAP_CB_CONTINUE; 1952} 1953 1954/* 1955static int 1956rbac_search( Operation *op, SlapReply *rs ) 1957{ 1958 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 1959 rbac_req_t *reqp = NULL; 1960 int rc = SLAP_CB_CONTINUE; 1961 1962 only session_permissions is implemented for now 1963 rc = rbac_search_parse_session_permissions_req( 1964 op, &reqp, &rs->sr_text, NULL ); 1965 if ( !reqp ) { 1966 Debug( LDAP_DEBUG_ANY, "rbac_search: " 1967 "invalid search for session permissions\n" ); 1968 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1969 goto done; 1970 } 1971 1972 rc = rbac_session_permissions( op, rs, reqp ); 1973 if ( rc != LDAP_SUCCESS ) { 1974 Debug( LDAP_DEBUG_ANY, "rbac_search: " 1975 "session permissions failed\n" ); 1976 rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 1977 goto done; 1978 } 1979 1980 rs->sr_err = LDAP_SUCCESS; 1981 1982done:; 1983 send_ldap_result( op, rs ); 1984 1985 return rc; 1986} 1987*/ 1988 1989static struct exop { 1990 struct berval oid; 1991 BI_op_extended *extended; 1992} rbac_exop_table[] = { 1993 { BER_BVC(LDAP_RBAC_EXOP_CREATE_SESSION), rbac_create_session }, 1994 { BER_BVC(LDAP_RBAC_EXOP_CHECK_ACCESS), rbac_check_access }, 1995 { BER_BVC(LDAP_RBAC_EXOP_ADD_ACTIVE_ROLE), rbac_add_active_role }, 1996 { BER_BVC(LDAP_RBAC_EXOP_DROP_ACTIVE_ROLE), rbac_drop_active_role }, 1997 { BER_BVC(LDAP_RBAC_EXOP_DELETE_SESSION), rbac_delete_session }, 1998 { BER_BVC(LDAP_RBAC_EXOP_SESSION_ROLES), rbac_session_roles }, 1999 2000 { BER_BVNULL, NULL } 2001}; 2002 2003static int 2004rbac_add( Operation *op, SlapReply *rs ) 2005{ 2006 return SLAP_CB_CONTINUE; 2007} 2008 2009static int 2010rbac_bind( Operation *op, SlapReply *rs ) 2011{ 2012 return SLAP_CB_CONTINUE; 2013} 2014 2015static int 2016rbac_compare( Operation *op, SlapReply *rs ) 2017{ 2018 return SLAP_CB_CONTINUE; 2019} 2020 2021static int 2022rbac_delete( Operation *op, SlapReply *rs ) 2023{ 2024 return SLAP_CB_CONTINUE; 2025} 2026 2027static int 2028rbac_modify( Operation *op, SlapReply *rs ) 2029{ 2030 return SLAP_CB_CONTINUE; 2031} 2032 2033static int 2034rbac_extended( Operation *op, SlapReply *rs ) 2035{ 2036 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; 2037 int rc = SLAP_CB_CONTINUE; 2038 int i; 2039 2040 for ( i = 0; rbac_exop_table[i].extended != NULL; i++ ) { 2041 if ( bvmatch( &rbac_exop_table[i].oid, &op->oq_extended.rs_reqoid ) ) { 2042 rc = rbac_exop_table[i].extended( op, rs ); 2043 switch ( rc ) { 2044 case LDAP_SUCCESS: 2045 break; 2046 case SLAP_CB_CONTINUE: 2047 case SLAPD_ABANDON: 2048 return rc; 2049 default: 2050 send_ldap_result( op, rs ); 2051 return rc; 2052 } 2053 break; 2054 } 2055 } 2056 2057 return rc; 2058} 2059 2060static int 2061rbac_db_init( BackendDB *be, ConfigReply *cr ) 2062{ 2063 slap_overinst *on = (slap_overinst *)be->bd_info; 2064 2065 return 0; 2066} 2067 2068static int 2069rbac_db_open( BackendDB *be, ConfigReply *cr ) 2070{ 2071 int rc = LDAP_SUCCESS; 2072 2073 rc = rbac_initialize_tenants( be, cr ); 2074 2075 return rc; 2076} 2077 2078static int 2079rbac_db_close( BackendDB *be, ConfigReply *cr ) 2080{ 2081 return 0; 2082} 2083 2084int 2085rbac_initialize() 2086{ 2087 int rc; 2088 2089 rc = load_extop2( (struct berval *)&slap_EXOP_CREATE_SESSION, 2090 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_create_session, 0 ); 2091 if ( rc != LDAP_SUCCESS ) { 2092 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 2093 "unable to register rbac_create_session exop: %d\n", 2094 rc ); 2095 return rc; 2096 } 2097 2098 rc = load_extop2( (struct berval *)&slap_EXOP_CHECK_ACCESS, 2099 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_check_access, 0 ); 2100 if ( rc != LDAP_SUCCESS ) { 2101 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 2102 "unable to register rbac_check_access exop: %d\n", 2103 rc ); 2104 return rc; 2105 } 2106 2107 rc = load_extop2( (struct berval *)&slap_EXOP_ADD_ACTIVE_ROLE, 2108 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_add_active_role, 0 ); 2109 if ( rc != LDAP_SUCCESS ) { 2110 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 2111 "unable to register rbac_add_active_role exop: %d\n", 2112 rc ); 2113 return rc; 2114 } 2115 2116 rc = load_extop2( (struct berval *)&slap_EXOP_DROP_ACTIVE_ROLE, 2117 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_drop_active_role, 0 ); 2118 if ( rc != LDAP_SUCCESS ) { 2119 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 2120 "unable to register rbac_drop_active_role exop: %d\n", 2121 rc ); 2122 return rc; 2123 } 2124 2125 rc = load_extop2( (struct berval *)&slap_EXOP_DELETE_SESSION, 2126 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_delete_session, 0 ); 2127 if ( rc != LDAP_SUCCESS ) { 2128 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 2129 "unable to register rbac_delete_session exop: %d\n", 2130 rc ); 2131 return rc; 2132 } 2133 2134 rc = load_extop2( (struct berval *)&slap_EXOP_SESSION_ROLES, 2135 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_session_roles, 0 ); 2136 if ( rc != LDAP_SUCCESS ) { 2137 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 2138 "unable to register rbac_session_roles exop: %d\n", 2139 rc ); 2140 return rc; 2141 } 2142 2143 rbac.on_bi.bi_type = "rbac"; 2144 rbac.on_bi.bi_db_init = rbac_db_init; 2145 rbac.on_bi.bi_db_open = rbac_db_open; 2146 rbac.on_bi.bi_db_close = rbac_db_close; 2147 2148 rbac.on_bi.bi_op_add = rbac_add; 2149 rbac.on_bi.bi_op_bind = rbac_bind; 2150 rbac.on_bi.bi_op_compare = rbac_compare; 2151 rbac.on_bi.bi_op_delete = rbac_delete; 2152 rbac.on_bi.bi_op_modify = rbac_modify; 2153 rbac.on_bi.bi_op_search = rbac_search; 2154 rbac.on_bi.bi_extended = rbac_extended; 2155 rbac.on_bi.bi_cf_ocs = rbac_ocs; 2156 2157 /* rbac.on_bi.bi_connection_destroy = rbac_connection_destroy; */ 2158 2159 rc = config_register_schema( rbaccfg, rbac_ocs ); 2160 if ( rc ) return rc; 2161 2162 rc = rbac_initialize_repository(); 2163 if ( rc != LDAP_SUCCESS ) { 2164 return rc; 2165 } 2166 2167 return overlay_register( &rbac ); 2168} 2169 2170int 2171init_module( int argc, char *argv[] ) 2172{ 2173 return rbac_initialize(); 2174} 2175