/* init.c - RBAC initialization */ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * . */ /* ACKNOWLEDGEMENTS: */ #include "portable.h" #include #include #include "slap.h" #include "slap-config.h" #include "lutil.h" #include "rbac.h" static slap_callback nullsc = { NULL, NULL, NULL, NULL }; struct slap_rbac_internal_schema slap_rbac_schema; extern rbac_tenant_t rbac_tenants; extern int initialize_jts( void ); rbac_ad_t rbac_session_ads[] = { { RBAC_SESSION_ID, BER_BVC("rbacSessid"), &slap_rbac_schema.ad_session_id }, { RBAC_USER_DN, BER_BVC("rbacUserDN"), &slap_rbac_schema.ad_session_user_dn }, { RBAC_ROLES, BER_BVC("rbacRoles"), &slap_rbac_schema.ad_session_roles }, { RBAC_ROLE_CONSTRAINTS, BER_BVC("rbacRoleConstraints"), &slap_rbac_schema.ad_session_role_constraints }, { RBAC_UID, BER_BVC("uid"), &slap_rbac_schema.ad_uid}, { RBAC_TENANT_ID, BER_BVC("tenantid"), &slap_rbac_schema.ad_tenant_id }, { RBAC_NONE, BER_BVNULL, NULL } }; rbac_ad_t rbac_session_permission_ads[] = { { RBAC_OP_NAME, BER_BVC("rbacOpName"), &slap_rbac_schema.ad_permission_opname }, { RBAC_OBJ_NAME, BER_BVC("rbacObjName"), &slap_rbac_schema.ad_permission_objname }, { RBAC_ROLE_NAME, BER_BVC("rbacRoleName"), &slap_rbac_schema.ad_permission_rolename }, { RBAC_NONE, BER_BVNULL, NULL } }; rbac_ad_t audit_ads[] = { { RBAC_AUDIT_OP, BER_BVC("rbacAuditOp"), &slap_rbac_schema.ad_audit_op }, { RBAC_AUDIT_ID, BER_BVC("rbacAuditId"), &slap_rbac_schema.ad_audit_id }, { RBAC_AUDIT_ROLES, BER_BVC("rbacAuditRoles"), &slap_rbac_schema.ad_audit_roles }, { RBAC_AUDIT_REQUESTED_ROLES, BER_BVC("rbacAuditRequestedRoles"), &slap_rbac_schema.ad_audit_requested_roles }, { RBAC_AUDIT_TIMESTAMP, BER_BVC("rbacAuditTimestamp"), &slap_rbac_schema.ad_audit_timestamp }, { RBAC_AUDIT_RESOURCES, BER_BVC("rbacAuditResources"), &slap_rbac_schema.ad_audit_resources }, { RBAC_AUDIT_OBJS, BER_BVC("rbacAuditObjects"), &slap_rbac_schema.ad_audit_objects }, { RBAC_AUDIT_OPS, BER_BVC("rbacAuditOperations"), &slap_rbac_schema.ad_audit_operations }, { RBAC_AUDIT_RESULT, BER_BVC("rbacAuditResult"), &slap_rbac_schema.ad_audit_result }, { RBAC_AUDIT_PROPERTIES, BER_BVC("rbacAuditProperties"), &slap_rbac_schema.ad_audit_properties }, { RBAC_AUDIT_MSGS, BER_BVC("rbacAuditMessages"), &slap_rbac_schema.ad_audit_messages }, { RBAC_NONE, BER_BVNULL, NULL } }; /* initialize repository attribute descriptions */ static int initialize_sessions() { int i, nattrs, rc = LDAP_SUCCESS; const char *text; for ( nattrs = 0; !BER_BVISNULL( &rbac_session_ads[nattrs].attr ); nattrs++ ) ; /* count the number of attrs */ slap_rbac_schema.session_attrs = slap_sl_calloc( sizeof(AttributeName), nattrs + 1, NULL ); for ( i = 0; !BER_BVISNULL( &rbac_session_ads[i].attr ); i++ ) { rc = slap_bv2ad( &rbac_session_ads[i].attr, rbac_session_ads[i].ad, &text ); if ( rc != LDAP_SUCCESS ) { goto done; } slap_rbac_schema.session_attrs[i].an_name = rbac_session_ads[i].attr; slap_rbac_schema.session_attrs[i].an_desc = *rbac_session_ads[i].ad; } BER_BVZERO( &slap_rbac_schema.session_attrs[nattrs].an_name ); done:; return rc; } static int initialize_audit() { int i, rc = LDAP_SUCCESS; const char *text; /* for audit */ for ( i = 0; !BER_BVISNULL( &audit_ads[i].attr ); i++ ) { rc = slap_bv2ad( &audit_ads[i].attr, audit_ads[i].ad, &text ); if ( rc != LDAP_SUCCESS ) { goto done; } } done:; return rc; } static int initialize_tenant( BackendDB *be, ConfigReply *cr, tenant_info_t *tenantp, int init_op ) { int rc = LDAP_SUCCESS; Entry *e = NULL; OperationBuffer opbuf; Operation *op2; SlapReply rs2 = { REP_RESULT }; Connection conn = { 0 }; struct berval rbac_container_oc = BER_BVC("rbacContainer"); struct berval rbac_audit_container = BER_BVC("audit"); struct berval rbac_session_container = BER_BVC("rbac"); void *thrctx = ldap_pvt_thread_pool_context(); e = entry_alloc(); switch ( init_op ) { case INIT_AUDIT_CONTAINER: ber_dupbv( &e->e_name, &tenantp->audit_basedn ); ber_dupbv( &e->e_nname, &tenantp->audit_basedn ); /* container cn */ attr_merge_one( e, slap_schema.si_ad_cn, &rbac_audit_container, NULL ); break; case INIT_SESSION_CONTAINER: ber_dupbv( &e->e_name, &tenantp->sessions_basedn ); ber_dupbv( &e->e_nname, &tenantp->sessions_basedn ); /* rendered dynmaicObject for session */ attr_merge_one( e, slap_schema.si_ad_objectClass, &slap_schema.si_oc_dynamicObject->soc_cname, NULL ); /* container cn */ attr_merge_one( e, slap_schema.si_ad_cn, &rbac_session_container, NULL ); break; default: break; } attr_merge_one( e, slap_schema.si_ad_objectClass, &rbac_container_oc, NULL ); attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, &rbac_container_oc, NULL ); /* store RBAC session */ connection_fake_init2( &conn, &opbuf, thrctx, 0 ); op2 = &opbuf.ob_op; op2->o_callback = &nullsc; op2->o_tag = LDAP_REQ_ADD; op2->o_protocol = LDAP_VERSION3; op2->o_req_dn = e->e_name; op2->o_req_ndn = e->e_nname; op2->ora_e = e; op2->o_bd = select_backend( &op2->o_req_ndn, 0 ); op2->o_dn = op2->o_bd->be_rootdn; op2->o_ndn = op2->o_bd->be_rootndn; rc = op2->o_bd->be_add( op2, &rs2 ); if ( e ) entry_free( e ); return rc; } int rbac_initialize_tenants( BackendDB *be, ConfigReply *cr ) { int rc = LDAP_SUCCESS; rbac_tenant_t *tenantp = NULL; for ( tenantp = &rbac_tenants; tenantp; tenantp = tenantp->next ) { rc = initialize_tenant( be, cr, &tenantp->tenant_info, INIT_AUDIT_CONTAINER ); if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_ALREADY_EXISTS ) { Debug( LDAP_DEBUG_ANY, "rbac_initialize: " "audit container exists, tenant (%s)\n", tenantp->tenant_info.tid.bv_val ? tenantp->tenant_info.tid.bv_val : "NULL" ); rc = LDAP_SUCCESS; } else { Debug( LDAP_DEBUG_ANY, "rbac_initialize: " "failed to initialize (%s): rc (%d)\n", tenantp->tenant_info.tid.bv_val ? tenantp->tenant_info.tid.bv_val : "NULL", rc ); goto done; } } else { Debug( LDAP_DEBUG_ANY, "rbac_initialize: " "created audit container for tenant (%s):\n", tenantp->tenant_info.tid.bv_val ? tenantp->tenant_info.tid.bv_val : "NULL" ); } rc = initialize_tenant( be, cr, &tenantp->tenant_info, INIT_SESSION_CONTAINER ); if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_ALREADY_EXISTS ) { Debug( LDAP_DEBUG_ANY, "rbac_initialize: " "session container exists, tenant (%s)\n", tenantp->tenant_info.tid.bv_val ? tenantp->tenant_info.tid.bv_val : "NULL" ); rc = LDAP_SUCCESS; } else { Debug( LDAP_DEBUG_ANY, "rbac_initialize: " "failed to initialize (%s): rc (%d)\n", tenantp->tenant_info.tid.bv_val ? tenantp->tenant_info.tid.bv_val : "NULL", rc ); goto done; } } else { Debug( LDAP_DEBUG_ANY, "rbac_initialize: " "created session container for tenant (%s):\n", tenantp->tenant_info.tid.bv_val ? tenantp->tenant_info.tid.bv_val : "NULL" ); } } done:; return rc; } static int initialize_rbac_session_permissions() { int i, rc = LDAP_SUCCESS; const char *text; for ( i = 0; !BER_BVISNULL( &rbac_session_permission_ads[i].attr ); i++ ) { rc = slap_bv2ad( &rbac_session_permission_ads[i].attr, rbac_session_permission_ads[i].ad, &text ); if ( rc != LDAP_SUCCESS ) { goto done; } } done:; return rc; } int rbac_initialize_repository() { int rc = LDAP_SUCCESS; rc = initialize_jts(); if ( rc != LDAP_SUCCESS ) { return rc; } rc = initialize_rbac_session_permissions(); if ( rc != LDAP_SUCCESS ) { return rc; } rc = initialize_sessions(); if ( rc != LDAP_SUCCESS ) { return rc; } rc = initialize_audit(); if ( rc != LDAP_SUCCESS ) { return rc; } return rc; }