[Date Prev][Date Next] [Chronological] [Thread] [Top]

RE: LDAP C API : ldap_next_attribute (ITS#778)



>Also, note that your example code is flawed.  It assumes
>LDAP_ERROR_NUMBER will be set to LDAP_SUCCESS on success.
>LDAP_ERROR_NUMBER behaves like errno.  The library only
>sets it upon error.

If this is the case, how is it possible to reliably check for
errors?  Unlike errno type calls which usually indicate an
error by returning -1, ldap_next_attribute overrides the
meaning of the return value to mean either 'no more attrs'
OR error.

The only way I can see to get around this is to set the error
code to LDAP_SUCCESS before the call to ldap_next_attribute.
Is this what you are suggesting?

Mark




-----Original Message-----
From: Kurt D. Zeilenga [mailto:Kurt@OpenLDAP.org]
Sent: Saturday, September 30, 2000 9:37 AM
To: markwhitehouse@home.com
Cc: openldap-its@OpenLDAP.org
Subject: Re: LDAP C API : ldap_next_attribute (ITS#778)


I committed changes to HEAD and OPENLDAP_REL_ENG_2 which
should resolve this problem.  Please test.

Also, note that your example code is flawed.  It assumes
LDAP_ERROR_NUMBER will be set to LDAP_SUCCESS on success.
LDAP_ERROR_NUMBER behaves like errno.  The library only
sets it upon error.

Kurt

At 06:53 PM 9/27/00 +0000, markwhitehouse@home.com wrote:
>Full_Name: Mark Whitehouse
>Version: 2.0.4
>OS: Linux RH 6.2
>URL: ftp://ftp.openldap.org/incoming/
>Submission from: (NULL) (24.0.41.53)
>
>
>Taken from draft-ietf-ldapext-ldap-c-api-04.txt:
>
>  ldap_first_attribute() and ldap_next_attribute() will return NULL when
>  the end of the attributes is reached, or if there is an error, in which
>  case the error parameters in the session handle ld will be set to indi-
>  cate the error.
>
>The code below (taken from draft-ietf-ldapext-ldap-c-api-04.txt)
illustrates
>why this does not work correctly in OpenLDAP 2.0.4.
>
>The last call to ldap_next_attribute() does return NULL as specified but
always
>sets LDAP_DECODING_ERROR flag.
>
>
>
>---------------------------------------------begin code
>
>#include <stdio.h>
>#include <ldap.h>
>
>
>/*
>  draft-ietf-ldapext-ldap-c-api-04.txt:
>
>  ldap_first_attribute() and ldap_next_attribute() will return NULL when
>  the end of the attributes is reached, or if there is an error, in which
>  case the error parameters in the session handle ld will be set to indi-
>  cate the error.
>*/
>
>void checkError(LDAP *ld, char *a)
>{
>  if (a == NULL)
>  {
>    // ok we have end of attributes or error
>    int ec;
>    ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ec);
>    if (ec != LDAP_SUCCESS)
>    {
>      // whoops we have an error here
>      printf( "ERROR: %s (%d)\n", ldap_err2string(ec), ec);
>    }
>  }
>}
>
>
>main()
>{
>  LDAP            *ld;
>  LDAPMessage     *res, *e;
>  int             i, rc;
>  char            *a, *dn;
>  BerElement      *ptr;
>  char            **vals;
>
>
>  /* open an LDAP session */
>  if ( (ld = ldap_init( "localhost", LDAP_PORT )) == NULL )
>    return 1;
>
>  /* authenticate as nobody */
>  if (( rc = ldap_simple_bind_s( ld, NULL, NULL )) != LDAP_SUCCESS ) {
>    fprintf( stderr, "ldap_simple_bind_s: %s\n",
>             ldap_err2string( rc ));
>    ldap_unbind( ld );
>    return 1;
>  }
>
>  /* search for entries with cn of "Babs Jensen",return all attrs  */
>  if (( rc = ldap_search_s( ld, "dc=mydomain,dc=com",
>                            LDAP_SCOPE_SUBTREE,
>                            "(objectclass=*)",
>                            NULL, 0, &res ))
>      != LDAP_SUCCESS )
>  {
>    fprintf( stderr, "ldap_search_s: %s\n",
>             ldap_err2string( rc ));
>    if ( res == NULL ) {
>      ldap_unbind( ld );
>      return 1;
>    }
>  }
>
>  /* step through each entry returned */
>  for ( e = ldap_first_entry( ld, res ); e != NULL;
>        e = ldap_next_entry( ld, e ) )
>  {
>    /* print its name */
>    dn = ldap_get_dn( ld, e );
>    printf( "dn: %s\n", dn );
>    ldap_memfree( dn );
>
>    /* print each attribute */
>    a = ldap_first_attribute( ld, e, &ptr );
>    checkError(ld, a);
>    while (a != NULL)
>    {
>      printf( "\tattribute: %s\n", a );
>
>      /* print each value */
>      vals = ldap_get_values( ld, e, a );
>      for ( i = 0; vals[i] != NULL; i++ ) {
>        printf( "\t\tvalue: %s\n", vals[i] );
>      }
>      ldap_value_free( vals );
>      ldap_memfree( a );
>
>      a = ldap_next_attribute( ld, e, ptr );
>      checkError(ld, a);
>    }
>    if ( ptr != NULL ) {
>      ber_free( ptr, 0 );
>    }
>  }
>
>  /* free the search results */
>  ldap_msgfree( res );
>
>  /* close and free connection resources */
>  ldap_unbind( ld );
>
>  return 0;
>}