help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] calling C API example using LDAP API


From: Stephen
Subject: [Help-smalltalk] calling C API example using LDAP API
Date: Fri, 16 Jan 2009 13:06:55 +1300
User-agent: Thunderbird 2.0.0.19 (Macintosh/20081209)

Sean Allen wrote:

On Jan 15, 2009, at 3:49 PM, Paolo Bonzini wrote:


Is there anything that does this right now that I could use as an exemplar?
Or should I just grep for #ptr #string and see what I find?

There's something somewhere, but I'll just point you to the mailing list
archives.  Look for the exchanges I had with Stephen (Woolerton) about
his LDAP bindings.

found those emails... having a hard time digesting...

Stephen... do you any code related to dealing with char ** or anything similar,
that I could take a look at.

i'm going to try printing out the emails and cutting them up and pasting them together in a different order, hoping, that might perhaps ease the absorbing of them.


_______________________________________________
help-smalltalk mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/help-smalltalk




I've attached a copy of a working C program to do an LDAP lookup - this
is what we were working from; the blueprint so to speak. You should find
this helpful as you can see what the C program was doing and then how it
was implemented in GST.

The C program was compiled on OS X like so...
  cc -g -o ldaptest main.c /usr/lib/libldap.dylib
It is from the "Advanced OS X Programming" book by dalrymple and hillegrass

Secondly, attached is the working script for where we got to.. best to
run it on a 32 bit system, (there was an issue which Paolo fixed on some
not all 64 bit systems).

Also attached is the ldap.h file (from Linux).

I'm just about to head out the door and away for the weekend so by all
means send questions through but you mightn't get a reply for a while.

Regards
Stephen

X bitmap

#!/usr/local/bin/gst -f
"call LDAP API"

DLD addLibrary: 'libldap'.

  CObject extend [ 
        "Will be in 3.1"
        isNull [ ^self address = 0 ]
  ] 

  UndefinedObject extend [ 
        isNull [ ^true ] ]

  CObject subclass: BER [
        " -----------------------
        LBER_F( void )
        ber_free LDAP_P((
                BerElement *ber,
                int freebuf ));
        ------------------------- "
      free [
        <cCall: 'ber_free' returning: #void args: #(#self #int)>
        ]
  ]

  CObject subclass: LDAPMessage [
      free [
        <cCall: 'ldap_msgfree' returning: #int args: #(#self)>
        ]
  ]

  CObject subclass: LDAP [
      "class variables"
      scopeBase := 0.
      nolimit := 0.

      LDAP class >> openOn: host port: port [
          "Maybe you prefer #open:port: as the selector, of course."
          <cCall: 'ldap_open' returning: #{LDAP} args: #(#string #int)>
      ]

      LDAP class >> on: host port: port [
          "Maybe you prefer #init:port: as the selector, of course."
          <cCall: 'ldap_init' returning: #{LDAP} args: #(#string #int)>
      ]

      LDAP class >> errorString: resultNum [
          "Utility methods might also go on the class side."
          <cCall: 'ldap_err2string' returning: #string args: #(#int)>
      ]

      simpleBindWithDN: who passwd: secret [
          <cCall: 'ldap_simple_bind_s' returning: #int args: #(#self #string 
#string)>
      ]

        " ldap_search_ext_s C definition -------------- 
        LDAP_F( int )
      ldap_search_ext_s LDAP_P((
        LDAP                    *ld,
        LDAP_CONST char *base,
        int                             scope,
        LDAP_CONST char *filter,
        char                    **attrs,
        int                             attrsonly,
        LDAPControl             **serverctrls,
        LDAPControl             **clientctrls,
        struct timeval  *timeout,
        int                             sizelimit,
        LDAPMessage             **res ));
        rc = ldap_search_ext_s( ld, FIND_DN, LDAP_SCOPE_BASE,
    ""(objectclass=*)"", NULL, 0, NULL, NULL, LDAP_NO_LIMIT,
    LDAP_NO_LIMIT, &result
                                        --------------- "
        "TODO: write a wrapper method which has less parameters and calls this 
one"
        searchWithBase: baseDN
          scope: aScope
          filter: aFilter
          attributes: theAttribs
          isAttrsOnly: attrsOnly
          serverctrls: serverControl
          clientctrls: clientControl
          timeout: timeval
          sizelimit: numResults
          searchResult: aSearchResult [
           <cCall: 'ldap_search_ext_s' returning: #int args: #(#self #string 
#int #string #cObject #int #cObject #cObject #cObject #int #cObjectPtr)>
        ]

        " ldap_first_entry C definition --------------
        LDAP_F( LDAPMessage * )
        ldap_first_entry LDAP_P((
                LDAP *ld,
                LDAPMessage *chain ));
                                        --------------"
        firstEntry: searchResult [
                <cCall: 'ldap_first_entry' returning: #cObject args: #(#self 
#cObject)> ]

        "                       -------------
        LDAP_F( char * )
        ldap_first_attribute LDAP_P((
                LDAP *ld,
                LDAPMessage *entry,
                BerElement **ber ));
                                -------------"
        firstAttribute: anEntry ber: aBer [
                <cCall: 'ldap_first_attribute' returning: #cObject args: 
#(#self #cObject #cObjectPtr)> ]

        "                       -------------
        LDAP_F( char * )
        ldap_next_attribute LDAP_P((
                LDAP *ld,
                LDAPMessage *entry,
                BerElement *ber ));
                                -------------"
        nextAttribute: anEntry ber: aBer [
                <cCall: 'ldap_next_attribute' returning: #cObject args: #(#self 
#cObject #cObject)> ]   

        "                       -------------
        #if LDAP_DEPRECATED
        LDAP_F( char ** )
        ldap_get_values LDAP_P((        /* deprecated, use ldap_get_values_len 
*/
                LDAP *ld,
                LDAPMessage *entry,
                LDAP_CONST char *target ));
                                -------------"
        getValues: anEntry attribute: anAttribute [
                <cCall: 'ldap_get_values' returning: #{CString} args: #(#self 
#cObject #cObject)> ]

]

| ldapcall ldap resultCode resultCode2 errorMsg hostName baseDN |
Transcript showCr: 'started'.
hostName := '192.168.0.1'.
baseDN := 'ou=Users,dc=example,dc=com'.
superviserDN := 'uid=myacct,ou=Users,dc=example,dc=com'.

ldap := LDAP openOn: hostName port: 389.
ldap isNil ifTrue: [ File checkError. ObjectMemory quit: 1 ].
resultCode := ldap simpleBindWithDN: superviserDN passwd: 'passwordhere.
(resultCode > 0) ifTrue: [
        "Transcript showCr: ('%1 is result from bind' % { resultCode })."
        errorCodeMsg := LDAP errorString: resultCode.
        Transcript showCr: 'The LDAP Bind failed with the message: 
',errorCodeMsg ].

(resultCode = 0) ifTrue: [
        Transcript showCr: '... about to run the search.'.
        resultCode := ldap searchWithBase: 
'uid=user2,ou=Users,dc=example,dc=com'
          scope: 16r0000 
          filter: '(objectclass=*)'
          attributes: nil
          isAttrsOnly: 0
          serverctrls: nil
          clientctrls: nil
          timeout: nil
          sizelimit: 0
          searchResult: (searchResult := LDAPMessage new).
        Transcript showCr: '... search completed'.      

        (resultCode > 0) ifTrue: [
                "Transcript showCr: ('%1 is result from bind' % { resultCode 
})."
                errorCodeMsg := LDAP errorString: resultCode.
                Transcript showCr: 'The LDAP search failed with the message: 
',errorCodeMsg ].

        entry := ldap firstEntry: searchResult.
        entry isNil ifFalse: [
                ('Found results with base DN: ', baseDN) displayNl.
                aPtr := ldap firstAttribute: entry ber: (ber := BER new).
                ('Found first attribute') displayNl.
                [ aPtr isNil ] whileFalse: [
                        attr := String fromCData: aPtr.
                        aPtr free.

                        vals := ldap getValues: entry attribute: attr.
                        vals isNull ifFalse: [
                                val := vals.
                                [ val value isNil ] whileFalse: [
                                        (attr->val value) printNl.
                                        val incr ].
                                "vals free. "
                        ].
                        vals isNull ifTrue: [
                                Transcript showCr: ('  **  Attribute %1 has 
null value.' % {attr}) ].
                        aPtr := ldap nextAttribute: entry ber: ber.
                ]
        ]
]


#include <stdio.h>
#include <ldap.h>

/* Adjust these setting for your own LDAP server */
#define HOSTNAME "192.168.0.1"
#define PORT_NUMBER  LDAP_PORT
#define FIND_DN "uid=myaccount,dc=example,dc=com"

int
main( int argc, const char * argv[] )
{
        LDAP         *ld;
        LDAPMessage  *result, *e;
        BerElement   *ber;
        char         *a;
        char         **vals;
        int          i, rc;
        
        /* Get a handle to an LDAP connection. */
        if ( (ld = ldap_init( HOSTNAME, PORT_NUMBER )) == NULL ) {
                perror( "ldap_init" );
                return( 1 );
        }
        
        /* Bind anonymously to the LDAP server. */
        rc = ldap_simple_bind_s( ld, NULL, NULL );
        if ( rc != LDAP_SUCCESS ) {
                fprintf(stderr, "ldap_simple_bind_s: %s\n", 
ldap_err2string(rc));
                return( 1 );
        }
        
        /* Search for the entry. */
        if ( ( rc = ldap_search_ext_s( ld, FIND_DN, LDAP_SCOPE_BASE,
                                                                  
"(objectclass=*)", NULL, 0, NULL, NULL, LDAP_NO_LIMIT,
                                                                  
LDAP_NO_LIMIT, &result ) ) != LDAP_SUCCESS ) {
                fprintf(stderr, "ldap_search_ext_s: %s\n", ldap_err2string(rc));
                return( 1 );
        }
        
        /* Since we are doing a base search, there should be only
     one matching entry. */
        e = ldap_first_entry( ld, result );
        if ( e != NULL ) {
                printf( "\nFound %s:\n\n", FIND_DN );
                
                /* Iterate through each attribute in the entry. */
                for ( a = ldap_first_attribute( ld, e, &ber );
                         a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
                        
                        /* For each attribute, print the attribute name and 
values. */
                        if ((vals = ldap_get_values( ld, e, a)) != NULL ) {
                                for ( i = 0; vals[i] != NULL; i++ ) {
                                        printf( "%s: %s\n", a, vals[i] );
                                }
                                ldap_value_free( vals );
                        }
                        ldap_memfree( a );
                }
                if ( ber != NULL ) {
                        ber_free( ber, 0 );
                }
        }
        ldap_msgfree( result );
        ldap_unbind( ld );
        return( 0 );
} 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]