3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2015 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
19 #include <ac/string.h>
28 slap_style_t pg_style;
32 static ObjectClass *pg_posixGroup;
33 static AttributeDescription *pg_memberUid;
34 static ObjectClass *pg_posixAccount;
35 static AttributeDescription *pg_uidNumber;
37 static int pg_dynacl_destroy( void *priv );
50 const char *text = NULL;
53 ber_str2bv( pattern, 0, 0, &pat );
55 pg = ch_calloc( 1, sizeof( pg_t ) );
59 switch ( pg->pg_style ) {
61 rc = dnNormalize( 0, NULL, NULL, &pat, &pg->pg_pat, NULL );
62 if ( rc != LDAP_SUCCESS ) {
63 fprintf( stderr, "%s line %d: posixGroup ACL: "
64 "unable to normalize DN \"%s\".\n",
65 fname, lineno, pattern );
70 case ACL_STYLE_EXPAND:
71 ber_dupbv( &pg->pg_pat, &pat );
75 fprintf( stderr, "%s line %d: posixGroup ACL: "
76 "unsupported style \"%s\".\n",
77 fname, lineno, style_strings[ pg->pg_style ] );
81 /* TODO: use opts to allow the use of different
82 * group objects and member attributes */
83 if ( pg_posixGroup == NULL ) {
84 pg_posixGroup = oc_find( "posixGroup" );
85 if ( pg_posixGroup == NULL ) {
86 fprintf( stderr, "%s line %d: posixGroup ACL: "
87 "unable to lookup \"posixGroup\" "
93 pg_posixAccount = oc_find( "posixAccount" );
94 if ( pg_posixGroup == NULL ) {
95 fprintf( stderr, "%s line %d: posixGroup ACL: "
96 "unable to lookup \"posixAccount\" "
102 rc = slap_str2ad( "memberUid", &pg_memberUid, &text );
103 if ( rc != LDAP_SUCCESS ) {
104 fprintf( stderr, "%s line %d: posixGroup ACL: "
105 "unable to lookup \"memberUid\" "
106 "attributeDescription (%d: %s).\n",
107 fname, lineno, rc, text );
111 rc = slap_str2ad( "uidNumber", &pg_uidNumber, &text );
112 if ( rc != LDAP_SUCCESS ) {
113 fprintf( stderr, "%s line %d: posixGroup ACL: "
114 "unable to lookup \"uidNumber\" "
115 "attributeDescription (%d: %s).\n",
116 fname, lineno, rc, text );
125 (void)pg_dynacl_destroy( (void *)pg );
135 pg_t *pg = (pg_t *)priv;
138 bv->bv_len = STRLENOF( " dynacl/posixGroup.expand=" ) + pg->pg_pat.bv_len;
139 bv->bv_val = ch_malloc( bv->bv_len + 1 );
141 ptr = lutil_strcopy( bv->bv_val, " dynacl/posixGroup" );
143 switch ( pg->pg_style ) {
145 ptr = lutil_strcopy( ptr, ".exact=" );
148 case ACL_STYLE_EXPAND:
149 ptr = lutil_strcopy( ptr, ".expand=" );
156 ptr = lutil_strncopy( ptr, pg->pg_pat.bv_val, pg->pg_pat.bv_len );
159 bv->bv_len = ptr - bv->bv_val;
169 AttributeDescription *desc,
173 slap_access_t *grant,
174 slap_access_t *deny )
176 pg_t *pg = (pg_t *)priv;
180 Backend *be = op->o_bd,
183 struct berval group_ndn;
185 ACL_INVALIDATE( *deny );
188 if ( target && dn_match( &target->e_nname, &op->o_ndn ) ) {
193 user_be = op->o_bd = select_backend( &op->o_ndn, 0 );
194 if ( op->o_bd == NULL ) {
198 rc = be_entry_get_rw( op, &op->o_ndn, pg_posixAccount, pg_uidNumber, 0, &user );
201 if ( rc != LDAP_SUCCESS || user == NULL ) {
207 if ( pg->pg_style == ACL_STYLE_EXPAND ) {
210 AclRegexMatches amatches = { 0 };
212 amatches.dn_count = nmatch;
213 AC_MEMCPY( amatches.dn_data, matches, sizeof( amatches.dn_data ) );
215 bv.bv_len = sizeof( buf ) - 1;
218 if ( acl_string_expand( &bv, &pg->pg_pat,
225 if ( dnNormalize( 0, NULL, NULL, &bv, &group_ndn,
226 op->o_tmpmemctx ) != LDAP_SUCCESS )
228 /* did not expand to a valid dn */
233 group_ndn = pg->pg_pat;
236 if ( target && dn_match( &target->e_nname, &group_ndn ) ) {
241 group_be = op->o_bd = select_backend( &group_ndn, 0 );
242 if ( op->o_bd == NULL ) {
245 rc = be_entry_get_rw( op, &group_ndn, pg_posixGroup, pg_memberUid, 0, &group );
248 if ( group_ndn.bv_val != pg->pg_pat.bv_val ) {
249 op->o_tmpfree( group_ndn.bv_val, op->o_tmpmemctx );
252 if ( rc == LDAP_SUCCESS && group != NULL ) {
256 a_uid = attr_find( user->e_attrs, pg_uidNumber );
257 if ( !a_uid || !BER_BVISNULL( &a_uid->a_nvals[ 1 ] ) ) {
258 rc = LDAP_NO_SUCH_ATTRIBUTE;
261 a_member = attr_find( group->e_attrs, pg_memberUid );
263 rc = LDAP_NO_SUCH_ATTRIBUTE;
266 rc = value_find_ex( pg_memberUid,
267 SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
268 SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
269 a_member->a_nvals, &a_uid->a_nvals[ 0 ],
275 rc = LDAP_NO_SUCH_OBJECT;
279 if ( rc == LDAP_SUCCESS ) {
280 ACL_LVL_ASSIGN_WRITE( *grant );
284 if ( group != NULL && group != target ) {
286 be_entry_release_r( op, group );
290 if ( user != NULL && user != target ) {
292 be_entry_release_r( op, user );
303 pg_t *pg = (pg_t *)priv;
306 if ( !BER_BVISNULL( &pg->pg_pat ) ) {
307 ber_memfree( pg->pg_pat.bv_val );
315 static struct slap_dynacl_t pg_dynacl = {
324 init_module( int argc, char *argv[] )
326 return slap_dynacl_register( &pg_dynacl );
329 #endif /* SLAP_DYNACL */