]> git.sur5r.net Git - openldap/blob - clients/tools/ldapvc.c
0094acf221cf2dc21a579394e0f4140d4fc9f0fa
[openldap] / clients / tools / ldapvc.c
1 /* ldapvc.c -- a tool for verifying credentials */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2011 The OpenLDAP Foundation.
6  * Portions Copyright 2010 Kurt D. Zeilenga.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms are permitted
21  * provided that this notice is preserved and that due credit is given
22  * to the University of Michigan at Ann Arbor.  The name of the
23  * University may not be used to endorse or promote products derived
24  * from this software without specific prior written permission.  This
25  * software is provided ``as is'' without express or implied warranty.
26  */
27 /* ACKNOWLEDGEMENTS:
28  * This work was originally developed by Kurt D. Zeilenga for inclusion
29  * in OpenLDAP Software based, in part, on other client tools.
30  */
31
32 #include "portable.h"
33
34 #include <stdio.h>
35
36 #include <ac/stdlib.h>
37
38 #include <ac/ctype.h>
39 #include <ac/socket.h>
40 #include <ac/string.h>
41 #include <ac/time.h>
42 #include <ac/unistd.h>
43
44 #include <ldap.h>
45 #include "lutil.h"
46 #include "lutil_ldap.h"
47 #include "ldap_defaults.h"
48
49 #include "common.h"
50
51 static int req_authzid = 0;
52 static int req_pp = 0;
53
54 static char * mech = NULL;
55 static char * dn = NULL;
56 static struct berval cred = {0, NULL};
57
58 void
59 usage( void )
60 {
61         fprintf( stderr, _("Issue LDAP Verify Credentials operation to verify a user's credentials\n\n"));
62         fprintf( stderr, _("usage: %s [options] (-S mech|[DN [cred]])\n"), prog);
63         fprintf( stderr, _("where:\n"));
64         fprintf( stderr, _("    DN\tDistinguished Name\n"));
65         fprintf( stderr, _("    cred\tCredentials (prompt if not present)\n"));
66         fprintf( stderr, _("options:\n"));
67         fprintf( stderr, _("    -a\tRequest AuthzId\n"));
68         fprintf( stderr, _("    -b\tRequest Password Policy Information\n"));
69         fprintf( stderr, _("    -S mech\tSASL mechanism (default "" e.g. Simple)\n"));
70         tool_common_usage();
71         exit( EXIT_FAILURE );
72 }
73
74
75 const char options[] = "abS:"
76         "d:D:e:h:H:InNO:o:p:QR:U:vVw:WxX:y:Y:Z";
77
78 int
79 handle_private_option( int i )
80 {
81         switch ( i ) {
82 #if 0
83                 char    *control, *cvalue;
84                 int             crit;
85         case 'E': /* vc extension */
86                 if( protocol == LDAP_VERSION2 ) {
87                         fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
88                                 prog, protocol );
89                         exit( EXIT_FAILURE );
90                 }
91
92                 /* should be extended to support comma separated list of
93                  *      [!]key[=value] parameters, e.g.  -E !foo,bar=567
94                  */
95
96                 crit = 0;
97                 cvalue = NULL;
98                 if( optarg[0] == '!' ) {
99                         crit = 1;
100                         optarg++;
101                 }
102
103                 control = strdup( optarg );
104                 if ( (cvalue = strchr( control, '=' )) != NULL ) {
105                         *cvalue++ = '\0';
106                 }
107
108                 fprintf( stderr, _("Invalid Verify Credentials extension name: %s\n"), control );
109                 usage();
110 #endif
111
112         case 'a':  /* request authzid */
113                 req_authzid++;
114                 break;
115
116         case 'b':  /* request authzid */
117                 req_pp++;
118                 break;
119
120         case 'S':  /* SASL mechanism */
121                 mech = optarg;
122                 break;
123
124         default:
125                 return 0;
126         }
127         return 1;
128 }
129
130
131 int
132 main( int argc, char *argv[] )
133 {
134         int             rc;
135         LDAP            *ld = NULL;
136         char            *matcheddn = NULL, *text = NULL, **refs = NULL;
137         int rcode;
138         char * diag = NULL;
139         struct berval   *scookie = NULL;
140         struct berval   *scred = NULL;
141         int             id, code = 0;
142         LDAPMessage     *res;
143         LDAPControl     **ctrls = NULL;
144         LDAPControl     **vcctrls = NULL;
145         int nvcctrls = 0;
146
147         tool_init( TOOL_VC );
148         prog = lutil_progname( "ldapvc", argc, argv );
149
150         /* LDAPv3 only */
151         protocol = LDAP_VERSION3;
152
153         tool_args( argc, argv );
154
155         if (mech) {
156                 if (argc - optind > 0) {
157                         usage();
158                 }
159
160                 fprintf(stderr, "SASL credential verification not yet implemented!\n");
161                 rc = EXIT_FAILURE;
162                 goto skip;
163
164         } else {
165                 if (argc - optind > 0) {
166                         dn = argv[optind++];
167                 }
168                 if (argc - optind > 0) {
169                         cred.bv_val = argv[optind++];
170                         cred.bv_len = strlen(cred.bv_val);
171                 }
172
173                 if (argc - optind > 0) {
174                     usage();
175             }
176
177             if (!cred.bv_val) {
178                     cred.bv_val = strdup(getpassphrase(_("User's password: ")));
179             }
180                 cred.bv_len = strlen(cred.bv_val);
181         }
182
183         ld = tool_conn_setup( 0, 0 );
184
185         tool_bind( ld );
186
187         if ( dont ) {
188                 rc = LDAP_SUCCESS;
189                 goto skip;
190         }
191
192         tool_server_controls( ld, NULL, 0 );
193
194     if (req_authzid) {
195                 vcctrls = (LDAPControl **) malloc(3*sizeof(LDAPControl *));
196                 vcctrls[nvcctrls] = (LDAPControl *) malloc(sizeof(LDAPControl));
197                 vcctrls[nvcctrls]->ldctl_oid = ldap_strdup(LDAP_CONTROL_AUTHZID_REQUEST);
198                 vcctrls[nvcctrls]->ldctl_iscritical = 0;
199                 vcctrls[nvcctrls]->ldctl_value.bv_val = NULL;
200                 vcctrls[nvcctrls]->ldctl_value.bv_len = 0;
201                 vcctrls[++nvcctrls] = NULL;
202     }
203
204     if (req_pp) {
205                 if (!vcctrls) vcctrls = (LDAPControl **) malloc(3*sizeof(LDAPControl *));
206                 vcctrls[nvcctrls] = (LDAPControl *) malloc(sizeof(LDAPControl));
207                 vcctrls[nvcctrls]->ldctl_oid = ldap_strdup(LDAP_CONTROL_PASSWORDPOLICYREQUEST);
208                 vcctrls[nvcctrls]->ldctl_iscritical = 0;
209                 vcctrls[nvcctrls]->ldctl_value.bv_val = NULL;
210                 vcctrls[nvcctrls]->ldctl_value.bv_len = 0;
211                 vcctrls[++nvcctrls] = NULL;
212     }
213
214         rc = ldap_verify_credentials( ld,
215                 NULL,
216                 dn, mech, cred.bv_val ? &cred: NULL, vcctrls,
217                 NULL, NULL, &id ); 
218
219         if( rc != LDAP_SUCCESS ) {
220                 tool_perror( "ldap_verify_credentials", rc, NULL, NULL, NULL, NULL );
221                 rc = EXIT_FAILURE;
222                 goto skip;
223         }
224
225         ldap_controls_free(vcctrls);
226         vcctrls = NULL;
227
228         for ( ; ; ) {
229                 struct timeval  tv;
230
231                 if ( tool_check_abandon( ld, id ) ) {
232                         return LDAP_CANCELLED;
233                 }
234
235                 tv.tv_sec = 0;
236                 tv.tv_usec = 100000;
237
238                 rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
239                 if ( rc < 0 ) {
240                         tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
241                         return rc;
242                 }
243
244                 if ( rc != 0 ) {
245                         break;
246                 }
247         }
248
249         rc = ldap_parse_result( ld, res,
250                 &code, &matcheddn, &text, &refs, &ctrls, 0 );
251
252         if ( rc == LDAP_SUCCESS ) {
253                 rc = code;
254         }
255
256         if ( rc != LDAP_SUCCESS ) {
257                 tool_perror( "ldap_parse_result", rc, NULL, matcheddn, text, refs );
258                 rc = EXIT_FAILURE;
259                 goto skip;
260         }
261
262         rc = ldap_parse_verify_credentials( ld, res, &rcode, &diag, &scookie, &scred, &vcctrls );
263         ldap_msgfree(res);
264
265         if( rc != LDAP_SUCCESS ) {
266                 tool_perror( "ldap_parse_verify_credentials", rc, NULL, NULL, NULL, NULL );
267                 rc = EXIT_FAILURE;
268                 goto skip;
269         }
270
271         if (rcode != LDAP_SUCCESS) {
272                 printf(_("Failed: %s (%d)\n"), ldap_err2string(rcode), rcode);
273         }
274
275         if (diag && *diag) {
276             printf(_("Diagnostic: %s\n"), diag);
277         }
278
279         if (vcctrls) {
280                 tool_print_ctrls( ld, vcctrls );
281         }
282
283 skip:
284         if ( verbose || ( code != LDAP_SUCCESS ) ||
285                 matcheddn || text || refs || ctrls )
286         {
287                 printf( _("Result: %s (%d)\n"), ldap_err2string( code ), code );
288
289                 if( text && *text ) {
290                         printf( _("Additional info: %s\n"), text );
291                 }
292
293                 if( matcheddn && *matcheddn ) {
294                         printf( _("Matched DN: %s\n"), matcheddn );
295                 }
296
297                 if( refs ) {
298                         int i;
299                         for( i=0; refs[i]; i++ ) {
300                                 printf(_("Referral: %s\n"), refs[i] );
301                         }
302                 }
303
304                 if (ctrls) {
305                         tool_print_ctrls( ld, ctrls );
306                         ldap_controls_free( ctrls );
307                 }
308         }
309
310         ber_memfree( text );
311         ber_memfree( matcheddn );
312         ber_memvfree( (void **) refs );
313         ber_bvfree( scookie );
314         ber_bvfree( scred );
315         ber_memfree( diag );
316
317         /* disconnect from server */
318         tool_unbind( ld );
319         tool_destroy();
320
321         return code == LDAP_SUCCESS ? EXIT_SUCCESS : EXIT_FAILURE;
322 }