/* $OpenLDAP$ */
/*
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted only
LDAPControl *ctrl,
const char **text ));
+static SLAP_CTRL_PARSE_FN parseProxyAuthz;
static SLAP_CTRL_PARSE_FN parseManageDSAit;
-static SLAP_CTRL_PARSE_FN parseSubentries;
static SLAP_CTRL_PARSE_FN parseNoOp;
static SLAP_CTRL_PARSE_FN parsePagedResults;
static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
+#ifdef LDAP_CONTROL_SUBENTRIES
+static SLAP_CTRL_PARSE_FN parseSubentries;
+#endif
#ifdef LDAP_CLIENT_UPDATE
static SLAP_CTRL_PARSE_FN parseClientUpdate;
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
#undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
+static char *proxy_authz_extops[] = {
+ LDAP_EXOP_MODIFY_PASSWD,
+ LDAP_EXOP_X_WHO_AM_I,
+ NULL
+};
+
static struct slap_control {
char *sc_oid;
slap_mask_t sc_mask;
SLAP_CTRL_PARSE_FN *sc_parse;
} supportedControls[] = {
+ { LDAP_CONTROL_PROXY_AUTHZ,
+ SLAP_CTRL_FRONTEND|SLAP_CTRL_ACCESS, proxy_authz_extops,
+ parseProxyAuthz },
{ LDAP_CONTROL_MANAGEDSAIT,
SLAP_CTRL_ACCESS, NULL,
parseManageDSAit },
-#ifdef LDAP_CONTROL_SUBENTRIES
- { LDAP_CONTROL_SUBENTRIES,
- SLAP_CTRL_SEARCH, NULL,
- parseSubentries },
-#endif
-#ifdef LDAP_CONTROL_NOOP
{ LDAP_CONTROL_NOOP,
SLAP_CTRL_ACCESS, NULL,
parseNoOp },
-#endif
-#ifdef LDAP_CONTROL_PAGEDRESULTS
{ LDAP_CONTROL_PAGEDRESULTS,
SLAP_CTRL_SEARCH, NULL,
parsePagedResults },
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
{ LDAP_CONTROL_VALUESRETURNFILTER,
SLAP_CTRL_SEARCH, NULL,
- parseValuesReturnFilter },
+ parseValuesReturnFilter },
+#ifdef LDAP_CONTROL_SUBENTRIES
+ { LDAP_CONTROL_SUBENTRIES,
+ SLAP_CTRL_SEARCH, NULL,
+ parseSubentries },
#endif
#ifdef LDAP_CLIENT_UPDATE
{ LDAP_CONTROL_CLIENT_UPDATE,
SLAP_CTRL_SEARCH, NULL,
parseClientUpdate },
#endif /* LDAP_CLIENT_UPDATE */
- { NULL }
+ { NULL, 0, NULL, 0 }
};
char *
return supportedControls[index].sc_oid;
}
+slap_mask_t
+get_supported_ctrl_mask(int index)
+{
+ return supportedControls[index].sc_mask;
+}
+
static struct slap_control *
find_ctrl( const char *oid )
{
}
#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, ENTRY, "get_ctrls: conn %lu\n", conn->c_connid, 0, 0 );
+ LDAP_LOG( OPERATION, ENTRY,
+ "get_ctrls: conn %lu\n", conn->c_connid, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "=> get_ctrls\n", 0, 0, 0 );
#endif
+
if( op->o_protocol < LDAP_VERSION3 ) {
rc = SLAPD_DISCONNECT;
errmsg = "controls require LDAPv3";
}
/* one for first control, one for termination */
-#ifndef LDAP_CONTROL_PAGEDRESULTS
op->o_ctrls = ch_malloc( 2 * sizeof(LDAPControl *) );
-#else /* LDAP_CONTROL_PAGEDRESULTS */
- /* FIXME: are we sure we need this? */
- op->o_ctrls = ch_malloc( 3 * sizeof(LDAPControl *) );
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
#if 0
if( op->ctrls == NULL ) {
Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n",
0, 0, 0 );
#endif
+
ldap_controls_free( op->o_ctrls );
op->o_ctrls = NULL;
rc = SLAPD_DISCONNECT;
errmsg = "decoding controls error";
goto return_results;
+
+ } else if( c->ldctl_oid == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO,
+ "get_ctrls: conn %lu got emtpy OID.\n",
+ conn->c_connid, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "get_ctrls: conn %lu got emtpy OID.\n",
+ conn->c_connid, 0, 0 );
+#endif
+
+ ldap_controls_free( op->o_ctrls );
+ op->o_ctrls = NULL;
+ rc = LDAP_PROTOCOL_ERROR;
+ errmsg = "OID field is empty";
+ goto return_results;
}
tag = ber_peek_tag( ber, &len );
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "get_ctrls: conn %lu: "
"%s (%scritical): get value failed.\n",
- conn->c_connid, c->ldctl_oid ? c->ldctl_oid : "(NULL)",
+ conn->c_connid, c->ldctl_oid,
c->ldctl_iscritical ? "" : "non" );
#else
Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: conn %lu: "
"%s (%scritical): get value failed.\n",
- conn->c_connid,
- c->ldctl_oid ? c->ldctl_oid : "(NULL)",
+ conn->c_connid, c->ldctl_oid,
c->ldctl_iscritical ? "" : "non" );
#endif
ldap_controls_free( op->o_ctrls );
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO,
"get_ctrls: conn %lu oid=\"%s\" (%scritical)\n",
- conn->c_connid, c->ldctl_oid ? c->ldctl_oid : "(NULL)",
- c->ldctl_iscritical ? "" : "non" );
+ conn->c_connid, c->ldctl_oid, c->ldctl_iscritical ? "" : "non" );
#else
- Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n",
- c->ldctl_oid ? c->ldctl_oid : "(NULL)",
- c->ldctl_iscritical ? "" : "non",
- 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "=> get_ctrls: oid=\"%s\" (%scritical)\n",
+ c->ldctl_oid, c->ldctl_iscritical ? "" : "non", 0 );
#endif
sc = find_ctrl( c->ldctl_oid );
tagmask = SLAP_CTRL_ABANDON;
break;
case LDAP_REQ_EXTENDED:
- /* FIXME: check list of extended operations */
- tagmask = ~0U;
+ tagmask=~0L;
+ assert( op->o_extendedop != NULL );
+ if( sc->sc_extendedops != NULL ) {
+ int i;
+ for( i=0; sc->sc_extendedops[i] != NULL; i++ ) {
+ if( strcmp( op->o_extendedop, sc->sc_extendedops[i] )
+ == 0 )
+ {
+ tagmask=0L;
+ break;
+ }
+ }
+ }
break;
default:
rc = LDAP_OTHER;
return_results:
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, RESULTS,
- "get_ctrls: n=%d rc=%d err=%s\n", nctrls, rc, errmsg ? errmsg : "" );
+ "get_ctrls: n=%d rc=%d err=\"%s\"\n",
+ nctrls, rc, errmsg ? errmsg : "" );
#else
- Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: n=%d rc=%d err=%s\n",
+ Debug( LDAP_DEBUG_TRACE,
+ "<= get_ctrls: n=%d rc=%d err=\"%s\"\n",
nctrls, rc, errmsg ? errmsg : "");
#endif
return LDAP_SUCCESS;
}
-#ifdef LDAP_CONTROL_SUBENTRIES
-static int parseSubentries (
+static int parseProxyAuthz (
Connection *conn,
Operation *op,
LDAPControl *ctrl,
const char **text )
{
- if ( op->o_subentries != SLAP_NO_CONTROL ) {
- *text = "subentries control specified multiple times";
- return LDAP_PROTOCOL_ERROR;
- }
+ int rc;
+ struct berval dn;
- /* FIXME: should use BER library */
- if( ( ctrl->ldctl_value.bv_len != 3 )
- && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
- && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
- {
- *text = "subentries control value encoding is bogus";
+ if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
+ *text = "proxy authorization control specified multiple times";
return LDAP_PROTOCOL_ERROR;
}
- op->o_subentries = ctrl->ldctl_iscritical
+ op->o_proxy_authz = ctrl->ldctl_iscritical
? SLAP_CRITICAL_CONTROL
: SLAP_NONCRITICAL_CONTROL;
- op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ARGS,
+ "parseProxyAuthz: conn %lu authzid=\"%s\"\n",
+ conn->c_connid,
+ ctrl->ldctl_value.bv_len ? ctrl->ldctl_value.bv_val : "anonymous",
+ 0 );
+#else
+ Debug( LDAP_DEBUG_ARGS,
+ "parseProxyAuthz: conn %lu authzid=\"%s\"\n",
+ conn->c_connid,
+ ctrl->ldctl_value.bv_len ? ctrl->ldctl_value.bv_val : "anonymous",
+ 0 );
+#endif
+
+ if( ctrl->ldctl_value.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, RESULTS,
+ "parseProxyAuthz: conn=%lu anonymous\n",
+ conn->c_connid, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "parseProxyAuthz: conn=%lu anonymous\n",
+ conn->c_connid, 0, 0 );
+#endif
+
+ /* anonymous */
+ free( op->o_dn.bv_val );
+ op->o_dn.bv_len = 0;
+ op->o_dn.bv_val = ch_strdup( "" );
+
+ free( op->o_ndn.bv_val );
+ op->o_ndn.bv_len = 0;
+ op->o_ndn.bv_val = ch_strdup( "" );
+
+ return LDAP_SUCCESS;
+ }
+
+ rc = slap_sasl_getdn( conn,
+ ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
+ NULL, &dn, SLAP_GETDN_AUTHZID );
+
+ if( rc != LDAP_SUCCESS || !dn.bv_len ) {
+ *text = "authzId mapping failed";
+ return LDAP_PROXY_AUTHZ_FAILURE;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, RESULTS,
+ "parseProxyAuthz: conn=%lu \"%s\"\n",
+ conn->c_connid,
+ dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "parseProxyAuthz: conn=%lu \"%s\"\n",
+ conn->c_connid,
+ dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#endif
+
+ rc = slap_sasl_authorized( conn, &op->o_ndn, &dn );
+
+ if( rc ) {
+ ch_free( dn.bv_val );
+ *text = "not authorized to assume identity";
+ return LDAP_PROXY_AUTHZ_FAILURE;
+ }
+
+ ch_free( op->o_dn.bv_val );
+ ch_free( op->o_ndn.bv_val );
+
+ op->o_dn.bv_val = NULL;
+ op->o_ndn = dn;
+ ber_dupbv( &op->o_dn, &dn );
return LDAP_SUCCESS;
}
-#endif
-#ifdef LDAP_CONTROL_NOOP
static int parseNoOp (
Connection *conn,
Operation *op,
return LDAP_SUCCESS;
}
-#endif
-#ifdef LDAP_CONTROL_PAGEDRESULTS
static int parsePagedResults (
Connection *conn,
Operation *op,
}
if ( ctrl->ldctl_value.bv_len == 0 ) {
- *text = "paged results control value is empty";
+ *text = "paged results control value is empty (or absent)";
return LDAP_PROTOCOL_ERROR;
}
return LDAP_PROTOCOL_ERROR;
}
- if( size <= 0 ) {
+ if( size < 0 ) {
*text = "paged results control size invalid";
return LDAP_PROTOCOL_ERROR;
}
return LDAP_SUCCESS;
}
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
int parseValuesReturnFilter (
Connection *conn,
Operation *op,
const char *err_msg = "";
if ( op->o_valuesreturnfilter != SLAP_NO_CONTROL ) {
- *text = "valuesreturnfilter control specified multiple times";
+ *text = "valuesReturnFilter control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if ( ctrl->ldctl_value.bv_len == 0 ) {
+ *text = "valuesReturnFilter control value is empty (or absent)";
return LDAP_PROTOCOL_ERROR;
}
return LDAP_SUCCESS;
}
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+static int parseSubentries (
+ Connection *conn,
+ Operation *op,
+ LDAPControl *ctrl,
+ const char **text )
+{
+ if ( op->o_subentries != SLAP_NO_CONTROL ) {
+ *text = "subentries control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ /* FIXME: should use BER library */
+ if( ( ctrl->ldctl_value.bv_len != 3 )
+ && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+ && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
+ {
+ *text = "subentries control value encoding is bogus";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_subentries = ctrl->ldctl_iscritical
+ ? SLAP_CRITICAL_CONTROL
+ : SLAP_NONCRITICAL_CONTROL;
+
+ op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+
+ return LDAP_SUCCESS;
+}
#endif
#ifdef LDAP_CLIENT_UPDATE
}
if ( ctrl->ldctl_value.bv_len == 0 ) {
- *text = "LCUP client update control value is empty";
+ *text = "LCUP client update control value is empty (or absent)";
return LDAP_PROTOCOL_ERROR;
}