1 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 * Copyright 2004-2008 The OpenLDAP Foundation.
4 * Portions Copyright 2004 Pierangelo Masarati.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by Pierangelo Masarati for inclusion
17 * in OpenLDAP Software.
24 #include <ac/stdlib.h>
27 #include <ac/string.h>
28 #include <ac/socket.h>
29 #include <ac/unistd.h>
35 #include "slapcommon.h"
41 AttributeDescription
*desc
,
47 char accessmaskbuf
[ACCESSMASK_MAXLEN
];
49 rc
= access_allowed_mask( op
, e
, desc
, nval
, ACL_AUTH
, NULL
, &mask
);
51 fprintf( stderr
, "%s%s%s: %s\n",
52 desc
->ad_cname
.bv_val
,
53 ( val
&& !BER_BVISNULL( val
) ) ? "=" : "",
54 ( val
&& !BER_BVISNULL( val
) ) ?
55 ( desc
== slap_schema
.si_ad_userPassword
?
56 "****" : val
->bv_val
) : "",
57 accessmask2str( mask
, accessmaskbuf
, 1 ) );
63 slapacl( int argc
, char **argv
)
65 int rc
= EXIT_SUCCESS
;
66 const char *progname
= "slapacl";
67 Connection conn
= { 0 };
69 OperationBuffer opbuf
;
71 Entry e
= { 0 }, *ep
= &e
;
76 slap_tool_init( progname
, SLAPACL
, argc
, argv
);
81 LDAP_STAILQ_FOREACH( bd
, &backendDB
, be_next
) {
82 if ( bd
!= be
&& backend_startup( bd
) ) {
83 fprintf( stderr
, "backend_startup(#%d%s%s) failed\n",
85 bd
->be_suffix
? ": " : "",
86 bd
->be_suffix
? bd
->be_suffix
[0].bv_val
: "" );
95 argv
= &argv
[ optind
];
98 connection_fake_init( &conn
, &opbuf
, &conn
);
101 conn
.c_listener
= &listener
;
102 conn
.c_listener_url
= listener_url
;
103 conn
.c_peer_domain
= peer_domain
;
104 conn
.c_peer_name
= peer_name
;
105 conn
.c_sock_name
= sock_name
;
107 op
->o_transport_ssf
= transport_ssf
;
108 op
->o_tls_ssf
= tls_ssf
;
109 op
->o_sasl_ssf
= sasl_ssf
;
111 if ( !BER_BVISNULL( &authcID
) ) {
112 if ( !BER_BVISNULL( &authcDN
) ) {
113 fprintf( stderr
, "both authcID=\"%s\" "
114 "and authcDN=\"%s\" provided\n",
115 authcID
.bv_val
, authcDN
.bv_val
);
120 rc
= slap_sasl_getdn( &conn
, op
, &authcID
, NULL
,
121 &authcDN
, SLAP_GETDN_AUTHCID
);
122 if ( rc
!= LDAP_SUCCESS
) {
123 fprintf( stderr
, "authcID: <%s> check failed %d (%s)\n",
125 ldap_err2string( rc
) );
130 } else if ( !BER_BVISNULL( &authcDN
) ) {
133 rc
= dnNormalize( 0, NULL
, NULL
, &authcDN
, &ndn
, NULL
);
134 if ( rc
!= LDAP_SUCCESS
) {
135 fprintf( stderr
, "autchDN=\"%s\" normalization failed %d (%s)\n",
137 ldap_err2string( rc
) );
141 ch_free( authcDN
.bv_val
);
145 if ( !BER_BVISNULL( &authzID
) ) {
146 if ( !BER_BVISNULL( &authzDN
) ) {
147 fprintf( stderr
, "both authzID=\"%s\" "
148 "and authzDN=\"%s\" provided\n",
149 authzID
.bv_val
, authzDN
.bv_val
);
154 rc
= slap_sasl_getdn( &conn
, op
, &authzID
, NULL
,
155 &authzDN
, SLAP_GETDN_AUTHZID
);
156 if ( rc
!= LDAP_SUCCESS
) {
157 fprintf( stderr
, "authzID: <%s> check failed %d (%s)\n",
159 ldap_err2string( rc
) );
164 } else if ( !BER_BVISNULL( &authzDN
) ) {
167 rc
= dnNormalize( 0, NULL
, NULL
, &authzDN
, &ndn
, NULL
);
168 if ( rc
!= LDAP_SUCCESS
) {
169 fprintf( stderr
, "autchDN=\"%s\" normalization failed %d (%s)\n",
171 ldap_err2string( rc
) );
175 ch_free( authzDN
.bv_val
);
180 if ( !BER_BVISNULL( &authcDN
) ) {
181 fprintf( stderr
, "authcDN: \"%s\"\n", authcDN
.bv_val
);
184 if ( !BER_BVISNULL( &authzDN
) ) {
185 fprintf( stderr
, "authzDN: \"%s\"\n", authzDN
.bv_val
);
188 if ( !BER_BVISNULL( &authzDN
) ) {
192 if ( !BER_BVISNULL( &authcDN
) ) {
193 op
->o_conn
->c_dn
= authcDN
;
194 op
->o_conn
->c_ndn
= authcDN
;
197 op
->o_conn
->c_dn
= authzDN
;
198 op
->o_conn
->c_ndn
= authzDN
;
201 } else if ( !BER_BVISNULL( &authcDN
) ) {
202 op
->o_conn
->c_dn
= authcDN
;
203 op
->o_conn
->c_ndn
= authcDN
;
208 assert( !BER_BVISNULL( &baseDN
) );
209 rc
= dnPrettyNormal( NULL
, &baseDN
, &e
.e_name
, &e
.e_nname
, NULL
);
210 if ( rc
!= LDAP_SUCCESS
) {
211 fprintf( stderr
, "base=\"%s\" normalization failed %d (%s)\n",
213 ldap_err2string( rc
) );
219 if ( op
->o_bd
== NULL
) {
220 /* NOTE: if no database could be found (e.g. because
221 * accessing the rootDSE or so), use the frontendDB
222 * rules; might need work */
223 op
->o_bd
= frontendDB
;
230 fprintf( stderr
, "%s: no target database "
231 "has been found for baseDN=\"%s\"; "
232 "you may try with \"-u\" (dry run).\n",
233 baseDN
.bv_val
, progname
);
238 if ( !be
->be_entry_open
||
239 !be
->be_entry_close
||
243 fprintf( stderr
, "%s: target database "
244 "doesn't support necessary operations; "
245 "you may try with \"-u\" (dry run).\n",
251 if ( be
->be_entry_open( be
, 0 ) != 0 ) {
252 fprintf( stderr
, "%s: could not open database.\n",
260 id
= be
->be_dn2id_get( be
, &e
.e_nname
);
262 fprintf( stderr
, "%s: unable to fetch ID of DN \"%s\"\n",
263 progname
, e
.e_nname
.bv_val
);
267 ep
= be
->be_entry_get( be
, id
);
269 fprintf( stderr
, "%s: unable to fetch entry \"%s\" (%lu)\n",
270 progname
, e
.e_nname
.bv_val
, id
);
279 (void)print_access( op
, ep
, slap_schema
.si_ad_entry
, NULL
, NULL
);
280 (void)print_access( op
, ep
, slap_schema
.si_ad_children
, NULL
, NULL
);
282 for ( a
= ep
->e_attrs
; a
; a
= a
->a_next
) {
285 for ( i
= 0; !BER_BVISNULL( &a
->a_nvals
[ i
] ); i
++ ) {
286 (void)print_access( op
, ep
, a
->a_desc
,
294 for ( ; argc
--; argv
++ ) {
296 AttributeDescription
*desc
= NULL
;
297 struct berval val
= BER_BVNULL
,
300 char accessmaskbuf
[ACCESSMASK_MAXLEN
];
302 slap_access_t access
= ACL_AUTH
;
304 if ( attr
== NULL
) {
308 val
.bv_val
= strchr( attr
, ':' );
309 if ( val
.bv_val
!= NULL
) {
310 val
.bv_val
[0] = '\0';
312 val
.bv_len
= strlen( val
.bv_val
);
316 accessstr
= strchr( attr
, '/' );
317 if ( accessstr
!= NULL
) {
322 access
= str2access( accessstr
);
324 case ACL_INVALID_ACCESS
:
325 fprintf( stderr
, "unknown access \"%s\" for attribute \"%s\"\n",
331 fprintf( stderr
, "\"none\" not allowed for attribute \"%s\"\n",
341 if ( continuemode
) {
348 rc
= slap_str2ad( attr
, &desc
, &text
);
349 if ( rc
!= LDAP_SUCCESS
) {
350 fprintf( stderr
, "slap_str2ad(%s) failed %d (%s)\n",
351 attr
, rc
, ldap_err2string( rc
) );
352 if ( continuemode
) {
358 rc
= access_allowed_mask( op
, ep
, desc
, valp
, access
,
362 fprintf( stderr
, "%s access to %s%s%s: %s\n",
364 desc
->ad_cname
.bv_val
,
365 val
.bv_val
? "=" : "",
366 val
.bv_val
? val
.bv_val
: "",
367 rc
? "ALLOWED" : "DENIED" );
370 fprintf( stderr
, "%s%s%s: %s\n",
371 desc
->ad_cname
.bv_val
,
372 val
.bv_val
? "=" : "",
373 val
.bv_val
? val
.bv_val
: "",
374 accessmask2str( mask
, accessmaskbuf
, 1 ) );
381 if ( !BER_BVISNULL( &e
.e_name
) ) {
382 ber_memfree( e
.e_name
.bv_val
);
384 if ( !BER_BVISNULL( &e
.e_nname
) ) {
385 ber_memfree( e
.e_nname
.bv_val
);
387 if ( !dryrun
&& be
) {
388 if ( ep
&& ep
!= &e
) {
389 be_entry_release_r( op
, ep
);
392 be
->be_entry_close( be
);
395 LDAP_STAILQ_FOREACH( bd
, &backendDB
, be_next
) {
397 backend_shutdown( bd
);