static int do_check( Connection *c, Operation *op, struct berval *id ) { struct berval authcdn; int rc; rc = slap_sasl_getdn( c, op, id, realm, &authcdn, SLAP_GETDN_AUTHCID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ID: <%s> check failed %d (%s)\n", id->bv_val, rc, ldap_err2string( rc ) ); rc = 1; } else { if ( !BER_BVISNULL( &authzID ) ) { rc = slap_sasl_authorized( op, &authcdn, &authzID ); fprintf( stderr, "ID: <%s>\n" "authcDN: <%s>\n" "authzDN: <%s>\n" "authorization %s\n", id->bv_val, authcdn.bv_val, authzID.bv_val, rc == LDAP_SUCCESS ? "OK" : "failed" ); } else { fprintf( stderr, "ID: <%s> check succeeded\n" "authcID: <%s>\n", id->bv_val, authcdn.bv_val ); op->o_tmpfree( authcdn.bv_val, op->o_tmpmemctx ); } rc = 0; } return rc; }
static int proxyOld_parse( Operation *op, SlapReply *rs, LDAPControl *ctrl ) { int rc; BerElement *ber; ber_tag_t tag; struct berval dn = BER_BVNULL; struct berval authzDN = BER_BVNULL; /* We hijack the flag for the new control. Clearly only one or the * other can be used at any given time. */ if ( op->o_proxy_authz != SLAP_CONTROL_NONE ) { rs->sr_text = "proxy authorization control specified multiple times"; return LDAP_PROTOCOL_ERROR; } op->o_proxy_authz = ctrl->ldctl_iscritical ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL; /* Parse the control value * proxyAuthzControlValue ::= SEQUENCE { * proxyDN LDAPDN * } */ ber = ber_init( &ctrl->ldctl_value ); if ( ber == NULL ) { rs->sr_text = "ber_init failed"; return LDAP_OTHER; } tag = ber_scanf( ber, "{m}", &dn ); if ( tag == LBER_ERROR ) { rs->sr_text = "proxyOld control could not be decoded"; rc = LDAP_OTHER; goto done; } if ( BER_BVISEMPTY( &dn )) { Debug( LDAP_DEBUG_TRACE, "proxyOld_parse: conn=%lu anonymous\n", op->o_connid, 0, 0 ); authzDN.bv_val = ch_strdup(""); } else { Debug( LDAP_DEBUG_ARGS, "proxyOld_parse: conn %lu ctrl DN=\"%s\"\n", op->o_connid, dn.bv_val, 0 ); rc = dnNormalize( 0, NULL, NULL, &dn, &authzDN, op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { goto done; } rc = slap_sasl_authorized( op, &op->o_ndn, &authzDN ); if ( rc ) { op->o_tmpfree( authzDN.bv_val, op->o_tmpmemctx ); rs->sr_text = "not authorized to assume identity"; /* new spec uses LDAP_PROXY_AUTHZ_FAILURE */ rc = LDAP_INSUFFICIENT_ACCESS; goto done; } } free( op->o_ndn.bv_val ); free( op->o_dn.bv_val ); op->o_ndn = authzDN; ber_dupbv( &op->o_dn, &authzDN ); Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu PROXYOLD dn=\"%s\"\n", op->o_connid, op->o_opid, authzDN.bv_len ? authzDN.bv_val : "anonymous", 0, 0 ); rc = LDAP_SUCCESS; done: ber_free( ber, 1 ); return rc; }
static int slap_sasl_authorize( sasl_conn_t *sconn, void *context, char *requested_user, unsigned rlen, char *auth_identity, unsigned alen, const char *def_realm, unsigned urlen, struct propctx *props) { Connection *conn = (Connection *)context; /* actually: * (SLAP_SASL_PROP_COUNT - 1) because we skip "conn", * + 1 for NULL termination? */ struct propval auxvals[ SLAP_SASL_PROP_COUNT ] = { { 0 } }; struct berval authcDN, authzDN = BER_BVNULL; int rc; /* Simple Binds don't support proxy authorization, ignore it */ if ( !conn->c_sasl_bindop || conn->c_sasl_bindop->orb_method != LDAP_AUTH_SASL ) return SASL_OK; Debug( LDAP_DEBUG_ARGS, "SASL proxy authorize [conn=%ld]: " "authcid=\"%s\" authzid=\"%s\"\n", conn ? (long) conn->c_connid : -1L, auth_identity, requested_user ); if ( conn->c_sasl_dn.bv_val ) { BER_BVZERO( &conn->c_sasl_dn ); } /* Skip SLAP_SASL_PROP_CONN */ prop_getnames( props, slap_propnames+1, auxvals ); /* Should not happen */ if ( !auxvals[0].values ) { sasl_seterror( sconn, 0, "invalid authcid" ); return SASL_NOAUTHZ; } AC_MEMCPY( &authcDN.bv_len, auxvals[0].values[0], sizeof(authcDN.bv_len) ); authcDN.bv_val = auxvals[1].values ? (char *)auxvals[1].values[0] : NULL; conn->c_sasl_dn = authcDN; /* Nothing to do if no authzID was given */ if ( !auxvals[2].name || !auxvals[2].values ) { goto ok; } AC_MEMCPY( &authzDN.bv_len, auxvals[2].values[0], sizeof(authzDN.bv_len) ); authzDN.bv_val = auxvals[3].values ? (char *)auxvals[3].values[0] : NULL; rc = slap_sasl_authorized( conn->c_sasl_bindop, &authcDN, &authzDN ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "SASL Proxy Authorize [conn=%ld]: " "proxy authorization disallowed (%d)\n", conn ? (long) conn->c_connid : -1L, rc, 0 ); sasl_seterror( sconn, 0, "not authorized" ); return SASL_NOAUTHZ; } /* FIXME: we need yet another dup because slap_sasl_getdn() * is using the bind operation slab */ ber_dupbv( &conn->c_sasl_authz_dn, &authzDN ); ok: if (conn->c_sasl_bindop) { Statslog( LDAP_DEBUG_STATS, "%s BIND authcid=\"%s\" authzid=\"%s\"\n", conn->c_sasl_bindop->o_log_prefix, auth_identity, requested_user, 0, 0 ); } Debug( LDAP_DEBUG_TRACE, "SASL Authorize [conn=%ld]: " " proxy authorization allowed authzDN=\"%s\"\n", conn ? (long) conn->c_connid : -1L, authzDN.bv_val ? authzDN.bv_val : "", 0 ); return SASL_OK; }