$NetBSD: patch-am,v 1.3 2005/11/12 16:49:24 aolcarton Exp $ --- lib/scepldap.c.orig Tue Feb 19 23:40:06 2002 +++ lib/scepldap.c @@ -7,2 +7,3 @@ */ +#include #include @@ -41,2 +42,4 @@ char *x509_to_ldap(scep_t *scep, X509_NA __FILE__, __LINE__, oname); + syslog(LOG_DEBUG, "%s:%d: LDAP mapping of %s requested\n", + __FILE__, __LINE__, oname); } @@ -47,2 +50,4 @@ char *x509_to_ldap(scep_t *scep, X509_NA __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: unstructuredName not found\n", + __FILE__, __LINE__); goto err; @@ -68,2 +73,4 @@ char *x509_to_ldap(scep_t *scep, X509_NA " attribute\n", __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: no data for unstruturedName" + " attribute\n", __FILE__, __LINE__); goto err; @@ -73,3 +80,3 @@ char *x509_to_ldap(scep_t *scep, X509_NA dn = (char *)malloc(dnl); - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: unstructuredName has type " @@ -79,2 +86,8 @@ char *x509_to_ldap(scep_t *scep, X509_NA as->length, as->data, dnl); + syslog(LOG_DEBUG, "%s:%d: unstructuredName has type " + "%d length %d with value '%*.*s', allocated %d " + " bytes\n", __FILE__, + __LINE__, as->type, as->length, as->length, + as->length, as->data, dnl); + } snprintf(dn, dnl, "unstructuredName=%*.*s,%s", as->length, @@ -103,5 +116,8 @@ char *x509_to_ldap(scep_t *scep, X509_NA reply: - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: X509_NAME '%s' mapped to '%s'\n", __FILE__, __LINE__, oname, dn); + syslog(LOG_DEBUG, "%s:%d: X509_NAME '%s' mapped to '%s'\n", + __FILE__, __LINE__, oname, dn); + } return dn; @@ -148,2 +164,4 @@ X509_NAME *ldap_to_x509(char *dn) { __FILE__, __LINE__, name); + syslog(LOG_ERR, "%s:%d: no = on dn component %s\n", + __FILE__, __LINE__, name); goto err; @@ -151,3 +169,3 @@ X509_NAME *ldap_to_x509(char *dn) { *value = '\0'; value++; - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: found name = '%s', " @@ -155,2 +173,6 @@ X509_NAME *ldap_to_x509(char *dn) { value); + syslog(LOG_DEBUG, "%s:%d: found name = '%s', " + "value = '%s'\n", __FILE__, __LINE__, name, + value); + } @@ -165,2 +187,4 @@ X509_NAME *ldap_to_x509(char *dn) { "%s=%s\n", __FILE__, __LINE__, name, value); + syslog(LOG_ERR, "%s:%d: cannot create name entry " + "%s=%s\n", __FILE__, __LINE__, name, value); goto err; @@ -182,26 +206,45 @@ err: int scep_ldap_init(scep_t *scep) { + int version3 = 3, rc; + /* initialize the LDAP structure */ - if (NULL == (scep->l.ldap = ldap_init(scep->l.ldaphost, - scep->l.ldapport))) { - BIO_printf(bio_err, "%s:%d: cannot initialize LDAP: %s (%d)\n", - __FILE__, __LINE__, strerror(errno), errno); + rc = ldap_initialize(&scep->l.ldap, scep->l.ldapuri); + if (rc || scep->l.ldap == NULL) { + BIO_printf(bio_err, "%s:%d: cannot initialize LDAP connection to %s: %s (%d)\n", + __FILE__, __LINE__, scep->l.ldapuri != NULL ? scep->l.ldapuri : "", ldap_err2string(rc), rc); + syslog(LOG_ERR, "%s:%d: cannot initialize LDAP connection to %s: %s (%d)\n", + __FILE__, __LINE__, scep->l.ldapuri != NULL ? scep->l.ldapuri : "", ldap_err2string(rc), rc); goto err; } - if (debug) - BIO_printf(bio_err, "%s:%d: LDAP %s:%d initialized\n", - __FILE__, __LINE__, scep->l.ldaphost, scep->l.ldapport); - + if (debug) { + BIO_printf(bio_err, "%s:%d: LDAP URI %s initialized\n", + __FILE__, __LINE__, scep->l.ldapuri != NULL ? scep->l.ldapuri : ""); + syslog(LOG_DEBUG, "%s:%d: LDAP URI %s initialized\n", + __FILE__, __LINE__, scep->l.ldapuri != NULL ? scep->l.ldapuri : ""); + } + if (ldap_set_option(scep->l.ldap, LDAP_OPT_PROTOCOL_VERSION, &version3) + != LDAP_OPT_SUCCESS ) { + BIO_printf(bio_err, "%s:%d: couldn't set LDAP protocol version 3\n", + __FILE__, __LINE__); + syslog(LOG_DEBUG, "%s:%d: couldn't set LDAP protocol version 3\n", + __FILE__, __LINE__); + goto err; + } /* perform a bind, if required by the configuration */ if ((scep->l.binddn) && (scep->l.bindpw)) { - if (LDAP_SUCCESS != ldap_simple_bind_s(scep->l.ldap, - scep->l.binddn, scep->l.bindpw)) { - BIO_printf(bio_err, "%s:%d: bind failed\n", __FILE__, - __LINE__); + if (LDAP_SUCCESS != (rc = ldap_simple_bind_s(scep->l.ldap, + scep->l.binddn, scep->l.bindpw))) { + BIO_printf(bio_err, "%s:%d: bind failed: %s\n", __FILE__, + __LINE__, ldap_err2string(rc)); + syslog(LOG_ERR, "%s:%d: bind failed: %s\n", __FILE__, + __LINE__, ldap_err2string(rc)); goto err; } - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: LDAP bind complete\n", __FILE__, __LINE__); - } else - if (debug) + syslog(LOG_DEBUG, "%s:%d: LDAP bind complete\n", + __FILE__, __LINE__); + } + } else { + if (debug) { BIO_printf(bio_err, "%s:%d: LDAP bind not necessary, " @@ -209,2 +252,7 @@ int scep_ldap_init(scep_t *scep) { __LINE__); + syslog(LOG_DEBUG, "%s:%d: LDAP bind not necessary, " + "insufficient parameters\n", __FILE__, + __LINE__); + } + } return 0; @@ -256,6 +304,7 @@ int ldap_store_cert(scep_t *scep) { char *ocvals[3], *idnvals[2], *sdnvals[2], *servals[2], - *upvals[2]; - struct berval *certvals[2]; + *upvals[2], *firstdnvals[2], *usnvals[2]; + struct berval *certvals[2], *firstdnbvals[2], *usnbvals[2]; struct berval certval; - LDAPMod ocmod, idnmod, sdnmod, sermod, certmod, upmod; + LDAPMod ocmod, idnmod, sdnmod, sermod, certmod, upmod, + firstdnmod, usnmod; LDAPMod *mods[5]; @@ -263,2 +312,3 @@ int ldap_store_cert(scep_t *scep) { int rc; + LDAPDN ldapdn; @@ -270,2 +320,4 @@ int ldap_store_cert(scep_t *scep) { "faked\n", __FILE__, __LINE__); + syslog(LOG_DEBUG, "%s:%d: no LDAP, store_cert " + "faked\n", __FILE__, __LINE__); return 0; @@ -285,2 +337,5 @@ int ldap_store_cert(scep_t *scep) { __LINE__); + syslog(LOG_ERR, "%s:%d: cannot get the client " + "certificate from the file system\n", __FILE__, + __LINE__); goto err; @@ -296,2 +351,4 @@ int ldap_store_cert(scep_t *scep) { __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: cannot convert DN to LDAP form\n", + __FILE__, __LINE__); goto err; @@ -305,3 +362,4 @@ int ldap_store_cert(scep_t *scep) { ocvals[1] = "sCEPClient"; - ocvals[2] = NULL; + ocvals[2] = "device"; + ocvals[3] = NULL; ocmod.mod_op = LDAP_MOD_ADD; @@ -309,12 +367,112 @@ int ldap_store_cert(scep_t *scep) { ocmod.mod_values = ocvals; + rc = ldap_str2dn(dn, &ldapdn, LDAP_DN_FORMAT_LDAPV3); + if (rc != LDAP_SUCCESS) { + BIO_printf(bio_err, "%s:%d: cannot convert LDAP DN \"%s\" to opaque form: %s\n", + __FILE__, __LINE__, dn, ldap_err2string(rc)); + syslog(LOG_ERR, "%s:%d: cannot convert LDAP DN \"%s\" to opaque form: %s\n", + __FILE__, __LINE__, dn, ldap_err2string(rc)); + goto err; + } + + /* + * in LDAPv3 first element of dn X=y + * must appear as an attribute-value + * x: y + * ...apparently. Whatever. I could + * strap on a suit and tie and fly + * to Leysin for some conference to + * decide what goes in an X.500 + * object, or I could just keep + * slapping crap into the object until + * slapd shuts up. + */ + firstdnmod.mod_op = LDAP_MOD_ADD; + /* + * LDAPv3 DNs can have _RDN components_ separated by , which + * are each in a different scope and arranged heirarchically, + * like domain name components. Then, each RDN can have + * components which are in the same scope and not + * heirarchical. I've never seen that used and don't know + * what the narrative scenario is for that, but apparently + * they're separated by + like + * + * CN=Ada+CN=Lucette,O=WIPO,ST=ASSO,C=FR + * + * Silly. next, the ldap_explode_dn man page is wrong. It + * has an extra pointer indirection in the + * typedef **LDAPRDN LDAPDN. In ldap.h it is just + * typedef *LDAPRDN LDAPDN, which makes sense because LDAPRDN + * is not a struct. Then there is another extra * in the + * prototype of ldap_str2dn, and another extra star in the + * 'struct berval *la_attr, *la_value'. just use the header + * file. The man page is so broken. + * + * the (X[0])[0]->y selects the first AVA pair of the + * first component of the DN, so in this case ldapdn[0] + * would select CN=Ada+CN=Lucette and (ldapdn[0])[0] would + * select CN=Ada and (X[0])[0]->la_value would select Ada. + * + * But then you don't know for sure that Ada isn't + * BER-encoded, and if it's not, how to typecast or reference + * structure members to get a string out of it. And in + * ldap.h, la_attr is a berval also, but there is no flag + * in an LDAPAVA nor in an LDAPMod to deal with BER-encoded + * attribute names. according to libraries/libldap/getdn.c + * la_attr could actually be binary if attribute names of the + * form 'oid.1.3.6.1...' are used, and with this API we just + * pass this into a (char *) like any string. :( + * + * This is all just a complete motherfucking standardsbloat + * disaster. + */ + if ( (ldapdn[0])[0]->la_flags == LDAP_AVA_BINARY) { + firstdnmod.mod_op |= LDAP_MOD_BVALUES; + firstdnbvals[0] = &(ldapdn[0])[0]->la_value; + firstdnbvals[1] = NULL; + firstdnmod.mod_bvalues = firstdnbvals; + } else { + firstdnvals[0] = (ldapdn[0])[0]->la_value.bv_val; + firstdnvals[1] = NULL; + firstdnmod.mod_values = firstdnvals; + } + firstdnmod.mod_type = (ldapdn[0])[0]->la_attr.bv_val; + /* + * the 'device' structural objectclass says an + * common name is mandatory, even though we're allowed + * to use the unstructuredName in the DN. + */ + if (strcmp(firstdnmod.mod_type, "cn") != 0) { + usnmod.mod_op = LDAP_MOD_ADD; + if ( (ldapdn[0])[0]->la_flags == LDAP_AVA_BINARY) { + usnmod.mod_op |= LDAP_MOD_BVALUES; + usnbvals[0] = &(ldapdn[0])[0]->la_value; + usnbvals[1] = NULL; + usnmod.mod_bvalues = usnbvals; + } else { + usnvals[0] = (ldapdn[0])[0]->la_value.bv_val; + usnvals[1] = NULL; + usnmod.mod_values = usnvals; + } + usnmod.mod_type = "cn"; + mods[2] = &usnmod; + } else + mods[2] = NULL; mods[0] = &ocmod; - mods[1] = NULL; + mods[1] = &firstdnmod; + mods[3] = NULL; if (ldap_add_s(scep->l.ldap, dn, mods) != LDAP_SUCCESS) { + ldap_memfree(ldapdn); BIO_printf(bio_err, "%s:%d: cannot add new node %s\n", __FILE__, __LINE__, dn); + syslog(LOG_ERR, "%s:%d: cannot add new node %s\n", + __FILE__, __LINE__, dn); goto err; } - if (debug) - BIO_printf(bio_err, "%s:%d: adding skeleton node for " + ldap_memfree(ldapdn); + if (debug) { + BIO_printf(bio_err, "%s:%d: added skeleton node for " "%s\n", __FILE__, __LINE__, dn); + syslog(LOG_DEBUG, "%s:%d: added skeleton node for " + "%s\n", __FILE__, __LINE__, dn); + } } @@ -337,2 +495,10 @@ int ldap_store_cert(scep_t *scep) { __LINE__, serial); + syslog(LOG_DEBUG, "%s:%d: replacing attributes in dn = %s:\n", + __FILE__, __LINE__, dn); + syslog(LOG_DEBUG, "%s:%d:\tissuerDN=%s\n", __FILE__, + __LINE__, issuerDN); + syslog(LOG_DEBUG, "%s:%d:\tsubjectDN=%s\n", __FILE__, + __LINE__, subjectDN); + syslog(LOG_DEBUG, "%s:%d:\tserialNumber=%s\n", __FILE__, + __LINE__, serial); } @@ -341,5 +507,8 @@ int ldap_store_cert(scep_t *scep) { challenge = get_challenge(scep); - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: got challenge password: %s\n", __FILE__, __LINE__, (challenge) ? challenge: ""); + syslog(LOG_DEBUG, "%s:%d: got challenge password: %s\n", + __FILE__, __LINE__, (challenge) ? "" : ""); + } @@ -376,2 +545,4 @@ int ldap_store_cert(scep_t *scep) { __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: cannot write client cert as DER\n", + __FILE__, __LINE__); goto err; @@ -401,7 +572,12 @@ int ldap_store_cert(scep_t *scep) { "and attributes\n", __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: cannot update directory with cert " + "and attributes\n", __FILE__, __LINE__); goto err; } - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: certificate and attributes for " - "%s successfully added\n", __FILE__, __LINE__, dn); + "%s successfully modified\n", __FILE__, __LINE__, dn); + syslog(LOG_DEBUG, "%s:%d: certificate and attributes for " + "%s successfully modified\n", __FILE__, __LINE__, dn); + } @@ -439,2 +615,4 @@ static int ldap_get_cert_common(scep_t * __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: cannot find certificate\n", + __FILE__, __LINE__); goto err; @@ -446,2 +624,4 @@ static int ldap_get_cert_common(scep_t * __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: wrong number of entries returned\n", + __FILE__, __LINE__); goto err; @@ -451,5 +631,8 @@ static int ldap_get_cert_common(scep_t * e = ldap_first_entry(scep->l.ldap, result); - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: retrieving certificate from %s\n", __FILE__, __LINE__, ldap_get_dn(scep->l.ldap, e)); + syslog(LOG_DEBUG, "%s:%d: retrieving certificate from %s\n", + __FILE__, __LINE__, ldap_get_dn(scep->l.ldap, e)); + } @@ -461,2 +644,4 @@ static int ldap_get_cert_common(scep_t * __LINE__); + syslog(LOG_ERR, "%s:%d: attribute not found\n", __FILE__, + __LINE__); goto err; @@ -472,2 +657,4 @@ static int ldap_get_cert_common(scep_t * "retrieved from LDAP directory\n", __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: cannot decode certificate " + "retrieved from LDAP directory\n", __FILE__, __LINE__); goto err; @@ -503,5 +690,8 @@ int ldap_get_cert_from_issuer_and_serial issuerDN, serial); - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: search filter: %s\n", __FILE__, __LINE__, filter); + syslog(LOG_DEBUG, "%s:%d: search filter: %s\n", + __FILE__, __LINE__, filter); + } @@ -512,2 +702,4 @@ int ldap_get_cert_from_issuer_and_serial "failed\n", __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: certificate retrieval common part " + "failed\n", __FILE__, __LINE__); goto err; @@ -542,5 +734,8 @@ int ldap_get_cert_from_issuer_and_subjec issuerDN, subjectDN); - if (debug) + if (debug) { BIO_printf(bio_err, "%s:%d: searching for certificate with " "filter '%s'\n", __FILE__, __LINE__, filter); + syslog(LOG_DEBUG, "%s:%d: searching for certificate with " + "filter '%s'\n", __FILE__, __LINE__, filter); + } @@ -550,2 +745,4 @@ int ldap_get_cert_from_issuer_and_subjec BIO_printf(bio_err, "%s:%d: cannot get cert common\n", + __FILE__, __LINE__); + syslog(LOG_ERR, "%s:%d: cannot get cert common\n", __FILE__, __LINE__);