Commit a18e199e authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

more on identity assertion

parent 725ca08f
......@@ -77,14 +77,17 @@ The URI list is space- or comma-separated.
.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>"
......@@ -94,7 +97,7 @@ belong to the DIT fragment that is being proxyied by back-ldap.
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.
......@@ -130,11 +133,11 @@ The supported modes are:
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;
......@@ -152,7 +155,7 @@ identity
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:
......
......@@ -82,12 +82,27 @@ struct ldaprwmap {
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;
......@@ -98,18 +113,17 @@ struct ldapinfo {
#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 */
......
......@@ -224,6 +224,7 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
|| (op->o_conn
&& (op->o_bd == op->o_conn->c_authz_backend ))) {
lc_curr.conn = op->o_conn;
} else {
lc_curr.conn = NULL;
}
......@@ -233,6 +234,7 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
lc_curr.local_dn = li->be->be_rootndn;
lc_curr.conn = NULL;
is_priv = 1;
} else {
lc_curr.local_dn = op->o_ndn;
}
......@@ -283,8 +285,9 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
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 );
......@@ -404,17 +407,18 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
&& ( 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;
......@@ -432,20 +436,40 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
}
}
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 ) {
......@@ -461,12 +485,6 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
}
#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,
......@@ -474,12 +492,15 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
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 ) {
......@@ -490,9 +511,10 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
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,
......@@ -714,7 +736,8 @@ ldap_back_proxy_authz_ctrl(
*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;
}
......@@ -749,11 +772,11 @@ ldap_back_proxy_authz_ctrl(
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;
......
......@@ -133,24 +133,26 @@ ldap_back_db_config(
#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... */
......@@ -721,7 +723,8 @@ parse_idassert(
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 );
......@@ -733,6 +736,9 @@ parse_idassert(
/* 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",
......@@ -740,13 +746,6 @@ parse_idassert(
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",
......@@ -754,7 +753,20 @@ parse_idassert(
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
......@@ -837,16 +849,39 @@ parse_idassert(
}
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",
......
......@@ -98,8 +98,8 @@ ldap_back_db_init(
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;
......@@ -210,13 +210,13 @@ ldap_back_db_destroy(
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 ) ) {
......
......@@ -368,12 +368,15 @@ ldap_build_entry(
*
* 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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment