home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / extended.c < prev    next >
C/C++ Source or Header  |  2000-07-05  |  8KB  |  389 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/extended.c,v 1.8.4.3 2000/07/04 17:58:51 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6.  
  7. /*
  8.  * LDAPv3 Extended Operation Request
  9.  *    ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
  10.  *        requestName      [0] LDAPOID,
  11.  *        requestValue     [1] OCTET STRING OPTIONAL
  12.  *    }
  13.  *
  14.  * LDAPv3 Extended Operation Response
  15.  *    ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
  16.  *        COMPONENTS OF LDAPResult,
  17.  *        responseName     [10] LDAPOID OPTIONAL,
  18.  *        response         [11] OCTET STRING OPTIONAL
  19.  *    }
  20.  *
  21.  */
  22.  
  23. #include "portable.h"
  24.  
  25. #include <stdio.h>
  26. #include <ac/stdlib.h>
  27.  
  28. #include <ac/socket.h>
  29. #include <ac/string.h>
  30. #include <ac/time.h>
  31.  
  32. #include "ldap-int.h"
  33.  
  34. int
  35. ldap_extended_operation(
  36.     LDAP            *ld,
  37.     LDAP_CONST char    *reqoid,
  38.     struct berval    *reqdata,
  39.     LDAPControl        **sctrls,
  40.     LDAPControl        **cctrls,
  41.     int                *msgidp )
  42. {
  43.     BerElement *ber;
  44.     int rc;
  45.  
  46.     Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n", 0, 0, 0 );
  47.  
  48.     assert( ld != NULL );
  49.     assert( LDAP_VALID( ld ) );
  50.     assert( reqoid != NULL || *reqoid == '\0' );
  51.     assert( msgidp != NULL );
  52.  
  53.     /* must be version 3 (or greater) */
  54.     if ( ld->ld_version < LDAP_VERSION3 ) {
  55.         ld->ld_errno = LDAP_NOT_SUPPORTED;
  56.         return( ld->ld_errno );
  57.     }
  58.  
  59.     if( reqoid == NULL || *reqoid == '\0' || msgidp == NULL ) {
  60.         ld->ld_errno = LDAP_PARAM_ERROR;
  61.         return( ld->ld_errno );
  62.     }
  63.  
  64.     /* create a message to send */
  65.     if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
  66.         ld->ld_errno = LDAP_NO_MEMORY;
  67.         return( ld->ld_errno );
  68.     }
  69.  
  70.     if ( reqdata != NULL ) {
  71.         rc = ber_printf( ber, "{it{tstON}", /* '}' */
  72.             ++ld->ld_msgid, LDAP_REQ_EXTENDED,
  73.             LDAP_TAG_EXOP_REQ_OID, reqoid,
  74.             LDAP_TAG_EXOP_REQ_VALUE, reqdata );
  75.  
  76.     } else {
  77.         rc = ber_printf( ber, "{it{tsN}", /* '}' */
  78.             ++ld->ld_msgid, LDAP_REQ_EXTENDED,
  79.             LDAP_TAG_EXOP_REQ_OID, reqoid );
  80.     }
  81.  
  82.     if( rc == -1 ) {
  83.         ld->ld_errno = LDAP_ENCODING_ERROR;
  84.         ber_free( ber, 1 );
  85.         return( ld->ld_errno );
  86.     }
  87.  
  88.     /* Put Server Controls */
  89.     if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
  90.         ber_free( ber, 1 );
  91.         return ld->ld_errno;
  92.     }
  93.  
  94.     if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
  95.         ld->ld_errno = LDAP_ENCODING_ERROR;
  96.         ber_free( ber, 1 );
  97.         return( ld->ld_errno );
  98.     }
  99.  
  100.     /* send the message */
  101.     *msgidp = ldap_send_initial_request( ld, LDAP_REQ_EXTENDED, NULL, ber );
  102.  
  103.     return( *msgidp < 0 ? ld->ld_errno : LDAP_SUCCESS );
  104. }
  105.  
  106. int
  107. ldap_extended_operation_s(
  108.     LDAP            *ld,
  109.     LDAP_CONST char    *reqoid,
  110.     struct berval    *reqdata,
  111.     LDAPControl        **sctrls,
  112.     LDAPControl        **cctrls,
  113.     char            **retoidp,
  114.     struct berval    **retdatap )
  115. {
  116.     int     rc;
  117.     int     msgid;
  118.     LDAPMessage *res;
  119.  
  120.     Debug( LDAP_DEBUG_TRACE, "ldap_extended_operation_s\n", 0, 0, 0 );
  121.  
  122.     assert( ld != NULL );
  123.     assert( LDAP_VALID( ld ) );
  124.     assert( reqoid != NULL || *reqoid == '\0' );
  125.     assert( retoidp != NULL || retdatap != NULL );
  126.  
  127.     if( retoidp == NULL || retdatap == NULL ) {
  128.         ld->ld_errno = LDAP_PARAM_ERROR;
  129.         return( ld->ld_errno );
  130.     }
  131.  
  132.     rc = ldap_extended_operation( ld, reqoid, reqdata,
  133.         sctrls, cctrls, &msgid );
  134.         
  135.     if ( rc != LDAP_SUCCESS ) {
  136.         return( rc );
  137.     }
  138.  
  139.     if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) {
  140.         return( ld->ld_errno );
  141.     }
  142.  
  143.     *retoidp = NULL;
  144.     *retdatap = NULL;
  145.  
  146.     rc = ldap_parse_extended_result( ld, res, retoidp, retdatap, 0 );
  147.  
  148.     if( rc != LDAP_SUCCESS ) {
  149.         ldap_msgfree( res );
  150.         return rc;
  151.     }
  152.  
  153.     return( ldap_result2error( ld, res, 1 ) );
  154. }
  155.  
  156. /* Parse an extended result */
  157. int
  158. ldap_parse_extended_result (
  159.     LDAP            *ld,
  160.     LDAPMessage        *res,
  161.     char            **retoidp,
  162.     struct berval    **retdatap,
  163.     int                freeit )
  164. {
  165.     BerElement *ber;
  166.     ber_tag_t rc;
  167.     ber_tag_t tag;
  168.     ber_len_t len;
  169.     struct berval *resdata;
  170.     ber_int_t errcode;
  171.     char *resoid;
  172.  
  173.     assert( ld != NULL );
  174.     assert( LDAP_VALID( ld ) );
  175.     assert( res != NULL );
  176.  
  177.     Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n", 0, 0, 0 );
  178.  
  179.     if( ld->ld_version < LDAP_VERSION3 ) {
  180.         ld->ld_errno = LDAP_NOT_SUPPORTED;
  181.         return ld->ld_errno;
  182.     }
  183.  
  184.     if( res->lm_msgtype != LDAP_RES_EXTENDED ) {
  185.         ld->ld_errno = LDAP_PARAM_ERROR;
  186.         return ld->ld_errno;
  187.     }
  188.  
  189.     if( retoidp != NULL ) *retoidp = NULL;
  190.     if( retdatap != NULL ) *retdatap = NULL;
  191.  
  192.     if ( ld->ld_error ) {
  193.         LDAP_FREE( ld->ld_error );
  194.         ld->ld_error = NULL;
  195.     }
  196.  
  197.     if ( ld->ld_matched ) {
  198.         LDAP_FREE( ld->ld_matched );
  199.         ld->ld_matched = NULL;
  200.     }
  201.  
  202.     ber = ber_dup( res->lm_ber );
  203.  
  204.     if ( ber == NULL ) {
  205.         ld->ld_errno = LDAP_NO_MEMORY;
  206.         return ld->ld_errno;
  207.     }
  208.  
  209.     rc = ber_scanf( ber, "{iaa" /*}*/, &errcode,
  210.         &ld->ld_matched, &ld->ld_error );
  211.  
  212.     if( rc == LBER_ERROR ) {
  213.         ld->ld_errno = LDAP_DECODING_ERROR;
  214.         ber_free( ber, 0 );
  215.         return ld->ld_errno;
  216.     }
  217.  
  218.     resoid = NULL;
  219.     resdata = NULL;
  220.  
  221.     tag = ber_peek_tag( ber, &len );
  222.  
  223.     if( tag == LDAP_TAG_REFERRAL ) {
  224.         /* skip over referral */
  225.         if( ber_scanf( ber, "x" ) == LBER_ERROR ) {
  226.             ld->ld_errno = LDAP_DECODING_ERROR;
  227.             ber_free( ber, 0 );
  228.             return ld->ld_errno;
  229.         }
  230.  
  231.         tag = ber_peek_tag( ber, &len );
  232.     }
  233.  
  234.     if( tag == LDAP_TAG_EXOP_RES_OID ) {
  235.         /* we have a resoid */
  236.         if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
  237.             ld->ld_errno = LDAP_DECODING_ERROR;
  238.             ber_free( ber, 0 );
  239.             return ld->ld_errno;
  240.         }
  241.  
  242.         tag = ber_peek_tag( ber, &len );
  243.     }
  244.  
  245.     if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
  246.         /* we have a resdata */
  247.         if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
  248.             ld->ld_errno = LDAP_DECODING_ERROR;
  249.             ber_free( ber, 0 );
  250.             if( resoid != NULL ) LDAP_FREE( resoid );
  251.             return ld->ld_errno;
  252.         }
  253.     }
  254.  
  255.     ber_free( ber, 0 );
  256.  
  257.     if( retoidp != NULL ) {
  258.         *retoidp = resoid;
  259.     } else {
  260.         LDAP_FREE( resoid );
  261.     }
  262.  
  263.     if( retdatap != NULL ) {
  264.         *retdatap = resdata;
  265.     } else {
  266.         ber_bvfree( resdata );
  267.     }
  268.  
  269.     ld->ld_errno = errcode;
  270.  
  271.     if( freeit ) {
  272.         ldap_msgfree( res );
  273.     }
  274.  
  275.     return LDAP_SUCCESS;
  276. }
  277.  
  278.  
  279. /* Parse an extended partial */
  280. int
  281. ldap_parse_extended_partial (
  282.     LDAP            *ld,
  283.     LDAPMessage        *res,
  284.     char            **retoidp,
  285.     struct berval    **retdatap,
  286.     LDAPControl        ***serverctrls,
  287.     int                freeit )
  288. {
  289.     BerElement *ber;
  290.     ber_tag_t rc;
  291.     ber_tag_t tag;
  292.     ber_len_t len;
  293.     struct berval *resdata;
  294.     char *resoid;
  295.  
  296.     assert( ld != NULL );
  297.     assert( LDAP_VALID( ld ) );
  298.     assert( res != NULL );
  299.  
  300.     Debug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n", 0, 0, 0 );
  301.  
  302.     if( ld->ld_version < LDAP_VERSION3 ) {
  303.         ld->ld_errno = LDAP_NOT_SUPPORTED;
  304.         return ld->ld_errno;
  305.     }
  306.  
  307.     if( res->lm_msgtype != LDAP_RES_EXTENDED_PARTIAL ) {
  308.         ld->ld_errno = LDAP_PARAM_ERROR;
  309.         return ld->ld_errno;
  310.     }
  311.  
  312.     if( retoidp != NULL ) *retoidp = NULL;
  313.     if( retdatap != NULL ) *retdatap = NULL;
  314.  
  315.     ber = ber_dup( res->lm_ber );
  316.  
  317.     if ( ber == NULL ) {
  318.         ld->ld_errno = LDAP_NO_MEMORY;
  319.         return ld->ld_errno;
  320.     }
  321.  
  322.     rc = ber_scanf( ber, "{" /*}*/ );
  323.  
  324.     if( rc == LBER_ERROR ) {
  325.         ld->ld_errno = LDAP_DECODING_ERROR;
  326.         ber_free( ber, 0 );
  327.         return ld->ld_errno;
  328.     }
  329.  
  330.     resoid = NULL;
  331.     resdata = NULL;
  332.  
  333.     tag = ber_peek_tag( ber, &len );
  334.  
  335.     if( tag == LDAP_TAG_EXOP_RES_OID ) {
  336.         /* we have a resoid */
  337.         if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
  338.             ld->ld_errno = LDAP_DECODING_ERROR;
  339.             ber_free( ber, 0 );
  340.             return ld->ld_errno;
  341.         }
  342.  
  343.         tag = ber_peek_tag( ber, &len );
  344.     }
  345.  
  346.     if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
  347.         /* we have a resdata */
  348.         if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
  349.             ld->ld_errno = LDAP_DECODING_ERROR;
  350.             ber_free( ber, 0 );
  351.             if( resoid != NULL ) LDAP_FREE( resoid );
  352.             return ld->ld_errno;
  353.         }
  354.     }
  355.  
  356.     if ( serverctrls == NULL ) {
  357.         rc = LDAP_SUCCESS;
  358.         goto free_and_return;
  359.     }
  360.  
  361.     if ( ber_scanf( ber, /*{*/ "}" ) == LBER_ERROR ) {
  362.         rc = LDAP_DECODING_ERROR;
  363.         goto free_and_return;
  364.     }
  365.  
  366.     rc = ldap_int_get_controls( ber, serverctrls );
  367.  
  368. free_and_return:
  369.     ber_free( ber, 0 );
  370.  
  371.     if( retoidp != NULL ) {
  372.         *retoidp = resoid;
  373.     } else {
  374.         LDAP_FREE( resoid );
  375.     }
  376.  
  377.     if( retdatap != NULL ) {
  378.         *retdatap = resdata;
  379.     } else {
  380.         ber_bvfree( resdata );
  381.     }
  382.  
  383.     if( freeit ) {
  384.         ldap_msgfree( res );
  385.     }
  386.  
  387.     return LDAP_SUCCESS;
  388. }
  389.