2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* This file provides the easiest, turn-key interface to the authication
14 #include "../afs/param.h"
16 #include <afs/param.h>
18 #include <afsconfig.h>
23 #include "../afs/sysincludes.h"
24 #include "../afs/afsincludes.h"
25 #include "../afs/stds.h"
26 #include "../afs/com_err.h"
27 #include "../afs/cellconfig.h"
28 #include "../afs/auth.h"
29 #include "../afsint/ptint.h"
30 #include "../afs/pterror.h"
31 #include "../afs/ptserver.h"
33 #include "../rx/rx_globals.h"
34 #include "../rx/rxkad.h"
35 #include "../afsint/kauth.h"
36 #include "../afs/kautils.h"
37 #include "../afs/afsutil.h"
38 #else /* defined(UKERNEL) */
41 #include <afs/com_err.h>
45 #include <netinet/in.h>
47 #include <afs/cellconfig.h>
49 #include <afs/ptint.h>
50 #include <afs/pterror.h>
51 #include <afs/ptserver.h>
52 #include <afs/afsutil.h>
54 #include <rx/rx_globals.h>
55 #include <rx/rxkad.h> /* max ticket lifetime */
58 #endif /* defined(UKERNEL) */
61 afs_int32 GetTickets (
65 struct ktc_encryptionKey *key,
71 struct ktc_token token;
73 code = ka_GetAuthToken (name, instance, realm, key, lifetime, pwexpires);
74 bzero (key, sizeof(*key));
75 if (code) return code;
76 code = ka_GetAFSTicket (name, instance, realm, lifetime, flags);
81 * Requires that you already possess a TGT.
83 afs_int32 ka_GetAFSTicket (
91 struct ktc_token token;
92 struct ktc_principal server, client;
94 code = ka_GetServerToken ("afs", "", realm, lifetime, &token, /*new*/1,
96 if (code) return code;
97 if (ktc_OldPioctl()) {
99 char username[MAXKTCNAMELEN];
102 char *whoami = "UserAuthenticate: ptserver";
104 strcpy (server.name, "afs");
105 strcpy (server.instance, "");
106 code = ka_ExpandCell (realm, server.cell, &local);
107 if (code) return code;
108 code = pr_Initialize (0, AFSDIR_CLIENT_ETC_DIRPATH, server.cell);
110 com_err (whoami, code, "initializing ptserver in cell '%s'", server.cell);
114 if (instance[0]) len += strlen(instance)+1;
115 if (len >= sizeof(username)) {
116 fprintf (stderr, "user's name '%s'.'%s' would be too large\n",
120 strcpy (username, name);
122 strcat (username, ".");
123 strcat (username, instance);
125 code = pr_SNameToId (username, &viceId);
126 /* Before going further, shutdown the pr ubik connection */
128 if ((code == 0) && (viceId == ANONYMOUSID)) code = PRNOENT;
130 com_err (whoami, code, "translating %s to id", username);
134 sprintf (client.name, "AFS ID %d", viceId);
135 strcpy (client.instance, "");
136 strcpy (client.cell, server.cell);
137 code = ktc_SetToken (&server, &token, &client, /*dosetpag*/0);
138 if (code) return code;
143 #ifdef ka_UserAuthenticate
144 #undef ka_UserAuthenticate
147 afs_int32 ka_UserAuthenticateGeneral (
154 afs_int32 *password_expires, /* days 'til, or don't change if not set */
158 int remainingTime = 0;
159 struct ktc_encryptionKey key;
160 afs_int32 code, dosetpag = 0;
163 if (reasonP) *reasonP = "";
164 if ((flags & KA_USERAUTH_VERSION_MASK) != KA_USERAUTH_VERSION)
165 return KAOLDINTERFACE;
166 if ((strcmp(name, "root") == 0) && (instance == 0)) {
167 if (reasonP) *reasonP = "root is only authenticated locally";
171 if (code) return code;
173 ka_StringToKey (password, realm, &key);
176 * alarm is set by klogin and kpasswd only so ignore for
181 { /* Rx uses timers, save to be safe */
183 /* don't reset alarms, rx already running */
185 } else remainingTime = alarm(0);
189 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && !defined(AFS_FBSD_ENV)
190 /* handle smoothly the case where no AFS system calls exists (yet) */
191 old = (int (*)())signal(SIGSYS, SIG_IGN);
193 #ifdef AFS_DECOSF_ENV
194 (void) signal(SIGTRAP, SIG_IGN);
195 #endif /* AFS_DECOSF_ENV */
196 if (instance == 0) instance = "";
197 if (flags & KA_USERAUTH_ONLY_VERIFY) {
198 code = ka_VerifyUserToken(name, instance, realm, &key);
199 if (code == KABADREQUEST) {
200 des_string_to_key(password, &key);
201 code = ka_VerifyUserToken(name, instance, realm, &key);
206 if (flags & KA_USERAUTH_DOSETPAG) afs_setpag();
208 #if !defined(UKERNEL) && !defined(AFS_NT40_ENV)
209 if (flags & KA_USERAUTH_DOSETPAG) setpag();
212 if (flags & KA_USERAUTH_DOSETPAG2) dosetpag = 1;
213 #ifdef AFS_KERBEROS_ENV
214 if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag) ktc_newpag();
216 if (lifetime == 0) lifetime = MAXKTCTICKETLIFETIME;
217 code = GetTickets (name, instance, realm, &key, lifetime, password_expires, dosetpag);
218 if (code == KABADREQUEST) {
219 des_string_to_key(password, &key);
220 code = GetTickets(name, instance, realm, &key, lifetime, password_expires, dosetpag);
223 /* By the time 3.3 comes out, these "old-style" passwd programs should be
224 * well and truly obsolete. Any passwords set with such a program
225 * OUGHT to have been changed years ago. Having 2 -or- 3
226 * authentication RPCs generated for every klog plays hob with the
227 * "failed login limits" code in the kaserver, and it's hard to
228 * explain to admins just how to set the limit properly. By removing
229 * this function, we can just double it internally in the kaserver, and
230 * not document anything. kpasswd had the TRUNCATEPASSWORD "feature"
231 * disabled on 10/02/90.
234 if ((code == KABADREQUEST) && (strlen (password) > 8)) {
235 /* try with only the first 8 characters incase they set their password
236 * with an old style passwd program. */
238 strncpy (pass8, password, 8);
240 ka_StringToKey (pass8, realm, &key);
241 bzero (pass8, sizeof(pass8));
242 code = GetTickets (name, instance, realm, &key, lifetime,
243 password_expires, dosetpag);
245 fprintf (stderr, "%s %s\n%s %s\n%s\n",
246 "Warning: you have typed a password longer than 8",
247 "characters, but only the",
248 "first 8 characters were actually significant. If",
249 "you change your password",
250 "again this warning message will go away.\n");
253 #endif /* OLDCRUFT */
260 alarm(remainingTime); /* restore timer, if any */
264 if (code && reasonP) switch (code) {
266 *reasonP = "password was incorrect";
269 *reasonP = "Authentication Server was unavailable";
272 *reasonP = (char *)error_message (code);
277 /* For backward compatibility */
278 afs_int32 ka_UserAuthenticate (
286 return ka_UserAuthenticateGeneral
287 (KA_USERAUTH_VERSION + ((doSetPAG) ? KA_USERAUTH_DOSETPAG : 0),
288 name, instance, realm, password, /*lifetime*/0, /*spare1,2*/0,0,
292 #if !defined(UKERNEL)
293 afs_int32 ka_UserReadPassword (
301 if (reasonP) *reasonP = "";
303 if (code) return code;
304 code = read_pw_string (password, plen, prompt, 0);
305 if (code) code = KAREADPW;
306 else if (strlen(password) == 0) code = KANULLPASSWORD;
310 *reasonP = (char *)error_message (code);
314 #endif /* !defined(UKERNEL) */
316 afs_int32 ka_VerifyUserPassword(
327 version &= KA_USERAUTH_VERSION_MASK;
328 return ka_UserAuthenticateGeneral(version | KA_USERAUTH_ONLY_VERIFY,
329 name, instance, realm, password,
330 0, &pwexpires, spare, reasonP);