]> git.sur5r.net Git - openldap/commitdiff
Extend Verify Credentials encode/decode per -devel post.
authorKurt Zeilenga <kurt@openldap.org>
Mon, 3 Jan 2011 21:49:26 +0000 (21:49 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 3 Jan 2011 21:49:26 +0000 (21:49 +0000)
(ldapvc doesn't yet request/handle inner password policy control.

clients/tools/ldapvc.c
include/ldap.h
libraries/libldap/vc.c

index 8f14298459b7dac61fa94a81a2dbb7883148fa4f..c801cd17594b96460291429c2d2477add6b6d1d5 100644 (file)
@@ -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 )
index 4970d6e63ee2eee353bb5c0bf56c22281b941143..458174c6bd923231dc9fff5f87411a1c5250e44c 100644 (file)
@@ -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?
index 1ebd2ed417d0ae4d364b24a09a3e60086f2ca665..1e13aa1185f03e58eef9d1f82418e1cdab7b03ed 100644 (file)
  * 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;