]> git.sur5r.net Git - openldap/blob - clients/ud/auth.c
Some minor bugs for dntest ""
[openldap] / clients / ud / auth.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright (c) 1991, 1992 Regents of the University of Michigan.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms are permitted
11  * provided that this notice is preserved and that due credit is given
12  * to the University of Michigan at Ann Arbor. The name of the University
13  * may not be used to endorse or promote products derived from this
14  * software without specific prior written permission. This software
15  * is provided ``as is'' without express or implied warranty.
16  */
17
18 #include "portable.h"
19
20 #include <stdio.h>
21
22 #include <ac/stdlib.h>
23
24 #include <ac/ctype.h>
25 #include <ac/krb.h>
26 #include <ac/string.h>
27 #include <ac/time.h>
28 #include <ac/unistd.h>
29
30 #ifdef HAVE_PWD_H
31 #include <pwd.h>
32 #endif
33
34 #include <ldap.h>
35
36 #include "ldap_defaults.h"
37 #include "ud.h"
38
39 static void set_bound_dn(char *s);
40
41
42 int
43 auth( char *who, int implicit )
44 {
45         int rc;                 /* return code from ldap_bind() */
46         char *passwd = NULL;    /* returned by getpassphrase() */
47         char **rdns;            /* for fiddling with the DN */
48         int authmethod;
49         int name_provided;      /* was a name passed in? */
50 #ifdef HAVE_GETPWUID
51         struct passwd *pw;      /* for getting user id */
52 #else
53         char *user;
54 #endif
55         char uidname[20];
56         LDAPMessage *mp;        /* returned from find() */
57         static char prompt[MED_BUF_SIZE];       /* place for us to sprintf the prompt */
58         static char name[MED_BUF_SIZE]; /* place to store the user's name */
59         static char password[MED_BUF_SIZE];     /* password entered by user */
60
61 #ifdef DEBUG
62         if (debug & D_TRACE)
63                 fprintf(stderr, "auth(%s, NULL)\n", who);
64 #endif
65         name_provided = ( who != NULL );
66
67         /*
68          *  The user needs to bind.  If <who> is not specified, we
69          *  assume that authenticating as user id is what user wants.
70          */
71         if (who == NULL && implicit) {
72                 uidname[0] = '\0';
73
74 #ifdef HAVE_GETPWUID
75                 if ((pw = getpwuid((uid_t)geteuid())) != (struct passwd *) NULL) {
76                         sprintf(uidname, "uid=%s", pw->pw_name);
77                 }
78 #else
79                 user = getenv("USER");
80                 if(user == NULL) user = getenv("USERNAME");
81                 if(user == NULL) user = getenv("LOGNAME");
82
83                 if(user != NULL) {
84                         sprintf(uidname, "uid=%s", user);
85                 }
86 #endif
87
88                 if(uidname[0] != '\0') {
89                         who = uidname;
90                 }
91         }
92
93         if ( who == NULL ) {
94                 if ( implicit )
95                         printf( "You must first authenticate yourself to the Directory.\n" );
96 #ifdef UOFM
97                 printf("  What is your name or uniqname? ");
98 #else
99                 printf("  What is your name or user id? ");
100 #endif
101                 fflush(stdout);
102                 fetch_buffer(name, sizeof(name), stdin);
103                 if (name[0] == '\0')
104                         return( -1 );
105                 who = name;
106         }
107
108 #ifdef DEBUG
109         if (debug & D_AUTHENTICAT)
110                 printf("  Authenticating as \"%s\"\n", who);
111 #endif
112
113         /*
114          *  Bail out if the name is bogus.  If not, strip off the junk
115          *  at the start of the DN, build a prompt, and get a password 
116          *  from the user.  Then perform the ldap_bind().
117          */
118         if ((mp = find(who, TRUE)) == NULL) {
119                 printf("  I could not find \"%s\" in the Directory.\n", who);
120                 printf("  I used a search base of ");
121                 printbase("", search_base);
122                 printf("\n");
123 #ifdef DEBUG
124                 if (debug & D_AUTHENTICAT)
125                         printf("  Could not find \"%s\"\n", who);
126 #endif
127                 return(-1);
128         }
129
130         /*
131          *  Fill in the Entry structure.  May be handy later.
132          */
133         (void) parse_answer(mp);
134
135         rdns = ldap_explode_dn(Entry.DN, TRUE);
136         printf("  Authenticating to the directory as \"%s\"...\n", *rdns );
137
138 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
139         /*
140          * First, if the user has a choice of auth methods, ask which
141          * one they want to use.  if they want kerberos, ask which
142          * krbname they want to bind as.
143          */
144
145         if ( (krbnames = ldap_get_values( ld, mp, "krbName" )) != NULL ) {
146                 authmethod = LDAP_AUTH_KRBV4;
147                 (void) ldap_value_free(krbnames);
148         } else {
149                 authmethod = LDAP_AUTH_SIMPLE;
150         }
151         (void) ldap_msgfree(mp);
152
153         /*
154          * if they are already kinited, we don't need to ask for a 
155          * password.
156          */
157
158         if ( authmethod != LDAP_AUTH_KRBV4 )
159 #endif
160         {
161                 authmethod = LDAP_AUTH_SIMPLE;
162                 sprintf(prompt, "  Enter your LDAP password: ");
163                 do {
164                         passwd = getpassphrase(prompt);
165                 } while (passwd != NULL && *passwd == '\0');
166                 if (passwd == NULL) {
167                         (void) ldap_value_free(rdns);
168                         return(0);
169                 }
170         }
171
172         ldap_flush_cache( ld );
173         rc = ldap_bind_s(ld, Entry.DN, passwd, authmethod);
174         if (rc != LDAP_SUCCESS) {
175                 int ld_errno;
176                 ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
177                 if (ld_errno == LDAP_NO_SUCH_ATTRIBUTE)
178                         fprintf(stderr, "  Entry has no password\n");
179                 else if (ld_errno == LDAP_INVALID_CREDENTIALS)
180 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
181                         if ( authmethod == LDAP_AUTH_KRBV4 ) {
182                                 fprintf(stderr, "  The Kerberos credentials are invalid.\n");
183                         } else
184 #endif
185                         {
186                                 fprintf(stderr, "  The password you provided is incorrect.\n");
187                         }
188                 else
189                         ldap_perror(ld, "ldap_bind_s" );
190                 (void) ldap_bind_s(ld, default_bind_object,
191                          (char *) NULL, LDAP_AUTH_SIMPLE);
192                 if (default_bind_object == NULL)
193                         set_bound_dn(NULL);
194                 else
195                         set_bound_dn(default_bind_object);
196                 bind_status = UD_NOT_BOUND;
197                 if (verbose)
198                         printf("  Authentication failed.\n\n");
199                 (void) ldap_value_free(rdns);
200                 return(-1);
201         }
202         else if (verbose)
203                 printf("  Authentication successful.\n\n");
204         else
205                 printf("\n");
206         set_bound_dn(Entry.DN);
207         bind_status = UD_BOUND;
208         if (passwd != NULL)
209                 (void) strcpy(password, passwd);
210         (void) ldap_value_free(rdns);
211         return(0);
212 }
213
214 static void
215 set_bound_dn( char *s )
216 {
217         if (bound_dn != NULL)
218                 Free(bound_dn);
219         bound_dn = (s == NULL) ? NULL : strdup(s);
220 }