1 /* $NetBSD: rbac.c,v 1.2 2021/08/14 16:14:53 christos Exp $ */
2
3 /* rbac.c - RBAC main file */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 2013-2021 The OpenLDAP Foundation.
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: rbac.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 #define RBAC_REQ 1
37
38 static slap_overinst rbac;
39
40 static struct berval slap_EXOP_CREATE_SESSION =
41 BER_BVC(LDAP_RBAC_EXOP_CREATE_SESSION);
42 static struct berval slap_EXOP_CHECK_ACCESS =
43 BER_BVC(LDAP_RBAC_EXOP_CHECK_ACCESS);
44 static struct berval slap_EXOP_ADD_ACTIVE_ROLE =
45 BER_BVC(LDAP_RBAC_EXOP_ADD_ACTIVE_ROLE);
46 static struct berval slap_EXOP_DROP_ACTIVE_ROLE =
47 BER_BVC(LDAP_RBAC_EXOP_DROP_ACTIVE_ROLE);
48 static struct berval slap_EXOP_DELETE_SESSION =
49 BER_BVC(LDAP_RBAC_EXOP_DELETE_SESSION);
50 static struct berval slap_EXOP_SESSION_ROLES =
51 BER_BVC(LDAP_RBAC_EXOP_SESSION_ROLES);
52
53 rbac_tenant_t rbac_tenants = {
54 {
55 .schema = &slap_rbac_jts_schema,
56 },
57 NULL
58 };
59
60 static ConfigDriver rbac_cf_gen;
61
62 static ConfigTable rbaccfg[] = {
63 { "rbac-default-users-base-dn", "usersDN", 2, 2, 0,
64 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_USERS_BASE_DN,
65 rbac_cf_gen,
66 "(OLcfgCtAt:7.1 NAME 'olcRBACDefaultUsersBaseDn' "
67 "DESC 'default Base DN for RBAC users ' "
68 "SYNTAX OMsDirectoryString "
69 "SINGLE-VALUE )",
70 NULL, NULL
71 },
72 { "rbac-default-roles-base-dn", "rolesDN", 2, 2, 0,
73 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_ROLES_BASE_DN,
74 rbac_cf_gen,
75 "(OLcfgCtAt:7.2 NAME 'olcRBACDefaultRolesBaseDn' "
76 "DESC 'default base DN for RBAC roles ' "
77 "SYNTAX OMsDirectoryString "
78 "SINGLE-VALUE )",
79 NULL, NULL
80 },
81 { "rbac-default-permissions-base-dn", "permissionsDN", 2, 2, 0,
82 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_PERMISSIONS_BASE_DN,
83 rbac_cf_gen,
84 "(OLcfgCtAt:7.3 NAME 'olcRBACDefaultPermissionsBaseDn' "
85 "DESC 'default base DN for RBAC permissions ' "
86 "SYNTAX OMsDirectoryString "
87 "SINGLE-VALUE )",
88 NULL, NULL
89 },
90 { "rbac-default-sessions-base-dn", "sessionsDN", 2, 2, 0,
91 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_SESSIONS_BASE_DN,
92 rbac_cf_gen,
93 "(OLcfgCtAt:7.4 NAME 'olcRBACDefaultSessionsBaseDn' "
94 "DESC 'default base DN for RBAC permissions ' "
95 "SYNTAX OMsDirectoryString "
96 "SINGLE-VALUE )",
97 NULL, NULL
98 },
99 { "rbac-admin", "adminDN", 2, 2, 0,
100 ARG_MAGIC|ARG_DN|RBAC_ADMIN_DN,
101 rbac_cf_gen,
102 "(OLcfgCtAt:7.5 NAME 'olcRBACAdminDn' "
103 "DESC 'default admin DN for RBAC repository ' "
104 "SYNTAX OMsDirectoryString "
105 "SINGLE-VALUE )",
106 NULL, NULL
107 },
108 { "rbac-pwd", "adminPwd", 2, 2, 0,
109 ARG_MAGIC|RBAC_ADMIN_PWD,
110 rbac_cf_gen,
111 "(OLcfgCtAt:7.6 NAME 'olcRBACAdminPwd' "
112 "DESC 'default admin pwd for RBAC repository ' "
113 "SYNTAX OMsDirectoryString "
114 "SINGLE-VALUE )",
115 NULL, NULL
116 },
117 { "rbac-session-admin", "sessionAdminDN", 2, 2, 0,
118 ARG_MAGIC|ARG_DN|RBAC_SESSION_ADMIN_DN,
119 rbac_cf_gen,
120 "(OLcfgCtAt:7.7 NAME 'olcRBACSessionAdminDn' "
121 "DESC 'admin DN for RBAC session repository ' "
122 "SYNTAX OMsDirectoryString "
123 "SINGLE-VALUE )",
124 NULL, NULL
125 },
126 { "rbac-session-admin-pwd", "sessionAdminPwd", 2, 2, 0,
127 ARG_MAGIC|RBAC_SESSION_ADMIN_PWD,
128 rbac_cf_gen,
129 "(OLcfgCtAt:7.8 NAME 'olcRBACSessionAdminPwd' "
130 "DESC 'admin pwd for RBAC session repository ' "
131 "SYNTAX OMsDirectoryString SINGLE-VALUE )",
132 NULL, NULL
133 },
134 { "tenant", "tenant", 2, 2, 0,
135 ARG_MAGIC|ARG_DN|RBAC_TENANT,
136 rbac_cf_gen, "(OLcfgCtAt:7.9 NAME 'olcRBACTenant' "
137 "DESC 'RBAC tenant ' "
138 "SYNTAX OMsDirectoryString "
139 "SINGLE-VALUE )",
140 NULL, NULL
141 },
142 { "rbac-default-audit-base-dn", "auditDN", 2, 2, 0,
143 ARG_MAGIC|ARG_DN|RBAC_DEFAULT_AUDIT_BASE_DN,
144 rbac_cf_gen,
145 "(OLcfgCtAt:7.10 NAME 'olcRBACDefaultAuditBaseDn' "
146 "DESC 'default base DN for RBAC audit records ' "
147 "SYNTAX OMsDirectoryString "
148 "SINGLE-VALUE )",
149 NULL, NULL
150 },
151 { "rbac-default-tenant-id", "tenantId", 2, 2, 0,
152 ARG_MAGIC|RBAC_DEFAULT_TENANT_ID,
153 rbac_cf_gen,
154 "(OLcfgCtAt:7.11 NAME 'olcRBACDefaultTenantId' "
155 "DESC 'default tenant id' "
156 "SYNTAX OMsDirectoryString "
157 "SINGLE-VALUE )",
158 NULL, NULL
159 },
160
161 { NULL, NULL, 0, 0, 0, ARG_IGNORED }
162 };
163
164 static ConfigOCs rbac_ocs[] = {
165 { "( OLcfgCtOc:7.1 "
166 "NAME 'olcRBACConfig' "
167 "DESC 'RBAC configuration' "
168 "SUP olcOverlayConfig "
169 "MAY ( olcRBACDefaultUsersBaseDn $ olcRBACDefaultRolesBaseDn $ "
170 "olcRBACDefaultPermissionsBaseDn $ olcRBACDefaultSessionsBaseDn $ "
171 "olcRBACAdminDn $ olcRBACAdminPwd $ olcRBACSessionAdminDn $ "
172 "olcRBACSessionAdminPwd) )",
173 Cft_Overlay, rbaccfg },
174
175 { NULL, 0, NULL }
176 };
177
178 static slap_verbmasks rbac_keys[] = {
179 { BER_BVC("default_users_base_dn"), RBAC_DEFAULT_USERS_BASE_DN },
180 { BER_BVC("default_roles_base_dn"), RBAC_DEFAULT_ROLES_BASE_DN },
181 { BER_BVC("default_permissions_base_dn"),
182 RBAC_DEFAULT_PERMISSIONS_BASE_DN },
183 { BER_BVC("tenant"), RBAC_TENANT },
184
185 { BER_BVNULL, 0 }
186 };
187
188 static slap_verbmasks rbac_tenant_keys[] = {
189 { BER_BVC("id"), RBAC_TENANT_ID },
190 { BER_BVC("users_base_dn"), RBAC_USERS_BASE_DN },
191 { BER_BVC("roles_base_dn"), RBAC_ROLES_BASE_DN },
192 { BER_BVC("permissions_base_dn"), RBAC_PERMISSIONS_BASE_DN },
193
194 { BER_BVNULL, 0 }
195 };
196
197 static void
rbac_tenant_parse(char * tenent_info,tenant_info_t * tenants)198 rbac_tenant_parse( char *tenent_info, tenant_info_t *tenants )
199 {
200 return;
201 }
202
203 static int
rbac_cf_gen(ConfigArgs * c)204 rbac_cf_gen( ConfigArgs *c )
205 {
206 slap_overinst *on = (slap_overinst *)c->bi;
207 rbac_tenant_t *ri = &rbac_tenants;
208 int rc = 0;
209
210 if ( c->op == SLAP_CONFIG_EMIT ) {
211 switch ( c->type ) {
212 case RBAC_DEFAULT_USERS_BASE_DN:
213 value_add_one( &c->rvalue_vals, &ri->tenant_info.users_basedn );
214 break;
215 case RBAC_DEFAULT_ROLES_BASE_DN:
216 value_add_one( &c->rvalue_vals, &ri->tenant_info.roles_basedn );
217 break;
218 case RBAC_DEFAULT_PERMISSIONS_BASE_DN:
219 value_add_one(
220 &c->rvalue_vals, &ri->tenant_info.permissions_basedn );
221 break;
222 case RBAC_DEFAULT_SESSIONS_BASE_DN:
223 value_add_one(
224 &c->rvalue_vals, &ri->tenant_info.sessions_basedn );
225 break;
226 case RBAC_DEFAULT_AUDIT_BASE_DN:
227 value_add_one( &c->rvalue_vals, &ri->tenant_info.audit_basedn );
228 break;
229 case RBAC_ADMIN_DN:
230 value_add_one( &c->rvalue_vals, &ri->tenant_info.admin );
231 break;
232 case RBAC_ADMIN_PWD:
233 value_add_one( &c->rvalue_vals, &ri->tenant_info.pwd );
234 break;
235 case RBAC_SESSION_ADMIN_DN:
236 value_add_one(
237 &c->rvalue_vals, &ri->tenant_info.session_admin );
238 break;
239 case RBAC_DEFAULT_TENANT_ID:
240 value_add_one( &c->rvalue_vals, &ri->tenant_info.tid );
241 break;
242 default:
243 break;
244 }
245 return rc;
246 } else if ( c->op == LDAP_MOD_DELETE ) {
247 /* FIXME */
248 return 1;
249 }
250 switch ( c->type ) {
251 case RBAC_DEFAULT_USERS_BASE_DN: {
252 struct berval dn = BER_BVNULL;
253 ber_str2bv( c->argv[1], 0, 0, &dn );
254 rc = dnNormalize(
255 0, NULL, NULL, &dn, &ri->tenant_info.users_basedn, NULL );
256 break;
257 }
258 case RBAC_DEFAULT_ROLES_BASE_DN: {
259 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.roles_basedn );
260 break;
261 }
262 case RBAC_DEFAULT_PERMISSIONS_BASE_DN: {
263 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.permissions_basedn );
264 break;
265 }
266 case RBAC_DEFAULT_SESSIONS_BASE_DN: {
267 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.sessions_basedn );
268 break;
269 }
270 case RBAC_DEFAULT_AUDIT_BASE_DN: {
271 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.audit_basedn );
272 break;
273 }
274 case RBAC_ADMIN_DN: {
275 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.admin );
276 break;
277 }
278 case RBAC_ADMIN_PWD: {
279 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.pwd );
280 break;
281 }
282 case RBAC_SESSION_ADMIN_DN: {
283 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.session_admin );
284 break;
285 }
286 case RBAC_SESSION_ADMIN_PWD: {
287 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.session_admin_pwd );
288 break;
289 }
290 case RBAC_DEFAULT_TENANT_ID: {
291 ber_str2bv( c->argv[1], 0, 1, &ri->tenant_info.tid );
292 break;
293 }
294 case RBAC_TENANT: {
295 rbac_tenant_parse( c->argv[1], &ri->tenant_info );
296 break;
297 }
298 default:
299 break;
300 }
301
302 return rc;
303 }
304
305 /*
306 * rbac configuration
307 */
308
309 tenant_info_t *
rbac_tid2tenant(struct berval * tid)310 rbac_tid2tenant( struct berval *tid )
311 {
312 /* return the only tenant for now */
313 return &rbac_tenants.tenant_info;
314 }
315
316 //{ BER_BVC(LDAP_RBAC_EXOP_SESSION_ROLES), rbac_session_roles },
317
318 static int
slap_parse_rbac_session_roles(struct berval * in,rbac_req_t ** reqpp,const char ** text,void * ctx)319 slap_parse_rbac_session_roles(
320 struct berval *in,
321 rbac_req_t **reqpp,
322 const char **text,
323 void *ctx )
324 {
325 int rc = LDAP_SUCCESS;
326 struct berval reqdata = BER_BVNULL;
327 rbac_req_t *reqp = NULL;
328 BerElementBuffer berbuf;
329 BerElement *ber = (BerElement *)&berbuf;
330 ber_tag_t tag;
331 ber_len_t len = -1;
332
333 *text = NULL;
334
335 if ( in == NULL || in->bv_len == 0 ) {
336 *text = "empty request data field in rbac_session_roles exop";
337 return LDAP_PROTOCOL_ERROR;
338 }
339
340 reqp = rbac_alloc_req( RBAC_REQ_SESSION_ROLES );
341
342 if ( !reqp ) {
343 *text = "unable to allocate memory for rbac_session_roles exop";
344 return LDAP_PROTOCOL_ERROR;
345 }
346
347 ber_dupbv_x( &reqdata, in, ctx );
348
349 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */
350 ber_init2( ber, &reqdata, 0 );
351
352 tag = ber_scanf( ber, "{" /*}*/ );
353
354 if ( tag == LBER_ERROR ) {
355 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: "
356 "decoding error.\n" );
357 goto decoding_error;
358 }
359
360 tag = ber_peek_tag( ber, &len );
361 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID_SESS ) {
362 struct berval uid;
363 tag = ber_scanf( ber, "m", &uid );
364 if ( tag == LBER_ERROR ) {
365 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: "
366 "user id parse failed.\n" );
367 goto decoding_error;
368 }
369 ber_dupbv_x( &reqp->uid, &uid, ctx );
370 tag = ber_peek_tag( ber, &len );
371 }
372
373 //tag = ber_peek_tag( ber, &len );
374 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ) {
375 struct berval sessid;
376 tag = ber_scanf( ber, "m", &sessid );
377 if ( tag == LBER_ERROR ) {
378 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: "
379 "session id parse failed.\n" );
380 goto decoding_error;
381 }
382 ber_dupbv_x( &reqp->sessid, &sessid, ctx );
383 tag = ber_peek_tag( ber, &len );
384 }
385
386 if ( tag != LBER_DEFAULT || len != 0 ) {
387 decoding_error:;
388
389 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_session_roles: "
390 "decoding error, len=%ld\n",
391 (long)len );
392 rc = LDAP_PROTOCOL_ERROR;
393 *text = "data decoding error";
394 }
395
396 if ( rc == LDAP_SUCCESS ) {
397 *reqpp = reqp;
398 } else {
399 rbac_free_req( reqp );
400 *reqpp = NULL;
401 }
402
403 if ( !BER_BVISNULL( &reqdata ) ) {
404 ber_memfree_x( reqdata.bv_val, ctx );
405 }
406
407 return rc;
408 }
409
410 static int
rbac_session_roles(Operation * op,SlapReply * rs)411 rbac_session_roles( Operation *op, SlapReply *rs )
412 {
413 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
414 const struct berval rbac_op = BER_BVC("SessionRoles");
415 rbac_req_t *reqp = NULL;
416 rbac_session_t *sessp;
417 int rc;
418
419 rs->sr_err = slap_parse_rbac_session_roles(
420 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
421
422 assert( rs->sr_err == LDAP_SUCCESS );
423
424 /* get the session using the session id */
425 sessp = rbac_session_byid( op, reqp );
426 if ( !sessp ) {
427 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: "
428 "session not found\n" );
429 rc = LDAP_UNWILLING_TO_PERFORM;
430 goto done;
431 }
432
433 /* checking whether the session is owned by the user */
434 if ( !rbac_is_session_owner( sessp, reqp ) ) {
435 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: "
436 "session not owned by user\n" );
437 rc = LDAP_UNWILLING_TO_PERFORM;
438 goto done;
439 }
440
441 rc = rbac_int_delete_session( op, sessp );
442 if ( rc != LDAP_SUCCESS ) {
443 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: "
444 "unable to delete session\n" );
445 rc = LDAP_UNWILLING_TO_PERFORM;
446 goto done;
447 }
448
449 /*
450 * If we wanted to...
451 * load these roles into a response with a sequence nested within a
452 * sequence: (No, we're not actually doing this here.)
453 * 0x30 LL ber_printf( ber, "{" );
454 * 0x04 L1
455 * 0x04 L2 a b c d
456 * 0x04 L3 e f g h
457 * 0x04 L4 i j k l
458 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL );
459 * close it ber_printf( ber, "t{W}", LDAP_TAG_EXOP_RBAC_ROLES, roles );
460 */
461
462 /*
463 * Instead we are...
464 * loading these roles into the response within a sequence: (Yes, we are doing this here.)
465 * 0x30 LL ber_printf( ber, "{" );
466 * 0x04 L1 a b c d
467 * 0x04 L2 e f g h
468 * 0x04 L3 i j k l
469 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL );
470 * close it ber_printf( ber, "tW", LDAP_TAG_EXOP_RBAC_ROLES, roles );
471 */
472 BerElementBuffer berbuf;
473 BerElement *ber = (BerElement *)&berbuf;
474 ber_init_w_nullc( ber, LBER_USE_DER );
475 BerVarray roles = NULL;
476 if ( sessp->roles ) {
477 struct berval tmpbv;
478 // open the sequence:
479 ber_printf( ber, "{" /*}*/ );
480 //char *role;
481 int i = 0;
482 //BerVarray roles = NULL;
483 for ( i = 0; !BER_BVISNULL( &sessp->roles[i] ); i++ ) {
484 tmpbv.bv_val = sessp->roles[i].bv_val;
485 tmpbv.bv_len = sessp->roles[i].bv_len;
486 // add role name:
487 ber_bvarray_add_x( &roles, &tmpbv, NULL );
488
489 //LBER_F( int )
490 //ber_bvecadd_x LDAP_P(( struct berval ***bvec,
491 // struct berval *bv, void *ctx ));
492
493 // first attempt at sequence within a sequence...
494 // open another sequence:
495 /*
496 ber_printf( ber, "{" } );
497 // add role name (again):
498 ber_bvarray_add_x(&roles, &tmpbv, NULL);
499 // close the nested sequence:
500 ber_printf( ber, { "}" );
501 */
502 // end 2nd sequence
503 }
504 /*
505 * This is how we add several octet strings at one time. An array of struct berval's is supplied.
506 * The array is terminated by a struct berval with a NULL bv_val.
507 * Note that a construct like '{W}' is required to get an actual SEQUENCE OF octet strings.
508 * But here we are using 'tW' which allows passing a collection of octets w/out a nesting within a sequence.
509 */
510 ber_printf( ber, "tW",
511 LDAP_TAG_EXOP_RBAC_ROLES, roles);
512
513 // TODO: determine why free on roles array causes a seg fault:
514 //ber_bvarray_free_x(roles, NULL);
515
516 // close the sequence:
517 ber_printf( ber, /*{*/ "N}" );
518 }
519
520 if ( rc < 0 ) {
521 rs->sr_err = LDAP_OTHER;
522 rs->sr_text = "internal error";
523 } else {
524 (void)ber_flatten( ber, &rs->sr_rspdata );
525 rs->sr_err = LDAP_SUCCESS;
526 }
527 ber_free_buf( ber );
528 // END LOAD ROLES INTO RESPONSE
529
530 done:;
531 rs->sr_err = rc;
532
533 // always put the OID in the response:
534 rs->sr_rspoid = ch_strdup( slap_EXOP_SESSION_ROLES.bv_val );
535
536 /* generate audit log */
537 rbac_audit(
538 op, SessionRoles, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
539 rbac_free_session( sessp );
540 rbac_free_req( reqp );
541 return rs->sr_err;
542 }
543
544 static int
rbac_session_rolesx(Operation * op,SlapReply * rs)545 rbac_session_rolesx( Operation *op, SlapReply *rs )
546 {
547 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
548 const struct berval rbac_op = BER_BVC("SessionRoles");
549 rbac_session_t *sessp = NULL;
550 rbac_req_t *reqp = NULL;
551 int rc;
552
553 rs->sr_err = slap_parse_rbac_session_roles(
554 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
555
556 assert( rs->sr_err == LDAP_SUCCESS );
557
558 /* get the session using the session id */
559 sessp = rbac_session_byid( op, reqp );
560 if ( !sessp ) {
561 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: "
562 "session not found\n" );
563 rc = LDAP_UNWILLING_TO_PERFORM;
564 goto done;
565 }
566
567 /* checking whether the session is owned by the user */
568 if ( !rbac_is_session_owner( sessp, reqp ) ) {
569 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: "
570 "session not owned by user\n" );
571 rc = LDAP_UNWILLING_TO_PERFORM;
572 goto done;
573 }
574
575 rc = rbac_int_delete_session( op, sessp );
576 if ( rc != LDAP_SUCCESS ) {
577 Debug( LDAP_DEBUG_ANY, "rbac_session_roles: "
578 "unable to delete session\n" );
579 rc = LDAP_UNWILLING_TO_PERFORM;
580 goto done;
581 }
582
583 /*
584 * If we wanted to...
585 * load these roles into a response with a sequence nested within a
586 * sequence: (No, we're not actually doing this here.)
587 * 0x30 LL ber_printf( ber, "{" );
588 * 0x04 L1
589 * 0x04 L2 a b c d
590 * 0x04 L3 e f g h
591 * 0x04 L4 i j k l
592 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL );
593 * close it ber_printf( ber, "t{W}", LDAP_TAG_EXOP_RBAC_ROLES, roles );
594 */
595
596 /*
597 * Instead we are...
598 * loading these roles into the response within a sequence: (Yes, we are doing this here.)
599 * 0x30 LL ber_printf( ber, "{" );
600 * 0x04 L1 a b c d
601 * 0x04 L2 e f g h
602 * 0x04 L3 i j k l
603 * add all three ber_bvarray_add_x( &roles, &tmpbv, NULL );
604 * close it ber_printf( ber, "tW", LDAP_TAG_EXOP_RBAC_ROLES, roles );
605 */
606 BerElementBuffer berbuf;
607 BerElement *ber = (BerElement *)&berbuf;
608 ber_init_w_nullc( ber, LBER_USE_DER );
609 BerVarray roles = NULL;
610 if ( sessp->roles ) {
611 struct berval tmpbv;
612 // open the sequence:
613 ber_printf( ber, "{" /*}*/ );
614 //char *role;
615 int i = 0;
616 //BerVarray roles = NULL;
617 for ( i = 0; !BER_BVISNULL( &sessp->roles[i] ); i++ ) {
618 tmpbv.bv_val = sessp->roles[i].bv_val;
619 tmpbv.bv_len = sessp->roles[i].bv_len;
620 // add role name:
621 ber_bvarray_add_x( &roles, &tmpbv, NULL );
622
623 // first attempt at sequence within a sequence...
624 // open another sequence:
625 /*
626 ber_printf( ber, "{" } );
627 // add role name (again):
628 ber_bvarray_add_x(&roles, &tmpbv, NULL);
629 // close the nested sequence:
630 ber_printf( ber, { "}" );
631 */
632 // end 2nd sequence
633 }
634 /*
635 * This is how we add several octet strings at one time. An array of struct berval's is supplied.
636 * The array is terminated by a struct berval with a NULL bv_val.
637 * Note that a construct like '{W}' is required to get an actual SEQUENCE OF octet strings.
638 * But here we are using 'tW' which allows passing a collection of octets w/out a nesting within a sequence.
639 */
640 ber_printf( ber, "tW",
641 LDAP_TAG_EXOP_RBAC_ROLES, roles);
642
643 // TODO: determine why free on roles array causes a seg fault:
644 //ber_bvarray_free_x(roles, NULL);
645
646 // close the sequence:
647 ber_printf( ber, /*{*/ "N}" );
648 }
649
650 if ( rc < 0 ) {
651 rs->sr_err = LDAP_OTHER;
652 rs->sr_text = "internal error";
653 } else {
654 (void)ber_flatten( ber, &rs->sr_rspdata );
655 rs->sr_err = LDAP_SUCCESS;
656 }
657 ber_free_buf( ber );
658 // END LOAD ROLES INTO RESPONSE
659
660 done:;
661 rs->sr_err = rc;
662
663 // always put the OID in the response:
664 rs->sr_rspoid = ch_strdup( slap_EXOP_SESSION_ROLES.bv_val );
665
666 /* generate audit log */
667 rbac_audit(
668 op, SessionRoles, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
669 rbac_free_session( sessp );
670 rbac_free_req( reqp );
671 return rs->sr_err;
672 }
673
674 /*
675 * slap_parse_rbac_create_session
676 */
677 static int
slap_parse_rbac_create_session(struct berval * in,rbac_req_t ** reqpp,const char ** text,void * ctx)678 slap_parse_rbac_create_session(
679 struct berval *in,
680 rbac_req_t **reqpp,
681 const char **text,
682 void *ctx )
683 {
684 int rc = LDAP_SUCCESS;
685 struct berval reqdata = BER_BVNULL;
686 rbac_req_t *reqp = NULL;
687 BerElementBuffer berbuf;
688 BerElement *ber = (BerElement *)&berbuf;
689 ber_tag_t tag;
690 ber_len_t len = -1;
691
692 *text = NULL;
693
694 if ( in == NULL || in->bv_len == 0 ) {
695 *text = "empty request data field in rbac_create_session exop";
696 return LDAP_PROTOCOL_ERROR;
697 }
698
699 reqp = rbac_alloc_req( RBAC_REQ_CREATE_SESSION );
700
701 if ( !reqp ) {
702 *text = "unable to allocate memory for bac_create_session exop";
703 return LDAP_PROTOCOL_ERROR;
704 }
705
706 ber_dupbv_x( &reqdata, in, ctx );
707
708 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */
709 ber_init2( ber, &reqdata, 0 );
710
711 tag = ber_scanf( ber, "{" /*}*/ );
712
713 if ( tag == LBER_ERROR ) {
714 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
715 "decoding error.\n" );
716 goto decoding_error;
717 }
718
719 // Order: 1. sessionId, 2. tenantId, 3. userId, 4. password and 5. roles
720 /* must-have */
721 tag = ber_peek_tag( ber, &len );
722
723 // 1. SESSIONID
724 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID ) {
725 struct berval bv;
726 tag = ber_scanf( ber, "m", &bv );
727 if ( tag == LBER_ERROR ) {
728 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
729 "session id parse failed.\n" );
730 goto decoding_error;
731 }
732 ber_dupbv_x( &reqp->sessid, &bv, ctx );
733 tag = ber_peek_tag( ber, &len );
734 }
735
736 // 2. TENANT ID
737 if ( tag == LDAP_TAG_EXOP_RBAC_TENANT_ID ) {
738 struct berval bv;
739 tag = ber_scanf( ber, "m", &bv );
740 if ( tag == LBER_ERROR ) {
741 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
742 "tenant id parse failed.\n" );
743 goto decoding_error;
744 }
745 ber_dupbv_x( &reqp->tenantid, &bv, ctx );
746 tag = ber_peek_tag( ber, &len );
747 }
748
749 // 3. USERID
750 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID ) {
751 struct berval bv;
752 tag = ber_scanf( ber, "m", &bv );
753 if ( tag == LBER_ERROR ) {
754 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
755 "user id parse failed.\n" );
756 goto decoding_error;
757 }
758 ber_dupbv_x( &reqp->uid, &bv, ctx );
759 tag = ber_peek_tag( ber, &len );
760 }
761
762 // 4. PASSWORD
763 if ( tag == LDAP_TAG_EXOP_RBAC_AUTHTOK ) {
764 struct berval bv;
765 tag = ber_scanf( ber, "m", &bv);
766 if ( tag == LBER_ERROR ) {
767 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
768 "authtok parse failed.\n" );
769 goto decoding_error;
770 }
771 ber_dupbv_x( &reqp->authtok, &bv, ctx );
772 tag = ber_peek_tag( ber, &len );
773 }
774
775 // 5. ROLES
776 if ( tag == LDAP_TAG_EXOP_RBAC_ACTIVE_ROLE ) {
777 tag = ber_scanf( ber, "W", &reqp->roles);
778 if ( tag == LBER_ERROR ) {
779 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
780 "role parse failed.\n" );
781 goto decoding_error;
782 }
783 tag = ber_peek_tag( ber, &len );
784 }
785
786 if ( tag != LBER_DEFAULT || len != 0 ) {
787 decoding_error:;
788
789 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
790 "decoding error, len=%ld\n",
791 (long)len );
792 rc = LDAP_PROTOCOL_ERROR;
793 *text = "data decoding error";
794 }
795
796 if ( rc == LDAP_SUCCESS ) {
797 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_create_session: "
798 "SUCCESS\n" );
799
800 *reqpp = reqp;
801 } else {
802 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_create_session: "
803 "NO SUCCESS RC=%d\n", rc );
804
805 rbac_free_req( reqp );
806 *reqpp = NULL;
807 }
808
809 if ( !BER_BVISNULL( &reqdata ) ) {
810 ber_memfree_x( reqdata.bv_val, ctx );
811 }
812
813 return rc;
814 }
815
816 /*
817 * rbac_create_session:
818 * 1. authenticate user
819 * 2. evaluate pwd policy
820 * 3. create session
821 */
822 static int
rbac_create_session(Operation * op,SlapReply * rs)823 rbac_create_session( Operation *op, SlapReply *rs )
824 {
825 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
826 struct berval rbac_op = BER_BVC("CreateSession");
827 BerElementBuffer berbuf;
828 BerElement *ber = (BerElement *)&berbuf;
829 int rc = LDAP_SUCCESS;
830 rbac_session_t *sessp = NULL;
831 rbac_user_t *userp = NULL;
832 rbac_req_t *reqp = NULL;
833
834 rs->sr_err = slap_parse_rbac_create_session(
835 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
836
837 assert( rs->sr_err == LDAP_SUCCESS );
838
839 /* read user entry */
840 userp = rbac_read_user( op, reqp );
841 if ( !userp ) {
842 Debug( LDAP_DEBUG_ANY, "rbac_create_session: "
843 "unable to read user entry\n" );
844 rs->sr_err = LDAP_NO_SUCH_OBJECT;
845 rs->sr_text = "rbac_create_session: unable to read user entry";
846 goto done;
847 }
848
849 if ( !BER_BVISNULL( &userp->password ) ) {
850 /* if request is with pwd, authenticate the user */
851 rc = rbac_authenticate_user( op, userp );
852 if ( rc != LDAP_SUCCESS ) {
853 Debug( LDAP_DEBUG_ANY, "rbac_create_session: "
854 "rbac_authenticate_user failed!\n" );
855 rs->sr_err = LDAP_INVALID_CREDENTIALS;
856 rs->sr_text = "rbac_create_session: invalid credential";
857 goto done;
858 }
859 /*
860 rbac_user_t *ui = op->o_callback->sc_private;
861 int pVal = ui->authz;
862 printf("password reset val=%d", pVal );
863 */
864
865 } else {
866 /* no pwd is provided, check whether the requesting session */
867 /* id has the access privilege to create a session on behalf */
868 /* of the user */
869 rc = rbac_create_session_acl_check( &reqp->sessid, userp );
870 if ( rc != LDAP_SUCCESS ) {
871 Debug( LDAP_DEBUG_ANY, "rbac_create_session: "
872 "rbac_authenticate_user failed!\n" );
873 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
874 rs->sr_text = "rbac_create_session: session permission denied";
875 goto done;
876 }
877 }
878
879 /* check user temporal constraint */
880 rc = rbac_user_temporal_constraint( userp );
881 if ( rc != LDAP_SUCCESS ) {
882 Debug( LDAP_DEBUG_ANY, "rbac_create_session: "
883 "rbac_user_temporal_constraint() failed!\n" );
884 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
885 rs->sr_text = "rbac_create_session: temporal constraint violation";
886 goto done;
887 }
888
889 sessp = rbac_alloc_session();
890 if ( !sessp ) {
891 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
892 rs->sr_text = "rbac_create_session: unable to allocate session";
893 goto done;
894 }
895
896 rc = activate_session_roles( sessp, reqp, userp );
897 if ( rc != LDAP_SUCCESS ) {
898 Debug( LDAP_DEBUG_ANY, "rbac_create_session: "
899 "failed to activate roles to session!\n" );
900 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
901 rs->sr_text =
902 "rbac_create_session: failed to activate roles into session";
903 goto done;
904 }
905
906 /* store uid and tenant id in session */
907 ber_dupbv( &sessp->userdn, &userp->dn );
908 ber_dupbv( &sessp->uid, &reqp->uid );
909 ber_dupbv( &sessp->tenantid, &reqp->tenantid );
910
911 /* register RBAC session */
912 rc = rbac_register_session( op, rs, sessp );
913 if ( rc != LDAP_SUCCESS ) {
914 goto done;
915 }
916
917 ber_init_w_nullc( ber, LBER_USE_DER );
918 rc = ber_printf( ber, "{tO}", LDAP_TAG_EXOP_RBAC_SESSION_ID,
919 &sessp->sessid );
920 if ( rc < 0 ) {
921 rs->sr_err = LDAP_OTHER;
922 rs->sr_text = "internal error";
923 } else {
924 (void)ber_flatten( ber, &rs->sr_rspdata );
925 rs->sr_rspoid = ch_strdup( slap_EXOP_CREATE_SESSION.bv_val );
926 rs->sr_err = LDAP_SUCCESS;
927 }
928
929 ber_free_buf( ber );
930
931 done:;
932
933 // always put the OID in the response:
934 rs->sr_rspoid = ch_strdup( slap_EXOP_CREATE_SESSION.bv_val );
935 /* generate audit log */
936 rbac_audit(
937 op, CreateSession, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
938
939 rbac_free_req( reqp );
940 rbac_free_session( sessp );
941
942 //if (rs->sr_err != LDAP_SUCCESS) {
943 //send_ldap_result( op, rs );
944 //}
945
946 return rs->sr_err;
947 }
948
949 /*
950 * slap_parse_rbac_check_access
951 */
952 static int
slap_parse_rbac_check_access(struct berval * in,rbac_req_t ** reqpp,const char ** text,void * ctx)953 slap_parse_rbac_check_access(
954 struct berval *in,
955 rbac_req_t **reqpp,
956 const char **text,
957 void *ctx )
958 {
959 int rc = LDAP_SUCCESS;
960 struct berval reqdata = BER_BVNULL;
961 rbac_req_t *reqp = NULL;
962 BerElementBuffer berbuf;
963 BerElement *ber = (BerElement *)&berbuf;
964 ber_tag_t tag;
965 ber_len_t len;
966
967 *text = NULL;
968 reqp = rbac_alloc_req( RBAC_REQ_CHECK_ACCESS );
969
970 if ( !reqp ) {
971 *text = "unable to allocate memory for slap_parse_rbac_check_access";
972 return LDAP_PROTOCOL_ERROR;
973 }
974
975 if ( in == NULL || in->bv_len == 0 ) {
976 *text = "empty request data field in rbac_check_access exop";
977 return LDAP_PROTOCOL_ERROR;
978 }
979
980 ber_dupbv_x( &reqdata, in, ctx );
981
982 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */
983 ber_init2( ber, &reqdata, 0 );
984
985 tag = ber_scanf( ber, "{" /*}*/ );
986
987 if ( tag == LBER_ERROR ) {
988 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
989 "decoding error.\n" );
990 goto decoding_error;
991 }
992
993 // sessionId is required:
994 tag = ber_peek_tag( ber, &len );
995 if ( tag != LDAP_TAG_EXOP_RBAC_SESSION_ID ) {
996 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
997 "decoding error.\n" );
998 goto decoding_error;
999 } else {
1000 struct berval bv;
1001 tag = ber_scanf( ber, "m", &bv );
1002 if ( tag == LBER_ERROR ) {
1003 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1004 "session id parse failed.\n" );
1005 goto decoding_error;
1006 }
1007 ber_dupbv_x( &reqp->sessid, &bv, ctx );
1008 tag = ber_peek_tag( ber, &len );
1009 }
1010
1011 // operationName is required:
1012 if ( tag != LDAP_TAG_EXOP_RBAC_OPNAME ) {
1013 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1014 "decoding error.\n" );
1015 goto decoding_error;
1016 } else {
1017 struct berval bv;
1018 tag = ber_scanf( ber, "m", &bv );
1019 if ( tag == LBER_ERROR ) {
1020 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1021 "opname parse failed.\n" );
1022 goto decoding_error;
1023 }
1024 ber_dupbv_x( &reqp->opname, &bv, ctx );
1025 tag = ber_peek_tag( ber, &len );
1026 }
1027
1028 // objectName is required:
1029 if ( tag != LDAP_TAG_EXOP_RBAC_OBJNAME ) {
1030 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1031 "decoding error.\n" );
1032 goto decoding_error;
1033 } else {
1034 struct berval bv;
1035 tag = ber_scanf( ber, "m", &bv );
1036 if ( tag == LBER_ERROR ) {
1037 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1038 "objname parse failed.\n" );
1039 goto decoding_error;
1040 }
1041 ber_dupbv_x( &reqp->objname, &bv, ctx );
1042 tag = ber_peek_tag( ber, &len );
1043 }
1044
1045 // objectId is optional:
1046 if ( tag == LDAP_TAG_EXOP_RBAC_OBJID ) {
1047 struct berval bv;
1048 tag = ber_scanf( ber, "m", &bv );
1049 if ( tag == LBER_ERROR ) {
1050 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1051 "objid parse failed.\n" );
1052 goto decoding_error;
1053 }
1054 ber_dupbv_x( &reqp->objid, &bv, ctx );
1055 tag = ber_peek_tag( ber, &len );
1056 }
1057
1058 if ( tag != LBER_DEFAULT || len != 0 ) {
1059 decoding_error:;
1060
1061 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_check_access: "
1062 "decoding error, len=%ld\n",
1063 (long)len );
1064 rc = LDAP_PROTOCOL_ERROR;
1065 *text = "data decoding error";
1066 }
1067
1068 if ( rc == LDAP_SUCCESS ) {
1069 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_check_access: "
1070 "SUCCESS\n" );
1071 *reqpp = reqp;
1072 } else {
1073 Debug( LDAP_DEBUG_ANY, "slap_parse_rbac_check_access: "
1074 "FAIL\n" );
1075 rbac_free_req( reqp );
1076 }
1077
1078 if ( !BER_BVISNULL( &reqdata ) ) {
1079 ber_memfree_x( reqdata.bv_val, ctx );
1080 }
1081
1082 return rc;
1083 }
1084
1085 // checkAcess F (ALL)
1086 static int
rbac_check_access(Operation * op,SlapReply * rs)1087 rbac_check_access( Operation *op, SlapReply *rs )
1088 {
1089 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1090 rbac_session_t *sessp = NULL;
1091 rbac_permission_t *permp = NULL;
1092 rbac_constraint_t *cp = NULL;
1093 rbac_req_t *reqp = NULL;
1094 const struct berval rbac_op = BER_BVC("CheckAccess");
1095 int rc = LDAP_SUCCESS;
1096 int found = 0;
1097
1098 rs->sr_err = slap_parse_rbac_check_access(
1099 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
1100
1101 assert( rs->sr_err == LDAP_SUCCESS );
1102
1103 BER_BVZERO( &op->o_req_dn );
1104 BER_BVZERO( &op->o_req_ndn );
1105
1106 /* get the session using the session id */
1107 sessp = rbac_session_byid( op, reqp );
1108 if ( !sessp ) {
1109 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1110 "session not found\n" );
1111 rc = LDAP_UNWILLING_TO_PERFORM;
1112 goto done;
1113 }
1114
1115 /* read the permission using objectName and OpName */
1116 permp = rbac_read_permission( op, reqp );
1117 if ( !permp ) {
1118 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1119 "permission not found\n" );
1120 rc = LDAP_UNWILLING_TO_PERFORM;
1121 goto done;
1122 }
1123
1124 // Convert the user-role constraint data from BerVarray to rbac_constraint_t format
1125 cp = rbac_user_role_constraints( sessp->role_constraints );
1126
1127 // Now do the actual rbac checkAccess:
1128 rc = rbac_check_session_permission( sessp, permp, cp );
1129
1130 if ( rc != LDAP_SUCCESS ) {
1131 Debug( LDAP_DEBUG_ANY, "rbac_check_user_permission: "
1132 "failed\n" );
1133 rc = LDAP_UNWILLING_TO_PERFORM;
1134 goto done;
1135 }
1136
1137 done:
1138
1139 rs->sr_err = rc;
1140 // always put the OID in the response:
1141 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val );
1142
1143 /* generate audit log */
1144 rbac_audit( op, CheckAccess, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
1145
1146 rbac_free_permission( permp );
1147 rbac_free_req( reqp );
1148 rbac_free_session( sessp );
1149 rbac_free_constraints( cp );
1150
1151 return rs->sr_err;
1152 }
1153
1154 // checkAcess A loop back
1155 static int
rbac_check_accessA(Operation * op,SlapReply * rs)1156 rbac_check_accessA( Operation *op, SlapReply *rs )
1157 {
1158 int rc = LDAP_SUCCESS;
1159
1160 //rs->sr_err = slap_parse_rbac_check_access(op->ore_reqdata,
1161 // &reqp, &rs->sr_text, NULL);
1162
1163 // always put the OID in the response:
1164 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val );
1165 rs->sr_err = rc;
1166
1167 return rc;
1168 }
1169
1170 // checkAcess B parse
1171 static int
rbac_check_accessB(Operation * op,SlapReply * rs)1172 rbac_check_accessB( Operation *op, SlapReply *rs )
1173 {
1174 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1175 rbac_req_t *reqp = NULL;
1176 const struct berval rbac_op = BER_BVC("CheckAccess");
1177 int rc = LDAP_SUCCESS;
1178
1179 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" );
1180
1181 rs->sr_err = slap_parse_rbac_check_access(
1182 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
1183
1184 assert( rs->sr_err == LDAP_SUCCESS );
1185
1186 BER_BVZERO( &op->o_req_dn );
1187 BER_BVZERO( &op->o_req_ndn );
1188
1189 // always put the OID in the response:
1190 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val );
1191 rs->sr_err = rc;
1192
1193 rbac_free_req( reqp );
1194
1195 return rc;
1196 }
1197
1198 // checkAcess C - parse request & read session record
1199 static int
rbac_check_accessC(Operation * op,SlapReply * rs)1200 rbac_check_accessC( Operation *op, SlapReply *rs )
1201 {
1202 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1203 rbac_session_t *sessp = NULL;
1204 rbac_req_t *reqp = NULL;
1205 const struct berval rbac_op = BER_BVC("CheckAccess");
1206 int rc = LDAP_SUCCESS;
1207
1208 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" );
1209
1210 rs->sr_err = slap_parse_rbac_check_access(
1211 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
1212
1213 assert( rs->sr_err == LDAP_SUCCESS );
1214
1215 BER_BVZERO( &op->o_req_dn );
1216 BER_BVZERO( &op->o_req_ndn );
1217
1218 /* get the session using the session id */
1219 sessp = rbac_session_byid( op, reqp );
1220 if ( !sessp ) {
1221 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1222 "session not found\n" );
1223 rc = LDAP_UNWILLING_TO_PERFORM;
1224 goto done;
1225 }
1226
1227 done:
1228
1229 // always put the OID in the response:
1230 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val );
1231 rs->sr_err = rc;
1232
1233 rbac_free_req( reqp );
1234 rbac_free_session( sessp );
1235 return rc;
1236 }
1237
1238 // checkAcess D, parse, read perm
1239 static int
rbac_check_accessD(Operation * op,SlapReply * rs)1240 rbac_check_accessD( Operation *op, SlapReply *rs )
1241 {
1242 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1243 rbac_permission_t *permp = NULL;
1244 rbac_req_t *reqp = NULL;
1245 const struct berval rbac_op = BER_BVC("CheckAccess");
1246 int rc = LDAP_SUCCESS;
1247
1248 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" );
1249
1250 rs->sr_err = slap_parse_rbac_check_access(
1251 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
1252
1253 assert( rs->sr_err == LDAP_SUCCESS );
1254
1255 BER_BVZERO( &op->o_req_dn );
1256 BER_BVZERO( &op->o_req_ndn );
1257
1258 /* get the session using the session id */
1259 /*
1260 sessp = rbac_session_byid(op, reqp);
1261 if ( !sessp ) {
1262 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1263 "session not found\n" );
1264 rc = LDAP_UNWILLING_TO_PERFORM;
1265 goto done;
1266 }
1267 */
1268
1269 /* read the permission using objectName and OpName */
1270 permp = rbac_read_permission( op, reqp );
1271 if ( !permp ) {
1272 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1273 "permission not found\n" );
1274 rc = LDAP_UNWILLING_TO_PERFORM;
1275 goto done;
1276 }
1277
1278 done:
1279
1280 // always put the OID in the response:
1281 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val );
1282 rs->sr_err = rc;
1283
1284 rbac_free_permission( permp );
1285 rbac_free_req( reqp );
1286
1287 return rc;
1288 }
1289
1290 // checkAcess E everything but the audit insert
1291 static int
rbac_check_accessE(Operation * op,SlapReply * rs)1292 rbac_check_accessE( Operation *op, SlapReply *rs )
1293 {
1294 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1295 rbac_session_t *sessp = NULL;
1296 rbac_permission_t *permp = NULL;
1297 rbac_constraint_t *cp = NULL;
1298 rbac_req_t *reqp = NULL;
1299 const struct berval rbac_op = BER_BVC("CheckAccess");
1300 int rc = LDAP_SUCCESS;
1301
1302 Debug( LDAP_DEBUG_ANY, "rbac_check_access\n" );
1303
1304 rs->sr_err = slap_parse_rbac_check_access(
1305 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
1306
1307 assert( rs->sr_err == LDAP_SUCCESS );
1308
1309 BER_BVZERO( &op->o_req_dn );
1310 BER_BVZERO( &op->o_req_ndn );
1311
1312 /* get the session using the session id */
1313 sessp = rbac_session_byid( op, reqp );
1314 if ( !sessp ) {
1315 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1316 "session not found\n" );
1317 rc = LDAP_UNWILLING_TO_PERFORM;
1318 goto done;
1319 }
1320
1321 /* read the permission using objectName and OpName */
1322 permp = rbac_read_permission( op, reqp );
1323 if ( !permp ) {
1324 Debug( LDAP_DEBUG_ANY, "rbac_check_access: "
1325 "permission not found\n" );
1326 rc = LDAP_UNWILLING_TO_PERFORM;
1327 goto done;
1328 }
1329
1330 // Convert the user-role constraint data from BerVarray to rbac_constraint_t format
1331 cp = rbac_user_role_constraints( sessp->role_constraints );
1332
1333 // Now do the actual rbac checkAccess:
1334 rc = rbac_check_session_permission( sessp, permp, cp );
1335
1336 if ( rc != LDAP_SUCCESS ) {
1337 Debug( LDAP_DEBUG_ANY, "rbac_check_user_permission: "
1338 "failed\n" );
1339 rc = LDAP_UNWILLING_TO_PERFORM;
1340 goto done;
1341 }
1342
1343 done:
1344
1345 rs->sr_err = rc;
1346 // always put the OID in the response:
1347 rs->sr_rspoid = ch_strdup( slap_EXOP_CHECK_ACCESS.bv_val );
1348
1349 /* generate audit log */
1350 //rbac_audit(op, CheckAccess, sessp, reqp, rs->sr_err,
1351 // (char *) rs->sr_text);
1352
1353 rbac_free_permission( permp );
1354 rbac_free_req( reqp );
1355 rbac_free_session( sessp );
1356 rbac_free_constraints( cp );
1357
1358 return rs->sr_err;
1359 }
1360
1361 /* check whether role exists and role assigned to the user */
1362 static int
rbac_check_user_role(rbac_req_t * reqp,rbac_session_t * sessp,rbac_user_t * userp)1363 rbac_check_user_role(
1364 rbac_req_t *reqp,
1365 rbac_session_t *sessp,
1366 rbac_user_t *userp )
1367 {
1368 int rc = 0;
1369 int i;
1370
1371 //assert(!BER_BVISEMPTY(&reqp->roles[0]));
1372 assert( !BER_BVISEMPTY( &reqp->role ) );
1373
1374 for ( i = 0; !BER_BVISNULL( &userp->roles[i] ); i++ ) {
1375 //if (!ber_bvstrcasecmp(&userp->roles[i], &reqp->roles[0])) {
1376 if ( !ber_bvstrcasecmp( &userp->roles[i], &reqp->role ) ) {
1377 rc = 1; /* found the match */
1378 goto done;
1379 }
1380 }
1381
1382 done:;
1383
1384 return rc;
1385 }
1386
1387 /* check whether role exists and role assigned to the session */
1388 static int
rbac_check_session_role(rbac_req_t * reqp,rbac_session_t * sessp)1389 rbac_check_session_role( rbac_req_t *reqp, rbac_session_t *sessp )
1390 {
1391 int rc = 0;
1392 int i;
1393
1394 for ( i = 0; !BER_BVISNULL( &sessp->roles[i] ); i++ ) {
1395 //if (!ber_bvstrcasecmp(&sessp->roles[i], &reqp->roles[0])) {
1396 if ( !ber_bvstrcasecmp( &sessp->roles[i], &reqp->role ) ) {
1397 rc = 1; /* found the match */
1398 goto done;
1399 }
1400 }
1401
1402 done:;
1403
1404 return rc;
1405 }
1406
1407 /* make sure user is the owner of the session */
1408 static int
rbac_check_user_session(rbac_session_t * sessp,rbac_req_t * reqp)1409 rbac_check_user_session( rbac_session_t *sessp, rbac_req_t *reqp )
1410 {
1411 int rc = 0;
1412
1413 if ( BER_BVISNULL( &sessp->uid ) || BER_BVISNULL( &reqp->uid ) ||
1414 sessp->uid.bv_len != reqp->uid.bv_len ) {
1415 goto done;
1416 }
1417
1418 if ( !strncasecmp(
1419 sessp->uid.bv_val, reqp->uid.bv_val, reqp->uid.bv_len ) ) {
1420 rc = 1;
1421 goto done;
1422 }
1423
1424 done:;
1425
1426 return rc;
1427 }
1428
1429 /*
1430 * slap_parse_rbac_active_role
1431 */
1432 static int
slap_parse_rbac_active_role(struct berval * in,int add_or_drop_role,rbac_req_t ** reqpp,const char ** text,void * ctx)1433 slap_parse_rbac_active_role(
1434 struct berval *in,
1435 int add_or_drop_role,
1436 rbac_req_t **reqpp,
1437 const char **text,
1438 void *ctx )
1439 {
1440 int rc = LDAP_SUCCESS;
1441 struct berval reqdata = BER_BVNULL;
1442 rbac_req_t *reqp = NULL;
1443 BerElementBuffer berbuf;
1444 BerElement *ber = (BerElement *)&berbuf;
1445 ber_tag_t tag;
1446 ber_len_t len = -1;
1447
1448 *text = NULL;
1449
1450 if ( in == NULL || in->bv_len == 0 ) {
1451 *text = "empty request data field in rbac_create_session exop";
1452 return LDAP_PROTOCOL_ERROR;
1453 }
1454
1455 reqp = rbac_alloc_req( add_or_drop_role );
1456
1457 if ( !reqp ) {
1458 *text = "unable to allocate memory for rbac_add_drop_active_role exop";
1459 return LDAP_PROTOCOL_ERROR;
1460 }
1461
1462 ber_dupbv_x( &reqdata, in, ctx );
1463
1464 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */
1465 ber_init2( ber, &reqdata, 0 );
1466
1467 tag = ber_scanf( ber, "{" /*}*/ );
1468
1469 if ( tag == LBER_ERROR ) {
1470 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_active_role: "
1471 "decoding error.\n" );
1472 goto decoding_error;
1473 }
1474
1475 tag = ber_peek_tag( ber, &len );
1476 //if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID ) {
1477 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID_SESS ) {
1478 struct berval bv;
1479 tag = ber_scanf( ber, "m", &bv );
1480 if ( tag == LBER_ERROR ) {
1481 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_active_role: "
1482 "user id parse failed.\n" );
1483 goto decoding_error;
1484 }
1485 ber_dupbv( &reqp->uid, &bv );
1486 tag = ber_peek_tag( ber, &len );
1487 }
1488
1489 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ) {
1490 struct berval bv;
1491 tag = ber_scanf( ber, "m", &bv );
1492 if ( tag == LBER_ERROR ) {
1493 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_active_role: "
1494 "session id parse failed.\n" );
1495 goto decoding_error;
1496 }
1497 ber_dupbv( &reqp->sessid, &bv );
1498 tag = ber_peek_tag( ber, &len );
1499 }
1500
1501 if ( tag == LDAP_TAG_EXOP_RBAC_ROLE_NM_SESS ) {
1502 struct berval bv;
1503 tag = ber_scanf( ber, "m", &bv );
1504 //tag = ber_scanf( ber, "W", &reqp->roles);
1505 //tag = ber_scanf( ber, "m", &reqp->roles);
1506 //tag = ber_scanf( ber, "m", &reqp->roles[0]);
1507 if ( tag == LBER_ERROR ) {
1508 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
1509 "role parse failed.\n" );
1510 goto decoding_error;
1511 }
1512 ber_dupbv( &reqp->role, &bv );
1513 //ber_dupbv(&reqp->roles[0], &bv);
1514 tag = ber_peek_tag( ber, &len );
1515 }
1516
1517 if ( tag != LBER_DEFAULT || len != 0 ) {
1518 decoding_error:;
1519 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_create_session: "
1520 "decoding error, len=%ld\n",
1521 (long)len );
1522 rc = LDAP_PROTOCOL_ERROR;
1523 *text = "data decoding error";
1524 }
1525
1526 if ( rc == LDAP_SUCCESS ) {
1527 *reqpp = reqp;
1528 } else {
1529 rbac_free_req( reqp );
1530 *reqpp = NULL;
1531 }
1532
1533 if ( !BER_BVISNULL( &reqdata ) ) {
1534 ber_memfree_x( reqdata.bv_val, ctx );
1535 }
1536
1537 return rc;
1538 }
1539
1540 static int
rbac_add_active_role(Operation * op,SlapReply * rs)1541 rbac_add_active_role( Operation *op, SlapReply *rs )
1542 {
1543 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1544 struct berval rbac_op = BER_BVC("AddActiveRole");
1545 rbac_req_t *reqp = NULL;
1546 rbac_user_t *userp = NULL;
1547 rbac_session_t *sessp;
1548 int rc = LDAP_SUCCESS;
1549
1550 rs->sr_err = slap_parse_rbac_active_role( op->ore_reqdata,
1551 RBAC_REQ_ADD_ACTIVE_ROLE, &reqp, &rs->sr_text, NULL );
1552
1553 assert( rs->sr_err == LDAP_SUCCESS );
1554
1555 /* get the session using the session id */
1556 sessp = rbac_session_byid( op, reqp );
1557 if ( !sessp ) {
1558 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: "
1559 "session not found\n" );
1560 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1561 rs->sr_text = "rbac_add_active_role: session not found";
1562 goto done;
1563 }
1564
1565 /* read user entry */
1566 userp = rbac_read_user( op, reqp );
1567 if ( !userp ) {
1568 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: "
1569 "unable to read user entry\n" );
1570 rs->sr_err = LDAP_NO_SUCH_OBJECT;
1571 rs->sr_text = "rbac_add_active_role: unable to read user entry";
1572 goto done;
1573 }
1574
1575 /* make sure role exists and role assigned to the user */
1576 if ( !rbac_check_user_role( reqp, sessp, userp ) ) {
1577 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: "
1578 "role not assigned to the user\n" );
1579 rs->sr_err = LDAP_NO_SUCH_OBJECT;
1580 rs->sr_text = "rbac_add_active_role: role not assigned to the user";
1581 goto done;
1582 }
1583
1584 /* make sure user is the owner of the session */
1585 if ( !rbac_check_user_session( sessp, reqp ) ) {
1586 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: "
1587 "user not owner of session\n" );
1588 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1589 rs->sr_text = "rbac_add_active_role: user not owner of the session";
1590 goto done;
1591 }
1592
1593 /* add the role to the session */
1594 rc = rbac_session_add_role( op, sessp, reqp );
1595 if ( rc != LDAP_SUCCESS ) {
1596 rs->sr_err = rc;
1597 if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
1598 rs->sr_text =
1599 "rbac_add_active_role: role already activated in session";
1600 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: "
1601 "role already activated in session\n" );
1602 } else {
1603 rs->sr_text = "rbac_add_active_role: unable to add role to session";
1604 Debug( LDAP_DEBUG_ANY, "rbac_add_active_role: "
1605 "unable to add role to session\n" );
1606 }
1607 goto done;
1608 }
1609
1610 done:
1611
1612 // always put the OID in the response:
1613 rs->sr_rspoid = ch_strdup( slap_EXOP_ADD_ACTIVE_ROLE.bv_val );
1614
1615 /* generate audit log */
1616 rbac_audit(
1617 op, AddActiveRole, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
1618
1619 rbac_free_session( sessp );
1620 rbac_free_user( userp );
1621 rbac_free_req( reqp );
1622
1623 return rs->sr_err;
1624 }
1625
1626 static int
rbac_drop_active_role(Operation * op,SlapReply * rs)1627 rbac_drop_active_role( Operation *op, SlapReply *rs )
1628 {
1629 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1630 const struct berval rbac_op = BER_BVC("DropActiveRole");
1631 rbac_session_t *sessp;
1632 rbac_req_t *reqp = NULL;
1633 int rc = LDAP_SUCCESS;
1634
1635 rs->sr_err = slap_parse_rbac_active_role( op->ore_reqdata,
1636 RBAC_REQ_DROP_ACTIVE_ROLE, &reqp, &rs->sr_text, NULL );
1637
1638 assert( rs->sr_err == LDAP_SUCCESS );
1639
1640 /* get the session using the session id */
1641 sessp = rbac_session_byid( op, reqp );
1642 if ( !sessp ) {
1643 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: "
1644 "session not found\n" );
1645 rc = LDAP_UNWILLING_TO_PERFORM;
1646 goto done;
1647 }
1648
1649 if ( BER_BVISNULL( &reqp->role ) || !sessp->roles ||
1650 BER_BVISNULL( &sessp->roles[0] ) ) {
1651 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: "
1652 "unavailable role\n" );
1653 rc = LDAP_UNWILLING_TO_PERFORM;
1654 goto done;
1655 }
1656
1657 /* make sure role exists and role assigned to the user */
1658 if ( !rbac_check_session_role( reqp, sessp ) ) {
1659 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: "
1660 "role not assigned to session\n" );
1661 rc = LDAP_UNWILLING_TO_PERFORM;
1662 goto done;
1663 }
1664
1665 /* make sure user is the owner of the session */
1666 if ( !rbac_check_user_session( sessp, reqp ) ) {
1667 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: "
1668 "user not owner of session\n" );
1669 rc = LDAP_UNWILLING_TO_PERFORM;
1670 rs->sr_text = "rbac_drop_active_role: user not owner of the session";
1671 goto done;
1672 }
1673
1674 /* drop the role to the session */
1675 rc = rbac_session_drop_role( op, sessp, reqp );
1676 if ( rc != LDAP_SUCCESS ) {
1677 Debug( LDAP_DEBUG_ANY, "rbac_drop_active_role: "
1678 "unable to drop active role from session\n" );
1679 rc = LDAP_UNWILLING_TO_PERFORM;
1680 rs->sr_text = "rbac_drop_active_role: unable to drop role from session";
1681 goto done;
1682 }
1683
1684 done:
1685 rs->sr_err = rc;
1686
1687 // always put the OID in the response:
1688 rs->sr_rspoid = ch_strdup( slap_EXOP_DROP_ACTIVE_ROLE.bv_val );
1689
1690 /* generate audit log */
1691 rbac_audit(
1692 op, DropActiveRole, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
1693
1694 rbac_free_session( sessp );
1695 rbac_free_req( reqp );
1696
1697 return rs->sr_err;
1698 }
1699
1700 /*
1701 * slap_parse_rbac_delete_session
1702 */
1703 static int
slap_parse_rbac_delete_session(struct berval * in,rbac_req_t ** reqpp,const char ** text,void * ctx)1704 slap_parse_rbac_delete_session(
1705 struct berval *in,
1706 rbac_req_t **reqpp,
1707 const char **text,
1708 void *ctx )
1709 {
1710 int rc = LDAP_SUCCESS;
1711 struct berval reqdata = BER_BVNULL;
1712 rbac_req_t *reqp = NULL;
1713 BerElementBuffer berbuf;
1714 BerElement *ber = (BerElement *)&berbuf;
1715 ber_tag_t tag;
1716 ber_len_t len = -1;
1717
1718 *text = NULL;
1719
1720 if ( in == NULL || in->bv_len == 0 ) {
1721 *text = "empty request data field in rbac_delete_session exop";
1722 return LDAP_PROTOCOL_ERROR;
1723 }
1724
1725 reqp = rbac_alloc_req( RBAC_REQ_DELETE_SESSION );
1726
1727 if ( !reqp ) {
1728 *text = "unable to allocate memory for rbac_delete_session exop";
1729 return LDAP_PROTOCOL_ERROR;
1730 }
1731
1732 ber_dupbv_x( &reqdata, in, ctx );
1733
1734 /* ber_init2 uses reqdata directly, doesn't allocate new buffers */
1735 ber_init2( ber, &reqdata, 0 );
1736
1737 tag = ber_scanf( ber, "{" /*}*/ );
1738
1739 if ( tag == LBER_ERROR ) {
1740 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: "
1741 "decoding error.\n" );
1742 goto decoding_error;
1743 }
1744
1745 tag = ber_peek_tag( ber, &len );
1746 if ( tag == LDAP_TAG_EXOP_RBAC_USER_ID_SESS ) {
1747 struct berval uid;
1748 tag = ber_scanf( ber, "m", &uid );
1749 if ( tag == LBER_ERROR ) {
1750 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: "
1751 "user id parse failed.\n" );
1752 goto decoding_error;
1753 }
1754 ber_dupbv_x( &reqp->uid, &uid, ctx );
1755 tag = ber_peek_tag( ber, &len );
1756 }
1757
1758 //tag = ber_peek_tag( ber, &len );
1759 if ( tag == LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ) {
1760 struct berval sessid;
1761 tag = ber_scanf( ber, "m", &sessid );
1762 if ( tag == LBER_ERROR ) {
1763 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: "
1764 "session id parse failed.\n" );
1765 goto decoding_error;
1766 }
1767 ber_dupbv_x( &reqp->sessid, &sessid, ctx );
1768 tag = ber_peek_tag( ber, &len );
1769 }
1770
1771 if ( tag != LBER_DEFAULT || len != 0 ) {
1772 decoding_error:;
1773
1774 Debug( LDAP_DEBUG_TRACE, "slap_parse_rbac_delete_session: "
1775 "decoding error, len=%ld\n",
1776 (long)len );
1777 rc = LDAP_PROTOCOL_ERROR;
1778 *text = "data decoding error";
1779 }
1780
1781 if ( rc == LDAP_SUCCESS ) {
1782 *reqpp = reqp;
1783 } else {
1784 rbac_free_req( reqp );
1785 *reqpp = NULL;
1786 }
1787
1788 if ( !BER_BVISNULL( &reqdata ) ) {
1789 ber_memfree_x( reqdata.bv_val, ctx );
1790 }
1791
1792 return rc;
1793 }
1794
1795 static int
rbac_delete_session(Operation * op,SlapReply * rs)1796 rbac_delete_session( Operation *op, SlapReply *rs )
1797 {
1798 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1799 const struct berval rbac_op = BER_BVC("DeleteSession");
1800 rbac_session_t *sessp = NULL;
1801 rbac_req_t *reqp = NULL;
1802 int rc;
1803
1804 rs->sr_err = slap_parse_rbac_delete_session(
1805 op->ore_reqdata, &reqp, &rs->sr_text, NULL );
1806
1807 assert( rs->sr_err == LDAP_SUCCESS );
1808
1809 /* get the session using the session id */
1810 sessp = rbac_session_byid( op, reqp );
1811 if ( !sessp ) {
1812 Debug( LDAP_DEBUG_ANY, "rbac_delete_session: "
1813 "session not found\n" );
1814 rc = LDAP_UNWILLING_TO_PERFORM;
1815 goto done;
1816 }
1817
1818 /* checking whether the session is owned by the user */
1819 if ( !rbac_is_session_owner( sessp, reqp ) ) {
1820 Debug( LDAP_DEBUG_ANY, "rbac_delete_session: "
1821 "session not owned by user\n" );
1822 rc = LDAP_UNWILLING_TO_PERFORM;
1823 goto done;
1824 }
1825
1826 rc = rbac_int_delete_session( op, sessp );
1827 if ( rc != LDAP_SUCCESS ) {
1828 Debug( LDAP_DEBUG_ANY, "rbac_int_delete_session: "
1829 "unable to delete session\n" );
1830 rc = LDAP_UNWILLING_TO_PERFORM;
1831 goto done;
1832 }
1833
1834 done:;
1835
1836 rs->sr_err = rc;
1837
1838 // always put the OID in the response:
1839 rs->sr_rspoid = ch_strdup( slap_EXOP_DELETE_SESSION.bv_val );
1840
1841 /* generate audit log */
1842 rbac_audit(
1843 op, DeleteSession, sessp, reqp, rs->sr_err, (char *)rs->sr_text );
1844
1845 rbac_free_session( sessp );
1846 rbac_free_req( reqp );
1847
1848 return rs->sr_err;
1849 }
1850
1851 /* returns the permissions associated with a session */
1852 static int
rbac_session_permissions(Operation * op,SlapReply * rs,rbac_req_t * reqp)1853 rbac_session_permissions( Operation *op, SlapReply *rs, rbac_req_t *reqp )
1854 {
1855 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1856 const struct berval rbac_op = BER_BVC("SessionPermissions");
1857 rbac_session_t *sessp;
1858
1859 sessp = rbac_session_byid( op, reqp );
1860 if ( !sessp ) {
1861 Debug( LDAP_DEBUG_ANY, "rbac_session_permissions: "
1862 "session id not found\n" );
1863 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1864 goto done;
1865 }
1866
1867 rs->sr_err = rbac_int_session_permissions( op, rs, reqp, sessp );
1868 if ( rs->sr_err != LDAP_SUCCESS ) {
1869 Debug( LDAP_DEBUG_ANY, "rbac_session_permissions: "
1870 "permissions not found\n" );
1871 goto done;
1872 }
1873
1874 done:;
1875 return rs->sr_err;
1876 }
1877
1878 /* extract session permission info from op */
1879 int
rbac_search_parse_session_permissions_req(Operation * op,rbac_req_t ** reqpp,const char ** text,void * ctx)1880 rbac_search_parse_session_permissions_req(
1881 Operation *op,
1882 rbac_req_t **reqpp,
1883 const char **text,
1884 void *ctx )
1885 {
1886 int rc = LDAP_SUCCESS;
1887 struct berval *sessid = NULL;
1888 rbac_req_t *reqp = NULL;
1889 *text = NULL;
1890 struct berval rbac_session_id = BER_BVC("sessionID");
1891 struct berval rbac_session_permissions_attr =
1892 BER_BVC("sessionPermissions");
1893 AttributeDescription *ad = NULL;
1894 Filter *f;
1895
1896 /* check simple assertion (sessionID=<session id>) */
1897 f = op->ors_filter;
1898 ad = f->f_ava->aa_desc;
1899 if ( !ad || ber_bvstrcasecmp( &rbac_session_id, &ad->ad_cname ) ) {
1900 goto done;
1901 }
1902 sessid = &f->f_ava->aa_value;
1903
1904 if ( !rbac_is_valid_session_id( sessid ) ) {
1905 Debug( LDAP_DEBUG_ANY, "rbac_search_parse_session_permissions_req: "
1906 "invalid session id\n" );
1907 rc = LDAP_UNWILLING_TO_PERFORM;
1908 goto done;
1909 }
1910
1911 /* check requested attr */
1912
1913 if ( !op->oq_search.rs_attrs ||
1914 BER_BVISNULL( &op->oq_search.rs_attrs[0].an_name ) ||
1915 ber_bvstrcasecmp( &op->oq_search.rs_attrs[0].an_name,
1916 &rbac_session_permissions_attr ) ||
1917 !BER_BVISNULL( &op->oq_search.rs_attrs[1].an_name ) ) {
1918 Debug( LDAP_DEBUG_ANY, "rbac_search_parse_session_permissions_req: "
1919 "only sessionPermissions allowed\n" );
1920 rc = LDAP_UNWILLING_TO_PERFORM;
1921 goto done;
1922 }
1923
1924 reqp = rbac_alloc_req( RBAC_REQ_SESSION_PERMISSIONS );
1925 if ( !reqp ) {
1926 *text = "unable to allocate memory for rbac_session_permissions req";
1927 rc = LDAP_UNWILLING_TO_PERFORM;
1928 goto done;
1929 }
1930
1931 /* retrieve session id from search filter */
1932 ber_dupbv_x( &reqp->sessid, sessid, ctx );
1933
1934 done:;
1935
1936 if ( rc == LDAP_SUCCESS ) {
1937 *reqpp = reqp;
1938 } else {
1939 rbac_free_req( reqp );
1940 *reqpp = NULL;
1941 }
1942
1943 return rc;
1944 }
1945
1946 static int
rbac_search(Operation * op,SlapReply * rs)1947 rbac_search( Operation *op, SlapReply *rs )
1948 {
1949 Debug( LDAP_DEBUG_ANY, "rbac_search entry\n" );
1950
1951 return SLAP_CB_CONTINUE;
1952 }
1953
1954 /*
1955 static int
1956 rbac_search( Operation *op, SlapReply *rs )
1957 {
1958 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
1959 rbac_req_t *reqp = NULL;
1960 int rc = SLAP_CB_CONTINUE;
1961
1962 only session_permissions is implemented for now
1963 rc = rbac_search_parse_session_permissions_req(
1964 op, &reqp, &rs->sr_text, NULL );
1965 if ( !reqp ) {
1966 Debug( LDAP_DEBUG_ANY, "rbac_search: "
1967 "invalid search for session permissions\n" );
1968 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1969 goto done;
1970 }
1971
1972 rc = rbac_session_permissions( op, rs, reqp );
1973 if ( rc != LDAP_SUCCESS ) {
1974 Debug( LDAP_DEBUG_ANY, "rbac_search: "
1975 "session permissions failed\n" );
1976 rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
1977 goto done;
1978 }
1979
1980 rs->sr_err = LDAP_SUCCESS;
1981
1982 done:;
1983 send_ldap_result( op, rs );
1984
1985 return rc;
1986 }
1987 */
1988
1989 static struct exop {
1990 struct berval oid;
1991 BI_op_extended *extended;
1992 } rbac_exop_table[] = {
1993 { BER_BVC(LDAP_RBAC_EXOP_CREATE_SESSION), rbac_create_session },
1994 { BER_BVC(LDAP_RBAC_EXOP_CHECK_ACCESS), rbac_check_access },
1995 { BER_BVC(LDAP_RBAC_EXOP_ADD_ACTIVE_ROLE), rbac_add_active_role },
1996 { BER_BVC(LDAP_RBAC_EXOP_DROP_ACTIVE_ROLE), rbac_drop_active_role },
1997 { BER_BVC(LDAP_RBAC_EXOP_DELETE_SESSION), rbac_delete_session },
1998 { BER_BVC(LDAP_RBAC_EXOP_SESSION_ROLES), rbac_session_roles },
1999
2000 { BER_BVNULL, NULL }
2001 };
2002
2003 static int
rbac_add(Operation * op,SlapReply * rs)2004 rbac_add( Operation *op, SlapReply *rs )
2005 {
2006 return SLAP_CB_CONTINUE;
2007 }
2008
2009 static int
rbac_bind(Operation * op,SlapReply * rs)2010 rbac_bind( Operation *op, SlapReply *rs )
2011 {
2012 return SLAP_CB_CONTINUE;
2013 }
2014
2015 static int
rbac_compare(Operation * op,SlapReply * rs)2016 rbac_compare( Operation *op, SlapReply *rs )
2017 {
2018 return SLAP_CB_CONTINUE;
2019 }
2020
2021 static int
rbac_delete(Operation * op,SlapReply * rs)2022 rbac_delete( Operation *op, SlapReply *rs )
2023 {
2024 return SLAP_CB_CONTINUE;
2025 }
2026
2027 static int
rbac_modify(Operation * op,SlapReply * rs)2028 rbac_modify( Operation *op, SlapReply *rs )
2029 {
2030 return SLAP_CB_CONTINUE;
2031 }
2032
2033 static int
rbac_extended(Operation * op,SlapReply * rs)2034 rbac_extended( Operation *op, SlapReply *rs )
2035 {
2036 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
2037 int rc = SLAP_CB_CONTINUE;
2038 int i;
2039
2040 for ( i = 0; rbac_exop_table[i].extended != NULL; i++ ) {
2041 if ( bvmatch( &rbac_exop_table[i].oid, &op->oq_extended.rs_reqoid ) ) {
2042 rc = rbac_exop_table[i].extended( op, rs );
2043 switch ( rc ) {
2044 case LDAP_SUCCESS:
2045 break;
2046 case SLAP_CB_CONTINUE:
2047 case SLAPD_ABANDON:
2048 return rc;
2049 default:
2050 send_ldap_result( op, rs );
2051 return rc;
2052 }
2053 break;
2054 }
2055 }
2056
2057 return rc;
2058 }
2059
2060 static int
rbac_db_init(BackendDB * be,ConfigReply * cr)2061 rbac_db_init( BackendDB *be, ConfigReply *cr )
2062 {
2063 slap_overinst *on = (slap_overinst *)be->bd_info;
2064
2065 return 0;
2066 }
2067
2068 static int
rbac_db_open(BackendDB * be,ConfigReply * cr)2069 rbac_db_open( BackendDB *be, ConfigReply *cr )
2070 {
2071 int rc = LDAP_SUCCESS;
2072
2073 rc = rbac_initialize_tenants( be, cr );
2074
2075 return rc;
2076 }
2077
2078 static int
rbac_db_close(BackendDB * be,ConfigReply * cr)2079 rbac_db_close( BackendDB *be, ConfigReply *cr )
2080 {
2081 return 0;
2082 }
2083
2084 int
rbac_initialize()2085 rbac_initialize()
2086 {
2087 int rc;
2088
2089 rc = load_extop2( (struct berval *)&slap_EXOP_CREATE_SESSION,
2090 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_create_session, 0 );
2091 if ( rc != LDAP_SUCCESS ) {
2092 Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
2093 "unable to register rbac_create_session exop: %d\n",
2094 rc );
2095 return rc;
2096 }
2097
2098 rc = load_extop2( (struct berval *)&slap_EXOP_CHECK_ACCESS,
2099 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_check_access, 0 );
2100 if ( rc != LDAP_SUCCESS ) {
2101 Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
2102 "unable to register rbac_check_access exop: %d\n",
2103 rc );
2104 return rc;
2105 }
2106
2107 rc = load_extop2( (struct berval *)&slap_EXOP_ADD_ACTIVE_ROLE,
2108 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_add_active_role, 0 );
2109 if ( rc != LDAP_SUCCESS ) {
2110 Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
2111 "unable to register rbac_add_active_role exop: %d\n",
2112 rc );
2113 return rc;
2114 }
2115
2116 rc = load_extop2( (struct berval *)&slap_EXOP_DROP_ACTIVE_ROLE,
2117 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_drop_active_role, 0 );
2118 if ( rc != LDAP_SUCCESS ) {
2119 Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
2120 "unable to register rbac_drop_active_role exop: %d\n",
2121 rc );
2122 return rc;
2123 }
2124
2125 rc = load_extop2( (struct berval *)&slap_EXOP_DELETE_SESSION,
2126 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_delete_session, 0 );
2127 if ( rc != LDAP_SUCCESS ) {
2128 Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
2129 "unable to register rbac_delete_session exop: %d\n",
2130 rc );
2131 return rc;
2132 }
2133
2134 rc = load_extop2( (struct berval *)&slap_EXOP_SESSION_ROLES,
2135 SLAP_EXOP_WRITES|SLAP_EXOP_HIDE, rbac_session_roles, 0 );
2136 if ( rc != LDAP_SUCCESS ) {
2137 Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
2138 "unable to register rbac_session_roles exop: %d\n",
2139 rc );
2140 return rc;
2141 }
2142
2143 rbac.on_bi.bi_type = "rbac";
2144 rbac.on_bi.bi_db_init = rbac_db_init;
2145 rbac.on_bi.bi_db_open = rbac_db_open;
2146 rbac.on_bi.bi_db_close = rbac_db_close;
2147
2148 rbac.on_bi.bi_op_add = rbac_add;
2149 rbac.on_bi.bi_op_bind = rbac_bind;
2150 rbac.on_bi.bi_op_compare = rbac_compare;
2151 rbac.on_bi.bi_op_delete = rbac_delete;
2152 rbac.on_bi.bi_op_modify = rbac_modify;
2153 rbac.on_bi.bi_op_search = rbac_search;
2154 rbac.on_bi.bi_extended = rbac_extended;
2155 rbac.on_bi.bi_cf_ocs = rbac_ocs;
2156
2157 /* rbac.on_bi.bi_connection_destroy = rbac_connection_destroy; */
2158
2159 rc = config_register_schema( rbaccfg, rbac_ocs );
2160 if ( rc ) return rc;
2161
2162 rc = rbac_initialize_repository();
2163 if ( rc != LDAP_SUCCESS ) {
2164 return rc;
2165 }
2166
2167 return overlay_register( &rbac );
2168 }
2169
2170 int
init_module(int argc,char * argv[])2171 init_module( int argc, char *argv[] )
2172 {
2173 return rbac_initialize();
2174 }
2175