Home | History | Annotate | Line # | Download | only in rbac
      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 
     36 static slap_callback nullsc = { NULL, NULL, NULL, NULL };
     37 
     38 struct slap_rbac_internal_schema slap_rbac_schema;
     39 
     40 extern rbac_tenant_t rbac_tenants;
     41 extern int initialize_jts( void );
     42 
     43 rbac_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 
     61 rbac_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 
     72 rbac_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 
    103 static int
    104 initialize_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 
    128 done:;
    129 	return rc;
    130 }
    131 
    132 static int
    133 initialize_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 
    146 done:;
    147 	return rc;
    148 }
    149 
    150 static int
    151 initialize_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 
    219 int
    220 rbac_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 
    280 done:;
    281 
    282 	return rc;
    283 }
    284 
    285 static int
    286 initialize_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 
    299 done:;
    300 	return rc;
    301 }
    302 
    303 int
    304 rbac_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