mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-25 00:59:45 -05:00
more on identity assertion
This commit is contained in:
parent
725ca08f8d
commit
a18e199e0d
6 changed files with 150 additions and 72 deletions
|
|
@ -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,15 +849,38 @@ 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: "
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue