]> git.sur5r.net Git - openldap/commitdiff
Assertion control with no backend support (yet)
authorKurt Zeilenga <kurt@openldap.org>
Tue, 10 Jun 2003 02:19:30 +0000 (02:19 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 10 Jun 2003 02:19:30 +0000 (02:19 +0000)
clients/tools/common.c
include/ldap.h
servers/slapd/controls.c
servers/slapd/slap.h

index b558b2942b4648e8400946a9c0c25372255b0a7d..f6cac8bd1c27c6a55aa1543973df7f04116fd2a5 100644 (file)
@@ -41,6 +41,7 @@ char  *sasl_secprops = NULL;
 #endif
 int   use_tls = 0;
 
+char *assertion = NULL;
 char *authzid = NULL;
 int   manageDSAit = 0;
 int   noop = 0;
@@ -74,6 +75,7 @@ N_("  -C         chase referrals\n"),
 N_("  -d level   set LDAP debugging level to `level'\n"),
 N_("  -D binddn  bind DN\n"),
 N_("  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n")
+N_("             [!]assert=<filter>   (an RFC 2254 Filter)\n")
 N_("             [!]authzid=<authzid> (\"dn:<dn>\" or \"u:<user>\")\n")
 N_("             [!]manageDSAit       (alternate form, see -M)\n")
 N_("             [!]noop\n"),
@@ -155,7 +157,20 @@ tool_args( int argc, char **argv )
                                *cvalue++ = '\0';
                        }
 
-                       if ( strcasecmp( control, "authzid" ) == 0 ) {
+                       if ( strcasecmp( control, "assert" ) == 0 ) {
+                               if( assertion != NULL ) {
+                                       fprintf( stderr, "assert control previously specified\n");
+                                       exit( EXIT_FAILURE );
+                               }
+                               if( cvalue == NULL ) {
+                                       fprintf( stderr, "assert: control value expected\n" );
+                                       usage();
+                               }
+
+                               assert( assertion == NULL );
+                               assertion = cvalue;
+
+                       } else if ( strcasecmp( control, "authzid" ) == 0 ) {
                                if( authzid != NULL ) {
                                        fprintf( stderr, "authzid control previously specified\n");
                                        exit( EXIT_FAILURE );
@@ -710,7 +725,7 @@ void
 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
 {
        int i = 0, j, crit = 0, err;
-       LDAPControl c[3], **ctrls;
+       LDAPControl c[4], **ctrls;
 
        ctrls = (LDAPControl**) malloc(sizeof(c) + (count+1)*sizeof(LDAPControl*));
        if ( ctrls == NULL ) {
@@ -718,6 +733,35 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
                exit( EXIT_FAILURE );
        }
 
+       if ( assertion ) {
+               char berbuf[LBER_ELEMENT_SIZEOF];
+               BerElement *ber = (BerElement *)berbuf;
+               
+               if( *assertion == '\0' ) {
+                       fprintf( stderr, "Assertion=<empty>\n" );
+                       exit( EXIT_FAILURE );
+               }
+
+               ber_init2( ber, NULL, LBER_USE_DER );
+
+               err = ldap_pvt_put_filter( ber, assertion );
+               if( err < 0 ) {
+                       fprintf( stderr, "assertion encode failed (%d)\n", err );
+                       exit( EXIT_FAILURE );
+               }
+
+               err = ber_flatten2( ber, &c[i].ldctl_value, 0 );
+               if( err < 0 ) {
+                       fprintf( stderr, "assertion flatten failed (%d)\n", err );
+                       exit( EXIT_FAILURE );
+               }
+
+               c[i].ldctl_oid = LDAP_CONTROL_ASSERT;
+               c[i].ldctl_iscritical = 1;
+               ctrls[i] = &c[i];
+               i++;
+       }
+
        if ( authzid ) {
                c[i].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
                c[i].ldctl_value.bv_val = authzid;
index e28755214cde48173b70c9412f0c3983d8242e25..a6acd33c812ce6bec455092673cddd050df48a6e 100644 (file)
@@ -180,6 +180,7 @@ typedef struct ldapcontrol {
 } LDAPControl;
 
 /* LDAP Controls */
+#define LDAP_CONTROL_ASSERT                    "1.3.6.1.4.1.4203.666.5.9"
 #define LDAP_CONTROL_VALUESRETURNFILTER "1.2.826.0.1.334810.2.3"
 #define LDAP_CONTROL_SUBENTRIES                "1.3.6.1.4.1.4203.1.10.1"
 #define LDAP_CONTROL_NOOP                      "1.3.6.1.4.1.4203.1.10.2"
index c5eacd2029e87107062a57ef52f8edbc03016007..fcb2640a0f7a112aaa4013802b3cc0be3cec7a11 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "../../libraries/liblber/lber-int.h"
 
+static SLAP_CTRL_PARSE_FN parseAssert;
 static SLAP_CTRL_PARSE_FN parseProxyAuthz;
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
 static SLAP_CTRL_PARSE_FN parseNoOp;
@@ -39,31 +40,17 @@ static SLAP_CTRL_PARSE_FN parseLdupSync;
 
 #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
-};
-
 struct slap_control {
-       /*
-        * Control OID
-        */
+       /* Control OID */
        char *sc_oid;
 
-       /*
-        * Operations supported by control
-        */
+       /* Operations supported by control */
        slap_mask_t sc_mask;
 
-       /*
-        * Extended operations supported by control
-        */
+       /* Extended operations supported by control */
        char **sc_extendedops;
 
-       /*
-        * Control parsing callback
-        */
+       /* Control parsing callback */
        SLAP_CTRL_PARSE_FN *sc_parse;
 
        LDAP_SLIST_ENTRY(slap_control) sc_next;
@@ -77,7 +64,16 @@ static LDAP_SLIST_HEAD(ControlsList, slap_control) controls_list
  */
 char **slap_known_controls = NULL;
 
+static char *proxy_authz_extops[] = {
+       LDAP_EXOP_MODIFY_PASSWD,
+       LDAP_EXOP_X_WHO_AM_I,
+       NULL
+};
+
 static struct slap_control control_defs[] = {
+       { LDAP_CONTROL_ASSERT,
+               SLAP_CTRL_ACCESS, NULL,
+               parseAssert, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_VALUESRETURNFILTER,
                SLAP_CTRL_SEARCH, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
@@ -872,6 +868,69 @@ static int parsePagedResults (
 }
 #endif
 
+static int parseAssert (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       BerElement      *ber;
+       struct berval   fstr = { 0, NULL };
+       const char *err_msg = "";
+
+       if ( op->o_assert != SLAP_NO_CONTROL ) {
+               rs->sr_text = "assert control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
+               rs->sr_text = "assert control value is empty (or absent)";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ber = ber_init( &(ctrl->ldctl_value) );
+       if (ber == NULL) {
+               rs->sr_text = "internal error";
+               return LDAP_OTHER;
+       }
+       
+       rs->sr_err = get_filter( op, ber, &(op->o_assertion), &rs->sr_text);
+
+       if( rs->sr_err != LDAP_SUCCESS ) {
+               if( rs->sr_err == SLAPD_DISCONNECT ) {
+                       rs->sr_err = LDAP_PROTOCOL_ERROR;
+                       send_ldap_disconnect( op, rs );
+                       rs->sr_err = SLAPD_DISCONNECT;
+               } else {
+                       send_ldap_result( op, rs );
+               }
+               if( op->o_assertion != NULL) {
+                       filter_free_x( op, op->o_assertion ); 
+               }
+       }
+#ifdef LDAP_DEBUG
+       else {
+               filter2bv_x( op, op->o_assertion, &fstr );
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ARGS, 
+               "parseAssert: conn %d assert: %s\n", 
+               op->o_connid, fstr.bv_len ? fstr.bv_val : "empty" , 0 );
+#else
+       Debug( LDAP_DEBUG_ARGS, "parseAssert: conn %d assert: %s\n",
+               op->o_connid, fstr.bv_len ? fstr.bv_val : "empty" , 0 );
+#endif
+       op->o_tmpfree( fstr.bv_val, op->o_tmpmemctx );
+#endif
+
+       op->o_assert = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       rs->sr_err = LDAP_SUCCESS;
+       return LDAP_SUCCESS;
+}
+
 int parseValuesReturnFilter (
        Operation *op,
        SlapReply *rs,
@@ -897,7 +956,7 @@ int parseValuesReturnFilter (
                return LDAP_OTHER;
        }
        
-       rs->sr_err = get_vrFilter( op, ber, &(op->vrFilter), &rs->sr_text);
+       rs->sr_err = get_vrFilter( op, ber, &(op->o_vrFilter), &rs->sr_text);
 
        if( rs->sr_err != LDAP_SUCCESS ) {
                if( rs->sr_err == SLAPD_DISCONNECT ) {
@@ -907,12 +966,12 @@ int parseValuesReturnFilter (
                } else {
                        send_ldap_result( op, rs );
                }
-               if( op->vrFilter != NULL) vrFilter_free( op, op->vrFilter ); 
+               if( op->o_vrFilter != NULL) vrFilter_free( op, op->o_vrFilter ); 
 
        }
 #ifdef LDAP_DEBUG
        else {
-               vrFilter2bv( op, op->vrFilter, &fstr );
+               vrFilter2bv( op, op->o_vrFilter, &fstr );
        }
 
 #ifdef NEW_LOGGING
index 1de6599454e1f4201a562c617ac82bea8523d74f..e931a7d800cc5df1d8692d89d69b363146f3f193 100644 (file)
@@ -1915,6 +1915,9 @@ typedef struct slap_op {
        char o_subentries_visibility;
 #define get_subentries_visibility(op)  ((int)(op)->o_subentries_visibility)
 
+       char o_assert;
+#define get_assert(op)                                 ((int)(op)->o_assert)
+
        char o_valuesreturnfilter;
 
 #ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
@@ -1987,7 +1990,10 @@ typedef struct slap_op {
        void    *o_private;     /* anything the backend needs */
 
        LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list         */
-       ValuesReturnFilter *vrFilter; /* Structure represents ValuesReturnFilter */
+
+       Filter *o_assertion; /* Assert control filter */
+#define get_assertion(op)                              ((op)->o_assertion)
+       ValuesReturnFilter *o_vrFilter; /* ValuesReturnFilter */
 
 #ifdef LDAP_CACHING 
        char            o_caching_on;