.B server <hostport>
Obsolete option; same as `uri ldap://<hostport>/'.
.TP
-.B binddn "<administrative DN for access control purposes>"
+.B acl-authcDN "<administrative DN for access control purposes>"
DN which is used to query the target server for acl checking; it
should have read access on the target server to attributes used on the
proxy for acl checking.
There is no risk of giving away such values; they are only used to
check permissions.
+.B The acl-authcDN identity is by no means implicitly used by the proxy
+.B when the client connects anonymously, so it cannot be used to
+.B anonymously query Active Directory.
.TP
-.B bindpw <password>
+.B acl-passwd <password>
Password used with the bind DN above.
.TP
.B idassert-authcdn "<administrative DN for proxyAuthz purposes>"
This is useful when operations performed by users bound to another
backend are propagated through back-ldap.
This requires the entry with
-.B proxyauthzdn
+.B idassert-authcdn
identity on the remote server to have
.B proxyAuthz
privileges on a wide set of DNs, e.g.
The default is
.BR legacy ,
which implies that the proxy will bind as
-.I proxyauthzdn
+.I idassert-authcdn
and assert the client's identity when it is not anonymous.
Direct binds are always proxied.
The other modes imply that the proxy will always bind as
-.IR proxyauthzdn ,
+.IR idassert-authcdn ,
unless restricted by
.BR idassert-authz
rules (see below), in which case the operation will fail;
will be asserted;
.BR none ,
which means that no proxyAuthz control will be used, so the
-.I proxyauthzdn
+.I idassert-authcdn
identity will be asserted.
Moreover, if a string prefixed with
.B u:
struct ldapmap rwm_at;
};
+struct ldapauth {
+ struct berval la_authcID;
+ struct berval la_authcDN;
+ struct berval la_passwd;
+
+ struct berval la_authzID;
+
+ int la_authmethod;
+ int la_sasl_flags;
+ struct berval la_sasl_mech;
+ struct berval la_sasl_realm;
+};
+
struct ldapinfo {
struct slap_backend_db *be;
char *url;
LDAPURLDesc *lud;
- struct berval binddn;
- struct berval bindpw;
+ struct ldapauth acl_la;
+#define acl_authcDN acl_la.la_authcDN
+#define acl_passwd acl_la.la_passwd
+
#ifdef LDAP_BACK_PROXY_AUTHZ
/* ID assert stuff */
int idassert_mode;
#define LDAP_BACK_IDASSERT_OTHERDN 4
#define LDAP_BACK_IDASSERT_OTHERID 5
- struct berval idassert_authcID;
- struct berval idassert_authcDN;
- struct berval idassert_passwd;
-
- struct berval idassert_authzID;
+ struct ldapauth idassert_la;
+#define idassert_authcID idassert_la.la_authcID
+#define idassert_authcDN idassert_la.la_authcDN
+#define idassert_passwd idassert_la.la_passwd
+#define idassert_authzID idassert_la.la_authzID
+#define idassert_authmethod idassert_la.la_authmethod
+#define idassert_sasl_flags idassert_la.la_sasl_flags
+#define idassert_sasl_mech idassert_la.la_sasl_mech
+#define idassert_sasl_realm idassert_la.la_sasl_realm
BerVarray idassert_authz;
- int idassert_authmethod;
- int idassert_sasl_flags;
- struct berval idassert_sasl_mech;
- struct berval idassert_sasl_realm;
-
int idassert_ppolicy;
/* end of ID assert stuff */
#endif /* LDAP_BACK_PROXY_AUTHZ */
|| (op->o_conn
&& (op->o_bd == op->o_conn->c_authz_backend ))) {
lc_curr.conn = op->o_conn;
+
} else {
lc_curr.conn = NULL;
}
lc_curr.local_dn = li->be->be_rootndn;
lc_curr.conn = NULL;
is_priv = 1;
+
} else {
lc_curr.local_dn = op->o_ndn;
}
ldap_pvt_thread_mutex_init( &lc->lc_mutex );
if ( is_priv ) {
- ber_dupbv( &lc->cred, &li->bindpw );
- ber_dupbv( &lc->bound_dn, &li->binddn );
+ ber_dupbv( &lc->cred, &li->acl_passwd );
+ ber_dupbv( &lc->bound_dn, &li->acl_authcDN );
+
} else {
BER_BVZERO( &lc->cred );
BER_BVZERO( &lc->bound_dn );
&& ( BER_BVISNULL( &lc->bound_dn ) || BER_BVISEMPTY( &lc->bound_dn ) ) ) {
struct berval binddn = slap_empty_bv;
struct berval bindcred = slap_empty_bv;
+ int dobind = 0;
/* bind as proxyauthzdn only if no idassert mode is requested,
* or if the client's identity is authorized */
switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY:
if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
- if ( li->idassert_authmethod != LDAP_AUTH_SASL
- && !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) )
+ if ( !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) )
{
binddn = li->idassert_authcDN;
bindcred = li->idassert_passwd;
+ dobind = 1;
}
}
break;
}
}
- if ( li->idassert_authmethod != LDAP_AUTH_SASL ) {
- binddn = li->idassert_authcDN;
- }
+ binddn = li->idassert_authcDN;
bindcred = li->idassert_passwd;
+ dobind = 1;
break;
}
- /* NOTE: essentially copied from clients/tools/common.c :) */
- switch ( li->idassert_authmethod ) {
+ if ( dobind && li->idassert_authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
- case LDAP_AUTH_SASL:
- {
void *defaults = NULL;
struct berval authzID = BER_BVNULL;
+ int freeauthz = 0;
+
+ switch ( li->idassert_mode ) {
+ case LDAP_BACK_IDASSERT_OTHERID:
+ case LDAP_BACK_IDASSERT_OTHERDN:
+ authzID = li->idassert_authzID;
+ break;
+
+ case LDAP_BACK_IDASSERT_ANONYMOUS:
+ BER_BVSTR( &authzID, "dn:" );
+ break;
+
+ case LDAP_BACK_IDASSERT_SELF:
+ authzID.bv_len = STRLENOF( "dn:" ) + op->o_conn->c_dn.bv_len;
+ authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx );
+ AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
+ AC_MEMCPY( authzID.bv_val + STRLENOF( "dn:" ),
+ op->o_conn->c_dn.bv_val, op->o_conn->c_dn.bv_len + 1 );
+ freeauthz = 1;
+ break;
+
+ default:
+ break;
+ }
#if 0 /* will deal with this later... */
if ( sasl_secprops != NULL ) {
}
#endif
- switch ( li->idassert_mode ) {
- case LDAP_BACK_IDASSERT_OTHERID:
- case LDAP_BACK_IDASSERT_OTHERDN:
- authzID = li->idassert_authzID;
- }
-
defaults = lutil_sasl_defaults( lc->ld,
li->idassert_sasl_mech.bv_val,
li->idassert_sasl_realm.bv_val,
li->idassert_passwd.bv_val,
authzID.bv_val );
- rs->sr_err = ldap_sasl_interactive_bind_s( lc->ld, NULL,
+ rs->sr_err = ldap_sasl_interactive_bind_s( lc->ld, binddn.bv_val,
li->idassert_sasl_mech.bv_val, NULL, NULL,
li->idassert_sasl_flags, lutil_sasl_interact,
defaults );
lutil_sasl_freedefs( defaults );
+ if ( freeauthz ) {
+ slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
+ }
rs->sr_err = slap_map_api2result( rs );
if ( rs->sr_err != LDAP_SUCCESS ) {
lc->bound = 1;
}
goto done;
- }
+ }
#endif /* HAVE_CYRUS_SASL */
+ switch ( li->idassert_authmethod ) {
case LDAP_AUTH_SIMPLE:
rs->sr_err = ldap_sasl_bind(lc->ld,
binddn.bv_val, LDAP_SASL_SIMPLE,
*pctrls = NULL;
- if ( BER_BVISNULL( &li->idassert_authcID ) ) {
+ if ( ( BER_BVISNULL( &li->idassert_authcID ) || BER_BVISEMPTY( &li->idassert_authcID ) )
+ && ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) ) {
goto done;
}
goto done;
}
- if ( BER_BVISEMPTY( &li->idassert_authcID ) ) {
+ if ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) {
goto done;
}
- } else if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID && li->idassert_authmethod == LDAP_AUTH_SASL ) {
+ } else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) {
/* already asserted in SASL */
goto done;
#endif
/* name to use for ldap_back_group */
- } else if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
+ } else if ( strcasecmp( argv[0], "acl-authcdn" ) == 0
+ || strcasecmp( argv[0], "binddn" ) == 0 ) {
if (argc != 2) {
fprintf( stderr,
- "%s: line %d: missing name in \"binddn <name>\" line\n",
- fname, lineno );
+ "%s: line %d: missing name in \"%s <name>\" line\n",
+ fname, lineno, argv[0] );
return( 1 );
}
- ber_str2bv( argv[1], 0, 1, &li->binddn );
+ ber_str2bv( argv[1], 0, 1, &li->acl_authcDN );
/* password to use for ldap_back_group */
- } else if ( strcasecmp( argv[0], "bindpw" ) == 0 ) {
+ } else if ( strcasecmp( argv[0], "acl-passwd" ) == 0
+ || strcasecmp( argv[0], "bindpw" ) == 0 ) {
if (argc != 2) {
fprintf( stderr,
- "%s: line %d: missing password in \"bindpw <password>\" line\n",
- fname, lineno );
+ "%s: line %d: missing password in \"%s <password>\" line\n",
+ fname, lineno, argv[0] );
return( 1 );
}
- ber_str2bv( argv[1], 0, 1, &li->bindpw );
+ ber_str2bv( argv[1], 0, 1, &li->acl_passwd );
#ifdef LDAP_BACK_PROXY_AUTHZ
/* identity assertion stuff... */
return 1;
}
- li->idassert_authzID.bv_val = ch_malloc( STRLENOF( "dn:" ) + dn.bv_len + 1 );
+ li->idassert_authzID.bv_len = STRLENOF( "dn:" ) + dn.bv_len;
+ li->idassert_authzID.bv_val = ch_malloc( li->idassert_authzID.bv_len + 1 );
AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], dn.bv_val, dn.bv_len + 1 );
ch_free( dn.bv_val );
/* name to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0
|| strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
+ struct berval dn;
+ int rc;
+
if ( argc != 2 ) {
fprintf( stderr,
"%s: line %d: missing name in \"%s <name>\" line\n",
return( 1 );
}
- if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
- fprintf( stderr,
- "%s: line %d: authcDN incompatible with previously defined authcID\n",
- fname, lineno );
- return( 1 );
- }
-
if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
fprintf( stderr, "%s: line %d: "
"authcDN already defined; replacing...\n",
ch_free( li->idassert_authcDN.bv_val );
}
- ber_str2bv( argv[1], 0, 1, &li->idassert_authcDN );
+ ber_str2bv( argv[1], 0, 0, &dn );
+ rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: idassert ID \"%s\" is not a valid DN.\n",
+ fname, lineno, argv[1] );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: idassert ID \"%s\" is not a valid DN\n",
+ fname, lineno, argv[1] );
+#endif
+ return 1;
+ }
/* password to use for proxyAuthz propagation */
} else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0
}
ber_str2bv( val, 0, 1, &li->idassert_sasl_realm );
- } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
- char *val = argv[arg] + STRLENOF( "authcid=" );
+ } else if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) {
+ char *val = argv[arg] + STRLENOF( "authcdn=" );
+ struct berval dn;
+ int rc;
if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
- fprintf( stderr,
- "%s: line %d: SASL authcID incompatible with previously defined authcDN\n",
- fname, lineno );
- return( 1 );
+ fprintf( stderr, "%s: line %d: "
+ "SASL authcDN already defined; replacing...\n",
+ fname, lineno );
+ ch_free( li->idassert_authcDN.bv_val );
+ }
+ if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
+ val += STRLENOF( "dn:" );
}
+ ber_str2bv( val, 0, 0, &dn );
+ rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: SASL authcdn \"%s\" is not a valid DN.\n",
+ fname, lineno, val );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: SASL authcdn \"%s\" is not a valid DN\n",
+ fname, lineno, val );
+#endif
+ return 1;
+ }
+
+ } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
+ char *val = argv[arg] + STRLENOF( "authcid=" );
+
if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
fprintf( stderr, "%s: line %d: "
"SASL authcID already defined; replacing...\n",
return -1;
}
- BER_BVZERO( &li->binddn );
- BER_BVZERO( &li->bindpw );
+ BER_BVZERO( &li->acl_authcDN );
+ BER_BVZERO( &li->acl_passwd );
#ifdef LDAP_BACK_PROXY_AUTHZ
li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
ldap_free_urldesc( li->lud );
li->lud = NULL;
}
- if ( !BER_BVISNULL( &li->binddn ) ) {
- ch_free( li->binddn.bv_val );
- BER_BVZERO( &li->binddn );
+ if ( !BER_BVISNULL( &li->acl_authcDN ) ) {
+ ch_free( li->acl_authcDN.bv_val );
+ BER_BVZERO( &li->acl_authcDN );
}
- if ( !BER_BVISNULL( &li->bindpw ) ) {
- ch_free( li->bindpw.bv_val );
- BER_BVZERO( &li->bindpw );
+ if ( !BER_BVISNULL( &li->acl_passwd ) ) {
+ ch_free( li->acl_passwd.bv_val );
+ BER_BVZERO( &li->acl_passwd );
}
#ifdef LDAP_BACK_PROXY_AUTHZ
if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
*
* FIXME: should we log anything, or delegate to dnNormalize?
*/
+ /* Note: if the distinguished values or the naming attributes
+ * change, should we massage them as well?
+ */
if ( dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname,
op->o_tmpmemctx ) != LDAP_SUCCESS )
{
return LDAP_INVALID_DN_SYNTAX;
}
-
+
attrp = &ent->e_attrs;
#ifdef ENABLE_REWRITE