xref: /netbsd-src/external/bsd/openldap/dist/contrib/slapd-modules/rbac/init.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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
initialize_sessions()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
initialize_audit()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
initialize_tenant(BackendDB * be,ConfigReply * cr,tenant_info_t * tenantp,int init_op)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
rbac_initialize_tenants(BackendDB * be,ConfigReply * cr)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
initialize_rbac_session_permissions()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
rbac_initialize_repository()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