]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
Updated for schemas.
[openldap] / servers / slapd / controls.c
index 74fadeabba7dbc8654376f2b9379add800e95fb1..52fae3b09028f2797f8097eabb1568c08dc6cd23 100644 (file)
@@ -1,5 +1,6 @@
+/* $OpenLDAP$ */
 /* 
- * Copyright 1999 The OpenLDAP Foundation.
+ * Copyright 1999-2000 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms are permitted only
@@ -10,6 +11,8 @@
 #include "portable.h"
 
 #include <stdio.h>
+
+#include <ac/string.h>
 #include <ac/socket.h>
 
 #include "slap.h"
@@ -17,6 +20,8 @@
 #include "../../libraries/liblber/lber-int.h"
 
 char *supportedControls[] = {
+       LDAP_CONTROL_MANAGEDSAIT,
+/*     LDAP_CONTROL_X_CHANGE_PASSWD, */
        NULL
 };
 
@@ -25,47 +30,52 @@ int get_ctrls(
        Operation *op,
        int sendres )
 {
-       int nctrls;
+       int nctrls = 0;
        ber_tag_t tag;
        ber_len_t len;
        char *opaque;
        BerElement *ber = op->o_ber;
        LDAPControl ***ctrls = &op->o_ctrls;
        int rc = LDAP_SUCCESS;
+       char *errmsg = NULL;
 
        len = ber_pvt_ber_remaining(ber);
 
        if( len == 0) {
                /* no controls */
                rc = LDAP_SUCCESS;
-               goto return_results;
+               return rc;
        }
 
        if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
                if( tag == LBER_ERROR ) {
-                       rc = LDAP_PROTOCOL_ERROR;
+                       rc = SLAPD_DISCONNECT;
+                       errmsg = "unexpected data in PDU";
                }
 
                goto return_results;
        }
 
+       Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 );
+
        if( op->o_protocol < LDAP_VERSION3 ) {
-               rc = LDAP_PROTOCOL_ERROR;
+               rc = SLAPD_DISCONNECT;
+               errmsg = "controls require LDAPv3";
                goto return_results;
        }
 
        /* set through each element */
-       nctrls = 0;
        *ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
 
 #if 0
        if( *ctrls == NULL ) {
                rc = LDAP_NO_MEMORY;
+               errmsg = "no memory";
                goto return_results;
        }
 #endif
 
-       ctrls[nctrls] = NULL;
+       *ctrls[nctrls] = NULL;
 
        for( tag = ber_first_element( ber, &len, &opaque );
                tag != LBER_ERROR;
@@ -75,6 +85,8 @@ int get_ctrls(
                LDAPControl **tctrls;
 
                tctrl = ch_calloc( 1, sizeof(LDAPControl) );
+               tctrl->ldctl_oid = NULL;
+               tctrl->ldctl_value.bv_val = NULL;
 
                /* allocate pointer space for current controls (nctrls)
                 * + this control + extra NULL
@@ -94,48 +106,70 @@ int get_ctrls(
                        *ctrls = NULL;
 
                        rc = LDAP_NO_MEMORY;
+                       errmsg = "no memory";
                        goto return_results;
                }
 #endif
 
-
                tctrls[nctrls++] = tctrl;
                tctrls[nctrls] = NULL;
 
                tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
 
-               if( tag != LBER_ERROR ) {
-                       tag = ber_peek_tag( ber, &len );
+               if( tag == LBER_ERROR ) {
+                       Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n",
+                               0, 0, 0 );
+                       *ctrls = NULL;
+                       ldap_controls_free( tctrls );
+                       rc = SLAPD_DISCONNECT;
+                       errmsg = "decoding controls error";
+                       goto return_results;
                }
 
+               tag = ber_peek_tag( ber, &len );
+
                if( tag == LBER_BOOLEAN ) {
                        ber_int_t crit;
                        tag = ber_scanf( ber, "b", &crit );
-                       tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
-               }
 
-               if( tag != LBER_ERROR ) {
+                       if( tag == LBER_ERROR ) {
+                               Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get crit failed.\n",
+                                       0, 0, 0 );
+                               *ctrls = NULL;
+                               ldap_controls_free( tctrls );
+                               rc = SLAPD_DISCONNECT;
+                               errmsg = "decoding controls error";
+                               goto return_results;
+                       }
+
+                       tctrl->ldctl_iscritical = (crit != 0);
                        tag = ber_peek_tag( ber, &len );
                }
 
+               Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n",
+                       tctrl->ldctl_oid, 
+                       tctrl->ldctl_iscritical ? "" : "non",
+                       0 );
+
                if( tag == LBER_OCTETSTRING ) {
                        tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
 
-               } else {
-                       tctrl->ldctl_value.bv_val = NULL;
-               }
-
-               if( tag == LBER_ERROR ) {
-                       *ctrls = NULL;
-                       ldap_controls_free( tctrls );
-                       rc = LDAP_DECODING_ERROR;
-                       goto return_results;
+                       if( tag == LBER_ERROR ) {
+                               Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get value failed.\n",
+                                       0, 0, 0 );
+                               *ctrls = NULL;
+                               ldap_controls_free( tctrls );
+                               rc = SLAPD_DISCONNECT;
+                               errmsg = "decoding controls error";
+                               goto return_results;
+                       }
                }
 
                if( tctrl->ldctl_iscritical &&
                        !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
                {
-                       rc = LDAP_UNAVAILABLE_CRITICIAL_EXTENSION;
+                       rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+                       errmsg = "critical extension is unavailable ";
                        goto return_results;
                }
 
@@ -143,9 +177,36 @@ int get_ctrls(
        }
 
 return_results:
+       Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: %d %d %s\n",
+               nctrls, rc, errmsg ? errmsg : "");
+
        if( sendres && rc != LDAP_SUCCESS ) {
-               send_ldap_result( conn, op, rc, NULL, NULL );
+               if( rc == SLAPD_DISCONNECT ) {
+                       send_ldap_disconnect( conn, op, rc, errmsg );
+               } else {
+                       send_ldap_result( conn, op, rc,
+                               NULL, errmsg, NULL, NULL );
+               }
        }
 
        return rc;
 }
+
+
+int get_manageDSAit( Operation *op )
+{
+       int i;
+       if( op == NULL || op->o_ctrls == NULL ) {
+               return 0;
+       }
+
+       for( i=0; op->o_ctrls[i] != NULL; i++ ) {
+               if( strcmp( LDAP_CONTROL_MANAGEDSAIT, op->o_ctrls[i]->ldctl_oid )
+                       == 0 )
+               {
+                       return 1;
+               }
+       }
+
+       return 0;
+}