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