1*549b59edSchristos /* $NetBSD: ldapvc.c,v 1.2 2021/08/14 16:14:49 christos Exp $ */
2e670fd5cSchristos
3e670fd5cSchristos /* ldapvc.c -- a tool for verifying credentials */
4e670fd5cSchristos /* $OpenLDAP$ */
5e670fd5cSchristos /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6e670fd5cSchristos *
7e670fd5cSchristos * Copyright 1998-2021 The OpenLDAP Foundation.
8e670fd5cSchristos * Portions Copyright 2010 Kurt D. Zeilenga.
9e670fd5cSchristos * All rights reserved.
10e670fd5cSchristos *
11e670fd5cSchristos * Redistribution and use in source and binary forms, with or without
12e670fd5cSchristos * modification, are permitted only as authorized by the OpenLDAP
13e670fd5cSchristos * Public License.
14e670fd5cSchristos *
15e670fd5cSchristos * A copy of this license is available in the file LICENSE in the
16e670fd5cSchristos * top-level directory of the distribution or, alternatively, at
17e670fd5cSchristos * <http://www.OpenLDAP.org/license.html>.
18e670fd5cSchristos */
19e670fd5cSchristos /* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
20e670fd5cSchristos * All rights reserved.
21e670fd5cSchristos *
22e670fd5cSchristos * Redistribution and use in source and binary forms are permitted
23e670fd5cSchristos * provided that this notice is preserved and that due credit is given
24e670fd5cSchristos * to the University of Michigan at Ann Arbor. The name of the
25e670fd5cSchristos * University may not be used to endorse or promote products derived
26e670fd5cSchristos * from this software without specific prior written permission. This
27e670fd5cSchristos * software is provided ``as is'' without express or implied warranty.
28e670fd5cSchristos */
29e670fd5cSchristos /* ACKNOWLEDGEMENTS:
30e670fd5cSchristos * This work was originally developed by Kurt D. Zeilenga for inclusion
31e670fd5cSchristos * in OpenLDAP Software based, in part, on other client tools.
32e670fd5cSchristos */
33e670fd5cSchristos
34e670fd5cSchristos #include <sys/cdefs.h>
35*549b59edSchristos __RCSID("$NetBSD: ldapvc.c,v 1.2 2021/08/14 16:14:49 christos Exp $");
36e670fd5cSchristos
37e670fd5cSchristos #include "portable.h"
38e670fd5cSchristos
39e670fd5cSchristos #include <stdio.h>
40e670fd5cSchristos
41e670fd5cSchristos #include <ac/stdlib.h>
42e670fd5cSchristos
43e670fd5cSchristos #include <ac/ctype.h>
44e670fd5cSchristos #include <ac/socket.h>
45e670fd5cSchristos #include <ac/string.h>
46e670fd5cSchristos #include <ac/time.h>
47e670fd5cSchristos #include <ac/unistd.h>
48e670fd5cSchristos
49e670fd5cSchristos #include <ldap.h>
50e670fd5cSchristos #include "lutil.h"
51e670fd5cSchristos #include "lutil_ldap.h"
52e670fd5cSchristos #include "ldap_defaults.h"
53e670fd5cSchristos
54e670fd5cSchristos #include "common.h"
55e670fd5cSchristos
56e670fd5cSchristos static int req_authzid = 0;
57e670fd5cSchristos static int req_pp = 0;
58e670fd5cSchristos
59e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
60e670fd5cSchristos #define LDAP_SASL_NONE (~0U)
61e670fd5cSchristos static unsigned vc_sasl = LDAP_SASL_NONE;
62e670fd5cSchristos static char *vc_sasl_realm = NULL;
63e670fd5cSchristos static char *vc_sasl_authcid = NULL;
64e670fd5cSchristos static char *vc_sasl_authzid = NULL;
65e670fd5cSchristos static char *vc_sasl_mech = NULL;
66e670fd5cSchristos static char *vc_sasl_secprops = NULL;
67e670fd5cSchristos #endif
68e670fd5cSchristos static char * dn = NULL;
69e670fd5cSchristos static struct berval cred = {0, NULL};
70e670fd5cSchristos
71e670fd5cSchristos void
usage(void)72e670fd5cSchristos usage( void )
73e670fd5cSchristos {
74e670fd5cSchristos fprintf( stderr, _("Issue LDAP Verify Credentials operation to verify a user's credentials\n\n"));
75e670fd5cSchristos fprintf( stderr, _("usage: %s [options] [DN [cred]])\n"), prog);
76e670fd5cSchristos fprintf( stderr, _("where:\n"));
77e670fd5cSchristos fprintf( stderr, _(" DN\tDistinguished Name\n"));
78e670fd5cSchristos fprintf( stderr, _(" cred\tCredentials (prompt if not present)\n"));
79e670fd5cSchristos fprintf( stderr, _("options:\n"));
80e670fd5cSchristos fprintf( stderr, _(" -a\tRequest AuthzId\n"));
81e670fd5cSchristos fprintf( stderr, _(" -b\tRequest Password Policy Information\n"));
82e670fd5cSchristos fprintf( stderr, _(" -E sasl=(a[utomatic]|i[nteractive]|q[uiet]>\tSASL mode (defaults to automatic if any other -E option provided, otherwise none))\n"));
83e670fd5cSchristos fprintf( stderr, _(" -E mech=<mech>\tSASL mechanism (default "" e.g. Simple)\n"));
84e670fd5cSchristos fprintf( stderr, _(" -E realm=<realm>\tSASL Realm (defaults to none)\n"));
85e670fd5cSchristos fprintf( stderr, _(" -E authcid=<authcid>\tSASL Authentication Identity (defaults to USER)\n"));
86e670fd5cSchristos fprintf( stderr, _(" -E authzid=<authzid>\tSASL Authorization Identity (defaults to none)\n"));
87e670fd5cSchristos fprintf( stderr, _(" -E secprops=<secprops>\tSASL Security Properties (defaults to none)\n"));
88e670fd5cSchristos tool_common_usage();
89e670fd5cSchristos exit( EXIT_FAILURE );
90e670fd5cSchristos }
91e670fd5cSchristos
92e670fd5cSchristos
93e670fd5cSchristos const char options[] = "abE:"
94e670fd5cSchristos "d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
95e670fd5cSchristos
96e670fd5cSchristos int
handle_private_option(int i)97e670fd5cSchristos handle_private_option( int i )
98e670fd5cSchristos {
99e670fd5cSchristos switch ( i ) {
100e670fd5cSchristos char *control, *cvalue;
101e670fd5cSchristos case 'E': /* vc extension */
102e670fd5cSchristos if( protocol == LDAP_VERSION2 ) {
103e670fd5cSchristos fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
104e670fd5cSchristos prog, protocol );
105e670fd5cSchristos exit( EXIT_FAILURE );
106e670fd5cSchristos }
107e670fd5cSchristos
108e670fd5cSchristos /* should be extended to support comma separated list of
109e670fd5cSchristos * [!]key[=value] parameters, e.g. -E !foo,bar=567
110e670fd5cSchristos */
111e670fd5cSchristos
112e670fd5cSchristos cvalue = NULL;
113e670fd5cSchristos if( optarg[0] == '!' ) {
114e670fd5cSchristos optarg++;
115e670fd5cSchristos }
116e670fd5cSchristos
117e670fd5cSchristos control = optarg;
118e670fd5cSchristos if ( (cvalue = strchr( control, '=' )) != NULL ) {
119e670fd5cSchristos *cvalue++ = '\0';
120e670fd5cSchristos }
121e670fd5cSchristos
122e670fd5cSchristos if (strcasecmp(control, "sasl") == 0) {
123e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
124e670fd5cSchristos if (vc_sasl != LDAP_SASL_NONE) {
125e670fd5cSchristos fprintf(stderr,
126e670fd5cSchristos _("SASL option previously specified\n"));
127e670fd5cSchristos exit(EXIT_FAILURE);
128e670fd5cSchristos }
129e670fd5cSchristos if (cvalue == NULL) {
130e670fd5cSchristos fprintf(stderr,
131e670fd5cSchristos _("missing mode in SASL option\n"));
132e670fd5cSchristos exit(EXIT_FAILURE);
133e670fd5cSchristos }
134e670fd5cSchristos
135e670fd5cSchristos switch (*cvalue) {
136e670fd5cSchristos case 'a':
137e670fd5cSchristos case 'A':
138e670fd5cSchristos vc_sasl = LDAP_SASL_AUTOMATIC;
139e670fd5cSchristos break;
140e670fd5cSchristos case 'i':
141e670fd5cSchristos case 'I':
142e670fd5cSchristos vc_sasl = LDAP_SASL_INTERACTIVE;
143e670fd5cSchristos break;
144e670fd5cSchristos case 'q':
145e670fd5cSchristos case 'Q':
146e670fd5cSchristos vc_sasl = LDAP_SASL_QUIET;
147e670fd5cSchristos break;
148e670fd5cSchristos default:
149e670fd5cSchristos fprintf(stderr,
150e670fd5cSchristos _("unknown mode %s in SASL option\n"), cvalue);
151e670fd5cSchristos exit(EXIT_FAILURE);
152e670fd5cSchristos }
153e670fd5cSchristos #else
154e670fd5cSchristos fprintf(stderr,
155e670fd5cSchristos _("%s: not compiled with SASL support\n"), prog);
156e670fd5cSchristos exit(EXIT_FAILURE);
157e670fd5cSchristos #endif
158e670fd5cSchristos
159e670fd5cSchristos } else if (strcasecmp(control, "mech") == 0) {
160e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
161e670fd5cSchristos if (vc_sasl_mech) {
162e670fd5cSchristos fprintf(stderr,
163e670fd5cSchristos _("SASL mech previously specified\n"));
164e670fd5cSchristos exit(EXIT_FAILURE);
165e670fd5cSchristos }
166e670fd5cSchristos if (cvalue == NULL) {
167e670fd5cSchristos fprintf(stderr,
168e670fd5cSchristos _("missing mech in SASL option\n"));
169e670fd5cSchristos exit(EXIT_FAILURE);
170e670fd5cSchristos }
171e670fd5cSchristos
172e670fd5cSchristos vc_sasl_mech = ber_strdup(cvalue);
173e670fd5cSchristos #else
174e670fd5cSchristos #endif
175e670fd5cSchristos
176e670fd5cSchristos } else if (strcasecmp(control, "realm") == 0) {
177e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
178e670fd5cSchristos if (vc_sasl_realm) {
179e670fd5cSchristos fprintf(stderr,
180e670fd5cSchristos _("SASL realm previously specified\n"));
181e670fd5cSchristos exit(EXIT_FAILURE);
182e670fd5cSchristos }
183e670fd5cSchristos if (cvalue == NULL) {
184e670fd5cSchristos fprintf(stderr,
185e670fd5cSchristos _("missing realm in SASL option\n"));
186e670fd5cSchristos exit(EXIT_FAILURE);
187e670fd5cSchristos }
188e670fd5cSchristos
189e670fd5cSchristos vc_sasl_realm = ber_strdup(cvalue);
190e670fd5cSchristos #else
191e670fd5cSchristos fprintf(stderr,
192e670fd5cSchristos _("%s: not compiled with SASL support\n"), prog);
193e670fd5cSchristos exit(EXIT_FAILURE);
194e670fd5cSchristos #endif
195e670fd5cSchristos
196e670fd5cSchristos } else if (strcasecmp(control, "authcid") == 0) {
197e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
198e670fd5cSchristos if (vc_sasl_authcid) {
199e670fd5cSchristos fprintf(stderr,
200e670fd5cSchristos _("SASL authcid previously specified\n"));
201e670fd5cSchristos exit(EXIT_FAILURE);
202e670fd5cSchristos }
203e670fd5cSchristos if (cvalue == NULL) {
204e670fd5cSchristos fprintf(stderr,
205e670fd5cSchristos _("missing authcid in SASL option\n"));
206e670fd5cSchristos exit(EXIT_FAILURE);
207e670fd5cSchristos }
208e670fd5cSchristos
209e670fd5cSchristos vc_sasl_authcid = ber_strdup(cvalue);
210e670fd5cSchristos #else
211e670fd5cSchristos fprintf(stderr,
212e670fd5cSchristos _("%s: not compiled with SASL support\n"), prog);
213e670fd5cSchristos exit(EXIT_FAILURE);
214e670fd5cSchristos #endif
215e670fd5cSchristos
216e670fd5cSchristos } else if (strcasecmp(control, "authzid") == 0) {
217e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
218e670fd5cSchristos if (vc_sasl_authzid) {
219e670fd5cSchristos fprintf(stderr,
220e670fd5cSchristos _("SASL authzid previously specified\n"));
221e670fd5cSchristos exit(EXIT_FAILURE);
222e670fd5cSchristos }
223e670fd5cSchristos if (cvalue == NULL) {
224e670fd5cSchristos fprintf(stderr,
225e670fd5cSchristos _("missing authzid in SASL option\n"));
226e670fd5cSchristos exit(EXIT_FAILURE);
227e670fd5cSchristos }
228e670fd5cSchristos
229e670fd5cSchristos vc_sasl_authzid = ber_strdup(cvalue);
230e670fd5cSchristos #else
231e670fd5cSchristos fprintf(stderr,
232e670fd5cSchristos _("%s: not compiled with SASL support\n"), prog);
233e670fd5cSchristos exit(EXIT_FAILURE);
234e670fd5cSchristos #endif
235e670fd5cSchristos
236e670fd5cSchristos } else if (strcasecmp(control, "secprops") == 0) {
237e670fd5cSchristos #if defined(LDAP_API_FEATURES_VERIFY_CREDENTIALS_INTERACTIVE) && defined(HAVE_CYRUS_SASL)
238e670fd5cSchristos if (vc_sasl_secprops) {
239e670fd5cSchristos fprintf(stderr,
240e670fd5cSchristos _("SASL secprops previously specified\n"));
241e670fd5cSchristos exit(EXIT_FAILURE);
242e670fd5cSchristos }
243e670fd5cSchristos if (cvalue == NULL) {
244e670fd5cSchristos fprintf(stderr,
245e670fd5cSchristos _("missing secprops in SASL option\n"));
246e670fd5cSchristos exit(EXIT_FAILURE);
247e670fd5cSchristos }
248e670fd5cSchristos
249e670fd5cSchristos vc_sasl_secprops = ber_strdup(cvalue);
250e670fd5cSchristos #else
251e670fd5cSchristos fprintf(stderr,
252e670fd5cSchristos _("%s: not compiled with SASL support\n"), prog);
253e670fd5cSchristos exit(EXIT_FAILURE);
254e670fd5cSchristos #endif
255e670fd5cSchristos
256e670fd5cSchristos } else {
257e670fd5cSchristos fprintf( stderr, _("Invalid Verify Credentials extension name: %s\n"), control );
258e670fd5cSchristos usage();
259e670fd5cSchristos }
260e670fd5cSchristos break;
261e670fd5cSchristos
262e670fd5cSchristos case 'a': /* request authzid */
263e670fd5cSchristos req_authzid++;
264e670fd5cSchristos break;
265e670fd5cSchristos
266e670fd5cSchristos case 'b': /* request authzid */
267e670fd5cSchristos req_pp++;
268e670fd5cSchristos break;
269e670fd5cSchristos
270e670fd5cSchristos default:
271e670fd5cSchristos return 0;
272e670fd5cSchristos }
273e670fd5cSchristos return 1;
274e670fd5cSchristos }
275e670fd5cSchristos
276e670fd5cSchristos
277e670fd5cSchristos int
main(int argc,char * argv[])278e670fd5cSchristos main( int argc, char *argv[] )
279e670fd5cSchristos {
280e670fd5cSchristos int rc;
281e670fd5cSchristos LDAP *ld = NULL;
282e670fd5cSchristos char *matcheddn = NULL, *text = NULL, **refs = NULL;
283e670fd5cSchristos int rcode;
284e670fd5cSchristos char * diag = NULL;
285e670fd5cSchristos struct berval *scookie = NULL;
286e670fd5cSchristos struct berval *scred = NULL;
287e670fd5cSchristos int id, code = 0;
288e670fd5cSchristos LDAPMessage *res;
289e670fd5cSchristos LDAPControl **ctrls = NULL;
290e670fd5cSchristos LDAPControl **vcctrls = NULL;
291e670fd5cSchristos int nvcctrls = 0;
292e670fd5cSchristos
293e670fd5cSchristos tool_init( TOOL_VC );
294e670fd5cSchristos prog = lutil_progname( "ldapvc", argc, argv );
295e670fd5cSchristos
296e670fd5cSchristos /* LDAPv3 only */
297e670fd5cSchristos protocol = LDAP_VERSION3;
298e670fd5cSchristos
299e670fd5cSchristos tool_args( argc, argv );
300e670fd5cSchristos
301e670fd5cSchristos if (argc - optind > 0) {
302e670fd5cSchristos dn = argv[optind++];
303e670fd5cSchristos }
304e670fd5cSchristos if (argc - optind > 0) {
305e670fd5cSchristos cred.bv_val = strdup(argv[optind++]);
306e670fd5cSchristos cred.bv_len = strlen(cred.bv_val);
307e670fd5cSchristos }
308e670fd5cSchristos if (argc - optind > 0) {
309e670fd5cSchristos usage();
310e670fd5cSchristos }
311e670fd5cSchristos if (dn
312e670fd5cSchristos #ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS_INTERACTIVE
313e670fd5cSchristos && !vc_sasl_mech
314e670fd5cSchristos #endif
315e670fd5cSchristos && !cred.bv_val)
316e670fd5cSchristos {
317e670fd5cSchristos cred.bv_val = strdup(getpassphrase(_("User's password: ")));
318e670fd5cSchristos cred.bv_len = strlen(cred.bv_val);
319e670fd5cSchristos }
320e670fd5cSchristos
321e670fd5cSchristos #ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS_INTERACTIVE
322e670fd5cSchristos if (vc_sasl_mech && (vc_sasl == LDAP_SASL_NONE)) {
323e670fd5cSchristos vc_sasl = LDAP_SASL_AUTOMATIC;
324e670fd5cSchristos }
325e670fd5cSchristos #endif
326e670fd5cSchristos
327e670fd5cSchristos ld = tool_conn_setup( 0, 0 );
328e670fd5cSchristos
329e670fd5cSchristos tool_bind( ld );
330e670fd5cSchristos
331e670fd5cSchristos if ( dont ) {
332e670fd5cSchristos rc = LDAP_SUCCESS;
333e670fd5cSchristos goto skip;
334e670fd5cSchristos }
335e670fd5cSchristos
336e670fd5cSchristos tool_server_controls( ld, NULL, 0 );
337e670fd5cSchristos
338e670fd5cSchristos if (req_authzid) {
339e670fd5cSchristos vcctrls = (LDAPControl **) malloc(3*sizeof(LDAPControl *));
340e670fd5cSchristos vcctrls[nvcctrls] = (LDAPControl *) malloc(sizeof(LDAPControl));
341e670fd5cSchristos vcctrls[nvcctrls]->ldctl_oid = ldap_strdup(LDAP_CONTROL_AUTHZID_REQUEST);
342e670fd5cSchristos vcctrls[nvcctrls]->ldctl_iscritical = 0;
343e670fd5cSchristos vcctrls[nvcctrls]->ldctl_value.bv_val = NULL;
344e670fd5cSchristos vcctrls[nvcctrls]->ldctl_value.bv_len = 0;
345e670fd5cSchristos vcctrls[++nvcctrls] = NULL;
346e670fd5cSchristos }
347e670fd5cSchristos
348e670fd5cSchristos if (req_pp) {
349e670fd5cSchristos if (!vcctrls) vcctrls = (LDAPControl **) malloc(3*sizeof(LDAPControl *));
350e670fd5cSchristos vcctrls[nvcctrls] = (LDAPControl *) malloc(sizeof(LDAPControl));
351e670fd5cSchristos vcctrls[nvcctrls]->ldctl_oid = ldap_strdup(LDAP_CONTROL_PASSWORDPOLICYREQUEST);
352e670fd5cSchristos vcctrls[nvcctrls]->ldctl_iscritical = 0;
353e670fd5cSchristos vcctrls[nvcctrls]->ldctl_value.bv_val = NULL;
354e670fd5cSchristos vcctrls[nvcctrls]->ldctl_value.bv_len = 0;
355e670fd5cSchristos vcctrls[++nvcctrls] = NULL;
356e670fd5cSchristos }
357e670fd5cSchristos
358e670fd5cSchristos #ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS_INTERACTIVE
359e670fd5cSchristos #ifdef HAVE_CYRUS_SASL
360e670fd5cSchristos if (vc_sasl_mech) {
361e670fd5cSchristos int msgid;
362e670fd5cSchristos void * defaults;
363e670fd5cSchristos void * context = NULL;
364e670fd5cSchristos const char *rmech = NULL;
365e670fd5cSchristos
366e670fd5cSchristos defaults = lutil_sasl_defaults(ld,
367e670fd5cSchristos vc_sasl_mech,
368e670fd5cSchristos vc_sasl_realm,
369e670fd5cSchristos vc_sasl_authcid,
370e670fd5cSchristos cred.bv_val,
371e670fd5cSchristos sasl_authz_id);
372e670fd5cSchristos
373e670fd5cSchristos do {
374e670fd5cSchristos rc = ldap_verify_credentials_interactive(ld, dn, vc_sasl_mech,
375e670fd5cSchristos vcctrls, NULL, NULL,
376e670fd5cSchristos vc_sasl, lutil_sasl_interact, defaults, context,
377e670fd5cSchristos res, &rmech, &msgid);
378e670fd5cSchristos
379e670fd5cSchristos if (rc != LDAP_SASL_BIND_IN_PROGRESS) break;
380e670fd5cSchristos
381e670fd5cSchristos ldap_msgfree(res);
382e670fd5cSchristos
383e670fd5cSchristos if (ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res) == -1 || !res) {
384e670fd5cSchristos ldap_get_option(ld, LDAP_OPT_RESULT_CODE, (void*) &rc);
385e670fd5cSchristos ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*) &text);
386e670fd5cSchristos tool_perror( "ldap_verify_credentials_interactive", rc, NULL, NULL, text, NULL);
387e670fd5cSchristos ldap_memfree(text);
388e670fd5cSchristos tool_exit(ld, rc);
389e670fd5cSchristos }
390e670fd5cSchristos } while (rc == LDAP_SASL_BIND_IN_PROGRESS);
391e670fd5cSchristos
392e670fd5cSchristos lutil_sasl_freedefs(defaults);
393e670fd5cSchristos
394e670fd5cSchristos if( rc != LDAP_SUCCESS ) {
395e670fd5cSchristos ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*) &text);
396e670fd5cSchristos tool_perror( "ldap_verify_credentials", rc, NULL, NULL, text, NULL );
397e670fd5cSchristos rc = EXIT_FAILURE;
398e670fd5cSchristos goto skip;
399e670fd5cSchristos }
400e670fd5cSchristos
401e670fd5cSchristos } else
402e670fd5cSchristos #endif
403e670fd5cSchristos #endif
404e670fd5cSchristos {
405e670fd5cSchristos rc = ldap_verify_credentials( ld,
406e670fd5cSchristos NULL,
407e670fd5cSchristos dn, NULL, cred.bv_val ? &cred: NULL, vcctrls,
408e670fd5cSchristos NULL, NULL, &id );
409e670fd5cSchristos
410e670fd5cSchristos if( rc != LDAP_SUCCESS ) {
411e670fd5cSchristos ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*) &text);
412e670fd5cSchristos tool_perror( "ldap_verify_credentials", rc, NULL, NULL, text, NULL );
413e670fd5cSchristos rc = EXIT_FAILURE;
414e670fd5cSchristos goto skip;
415e670fd5cSchristos }
416e670fd5cSchristos
417e670fd5cSchristos for ( ; ; ) {
418e670fd5cSchristos struct timeval tv;
419e670fd5cSchristos
420e670fd5cSchristos if ( tool_check_abandon( ld, id ) ) {
421e670fd5cSchristos tool_exit( ld, LDAP_CANCELLED );
422e670fd5cSchristos }
423e670fd5cSchristos
424e670fd5cSchristos tv.tv_sec = 0;
425e670fd5cSchristos tv.tv_usec = 100000;
426e670fd5cSchristos
427e670fd5cSchristos rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
428e670fd5cSchristos if ( rc < 0 ) {
429e670fd5cSchristos tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
430e670fd5cSchristos tool_exit( ld, rc );
431e670fd5cSchristos }
432e670fd5cSchristos
433e670fd5cSchristos if ( rc != 0 ) {
434e670fd5cSchristos break;
435e670fd5cSchristos }
436e670fd5cSchristos }
437e670fd5cSchristos }
438e670fd5cSchristos
439e670fd5cSchristos ldap_controls_free(vcctrls);
440e670fd5cSchristos vcctrls = NULL;
441e670fd5cSchristos
442e670fd5cSchristos rc = ldap_parse_result( ld, res,
443e670fd5cSchristos &code, &matcheddn, &text, &refs, &ctrls, 0 );
444e670fd5cSchristos
445e670fd5cSchristos if (rc == LDAP_SUCCESS) rc = code;
446e670fd5cSchristos
447e670fd5cSchristos if (rc != LDAP_SUCCESS) {
448e670fd5cSchristos tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
449e670fd5cSchristos rc = EXIT_FAILURE;
450e670fd5cSchristos goto skip;
451e670fd5cSchristos }
452e670fd5cSchristos
453e670fd5cSchristos rc = ldap_parse_verify_credentials( ld, res, &rcode, &diag, &scookie, &scred, &vcctrls );
454e670fd5cSchristos ldap_msgfree(res);
455e670fd5cSchristos
456e670fd5cSchristos if (rc != LDAP_SUCCESS) {
457e670fd5cSchristos tool_perror( "ldap_parse_verify_credentials", rc, NULL, NULL, NULL, NULL );
458e670fd5cSchristos rc = EXIT_FAILURE;
459e670fd5cSchristos goto skip;
460e670fd5cSchristos }
461e670fd5cSchristos
462e670fd5cSchristos if (rcode != LDAP_SUCCESS) {
463e670fd5cSchristos printf(_("Failed: %s (%d)\n"), ldap_err2string(rcode), rcode);
464e670fd5cSchristos }
465e670fd5cSchristos
466e670fd5cSchristos if (diag && *diag) {
467e670fd5cSchristos printf(_("Diagnostic: %s\n"), diag);
468e670fd5cSchristos }
469e670fd5cSchristos
470e670fd5cSchristos if (vcctrls) {
471e670fd5cSchristos tool_print_ctrls( ld, vcctrls );
472e670fd5cSchristos }
473e670fd5cSchristos
474e670fd5cSchristos skip:
475e670fd5cSchristos if ( verbose || code != LDAP_SUCCESS ||
476e670fd5cSchristos ( matcheddn && *matcheddn ) || ( text && *text ) || refs || ctrls )
477e670fd5cSchristos {
478e670fd5cSchristos printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
479e670fd5cSchristos
480e670fd5cSchristos if( text && *text ) {
481e670fd5cSchristos printf( _("Additional info: %s\n"), text );
482e670fd5cSchristos }
483e670fd5cSchristos
484e670fd5cSchristos if( matcheddn && *matcheddn ) {
485e670fd5cSchristos printf( _("Matched DN: %s\n"), matcheddn );
486e670fd5cSchristos }
487e670fd5cSchristos
488e670fd5cSchristos if( refs ) {
489e670fd5cSchristos int i;
490e670fd5cSchristos for( i=0; refs[i]; i++ ) {
491e670fd5cSchristos printf(_("Referral: %s\n"), refs[i] );
492e670fd5cSchristos }
493e670fd5cSchristos }
494e670fd5cSchristos
495e670fd5cSchristos if (ctrls) {
496e670fd5cSchristos tool_print_ctrls( ld, ctrls );
497e670fd5cSchristos ldap_controls_free( ctrls );
498e670fd5cSchristos }
499e670fd5cSchristos }
500e670fd5cSchristos
501e670fd5cSchristos ber_memfree( text );
502e670fd5cSchristos ber_memfree( matcheddn );
503e670fd5cSchristos ber_memvfree( (void **) refs );
504e670fd5cSchristos ber_bvfree( scookie );
505e670fd5cSchristos ber_bvfree( scred );
506e670fd5cSchristos ber_memfree( diag );
507e670fd5cSchristos free( cred.bv_val );
508e670fd5cSchristos
509e670fd5cSchristos /* disconnect from server */
510e670fd5cSchristos tool_exit( ld, code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE );
511e670fd5cSchristos }
512