mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
ITS#6244 - Add "now" dynacl module
This commit is contained in:
parent
2c0707cf13
commit
92a8025f29
@ -13,7 +13,7 @@ DEFS =
|
||||
INCS = $(LDAP_INC)
|
||||
LIBS = $(LDAP_LIB)
|
||||
|
||||
PROGRAMS = posixgroup.la gssacl.la
|
||||
PROGRAMS = posixgroup.la gssacl.la now.la
|
||||
LTVER = 0:0:0
|
||||
|
||||
prefix=/usr/local
|
||||
@ -39,6 +39,10 @@ gssacl.la: gssacl.lo
|
||||
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -version-info $(LTVER) \
|
||||
-rpath $(moduledir) -module -o $@ $? $(LIBS)
|
||||
|
||||
now.la: now.lo
|
||||
$(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -version-info $(LTVER) \
|
||||
-rpath $(moduledir) -module -o $@ $? $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.lo *.la .libs
|
||||
|
||||
|
65
contrib/slapd-modules/acl/README.now
Normal file
65
contrib/slapd-modules/acl/README.now
Normal file
@ -0,0 +1,65 @@
|
||||
# create a simple slapd.conf (e.g. by running test003)
|
||||
|
||||
|
||||
|
||||
# define the attributes (replace MyOID with a valid OID)
|
||||
|
||||
attributetype ( MyOID:1 NAME 'validityStarts'
|
||||
EQUALITY generalizedTimeMatch
|
||||
ORDERING generalizedTimeOrderingMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
|
||||
attributetype ( MyOID:2 NAME 'validityEnds'
|
||||
EQUALITY generalizedTimeMatch
|
||||
ORDERING generalizedTimeOrderingMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )
|
||||
|
||||
|
||||
|
||||
# load the module
|
||||
|
||||
moduleload "now_dynacl.so"
|
||||
|
||||
|
||||
|
||||
# and apply the following access rules
|
||||
|
||||
access to dn.exact="dc=example,dc=com"
|
||||
by * read
|
||||
|
||||
access to dn.children="dc=example,dc=com"
|
||||
by dynacl/now=">=validityStarts" read break
|
||||
|
||||
access to dn.children="dc=example,dc=com"
|
||||
by dynacl/now="<=validityEnds" read
|
||||
|
||||
|
||||
|
||||
# Then load the LDIF
|
||||
|
||||
dn: cn=Too Late,dc=example,dc=com
|
||||
objectClass: device
|
||||
objectClass: extensibleObject
|
||||
cn: Too Late
|
||||
validityStarts: 20000101000000Z
|
||||
validityEnds: 20100101000000Z
|
||||
|
||||
dn: cn=Just in Time,dc=example,dc=com
|
||||
objectClass: device
|
||||
objectClass: extensibleObject
|
||||
cn: Just in Time
|
||||
validityStarts: 20100101000000Z
|
||||
validityEnds: 20200101000000Z
|
||||
|
||||
dn: cn=Too Early,dc=example,dc=com
|
||||
objectClass: device
|
||||
objectClass: extensibleObject
|
||||
cn: Too Early
|
||||
validityStarts: 20200101000000Z
|
||||
validityEnds: 20300101000000Z
|
||||
|
||||
|
||||
# an anonymous ldapsearch should only find the entry
|
||||
|
||||
$ ldapsearch -x -H ldap://:9011 -b dc=example,dc=com -LLL 1.1
|
||||
dn: cn=Just in Time,dc=example,dc=com
|
||||
|
234
contrib/slapd-modules/acl/now.c
Normal file
234
contrib/slapd-modules/acl/now.c
Normal file
@ -0,0 +1,234 @@
|
||||
/* $OpenLDAP$ */
|
||||
/*
|
||||
* Copyright 1998-2021 The OpenLDAP Foundation.
|
||||
* 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:
|
||||
* This work was initially developed by Pierangelo Masarati
|
||||
* for inclusion in OpenLDAP Software.
|
||||
*/
|
||||
/*
|
||||
* This dynacl module compares the value of a given attribute type
|
||||
* with the current time. The syntax is
|
||||
*
|
||||
* dynacl/now=<=attr
|
||||
*
|
||||
* where attr is an attribute whose syntax is generalizedTime
|
||||
* with generalizedTimeOrderingMatch as ORDERING rule.
|
||||
*/
|
||||
|
||||
#include <portable.h>
|
||||
|
||||
#include <ac/string.h>
|
||||
#include <slap.h>
|
||||
#include <lutil.h>
|
||||
|
||||
/* Need dynacl... */
|
||||
|
||||
#ifdef SLAP_DYNACL
|
||||
|
||||
typedef enum {
|
||||
NOW_GE,
|
||||
NOW_LE
|
||||
} now_style_t;
|
||||
|
||||
typedef struct now_t {
|
||||
AttributeDescription *now_ad;
|
||||
now_style_t now_style;
|
||||
} now_t;
|
||||
|
||||
static int now_dynacl_destroy( void *priv );
|
||||
|
||||
static int
|
||||
now_dynacl_parse(
|
||||
const char *fname,
|
||||
int lineno,
|
||||
const char *opts,
|
||||
slap_style_t style,
|
||||
const char *pattern,
|
||||
void **privp )
|
||||
{
|
||||
now_t *now;
|
||||
now_style_t sty = NOW_GE;
|
||||
AttributeDescription *ad = NULL;
|
||||
int rc;
|
||||
const char *text = NULL;
|
||||
Syntax *syn;
|
||||
MatchingRule *mr;
|
||||
|
||||
syn = syn_find( "1.3.6.1.4.1.1466.115.121.1.24" );
|
||||
if ( syn == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s line %d: unable to find syntax 1.3.6.1.4.1.1466.115.121.1.24 (generalizedTime)\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
|
||||
mr = mr_find( "generalizedTimeOrderingMatch" );
|
||||
if ( mr == NULL ) {
|
||||
fprintf( stderr,
|
||||
"%s line %d: unable to find generalizedTimeOrderingMatch rule\n",
|
||||
fname, lineno );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( strncmp( pattern, ">=", STRLENOF( ">=" ) ) == 0 ) {
|
||||
sty = NOW_GE;
|
||||
pattern += 2;
|
||||
|
||||
} else if ( strncmp( pattern, "<=", STRLENOF( "<=" ) ) == 0 ) {
|
||||
sty = NOW_LE;
|
||||
pattern += 2;
|
||||
}
|
||||
|
||||
rc = slap_str2ad( pattern, &ad, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "%s line %d: now ACL: "
|
||||
"unable to lookup \"%s\" "
|
||||
"attributeDescription (%d: %s).\n",
|
||||
fname, lineno, pattern, rc, text );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( ad->ad_type->sat_syntax != syn ) {
|
||||
fprintf( stderr,
|
||||
"%s line %d: syntax of attribute \"%s\" is not 1.3.6.1.4.1.1466.115.121.1.24 (generalizedTime)\n",
|
||||
fname, lineno, ad->ad_cname.bv_val );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( ad->ad_type->sat_ordering != mr ) {
|
||||
fprintf( stderr,
|
||||
"%s line %d: ordering matching rule of attribute \"%s\" is not generalizedTimeOrderingMatch\n",
|
||||
fname, lineno, ad->ad_cname.bv_val );
|
||||
return 1;
|
||||
}
|
||||
|
||||
now = ch_calloc( 1, sizeof( now_t ) );
|
||||
now->now_ad = ad;
|
||||
now->now_style = sty;
|
||||
|
||||
*privp = (void *)now;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
now_dynacl_unparse(
|
||||
void *priv,
|
||||
struct berval *bv )
|
||||
{
|
||||
now_t *now = (now_t *)priv;
|
||||
char *ptr;
|
||||
|
||||
bv->bv_len = STRLENOF( " dynacl/now=" ) + 2 + now->now_ad->ad_cname.bv_len;
|
||||
bv->bv_val = ch_malloc( bv->bv_len + 1 );
|
||||
|
||||
ptr = lutil_strcopy( bv->bv_val, " dynacl/now=" );
|
||||
ptr[ 0 ] = now->now_style == NOW_GE ? '>' : '<';
|
||||
ptr[ 1 ] = '=';
|
||||
ptr += 2;
|
||||
ptr = lutil_strncopy( ptr, now->now_ad->ad_cname.bv_val, now->now_ad->ad_cname.bv_len );
|
||||
ptr[ 0 ] = '\0';
|
||||
|
||||
bv->bv_len = ptr - bv->bv_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
now_dynacl_mask(
|
||||
void *priv,
|
||||
Operation *op,
|
||||
Entry *target,
|
||||
AttributeDescription *desc,
|
||||
struct berval *val,
|
||||
int nmatch,
|
||||
regmatch_t *matches,
|
||||
slap_access_t *grant,
|
||||
slap_access_t *deny )
|
||||
{
|
||||
now_t *now = (now_t *)priv;
|
||||
int rc;
|
||||
Attribute *a;
|
||||
|
||||
ACL_INVALIDATE( *deny );
|
||||
|
||||
assert( target != NULL );
|
||||
|
||||
a = attr_find( target->e_attrs, now->now_ad );
|
||||
if ( !a ) {
|
||||
rc = LDAP_NO_SUCH_ATTRIBUTE;
|
||||
|
||||
} else {
|
||||
char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
|
||||
struct berval timestamp;
|
||||
time_t t = slap_get_time();
|
||||
int match;
|
||||
MatchingRule *mr = now->now_ad->ad_type->sat_ordering;
|
||||
const char *text = NULL;
|
||||
|
||||
timestamp.bv_val = timebuf;
|
||||
timestamp.bv_len = sizeof( timebuf );
|
||||
|
||||
slap_timestamp( &t, ×tamp );
|
||||
|
||||
rc = value_match( &match, now->now_ad, mr, SLAP_MR_ORDERING,
|
||||
×tamp, &a->a_vals[ 0 ], &text );
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
if ( now->now_style == NOW_LE ) {
|
||||
match = -match;
|
||||
}
|
||||
|
||||
if ( match >= 0 ) {
|
||||
rc = LDAP_COMPARE_TRUE;
|
||||
|
||||
} else {
|
||||
rc = LDAP_COMPARE_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( rc == LDAP_COMPARE_TRUE ) {
|
||||
ACL_LVL_ASSIGN_WRITE( *grant );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
now_dynacl_destroy(
|
||||
void *priv )
|
||||
{
|
||||
now_t *now = (now_t *)priv;
|
||||
|
||||
if ( now != NULL ) {
|
||||
ch_free( now );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct slap_dynacl_t now_dynacl = {
|
||||
"now",
|
||||
now_dynacl_parse,
|
||||
now_dynacl_unparse,
|
||||
now_dynacl_mask,
|
||||
now_dynacl_destroy
|
||||
};
|
||||
|
||||
int
|
||||
init_module( int argc, char *argv[] )
|
||||
{
|
||||
return slap_dynacl_register( &now_dynacl );
|
||||
}
|
||||
|
||||
#endif /* SLAP_DYNACL */
|
Loading…
Reference in New Issue
Block a user