1/* $NetBSD: init.c,v 1.2 2021/08/14 16:14:53 christos Exp $ */ 2 3/* init.c - RBAC initialization */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * 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: init.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 36static slap_callback nullsc = { NULL, NULL, NULL, NULL }; 37 38struct slap_rbac_internal_schema slap_rbac_schema; 39 40extern rbac_tenant_t rbac_tenants; 41extern int initialize_jts( void ); 42 43rbac_ad_t rbac_session_ads[] = { 44 { RBAC_SESSION_ID, 45 BER_BVC("rbacSessid"), &slap_rbac_schema.ad_session_id }, 46 { RBAC_USER_DN, 47 BER_BVC("rbacUserDN"), &slap_rbac_schema.ad_session_user_dn }, 48 { RBAC_ROLES, 49 BER_BVC("rbacRoles"), &slap_rbac_schema.ad_session_roles }, 50 { RBAC_ROLE_CONSTRAINTS, 51 BER_BVC("rbacRoleConstraints"), 52 &slap_rbac_schema.ad_session_role_constraints }, 53 { RBAC_UID, 54 BER_BVC("uid"), &slap_rbac_schema.ad_uid}, 55 { RBAC_TENANT_ID, 56 BER_BVC("tenantid"), &slap_rbac_schema.ad_tenant_id }, 57 58 { RBAC_NONE, BER_BVNULL, NULL } 59}; 60 61rbac_ad_t rbac_session_permission_ads[] = { 62 { RBAC_OP_NAME, 63 BER_BVC("rbacOpName"), &slap_rbac_schema.ad_permission_opname }, 64 { RBAC_OBJ_NAME, 65 BER_BVC("rbacObjName"), &slap_rbac_schema.ad_permission_objname }, 66 { RBAC_ROLE_NAME, 67 BER_BVC("rbacRoleName"), &slap_rbac_schema.ad_permission_rolename }, 68 69 { RBAC_NONE, BER_BVNULL, NULL } 70}; 71 72rbac_ad_t audit_ads[] = { 73 { RBAC_AUDIT_OP, 74 BER_BVC("rbacAuditOp"), &slap_rbac_schema.ad_audit_op }, 75 { RBAC_AUDIT_ID, 76 BER_BVC("rbacAuditId"), &slap_rbac_schema.ad_audit_id }, 77 { RBAC_AUDIT_ROLES, 78 BER_BVC("rbacAuditRoles"), &slap_rbac_schema.ad_audit_roles }, 79 { RBAC_AUDIT_REQUESTED_ROLES, 80 BER_BVC("rbacAuditRequestedRoles"), 81 &slap_rbac_schema.ad_audit_requested_roles 82 }, 83 { RBAC_AUDIT_TIMESTAMP, 84 BER_BVC("rbacAuditTimestamp"), &slap_rbac_schema.ad_audit_timestamp }, 85 { RBAC_AUDIT_RESOURCES, 86 BER_BVC("rbacAuditResources"), &slap_rbac_schema.ad_audit_resources }, 87 { RBAC_AUDIT_OBJS, 88 BER_BVC("rbacAuditObjects"), &slap_rbac_schema.ad_audit_objects }, 89 { RBAC_AUDIT_OPS, 90 BER_BVC("rbacAuditOperations"), &slap_rbac_schema.ad_audit_operations }, 91 { RBAC_AUDIT_RESULT, 92 BER_BVC("rbacAuditResult"), &slap_rbac_schema.ad_audit_result }, 93 { RBAC_AUDIT_PROPERTIES, 94 BER_BVC("rbacAuditProperties"), &slap_rbac_schema.ad_audit_properties }, 95 { RBAC_AUDIT_MSGS, 96 BER_BVC("rbacAuditMessages"), &slap_rbac_schema.ad_audit_messages }, 97 98 { RBAC_NONE, BER_BVNULL, NULL } 99}; 100 101/* initialize repository attribute descriptions */ 102 103static int 104initialize_sessions() 105{ 106 int i, nattrs, rc = LDAP_SUCCESS; 107 const char *text; 108 109 for ( nattrs = 0; !BER_BVISNULL( &rbac_session_ads[nattrs].attr ); 110 nattrs++ ) 111 ; /* count the number of attrs */ 112 113 slap_rbac_schema.session_attrs = 114 slap_sl_calloc( sizeof(AttributeName), nattrs + 1, NULL ); 115 116 for ( i = 0; !BER_BVISNULL( &rbac_session_ads[i].attr ); i++ ) { 117 rc = slap_bv2ad( 118 &rbac_session_ads[i].attr, rbac_session_ads[i].ad, &text ); 119 if ( rc != LDAP_SUCCESS ) { 120 goto done; 121 } 122 slap_rbac_schema.session_attrs[i].an_name = rbac_session_ads[i].attr; 123 slap_rbac_schema.session_attrs[i].an_desc = *rbac_session_ads[i].ad; 124 } 125 126 BER_BVZERO( &slap_rbac_schema.session_attrs[nattrs].an_name ); 127 128done:; 129 return rc; 130} 131 132static int 133initialize_audit() 134{ 135 int i, rc = LDAP_SUCCESS; 136 const char *text; 137 138 /* for audit */ 139 for ( i = 0; !BER_BVISNULL( &audit_ads[i].attr ); i++ ) { 140 rc = slap_bv2ad( &audit_ads[i].attr, audit_ads[i].ad, &text ); 141 if ( rc != LDAP_SUCCESS ) { 142 goto done; 143 } 144 } 145 146done:; 147 return rc; 148} 149 150static int 151initialize_tenant( 152 BackendDB *be, 153 ConfigReply *cr, 154 tenant_info_t *tenantp, 155 int init_op ) 156{ 157 int rc = LDAP_SUCCESS; 158 Entry *e = NULL; 159 OperationBuffer opbuf; 160 Operation *op2; 161 SlapReply rs2 = { REP_RESULT }; 162 Connection conn = { 0 }; 163 struct berval rbac_container_oc = BER_BVC("rbacContainer"); 164 struct berval rbac_audit_container = BER_BVC("audit"); 165 struct berval rbac_session_container = BER_BVC("rbac"); 166 void *thrctx = ldap_pvt_thread_pool_context(); 167 168 e = entry_alloc(); 169 170 switch ( init_op ) { 171 case INIT_AUDIT_CONTAINER: 172 ber_dupbv( &e->e_name, &tenantp->audit_basedn ); 173 ber_dupbv( &e->e_nname, &tenantp->audit_basedn ); 174 175 /* container cn */ 176 attr_merge_one( 177 e, slap_schema.si_ad_cn, &rbac_audit_container, NULL ); 178 break; 179 case INIT_SESSION_CONTAINER: 180 ber_dupbv( &e->e_name, &tenantp->sessions_basedn ); 181 ber_dupbv( &e->e_nname, &tenantp->sessions_basedn ); 182 183 /* rendered dynmaicObject for session */ 184 attr_merge_one( e, slap_schema.si_ad_objectClass, 185 &slap_schema.si_oc_dynamicObject->soc_cname, NULL ); 186 187 /* container cn */ 188 attr_merge_one( 189 e, slap_schema.si_ad_cn, &rbac_session_container, NULL ); 190 break; 191 default: 192 break; 193 } 194 195 attr_merge_one( 196 e, slap_schema.si_ad_objectClass, &rbac_container_oc, NULL ); 197 attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, 198 &rbac_container_oc, NULL ); 199 200 /* store RBAC session */ 201 connection_fake_init2( &conn, &opbuf, thrctx, 0 ); 202 op2 = &opbuf.ob_op; 203 op2->o_callback = &nullsc; 204 op2->o_tag = LDAP_REQ_ADD; 205 op2->o_protocol = LDAP_VERSION3; 206 op2->o_req_dn = e->e_name; 207 op2->o_req_ndn = e->e_nname; 208 op2->ora_e = e; 209 op2->o_bd = select_backend( &op2->o_req_ndn, 0 ); 210 op2->o_dn = op2->o_bd->be_rootdn; 211 op2->o_ndn = op2->o_bd->be_rootndn; 212 rc = op2->o_bd->be_add( op2, &rs2 ); 213 214 if ( e ) entry_free( e ); 215 216 return rc; 217} 218 219int 220rbac_initialize_tenants( BackendDB *be, ConfigReply *cr ) 221{ 222 int rc = LDAP_SUCCESS; 223 rbac_tenant_t *tenantp = NULL; 224 225 for ( tenantp = &rbac_tenants; tenantp; tenantp = tenantp->next ) { 226 rc = initialize_tenant( 227 be, cr, &tenantp->tenant_info, INIT_AUDIT_CONTAINER ); 228 if ( rc != LDAP_SUCCESS ) { 229 if ( rc == LDAP_ALREADY_EXISTS ) { 230 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 231 "audit container exists, tenant (%s)\n", 232 tenantp->tenant_info.tid.bv_val ? 233 tenantp->tenant_info.tid.bv_val : 234 "NULL" ); 235 rc = LDAP_SUCCESS; 236 } else { 237 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 238 "failed to initialize (%s): rc (%d)\n", 239 tenantp->tenant_info.tid.bv_val ? 240 tenantp->tenant_info.tid.bv_val : 241 "NULL", 242 rc ); 243 goto done; 244 } 245 } else { 246 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 247 "created audit container for tenant (%s):\n", 248 tenantp->tenant_info.tid.bv_val ? 249 tenantp->tenant_info.tid.bv_val : 250 "NULL" ); 251 } 252 rc = initialize_tenant( 253 be, cr, &tenantp->tenant_info, INIT_SESSION_CONTAINER ); 254 if ( rc != LDAP_SUCCESS ) { 255 if ( rc == LDAP_ALREADY_EXISTS ) { 256 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 257 "session container exists, tenant (%s)\n", 258 tenantp->tenant_info.tid.bv_val ? 259 tenantp->tenant_info.tid.bv_val : 260 "NULL" ); 261 rc = LDAP_SUCCESS; 262 } else { 263 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 264 "failed to initialize (%s): rc (%d)\n", 265 tenantp->tenant_info.tid.bv_val ? 266 tenantp->tenant_info.tid.bv_val : 267 "NULL", 268 rc ); 269 goto done; 270 } 271 } else { 272 Debug( LDAP_DEBUG_ANY, "rbac_initialize: " 273 "created session container for tenant (%s):\n", 274 tenantp->tenant_info.tid.bv_val ? 275 tenantp->tenant_info.tid.bv_val : 276 "NULL" ); 277 } 278 } 279 280done:; 281 282 return rc; 283} 284 285static int 286initialize_rbac_session_permissions() 287{ 288 int i, rc = LDAP_SUCCESS; 289 const char *text; 290 291 for ( i = 0; !BER_BVISNULL( &rbac_session_permission_ads[i].attr ); i++ ) { 292 rc = slap_bv2ad( &rbac_session_permission_ads[i].attr, 293 rbac_session_permission_ads[i].ad, &text ); 294 if ( rc != LDAP_SUCCESS ) { 295 goto done; 296 } 297 } 298 299done:; 300 return rc; 301} 302 303int 304rbac_initialize_repository() 305{ 306 int rc = LDAP_SUCCESS; 307 308 rc = initialize_jts(); 309 if ( rc != LDAP_SUCCESS ) { 310 return rc; 311 } 312 313 rc = initialize_rbac_session_permissions(); 314 if ( rc != LDAP_SUCCESS ) { 315 return rc; 316 } 317 318 rc = initialize_sessions(); 319 if ( rc != LDAP_SUCCESS ) { 320 return rc; 321 } 322 323 rc = initialize_audit(); 324 if ( rc != LDAP_SUCCESS ) { 325 return rc; 326 } 327 328 return rc; 329} 330