Commit d594ffe9 authored by Ondřej Kuzník's avatar Ondřej Kuzník Committed by Quanah Gibson-Mount
Browse files

ITS#9471 Add RBAC overlay to contrib

parent fd39b726
# $OpenLDAP$
LDAP_SRC = ../../..
LDAP_BUILD = $(LDAP_SRC)
LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
LDAP_LIB = $(LDAP_BUILD)/libraries/libldap/libldap.la \
$(LDAP_BUILD)/libraries/liblber/liblber.la
LIBTOOL = $(LDAP_BUILD)/libtool
CC = gcc
OPT = -g -O2 -Wall
DEFS = -DSLAPD_OVER_RBAC=SLAPD_MOD_DYNAMIC
INCS = $(LDAP_INC)
LIBS = $(LDAP_LIB)
PROGRAMS = rbac.la
LTVER = 0:0:0
prefix=/usr/local
exec_prefix=$(prefix)
ldap_subdir=/openldap
libdir=$(exec_prefix)/lib
libexecdir=$(exec_prefix)/libexec
moduledir = $(libexecdir)$(ldap_subdir)
SRCS = rbac.c rbacperm.c rbacsess.c rbacuser.c rbacreq.c rbacaudit.c init.c rbacacl.c util.c jts.c
OBJS = $(patsubst %.c,%.o,$(SRCS))
LOBJS = $(patsubst %.c,%.lo,$(SRCS))
.SUFFIXES: .c .lo
%.lo: %.c rbac.h
$(LIBTOOL) --mode=compile $(CC) $(OPT) $(DEFS) $(INCS) -c $<
all: $(PROGRAMS)
rbac.la: $(LOBJS)
$(LIBTOOL) --mode=link $(CC) $(OPT) -version-info $(LTVER) \
-rpath $(moduledir) -module -o $@ $^ $(LIBS)
clean:
rm -rf *.o *.lo *.la .libs
install: $(PROGRAMS)
mkdir -p $(DESTDIR)$(moduledir)
for p in $(PROGRAMS) ; do \
$(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \
done
/* init.c - RBAC initialization */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "slap.h"
#include "slap-config.h"
#include "lutil.h"
#include "rbac.h"
static slap_callback nullsc = { NULL, NULL, NULL, NULL };
struct slap_rbac_internal_schema slap_rbac_schema;
extern rbac_tenant_t rbac_tenants;
extern int initialize_jts( void );
rbac_ad_t rbac_session_ads[] = {
{ RBAC_SESSION_ID,
BER_BVC("rbacSessid"), &slap_rbac_schema.ad_session_id },
{ RBAC_USER_DN,
BER_BVC("rbacUserDN"), &slap_rbac_schema.ad_session_user_dn },
{ RBAC_ROLES,
BER_BVC("rbacRoles"), &slap_rbac_schema.ad_session_roles },
{ RBAC_ROLE_CONSTRAINTS,
BER_BVC("rbacRoleConstraints"),
&slap_rbac_schema.ad_session_role_constraints },
{ RBAC_UID,
BER_BVC("uid"), &slap_rbac_schema.ad_uid},
{ RBAC_TENANT_ID,
BER_BVC("tenantid"), &slap_rbac_schema.ad_tenant_id },
{ RBAC_NONE, BER_BVNULL, NULL }
};
rbac_ad_t rbac_session_permission_ads[] = {
{ RBAC_OP_NAME,
BER_BVC("rbacOpName"), &slap_rbac_schema.ad_permission_opname },
{ RBAC_OBJ_NAME,
BER_BVC("rbacObjName"), &slap_rbac_schema.ad_permission_objname },
{ RBAC_ROLE_NAME,
BER_BVC("rbacRoleName"), &slap_rbac_schema.ad_permission_rolename },
{ RBAC_NONE, BER_BVNULL, NULL }
};
rbac_ad_t audit_ads[] = {
{ RBAC_AUDIT_OP,
BER_BVC("rbacAuditOp"), &slap_rbac_schema.ad_audit_op },
{ RBAC_AUDIT_ID,
BER_BVC("rbacAuditId"), &slap_rbac_schema.ad_audit_id },
{ RBAC_AUDIT_ROLES,
BER_BVC("rbacAuditRoles"), &slap_rbac_schema.ad_audit_roles },
{ RBAC_AUDIT_REQUESTED_ROLES,
BER_BVC("rbacAuditRequestedRoles"),
&slap_rbac_schema.ad_audit_requested_roles
},
{ RBAC_AUDIT_TIMESTAMP,
BER_BVC("rbacAuditTimestamp"), &slap_rbac_schema.ad_audit_timestamp },
{ RBAC_AUDIT_RESOURCES,
BER_BVC("rbacAuditResources"), &slap_rbac_schema.ad_audit_resources },
{ RBAC_AUDIT_OBJS,
BER_BVC("rbacAuditObjects"), &slap_rbac_schema.ad_audit_objects },
{ RBAC_AUDIT_OPS,
BER_BVC("rbacAuditOperations"), &slap_rbac_schema.ad_audit_operations },
{ RBAC_AUDIT_RESULT,
BER_BVC("rbacAuditResult"), &slap_rbac_schema.ad_audit_result },
{ RBAC_AUDIT_PROPERTIES,
BER_BVC("rbacAuditProperties"), &slap_rbac_schema.ad_audit_properties },
{ RBAC_AUDIT_MSGS,
BER_BVC("rbacAuditMessages"), &slap_rbac_schema.ad_audit_messages },
{ RBAC_NONE, BER_BVNULL, NULL }
};
/* initialize repository attribute descriptions */
static int
initialize_sessions()
{
int i, nattrs, rc = LDAP_SUCCESS;
const char *text;
for ( nattrs = 0; !BER_BVISNULL( &rbac_session_ads[nattrs].attr );
nattrs++ )
; /* count the number of attrs */
slap_rbac_schema.session_attrs =
slap_sl_calloc( sizeof(AttributeName), nattrs + 1, NULL );
for ( i = 0; !BER_BVISNULL( &rbac_session_ads[i].attr ); i++ ) {
rc = slap_bv2ad(
&rbac_session_ads[i].attr, rbac_session_ads[i].ad, &text );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
slap_rbac_schema.session_attrs[i].an_name = rbac_session_ads[i].attr;
slap_rbac_schema.session_attrs[i].an_desc = *rbac_session_ads[i].ad;
}
BER_BVZERO( &slap_rbac_schema.session_attrs[nattrs].an_name );
done:;
return rc;
}
static int
initialize_audit()
{
int i, rc = LDAP_SUCCESS;
const char *text;
/* for audit */
for ( i = 0; !BER_BVISNULL( &audit_ads[i].attr ); i++ ) {
rc = slap_bv2ad( &audit_ads[i].attr, audit_ads[i].ad, &text );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
}
done:;
return rc;
}
static int
initialize_tenant(
BackendDB *be,
ConfigReply *cr,
tenant_info_t *tenantp,
int init_op )
{
int rc = LDAP_SUCCESS;
Entry *e = NULL;
OperationBuffer opbuf;
Operation *op2;
SlapReply rs2 = { REP_RESULT };
Connection conn = { 0 };
struct berval rbac_container_oc = BER_BVC("rbacContainer");
struct berval rbac_audit_container = BER_BVC("audit");
struct berval rbac_session_container = BER_BVC("rbac");
void *thrctx = ldap_pvt_thread_pool_context();
e = entry_alloc();
switch ( init_op ) {
case INIT_AUDIT_CONTAINER:
ber_dupbv( &e->e_name, &tenantp->audit_basedn );
ber_dupbv( &e->e_nname, &tenantp->audit_basedn );
/* container cn */
attr_merge_one(
e, slap_schema.si_ad_cn, &rbac_audit_container, NULL );
break;
case INIT_SESSION_CONTAINER:
ber_dupbv( &e->e_name, &tenantp->sessions_basedn );
ber_dupbv( &e->e_nname, &tenantp->sessions_basedn );
/* rendered dynmaicObject for session */
attr_merge_one( e, slap_schema.si_ad_objectClass,
&slap_schema.si_oc_dynamicObject->soc_cname, NULL );
/* container cn */
attr_merge_one(
e, slap_schema.si_ad_cn, &rbac_session_container, NULL );
break;
default:
break;
}
attr_merge_one(
e, slap_schema.si_ad_objectClass, &rbac_container_oc, NULL );
attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
&rbac_container_oc, NULL );
/* store RBAC session */
connection_fake_init2( &conn, &opbuf, thrctx, 0 );
op2 = &opbuf.ob_op;
op2->o_callback = &nullsc;
op2->o_tag = LDAP_REQ_ADD;
op2->o_protocol = LDAP_VERSION3;
op2->o_req_dn = e->e_name;
op2->o_req_ndn = e->e_nname;
op2->ora_e = e;
op2->o_bd = select_backend( &op2->o_req_ndn, 0 );
op2->o_dn = op2->o_bd->be_rootdn;
op2->o_ndn = op2->o_bd->be_rootndn;
rc = op2->o_bd->be_add( op2, &rs2 );
if ( e ) entry_free( e );
return rc;
}
int
rbac_initialize_tenants( BackendDB *be, ConfigReply *cr )
{
int rc = LDAP_SUCCESS;
rbac_tenant_t *tenantp = NULL;
for ( tenantp = &rbac_tenants; tenantp; tenantp = tenantp->next ) {
rc = initialize_tenant(
be, cr, &tenantp->tenant_info, INIT_AUDIT_CONTAINER );
if ( rc != LDAP_SUCCESS ) {
if ( rc == LDAP_ALREADY_EXISTS ) {
Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
"audit container exists, tenant (%s)\n",
tenantp->tenant_info.tid.bv_val ?
tenantp->tenant_info.tid.bv_val :
"NULL" );
rc = LDAP_SUCCESS;
} else {
Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
"failed to initialize (%s): rc (%d)\n",
tenantp->tenant_info.tid.bv_val ?
tenantp->tenant_info.tid.bv_val :
"NULL",
rc );
goto done;
}
} else {
Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
"created audit container for tenant (%s):\n",
tenantp->tenant_info.tid.bv_val ?
tenantp->tenant_info.tid.bv_val :
"NULL" );
}
rc = initialize_tenant(
be, cr, &tenantp->tenant_info, INIT_SESSION_CONTAINER );
if ( rc != LDAP_SUCCESS ) {
if ( rc == LDAP_ALREADY_EXISTS ) {
Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
"session container exists, tenant (%s)\n",
tenantp->tenant_info.tid.bv_val ?
tenantp->tenant_info.tid.bv_val :
"NULL" );
rc = LDAP_SUCCESS;
} else {
Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
"failed to initialize (%s): rc (%d)\n",
tenantp->tenant_info.tid.bv_val ?
tenantp->tenant_info.tid.bv_val :
"NULL",
rc );
goto done;
}
} else {
Debug( LDAP_DEBUG_ANY, "rbac_initialize: "
"created session container for tenant (%s):\n",
tenantp->tenant_info.tid.bv_val ?
tenantp->tenant_info.tid.bv_val :
"NULL" );
}
}
done:;
return rc;
}
static int
initialize_rbac_session_permissions()
{
int i, rc = LDAP_SUCCESS;
const char *text;
for ( i = 0; !BER_BVISNULL( &rbac_session_permission_ads[i].attr ); i++ ) {
rc = slap_bv2ad( &rbac_session_permission_ads[i].attr,
rbac_session_permission_ads[i].ad, &text );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
}
done:;
return rc;
}
int
rbac_initialize_repository()
{
int rc = LDAP_SUCCESS;
rc = initialize_jts();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = initialize_rbac_session_permissions();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = initialize_sessions();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = initialize_audit();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
return rc;
}
/* jts.c - RBAC JTS initialization */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "slap.h"
#include "slap-config.h"
#include "lutil.h"
#include "rbac.h"
struct slap_rbac_tenant_schema slap_rbac_jts_schema;
/* to replace all JTS schema initialization */
rbac_ad_t ft_ads[] = {
{ RBAC_ROLE_ASSIGNMENT,
BER_BVC("ftRA"), &slap_rbac_jts_schema.ad_role },
{ RBAC_ROLE_CONSTRAINTS,
BER_BVC("ftRC"), &slap_rbac_jts_schema.ad_role_constraint },
{ RBAC_USER_CONSTRAINTS,
BER_BVC("ftCstr"), &slap_rbac_jts_schema.ad_user_constraint },
{ RBAC_UID,
BER_BVC("uid"), &slap_rbac_jts_schema.ad_uid },
{ RBAC_USERS,
BER_BVC("ftUsers"), &slap_rbac_jts_schema.ad_permission_users },
{ RBAC_ROLES,
BER_BVC("ftRoles"), &slap_rbac_jts_schema.ad_permission_roles },
{ RBAC_OBJ_NAME,
BER_BVC("ftObjNm"), &slap_rbac_jts_schema.ad_permission_objname },
{ RBAC_OP_NAME,
BER_BVC("ftOpNm"), &slap_rbac_jts_schema.ad_permission_opname },
{ RBAC_NONE, BER_BVNULL, NULL }
};
rbac_ad_t ft_user_ads[] = {
{ RBAC_ROLE_ASSIGNMENT,
BER_BVC("ftRA"), &slap_rbac_jts_schema.ad_role },
{ RBAC_ROLE_CONSTRAINTS,
BER_BVC("ftRC"), &slap_rbac_jts_schema.ad_role_constraint },
{ RBAC_USER_CONSTRAINTS,
BER_BVC("ftCstr"), &slap_rbac_jts_schema.ad_user_constraint },
{ RBAC_UID,
BER_BVC("uid"), &slap_rbac_jts_schema.ad_uid },
{ RBAC_NONE, BER_BVNULL, NULL }
};
rbac_ad_t ft_perm_ads[] = {
{ RBAC_USERS,
BER_BVC("ftUsers"), &slap_rbac_jts_schema.ad_permission_users },
{ RBAC_ROLES,
BER_BVC("ftRoles"), &slap_rbac_jts_schema.ad_permission_roles },
{ RBAC_NONE, BER_BVNULL, NULL }
};
rbac_ad_t ft_session_perm_ads[] = {
{ RBAC_USERS,
BER_BVC("ftUsers"), &slap_rbac_jts_schema.ad_permission_users },
{ RBAC_ROLES,
BER_BVC("ftRoles"), &slap_rbac_jts_schema.ad_permission_roles },
{ RBAC_OBJ_NAME,
BER_BVC("ftObjNm"), &slap_rbac_jts_schema.ad_permission_objname },
{ RBAC_OP_NAME,
BER_BVC("ftOpNm"), &slap_rbac_jts_schema.ad_permission_opname },
{ RBAC_NONE, BER_BVNULL, NULL }
};
static int
initialize_jts_session_permission_ads()
{
int i, nattrs, rc = LDAP_SUCCESS;
for ( nattrs = 0; !BER_BVISNULL( &ft_session_perm_ads[nattrs].attr );
nattrs++ )
; /* count the number of attrs */
slap_rbac_jts_schema.session_perm_attrs =
slap_sl_calloc( sizeof(AttributeName), nattrs + 1, NULL );
for ( i = 0; !BER_BVISNULL( &ft_session_perm_ads[i].attr ); i++ ) {
slap_rbac_jts_schema.session_perm_attrs[i].an_name =
ft_session_perm_ads[i].attr;
slap_rbac_jts_schema.session_perm_attrs[i].an_desc =
*ft_session_perm_ads[i].ad;
}
BER_BVZERO( &slap_rbac_jts_schema.session_perm_attrs[nattrs].an_name );
slap_rbac_jts_schema.session_permissions_ads = ft_session_perm_ads;
return rc;
}
static int
initialize_jts_permission_ads()
{
int i, nattrs, rc = LDAP_SUCCESS;
/* jts permissions configuration */
for ( nattrs = 0; !BER_BVISNULL( &ft_perm_ads[nattrs].attr ); nattrs++ )
; /* count the number of attrs */
slap_rbac_jts_schema.perm_attrs =
slap_sl_calloc( sizeof(AttributeName), nattrs + 1, NULL );
for ( i = 0; !BER_BVISNULL( &ft_perm_ads[i].attr ); i++ ) {
slap_rbac_jts_schema.perm_attrs[i].an_name = ft_perm_ads[i].attr;
slap_rbac_jts_schema.perm_attrs[i].an_desc = *ft_perm_ads[i].ad;
}
BER_BVZERO( &slap_rbac_jts_schema.perm_attrs[nattrs].an_name );
slap_rbac_jts_schema.permission_ads = ft_perm_ads;
return rc;
}
static int
initialize_jts_user_ads()
{
int i, nattrs, rc = LDAP_SUCCESS;
/* jts user attribute descriptions */
/* jts user attributes */
for ( nattrs = 0; !BER_BVISNULL( &ft_user_ads[nattrs].attr ); nattrs++ )
; /* count the number of attrs */
slap_rbac_jts_schema.user_attrs =
slap_sl_calloc( sizeof(AttributeName), nattrs + 1, NULL );
for ( i = 0; !BER_BVISNULL( &ft_user_ads[i].attr ); i++ ) {
slap_rbac_jts_schema.user_attrs[i].an_name = ft_user_ads[i].attr;
slap_rbac_jts_schema.user_attrs[i].an_desc = *ft_user_ads[i].ad;
}
BER_BVZERO( &slap_rbac_jts_schema.user_attrs[nattrs].an_name );
slap_rbac_jts_schema.user_ads = ft_user_ads;
return rc;
}
int
initialize_jts()
{
int i, rc;
const char *text;
/* jts attributes */
for ( i = 0; !BER_BVISNULL( &ft_ads[i].attr ); i++ ) {
rc = slap_bv2ad( &ft_ads[i].attr, ft_ads[i].ad, &text );
if ( rc != LDAP_SUCCESS ) {
goto done;
}
}
rc = initialize_jts_user_ads();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = initialize_jts_permission_ads();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
rc = initialize_jts_session_permission_ads();
if ( rc != LDAP_SUCCESS ) {
return rc;
}
done:;
return rc;
}
#ifndef LDAP_RBAC_H
#define LDAP_RBAC_H
/* extended operations for RBAC */
#define LDAP_RBAC_EXOP_CREATE_SESSION "1.3.6.1.4.1.4203.555.1" /* RFC xxxx */
#define LDAP_RBAC_EXOP_CHECK_ACCESS "1.3.6.1.4.1.4203.555.2"
#define LDAP_RBAC_EXOP_ADD_ACTIVE_ROLE "1.3.6.1.4.1.4203.555.3"
#define LDAP_RBAC_EXOP_DROP_ACTIVE_ROLE "1.3.6.1.4.1.4203.555.4"
#define LDAP_RBAC_EXOP_DELETE_SESSION "1.3.6.1.4.1.4203.555.5"
#define LDAP_RBAC_EXOP_SESSION_ROLES "1.3.6.1.4.1.4203.555.6"
#define LDAP_RBAC_EXOP_SESSION_PERMISSIONS "1.3.6.1.4.1.4203.555.7"
#define LDAP_TAG_EXOP_RBAC_SESSION_ID ((ber_tag_t)0x80U)
#define LDAP_TAG_EXOP_RBAC_TENANT_ID ((ber_tag_t)0x81U)
#define LDAP_TAG_EXOP_RBAC_USER_ID ((ber_tag_t)0x82U)
#define LDAP_TAG_EXOP_RBAC_USER ((ber_tag_t)0x80U)
#define LDAP_TAG_EXOP_RBAC_AUTHTOK ((ber_tag_t)0x83U)
#define LDAP_TAG_EXOP_RBAC_ACTIVE_ROLE ((ber_tag_t)0xA4U)
#define LDAP_TAG_EXOP_RBAC_OPNAME ((ber_tag_t)0x81U)
#define LDAP_TAG_EXOP_RBAC_OBJNAME ((ber_tag_t)0x82U)
#define LDAP_TAG_EXOP_RBAC_OBJID ((ber_tag_t)0x83U)
#define LDAP_TAG_EXOP_RBAC_PWPOLICY_STATE ((ber_tag_t)0x85U)
#define LDAP_TAG_EXOP_RBAC_PWPOLICY_VALUE ((ber_tag_t)0x86U)
#define LDAP_TAG_EXOP_RBAC_ROLES ((ber_tag_t)0x04U)
#define LDAP_TAG_EXOP_RBAC_USER_ID_SESS ((ber_tag_t)0x80U)
#define LDAP_TAG_EXOP_RBAC_SESSION_ID_SESS ((ber_tag_t)0x81U)
#define LDAP_TAG_EXOP_RBAC_ROLE_NM_SESS ((ber_tag_t)0x82U)
#define RBAC_REQ_CREATE_SESSION 0
#define RBAC_REQ_CHECK_ACCESS 1
#define RBAC_REQ_ADD_ACTIVE_ROLE 2
#define RBAC_REQ_DROP_ACTIVE_ROLE 3
#define RBAC_REQ_DELETE_SESSION 4
#define RBAC_REQ_SESSION_PERMISSIONS 5
#define RBAC_REQ_SESSION_ROLES 6