Hello Everyone,
I'm trying to develop my application in c. And since I've never done LDAP before I thought i'd do a test program to work out the how's of retrieving from an ldap directory. in this case I'm pulling a X509 certificate from the verisign directory. I successfully run the search and can retrieve the data, but the certificate;binary is incomplete. I've tried a number of different things but cannot seem to get the whole certificate. Below is the hard coded test program, and any help would be greatly appreciated!
-- Michael Luich Stone's Rose mluich@stonesrose.com
#include <stdio.h> #include "ldap.h" /* Specify the search criteria here. */
#define HOSTNAME "directory.verisign.com"
#define PORTNUMBER 389
#define BASEDN ""
#define SCOPE LDAP_SCOPE_SUBTREE
#define FILTER "(mail=mluich@stonesrose.com)"
char *encode_64 (char *message);
int main (int argc, char **argv) {
LDAP *ld;
LDAPMessage *result, *e;
char *dn, *cert; char **vals;
int rc;
LDAPMessage *res;
char *a;
int version, i;
BerElement *ber;
// /* Print out an informational message. */ // // printf ("Connecting to host %s at port %d...\n\n", HOSTNAME, PORTNUMBER);
/* STEP 1: Get a handle to an LDAP connection and
set any session preferences. */
if ((ld = ldap_init (HOSTNAME, PORTNUMBER)) == NULL) {
perror ("ldap_init");
return (1);
}
/* Use the LDAP_OPT_PROTOCOL_VERSION session preference to specify
that the client is an LDAPv3 client. */
version = LDAP_VERSION3;
ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version);
/* STEP 2: Bind to the server.
In this example, the client binds anonymously to the server
(no DN or credentials are specified). */
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);
}
/* STEP 3: Perform the LDAP operations.
In this example, a simple search operation is performed.
The client iterates through each of the entries returned and
prints out the DN of each entry. */
rc = ldap_search_ext_s (ld, BASEDN, SCOPE, FILTER, NULL, 0, NULL, NULL, NULL, 0, &result);
if (rc != LDAP_SUCCESS) {
fprintf (stderr, "ldap_search_ext_s: %s\n", ldap_err2string (rc));
return (1);
}
if ((vals = ldap_get_values_len (ld, result, "usercertificate;binary")) != NULL) { for (i = 0; vals[i] != NULL; i++) {
printf ("%d - %s: %s\n", i, a, vals[i]);
// if (!strcmp (a, "usercertificate;binary")) // {
printf ("%s: %s\nlength: %d\n\n", a, vals[i], sizeof (vals[i])); encode_64 (vals[i]); // } } } else { fprintf (stderr, "ldap_get_values_len: %s\n", ldap_err2string (rc)); }
ldap_value_free (vals); ldap_msgfree (result); /* STEP 4: Disconnect from the server. */ ldap_unbind (ld); return (0); }
char * encode_64 (char *message) { #include <openssl/bio.h> #include <openssl/evp.h>
BIO *bio, *b64; //char message[] = "Hello World \n";
b64 = BIO_new (BIO_f_base64 ()); bio = BIO_new_fp (stdout, BIO_NOCLOSE); bio = BIO_push (b64, bio); BIO_write (bio, message, strlen (message)); BIO_flush (bio);
BIO_free_all (bio);
}
printf ("%s: %s\nlength: %d\n\n", a, vals[i], sizeof (vals[i]));
vals is a struct berval**.
This means vals[i] is a struct berval*.
This means the sizeof operator, which returns the size of the type, will always return the size of the pointer, because it's only a pointer. This means 4 on most 32bit systems and 8 on most 64bit systems.
And bervals are not strings. If you want to know the length, you'll have to look inside the berval. In lber.h, we have
typedef struct berval { ber_len_t bv_len; char *bv_val; } BerValue;
char * encode_64 (char *message) { #include <openssl/bio.h> #include <openssl/evp.h>
Why are you including headers inside a function?
Matthew Backes Symas Corporation mbackes@symas.com
openldap-technical@openldap.org