From 7f4c7ebc1c62cef0d430e56be4e8269a727eb8cd Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Mon, 3 Jan 2011 21:49:26 +0000 Subject: [PATCH] Extend Verify Credentials encode/decode per -devel post. (ldapvc doesn't yet request/handle inner password policy control. --- clients/tools/ldapvc.c | 28 ++++++--- include/ldap.h | 16 ++++- libraries/libldap/vc.c | 132 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 152 insertions(+), 24 deletions(-) diff --git a/clients/tools/ldapvc.c b/clients/tools/ldapvc.c index 8f14298459..c801cd1759 100644 --- a/clients/tools/ldapvc.c +++ b/clients/tools/ldapvc.c @@ -121,6 +121,8 @@ main( int argc, char *argv[] ) int rc; LDAP *ld = NULL; char *matcheddn = NULL, *text = NULL, **refs = NULL; + int rcode; + char * diag = NULL; struct berval *scookie = NULL; struct berval *scred = NULL; struct berval *authzid = NULL; @@ -177,7 +179,7 @@ main( int argc, char *argv[] ) rc = ldap_verify_credentials( ld, NULL, - dn, mech, cred.bv_val ? &cred: NULL, + dn, mech, cred.bv_val ? &cred: NULL, NULL, NULL, NULL, &id ); if( rc != LDAP_SUCCESS ) { @@ -220,7 +222,7 @@ main( int argc, char *argv[] ) goto skip; } - rc = ldap_parse_verify_credentials( ld, res, &scookie, &scred, &authzid ); + rc = ldap_parse_verify_credentials( ld, res, &rcode, &diag, &scookie, &scred, &authzid, NULL ); ldap_msgfree(res); if( rc != LDAP_SUCCESS ) { @@ -229,14 +231,24 @@ main( int argc, char *argv[] ) goto skip; } - if( authzid != NULL ) { - if( authzid->bv_len == 0 ) { - printf(_("anonymous\n") ); - } else { - printf("%s\n", authzid->bv_val ); - } + if (!rcode) { + printf(_("Failed: %s (%d)\n"), ldap_err2string(rcode), rcode); + } else { + if( authzid != NULL ) { + if( authzid->bv_len == 0 ) { + printf(_("anonymous\n") ); + } else { + printf("%s\n", authzid->bv_val ); + } + } } + if (diag && *diag) { + printf(_("Diagnostic: %s\n"), diag); + } + + /* print vc controls here (once added) */ + skip: if ( verbose || ( code != LDAP_SUCCESS ) || matcheddn || text || refs || ctrls ) diff --git a/include/ldap.h b/include/ldap.h index 4970d6e63e..458174c6bd 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -391,6 +391,7 @@ typedef struct ldapcontrol { #define LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE ((ber_tag_t) 0x80U) #define LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS ((ber_tag_t) 0x81U) #define LDAP_TAG_EXOP_VERIFY_CREDENTIALS_AUTHZID ((ber_tag_t) 0x82U) +#define LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS ((ber_tag_t) 0xa3U) /* context specific + constructed + 3 */ #define LDAP_EXOP_WHO_AM_I "1.3.6.1.4.1.4203.1.11.3" /* RFC 4532 */ #define LDAP_EXOP_X_WHO_AM_I LDAP_EXOP_WHO_AM_I @@ -1362,7 +1363,7 @@ ldap_parse_result LDAP_P(( LDAPMessage *res, int *errcodep, char **matcheddnp, - char **errmsgp, + char **diagmsgp, char ***referralsp, LDAPControl ***serverctrls, int freeit )); @@ -2233,6 +2234,7 @@ ldap_verify_credentials LDAP_P(( LDAP_CONST char *dn, LDAP_CONST char *mechanism, struct berval *cred, + LDAPControl **ctrls, LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )); @@ -2244,19 +2246,27 @@ ldap_verify_credentials_s LDAP_P(( LDAP_CONST char *dn, LDAP_CONST char *mechanism, struct berval *cred, + LDAPControl **vcictrls, LDAPControl **serverctrls, LDAPControl **clientctrls, + int *code, + char **diagmsgp, struct berval **scookie, struct berval **servercredp, - struct berval **authzid )); + struct berval **authzid, + LDAPControl ***vcoctrls)); + LDAP_F( int ) ldap_parse_verify_credentials LDAP_P(( LDAP *ld, LDAPMessage *res, + int *code, + char **diagmsgp, struct berval **cookie, struct berval **servercredp, - struct berval **authzid)); + struct berval **authzid, + LDAPControl ***vcctrls)); /* * LDAP Who Am I? diff --git a/libraries/libldap/vc.c b/libraries/libldap/vc.c index 1ebd2ed417..1e13aa1185 100644 --- a/libraries/libldap/vc.c +++ b/libraries/libldap/vc.c @@ -33,29 +33,38 @@ * the BER encoding of: * * VCRequest ::= SEQUENCE { - * Cookie [0] OCTET STRING OPTIONAL, + * cookie [0] OCTET STRING OPTIONAL, * name LDAPDN, * authentication AuthenticationChoice + * controls [3] Controls OPTIONAL * } * - * where LDAPDN and AuthenticationChoice are as defined in RFC 4511. + * where LDAPDN, AuthenticationChoice, and Controls are as defined in RFC 4511. * * The response is an extended response with no OID and a value of the BER encoding of * * VCResponse ::= SEQUENCE { - * Cookie [0] OCTET STRING OPTIONAL, + * resultCode ResultCode, + * diagnosticMessage LDAPString, + * cookie [0] OCTET STRING OPTIONAL, * serverSaslCreds [1] OCTET STRING OPTIONAL * authzid [2] OCTET STRING OPTIONAL + * controls [3] Controls OPTIONAL * } * + * where ResultCode is the result code enumeration from RFC 4511, and LDAPString and Controls are as + * defined in RFC 4511. */ int ldap_parse_verify_credentials( LDAP *ld, LDAPMessage *res, + int * code, + char ** diagmsg, struct berval **cookie, struct berval **screds, - struct berval **authzid) + struct berval **authzid, + LDAPControl ***ctrls) { int rc; char *retoid = NULL; @@ -78,13 +87,15 @@ int ldap_parse_verify_credentials( if (retdata) { ber_tag_t tag; ber_len_t len; + ber_int_t i; BerElement * ber = ber_init(retdata); if (!ber) { rc = ld->ld_errno = LDAP_NO_MEMORY; goto done; } - ber_scanf(ber, "{" /*"}"*/); + ber_scanf(ber, "{is" /*"}"*/, &i, diagmsg); + *code = i; tag = ber_peek_tag(ber, &len); if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE) { @@ -101,6 +112,71 @@ int ldap_parse_verify_credentials( ber_scanf(ber, "O", authzid); } + if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS) { + int nctrls = 0; + char * opaque; + + *ctrls = LDAP_MALLOC(1 * sizeof(LDAPControl *)); + + if (*ctrls) { + rc = LDAP_NO_MEMORY; + goto done; + } + + *ctrls[nctrls] = NULL; + + for(tag = ber_first_element(ber, &len, &opaque); + tag != LBER_ERROR; + tag = ber_next_element(ber, &len, opaque)) + { + LDAPControl *tctrl; + LDAPControl **tctrls; + + tctrl = LDAP_CALLOC(1, sizeof(LDAPControl)); + + /* allocate pointer space for current controls (nctrls) + * + this control + extra NULL + */ + tctrls = !tctrl ? NULL : LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *)); + + if (!tctrls) { + /* allocation failure */ + if (tctrl) LDAP_FREE(tctrl); + ldap_controls_free(*ctrls); + *ctrls = NULL; + rc = LDAP_NO_MEMORY; + goto done; + } + + tctrls[nctrls++] = tctrl; + tctrls[nctrls] = NULL; + + tag = ber_scanf(ber, "{a" /*"}"*/, &tctrl->ldctl_oid); + if (tag == LBER_ERROR) { + *ctrls = NULL; + ldap_controls_free(tctrls); + rc = LDAP_DECODING_ERROR; + goto done; + } + + tag = ber_peek_tag(ber, &len); + if (tag == LBER_BOOLEAN) { + ber_int_t crit; + tag = ber_scanf(ber, "b", &crit); + tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0; + tag = ber_peek_tag(ber, &len); + } + + if (tag == LBER_OCTETSTRING) { + tag = ber_scanf( ber, "o", &tctrl->ldctl_value ); + } else { + BER_BVZERO( &tctrl->ldctl_value ); + } + + *ctrls = tctrls; + } + } + ber_free(ber, 1); } @@ -116,6 +192,7 @@ ldap_verify_credentials(LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *mechanism, struct berval *cred, + LDAPControl **vcctrls, LDAPControl **sctrls, LDAPControl **cctrls, int *msgidp) @@ -134,36 +211,61 @@ ldap_verify_credentials(LDAP *ld, if (mechanism == LDAP_SASL_SIMPLE) { assert(!cookie); - rc = ber_printf(ber, "{stON}", + rc = ber_printf(ber, "{stO" /*"}"*/, dn, LDAP_AUTH_SIMPLE, cred); } else { if (!cred || BER_BVISNULL(cred)) { if (cookie) { - rc = ber_printf(ber, "{tOst{sN}N}", + rc = ber_printf(ber, "{tOst{sN}" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie, dn, LDAP_AUTH_SASL, mechanism); } else { - rc = ber_printf(ber, "{st{sN}N}", + rc = ber_printf(ber, "{st{sN}N" /*"}"*/, dn, LDAP_AUTH_SASL, mechanism); } } else { if (cookie) { - rc = ber_printf(ber, "{tOst{sON}N}", + rc = ber_printf(ber, "{tOst{sON}" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie, dn, LDAP_AUTH_SASL, mechanism, cred); } else { - rc = ber_printf(ber, "{st{sON}N}", + rc = ber_printf(ber, "{st{sON}" /*"}"*/, dn, LDAP_AUTH_SASL, mechanism, cred); } } } + if (rc) goto done; + + if (!rc && vcctrls && *vcctrls) { + LDAPControl *const *c; + + rc = ber_printf(ber, "t{" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS); + + for (c=vcctrls; *c; c++) { + rc = ldap_pvt_put_control(*c, ber); + if (rc != LDAP_SUCCESS) { + rc = -1; + goto done; + } + } + + rc = ber_printf(ber, /*"{{"*/ "}N}"); + + } else { + rc = ber_printf(ber, /*"{"*/ "N}"); + } + + if (rc) goto done; + + ber_flatten(ber, &reqdata); rc = ldap_extended_operation(ld, LDAP_EXOP_VERIFY_CREDENTIALS, reqdata, sctrls, cctrls, msgidp); +done: ber_free(ber, 1); return rc; } @@ -175,24 +277,28 @@ ldap_verify_credentials_s( LDAP_CONST char *dn, LDAP_CONST char *mechanism, struct berval *cred, + LDAPControl **vcictrls, LDAPControl **sctrls, LDAPControl **cctrls, + int *rcode, + char **diagmsg, struct berval **scookie, struct berval **scred, - struct berval **authzid) + struct berval **authzid, + LDAPControl ***vcoctrls) { int rc; int msgid; LDAPMessage *res; - rc = ldap_verify_credentials(ld, cookie, dn, mechanism, cred, sctrls, cctrls, &msgid); + rc = ldap_verify_credentials(ld, cookie, dn, mechanism, cred, vcictrls, sctrls, cctrls, &msgid); if (rc != LDAP_SUCCESS) return rc; if (ldap_result(ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res) == -1 || !res) { return ld->ld_errno; } - rc = ldap_parse_verify_credentials(ld, res, scookie, scred, authzid); + rc = ldap_parse_verify_credentials(ld, res, rcode, diagmsg, scookie, scred, authzid, vcoctrls); if (rc != LDAP_SUCCESS) { ldap_msgfree(res); return rc; -- 2.39.5