[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk
From: |
Stephen |
Subject: |
Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk |
Date: |
Sat, 27 Sep 2008 21:53:31 +1200 |
User-agent: |
Thunderbird 2.0.0.17 (Macintosh/20080914) |
Hi,
Thanks Paolo. Lots of progress, I have a query mostly running now! Here
is the issue...
I've run the script over a number of LDAP entries and it is consistently
tripping up at the mail attribute. It isn't as though the mail attribute
is always in the nth index of an entry either; at whatever index the
mail attribute occurs in the attribute list, the script will crash at
that point.
Here is the output of the script attached below:-
started
... about to run the search.
... search completed
Found results with base DN: ou=Users,dc=example,dc=com
Found first attribute
'givenName'
'givenName'->'Test --'
'sn'
'sn'->'email'
'loginShell'
'loginShell'->'/bin/bash'
'uidNumber'
'uidNumber'->'2008'
'gidNumber'
'gidNumber'->'2008'
'displayName'
'displayName'->'Testing email'
'mail'
Object: nil error: did not understand #value
MessageNotUnderstood(Exception)>>signal (AnsiExcept.st:216)
UndefinedObject(Object)>>doesNotUnderstand: #value (AnsiExcept.st:1484)
UndefinedObject>>executeStatements (ldapapi.st:171)
For comparison, here is the output from an ldapsearch query on the same
record:-
# sw-apple, Users, example.com
dn: uid=sw-apple,ou=Users,dc=example,dc=com
givenName: Test --
sn: email
loginShell: /bin/bash
uidNumber: 2008
gidNumber: 2008
displayName: Testing email
mail: address@hidden
objectClass: top
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: inetmailrecipient
uid: sw-apple
cn: test email
homeDirectory: /home/sw-apple
maildrop: address@hidden
mailacceptinggeneralid: address@hidden
And here is the script below. Some notes first:-
- I have some LDAP entries with _no_ mail attribute and these query just
fine with the script.
- I haven't used any "free" methods yet. As I see it, by omitting the
"free" methods, the script will not release memory from C objects. This
doesn't matter in initial testing (or does it?).
- You talked about adding an isNull method to Object. I tried inserting
the code you gave as you can see at the top of the script. I've
obviously done something wrong as it wouldn't compile so I commented it
out. This has meant I've had to omit a line "vals isNull ifTrue: [". I'd
like to get this working as a null in vals would trigger a crash like
what I'm seeing I think (although as you can see the mail attribute does
have a value).
Do you know what would be causing the crash or have suggestions for
something I can test?
Thank you
Stephen
------------------------
stephenw$ cat ldapapi.st
#!/usr/local/bin/gst -f
"call LDAP API"
" CObject extend [ "
"Will be in 3.1"
" isNull [ ^address = 0 ]
] "
CObject subclass: BER [
" -----------------------
LBER_F( void )
ber_free LDAP_P((
BerElement *ber,
int freebuf ));
------------------------- "
BER class >> free [
<cCall: 'ber_free' returning: #void args: #(#self #int)>
]
]
CObject subclass: LDAPMessage [
LDAPMessage class >> 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: #{LDAPMessage} 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'.
DLD addLibrary: 'libldap'.
hostName := 'aserver'.
baseDN := 'ou=Users,dc=example,dc=com'.
superviserDN := 'uid=sw,ou=Users,dc=example,dc=com'.
password := 'apwd'.
ldap := LDAP openOn: hostName port: 389.
ldap isNil ifTrue: [ File checkError. ObjectMemory quit: 1 ].
resultCode := ldap simpleBindWithDN: superviserDN passwd: password.
(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: superviserDN
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.
val := vals.
"vals isNull ifTrue: [ ... omitted since isNull method
won't compile"
attr printNl.
[ val value isNil ] whileFalse: [
(attr->val value) printNl.
val incr ].
"vals free. "
aPtr := ldap nextAttribute: entry ber: ber.
]
]
]
!
- [Help-smalltalk] Calling LDAP C API from Smalltalk, Stephen, 2008/09/18
- [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Paolo Bonzini, 2008/09/19
- [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Paolo Bonzini, 2008/09/19
- [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Stephen, 2008/09/26
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Paolo Bonzini, 2008/09/26
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk,
Stephen <=
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Paolo Bonzini, 2008/09/27
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Stephen, 2008/09/27
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Paolo Bonzini, 2008/09/27
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Stephen, 2008/09/27
- Re: [Help-smalltalk] Re: Calling LDAP C API from Smalltalk, Paolo Bonzini, 2008/09/27