version 1.9, 2004/11/26 23:57:37
|
version 1.37, 2010/04/13 20:18:09
|
Line 1
|
Line 1
|
|
/* $OpenLDAP: pkg/ldap/servers/slapd/slapacl.c,v 1.36 2009/07/22 02:39:57 hyc Exp $ */ |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
* |
* |
* Copyright 2004 The OpenLDAP Foundation. |
* Copyright 2004-2010 The OpenLDAP Foundation. |
* Portions Copyright 2004 Pierangelo Masarati. |
* Portions Copyright 2004 Pierangelo Masarati. |
* All rights reserved. |
* All rights reserved. |
* |
* |
Line 34
|
Line 35
|
|
|
#include "slapcommon.h" |
#include "slapcommon.h" |
|
|
|
static int |
|
print_access( |
|
Operation *op, |
|
Entry *e, |
|
AttributeDescription *desc, |
|
struct berval *val, |
|
struct berval *nval ) |
|
{ |
|
int rc; |
|
slap_mask_t mask; |
|
char accessmaskbuf[ACCESSMASK_MAXLEN]; |
|
|
|
rc = access_allowed_mask( op, e, desc, nval, ACL_AUTH, NULL, &mask ); |
|
|
|
fprintf( stderr, "%s%s%s: %s\n", |
|
desc->ad_cname.bv_val, |
|
( val && !BER_BVISNULL( val ) ) ? "=" : "", |
|
( val && !BER_BVISNULL( val ) ) ? |
|
( desc == slap_schema.si_ad_userPassword ? |
|
"****" : val->bv_val ) : "", |
|
accessmask2str( mask, accessmaskbuf, 1 ) ); |
|
|
|
return rc; |
|
} |
|
|
int |
int |
slapacl( int argc, char **argv ) |
slapacl( int argc, char **argv ) |
{ |
{ |
int rc = EXIT_SUCCESS; |
int rc = EXIT_SUCCESS; |
const char *progname = "slapacl"; |
const char *progname = "slapacl"; |
Connection conn = {0}; |
Connection conn = { 0 }; |
char opbuf[OPERATION_BUFFER_SIZE]; |
Listener listener; |
Operation *op; |
OperationBuffer opbuf; |
Entry e = { 0 }; |
Operation *op = NULL; |
|
Entry e = { 0 }, *ep = &e; |
char *attr = NULL; |
char *attr = NULL; |
|
int doclose = 0; |
|
BackendDB *bd; |
|
void *thrctx; |
|
|
slap_tool_init( progname, SLAPACL, argc, argv ); |
slap_tool_init( progname, SLAPACL, argc, argv ); |
|
|
|
if ( !dryrun ) { |
|
int i = 0; |
|
|
|
LDAP_STAILQ_FOREACH( bd, &backendDB, be_next ) { |
|
if ( bd != be && backend_startup( bd ) ) { |
|
fprintf( stderr, "backend_startup(#%d%s%s) failed\n", |
|
i, |
|
bd->be_suffix ? ": " : "", |
|
bd->be_suffix ? bd->be_suffix[0].bv_val : "" ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
|
i++; |
|
} |
|
} |
|
|
argv = &argv[ optind ]; |
argv = &argv[ optind ]; |
argc -= optind; |
argc -= optind; |
|
|
op = (Operation *)opbuf; |
thrctx = ldap_pvt_thread_pool_context(); |
connection_fake_init( &conn, op, &conn ); |
connection_fake_init( &conn, &opbuf, thrctx ); |
|
op = &opbuf.ob_op; |
|
op->o_tmpmemctx = NULL; |
|
|
|
conn.c_listener = &listener; |
|
conn.c_listener_url = listener_url; |
|
conn.c_peer_domain = peer_domain; |
|
conn.c_peer_name = peer_name; |
|
conn.c_sock_name = sock_name; |
|
op->o_ssf = ssf; |
|
op->o_transport_ssf = transport_ssf; |
|
op->o_tls_ssf = tls_ssf; |
|
op->o_sasl_ssf = sasl_ssf; |
|
|
if ( !BER_BVISNULL( &authcID ) ) { |
if ( !BER_BVISNULL( &authcID ) ) { |
|
if ( !BER_BVISNULL( &authcDN ) ) { |
|
fprintf( stderr, "both authcID=\"%s\" " |
|
"and authcDN=\"%s\" provided\n", |
|
authcID.bv_val, authcDN.bv_val ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
rc = slap_sasl_getdn( &conn, op, &authcID, NULL, |
rc = slap_sasl_getdn( &conn, op, &authcID, NULL, |
&authcDN, SLAP_GETDN_AUTHCID ); |
&authcDN, SLAP_GETDN_AUTHCID ); |
if ( rc != LDAP_SUCCESS ) { |
if ( rc != LDAP_SUCCESS ) { |
fprintf( stderr, "ID: <%s> check failed %d (%s)\n", |
fprintf( stderr, "authcID: <%s> check failed %d (%s)\n", |
authcID.bv_val, rc, |
authcID.bv_val, rc, |
ldap_err2string( rc ) ); |
ldap_err2string( rc ) ); |
rc = 1; |
rc = 1; |
Line 79 slapacl( int argc, char **argv )
|
Line 146 slapacl( int argc, char **argv )
|
authcDN = ndn; |
authcDN = ndn; |
} |
} |
|
|
|
if ( !BER_BVISNULL( &authzID ) ) { |
|
if ( !BER_BVISNULL( &authzDN ) ) { |
|
fprintf( stderr, "both authzID=\"%s\" " |
|
"and authzDN=\"%s\" provided\n", |
|
authzID.bv_val, authzDN.bv_val ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
|
rc = slap_sasl_getdn( &conn, op, &authzID, NULL, |
|
&authzDN, SLAP_GETDN_AUTHZID ); |
|
if ( rc != LDAP_SUCCESS ) { |
|
fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", |
|
authzID.bv_val, rc, |
|
ldap_err2string( rc ) ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
|
} else if ( !BER_BVISNULL( &authzDN ) ) { |
|
struct berval ndn; |
|
|
|
rc = dnNormalize( 0, NULL, NULL, &authzDN, &ndn, NULL ); |
|
if ( rc != LDAP_SUCCESS ) { |
|
fprintf( stderr, "autchDN=\"%s\" normalization failed %d (%s)\n", |
|
authzDN.bv_val, rc, |
|
ldap_err2string( rc ) ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
ch_free( authzDN.bv_val ); |
|
authzDN = ndn; |
|
} |
|
|
|
|
if ( !BER_BVISNULL( &authcDN ) ) { |
if ( !BER_BVISNULL( &authcDN ) ) { |
fprintf( stderr, "DN: \"%s\"\n", authcDN.bv_val ); |
fprintf( stderr, "authcDN: \"%s\"\n", authcDN.bv_val ); |
|
} |
|
|
|
if ( !BER_BVISNULL( &authzDN ) ) { |
|
fprintf( stderr, "authzDN: \"%s\"\n", authzDN.bv_val ); |
|
} |
|
|
|
if ( !BER_BVISNULL( &authzDN ) ) { |
|
op->o_dn = authzDN; |
|
op->o_ndn = authzDN; |
|
|
|
if ( !BER_BVISNULL( &authcDN ) ) { |
|
op->o_conn->c_dn = authcDN; |
|
op->o_conn->c_ndn = authcDN; |
|
|
|
} else { |
|
op->o_conn->c_dn = authzDN; |
|
op->o_conn->c_ndn = authzDN; |
|
} |
|
|
|
} else if ( !BER_BVISNULL( &authcDN ) ) { |
|
op->o_conn->c_dn = authcDN; |
|
op->o_conn->c_ndn = authcDN; |
|
op->o_dn = authcDN; |
|
op->o_ndn = authcDN; |
} |
} |
|
|
assert( !BER_BVISNULL( &baseDN ) ); |
assert( !BER_BVISNULL( &baseDN ) ); |
Line 95 slapacl( int argc, char **argv )
|
Line 220 slapacl( int argc, char **argv )
|
} |
} |
|
|
op->o_bd = be; |
op->o_bd = be; |
if ( !BER_BVISNULL( &authcDN ) ) { |
if ( op->o_bd == NULL ) { |
op->o_dn = authcDN; |
/* NOTE: if no database could be found (e.g. because |
op->o_ndn = authcDN; |
* accessing the rootDSE or so), use the frontendDB |
|
* rules; might need work */ |
|
op->o_bd = frontendDB; |
} |
} |
|
|
if ( argc == 0 ) { |
if ( !dryrun ) { |
argc = 1; |
ID id; |
attr = slap_schema.si_ad_entry->ad_cname.bv_val; |
|
|
if ( be == NULL ) { |
|
fprintf( stderr, "%s: no target database " |
|
"has been found for baseDN=\"%s\"; " |
|
"you may try with \"-u\" (dry run).\n", |
|
baseDN.bv_val, progname ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
|
if ( !be->be_entry_open || |
|
!be->be_entry_close || |
|
!be->be_dn2id_get || |
|
!be->be_entry_get ) |
|
{ |
|
fprintf( stderr, "%s: target database " |
|
"doesn't support necessary operations; " |
|
"you may try with \"-u\" (dry run).\n", |
|
progname ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
|
if ( be->be_entry_open( be, 0 ) != 0 ) { |
|
fprintf( stderr, "%s: could not open database.\n", |
|
progname ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
|
|
doclose = 1; |
|
|
|
id = be->be_dn2id_get( be, &e.e_nname ); |
|
if ( id == NOID ) { |
|
fprintf( stderr, "%s: unable to fetch ID of DN \"%s\"\n", |
|
progname, e.e_nname.bv_val ); |
|
rc = 1; |
|
goto destroy; |
|
} |
|
ep = be->be_entry_get( be, id ); |
|
if ( ep == NULL ) { |
|
fprintf( stderr, "%s: unable to fetch entry \"%s\" (%lu)\n", |
|
progname, e.e_nname.bv_val, id ); |
|
rc = 1; |
|
goto destroy; |
|
|
|
} |
|
|
|
if ( argc == 0 ) { |
|
Attribute *a; |
|
|
|
(void)print_access( op, ep, slap_schema.si_ad_entry, NULL, NULL ); |
|
(void)print_access( op, ep, slap_schema.si_ad_children, NULL, NULL ); |
|
|
|
for ( a = ep->e_attrs; a; a = a->a_next ) { |
|
int i; |
|
|
|
for ( i = 0; !BER_BVISNULL( &a->a_nvals[ i ] ); i++ ) { |
|
(void)print_access( op, ep, a->a_desc, |
|
&a->a_vals[ i ], |
|
&a->a_nvals[ i ] ); |
|
} |
|
} |
|
} |
} |
} |
|
|
for ( ; argc--; argv++ ) { |
for ( ; argc--; argv++ ) { |
slap_mask_t mask; |
slap_mask_t mask; |
AttributeDescription *desc = NULL; |
AttributeDescription *desc = NULL; |
int rc; |
struct berval val = BER_BVNULL, |
struct berval val; |
*valp = NULL; |
const char *text; |
const char *text; |
char accessmaskbuf[ACCESSMASK_MAXLEN]; |
char accessmaskbuf[ACCESSMASK_MAXLEN]; |
char *accessstr; |
char *accessstr; |
Line 124 slapacl( int argc, char **argv )
|
Line 314 slapacl( int argc, char **argv )
|
val.bv_val[0] = '\0'; |
val.bv_val[0] = '\0'; |
val.bv_val++; |
val.bv_val++; |
val.bv_len = strlen( val.bv_val ); |
val.bv_len = strlen( val.bv_val ); |
|
valp = &val; |
} |
} |
|
|
accessstr = strchr( attr, '/' ); |
accessstr = strchr( attr, '/' ); |
if ( accessstr != NULL ) { |
if ( accessstr != NULL ) { |
|
int invalid = 0; |
|
|
accessstr[0] = '\0'; |
accessstr[0] = '\0'; |
accessstr++; |
accessstr++; |
access = str2access( accessstr ); |
access = str2access( accessstr ); |
if ( access == ACL_INVALID_ACCESS ) { |
switch ( access ) { |
|
case ACL_INVALID_ACCESS: |
fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n", |
fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n", |
accessstr, attr ); |
accessstr, attr ); |
|
invalid = 1; |
|
break; |
|
|
|
case ACL_NONE: |
|
fprintf( stderr, "\"none\" not allowed for attribute \"%s\"\n", |
|
attr ); |
|
invalid = 1; |
|
break; |
|
|
|
default: |
|
break; |
|
} |
|
|
|
if ( invalid ) { |
if ( continuemode ) { |
if ( continuemode ) { |
continue; |
continue; |
} |
} |
Line 151 slapacl( int argc, char **argv )
|
Line 359 slapacl( int argc, char **argv )
|
break; |
break; |
} |
} |
|
|
rc = access_allowed_mask( op, &e, desc, &val, access, |
rc = access_allowed_mask( op, ep, desc, valp, access, |
NULL, &mask ); |
NULL, &mask ); |
|
|
if ( accessstr ) { |
if ( accessstr ) { |
Line 167 slapacl( int argc, char **argv )
|
Line 375 slapacl( int argc, char **argv )
|
desc->ad_cname.bv_val, |
desc->ad_cname.bv_val, |
val.bv_val ? "=" : "", |
val.bv_val ? "=" : "", |
val.bv_val ? val.bv_val : "", |
val.bv_val ? val.bv_val : "", |
accessmask2str( mask, accessmaskbuf ) ); |
accessmask2str( mask, accessmaskbuf, 1 ) ); |
} |
} |
rc = 0; |
rc = 0; |
attr = NULL; |
attr = NULL; |
} |
} |
|
|
destroy:; |
destroy:; |
slap_tool_destroy(); |
if ( !BER_BVISNULL( &e.e_name ) ) { |
|
ber_memfree( e.e_name.bv_val ); |
|
} |
|
if ( !BER_BVISNULL( &e.e_nname ) ) { |
|
ber_memfree( e.e_nname.bv_val ); |
|
} |
|
if ( !dryrun && be ) { |
|
if ( ep && ep != &e ) { |
|
be_entry_release_r( op, ep ); |
|
} |
|
if ( doclose ) { |
|
be->be_entry_close( be ); |
|
} |
|
|
|
LDAP_STAILQ_FOREACH( bd, &backendDB, be_next ) { |
|
if ( bd != be ) { |
|
backend_shutdown( bd ); |
|
} |
|
} |
|
} |
|
|
|
if ( slap_tool_destroy()) |
|
rc = EXIT_FAILURE; |
|
|
return rc; |
return rc; |
} |
} |