2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2010 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This program was orignally developed by Kurt D. Zeilenga for inclusion in
23 #include <ac/stdlib.h>
24 #include <ac/string.h>
30 * LDAP Verify Credentials operation
32 * The request is an extended request with OID 1.3.6.1.4.1.4203.666.6.5 with value of
33 * the BER encoding of:
35 * VCRequest ::= SEQUENCE {
36 * cookie [0] OCTET STRING OPTIONAL,
38 * authentication AuthenticationChoice
39 * controls [3] Controls OPTIONAL
42 * where LDAPDN, AuthenticationChoice, and Controls are as defined in RFC 4511.
44 * The response is an extended response with no OID and a value of the BER encoding of
46 * VCResponse ::= SEQUENCE {
47 * resultCode ResultCode,
48 * diagnosticMessage LDAPString,
49 * cookie [0] OCTET STRING OPTIONAL,
50 * serverSaslCreds [1] OCTET STRING OPTIONAL
51 * authzid [2] OCTET STRING OPTIONAL
52 * controls [3] Controls OPTIONAL
55 * where ResultCode is the result code enumeration from RFC 4511, and LDAPString and Controls are as
56 * defined in RFC 4511.
59 int ldap_parse_verify_credentials(
64 struct berval **cookie,
65 struct berval **screds,
66 struct berval **authzid,
71 struct berval *retdata = NULL;
74 assert(LDAP_VALID(ld));
76 assert(authzid != NULL);
80 rc = ldap_parse_extended_result(ld, res, &retoid, &retdata, 0);
82 if( rc != LDAP_SUCCESS ) {
83 ldap_perror(ld, "ldap_parse_verify_credentials");
91 BerElement * ber = ber_init(retdata);
93 rc = ld->ld_errno = LDAP_NO_MEMORY;
97 ber_scanf(ber, "{is" /*"}"*/, &i, diagmsg);
100 tag = ber_peek_tag(ber, &len);
101 if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE) {
102 ber_scanf(ber, "O", cookie);
103 tag = ber_peek_tag(ber, &len);
106 if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_SCREDS) {
107 ber_scanf(ber, "O", screds);
108 tag = ber_peek_tag(ber, &len);
111 if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_AUTHZID) {
112 ber_scanf(ber, "O", authzid);
115 if (tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS) {
119 *ctrls = LDAP_MALLOC(1 * sizeof(LDAPControl *));
126 *ctrls[nctrls] = NULL;
128 for(tag = ber_first_element(ber, &len, &opaque);
130 tag = ber_next_element(ber, &len, opaque))
133 LDAPControl **tctrls;
135 tctrl = LDAP_CALLOC(1, sizeof(LDAPControl));
137 /* allocate pointer space for current controls (nctrls)
138 * + this control + extra NULL
140 tctrls = !tctrl ? NULL : LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
143 /* allocation failure */
144 if (tctrl) LDAP_FREE(tctrl);
145 ldap_controls_free(*ctrls);
151 tctrls[nctrls++] = tctrl;
152 tctrls[nctrls] = NULL;
154 tag = ber_scanf(ber, "{a" /*"}"*/, &tctrl->ldctl_oid);
155 if (tag == LBER_ERROR) {
157 ldap_controls_free(tctrls);
158 rc = LDAP_DECODING_ERROR;
162 tag = ber_peek_tag(ber, &len);
163 if (tag == LBER_BOOLEAN) {
165 tag = ber_scanf(ber, "b", &crit);
166 tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
167 tag = ber_peek_tag(ber, &len);
170 if (tag == LBER_OCTETSTRING) {
171 tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
173 BER_BVZERO( &tctrl->ldctl_value );
190 ldap_verify_credentials(LDAP *ld,
191 struct berval *cookie,
193 LDAP_CONST char *mechanism,
195 LDAPControl **vcctrls,
196 LDAPControl **sctrls,
197 LDAPControl **cctrls,
202 struct berval * reqdata;
205 assert(LDAP_VALID(ld));
206 assert(msgidp != NULL);
208 ber = ber_alloc_t(LBER_USE_DER);
209 if (dn == NULL) dn = "";
211 if (mechanism == LDAP_SASL_SIMPLE) {
214 rc = ber_printf(ber, "{stO" /*"}"*/,
215 dn, LDAP_AUTH_SIMPLE, cred);
218 if (!cred || BER_BVISNULL(cred)) {
220 rc = ber_printf(ber, "{tOst{sN}" /*"}"*/,
221 LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie,
222 dn, LDAP_AUTH_SASL, mechanism);
224 rc = ber_printf(ber, "{st{sN}N" /*"}"*/,
225 dn, LDAP_AUTH_SASL, mechanism);
229 rc = ber_printf(ber, "{tOst{sON}" /*"}"*/,
230 LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE, cookie,
231 dn, LDAP_AUTH_SASL, mechanism, cred);
233 rc = ber_printf(ber, "{st{sON}" /*"}"*/,
234 dn, LDAP_AUTH_SASL, mechanism, cred);
241 if (!rc && vcctrls && *vcctrls) {
242 LDAPControl *const *c;
244 rc = ber_printf(ber, "t{" /*"}"*/, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS);
246 for (c=vcctrls; *c; c++) {
247 rc = ldap_pvt_put_control(*c, ber);
248 if (rc != LDAP_SUCCESS) {
254 rc = ber_printf(ber, /*"{{"*/ "}N}");
257 rc = ber_printf(ber, /*"{"*/ "N}");
263 ber_flatten(ber, &reqdata);
265 rc = ldap_extended_operation(ld, LDAP_EXOP_VERIFY_CREDENTIALS,
266 reqdata, sctrls, cctrls, msgidp);
274 ldap_verify_credentials_s(
276 struct berval *cookie,
278 LDAP_CONST char *mechanism,
280 LDAPControl **vcictrls,
281 LDAPControl **sctrls,
282 LDAPControl **cctrls,
285 struct berval **scookie,
286 struct berval **scred,
287 struct berval **authzid,
288 LDAPControl ***vcoctrls)
294 rc = ldap_verify_credentials(ld, cookie, dn, mechanism, cred, vcictrls, sctrls, cctrls, &msgid);
295 if (rc != LDAP_SUCCESS) return rc;
297 if (ldap_result(ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res) == -1 || !res) {
301 rc = ldap_parse_verify_credentials(ld, res, rcode, diagmsg, scookie, scred, authzid, vcoctrls);
302 if (rc != LDAP_SUCCESS) {
307 return( ldap_result2error(ld, res, 1));