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"
15 #include "../afs/sysincludes.h"
16 #include "../afs/afsincludes.h"
17 #include "../afs/stds.h"
18 #include "../afs/com_err.h"
19 #include "../afs/cellconfig.h"
20 #include "../afs/auth.h"
21 #include "../afsint/ptint.h"
22 #include "../afs/pterror.h"
23 #include "../afs/ptserver.h"
25 #include "../rx/rx_globals.h"
26 #include "../rx/rxkad.h"
27 #include "../afsint/kauth.h"
28 #include "../afs/kautils.h"
29 #include "../afs/afsutil.h"
30 #else /* defined(UKERNEL) */
31 #include <afs/param.h>
34 #include <afs/com_err.h>
38 #include <netinet/in.h>
40 #include <afs/cellconfig.h>
42 #include <afs/ptint.h>
43 #include <afs/pterror.h>
44 #include <afs/ptserver.h>
45 #include <afs/afsutil.h>
47 #include <rx/rx_globals.h>
48 #include <rx/rxkad.h> /* max ticket lifetime */
51 #endif /* defined(UKERNEL) */
54 static afs_int32 GetTickets (
58 struct ktc_encryptionKey *key,
64 struct ktc_token token;
66 code = ka_GetAuthToken (name, instance, realm, key, lifetime, pwexpires);
67 bzero (key, sizeof(*key));
68 if (code) return code;
69 code = ka_GetAFSTicket (name, instance, realm, lifetime, flags);
74 * Requires that you already possess a TGT.
76 afs_int32 ka_GetAFSTicket (
84 struct ktc_token token;
85 struct ktc_principal server, client;
87 code = ka_GetServerToken ("afs", "", realm, lifetime, &token, /*new*/1,
89 if (code) return code;
90 if (ktc_OldPioctl()) {
92 char username[MAXKTCNAMELEN];
95 char *whoami = "UserAuthenticate: ptserver";
97 strcpy (server.name, "afs");
98 strcpy (server.instance, "");
99 code = ka_ExpandCell (realm, server.cell, &local);
100 if (code) return code;
101 code = pr_Initialize (0, AFSDIR_CLIENT_ETC_DIRPATH, server.cell);
103 com_err (whoami, code, "initializing ptserver in cell '%s'", server.cell);
107 if (instance[0]) len += strlen(instance)+1;
108 if (len >= sizeof(username)) {
109 fprintf (stderr, "user's name '%s'.'%s' would be too large\n",
113 strcpy (username, name);
115 strcat (username, ".");
116 strcat (username, instance);
118 code = pr_SNameToId (username, &viceId);
119 /* Before going further, shutdown the pr ubik connection */
121 if ((code == 0) && (viceId == ANONYMOUSID)) code = PRNOENT;
123 com_err (whoami, code, "translating %s to id", username);
127 sprintf (client.name, "AFS ID %d", viceId);
128 strcpy (client.instance, "");
129 strcpy (client.cell, server.cell);
130 code = ktc_SetToken (&server, &token, &client, /*dosetpag*/0);
131 if (code) return code;
136 #ifdef ka_UserAuthenticate
137 #undef ka_UserAuthenticate
140 afs_int32 ka_UserAuthenticateGeneral (
147 afs_int32 *password_expires, /* days 'til, or don't change if not set */
151 int remainingTime = 0;
152 struct ktc_encryptionKey key;
153 afs_int32 code, dosetpag = 0;
156 if (reasonP) *reasonP = "";
157 if ((flags & KA_USERAUTH_VERSION_MASK) != KA_USERAUTH_VERSION)
158 return KAOLDINTERFACE;
159 if ((strcmp(name, "root") == 0) && (instance == 0)) {
160 if (reasonP) *reasonP = "root is only authenticated locally";
164 if (code) return code;
166 ka_StringToKey (password, realm, &key);
169 * alarm is set by klogin and kpasswd only so ignore for
174 { /* Rx uses timers, save to be safe */
176 /* don't reset alarms, rx already running */
178 } else remainingTime = alarm(0);
182 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV)
183 /* handle smoothly the case where no AFS system calls exists (yet) */
184 old = (int (*)())signal(SIGSYS, SIG_IGN);
186 #ifdef AFS_DECOSF_ENV
187 (void) signal(SIGTRAP, SIG_IGN);
188 #endif /* AFS_DECOSF_ENV */
189 if (instance == 0) instance = "";
190 if (flags & KA_USERAUTH_ONLY_VERIFY) {
191 code = ka_VerifyUserToken(name, instance, realm, &key);
192 if (code == KABADREQUEST) {
193 des_string_to_key(password, &key);
194 code = ka_VerifyUserToken(name, instance, realm, &key);
199 if (flags & KA_USERAUTH_DOSETPAG) afs_setpag();
201 #if !defined(UKERNEL) && !defined(AFS_NT40_ENV)
202 if (flags & KA_USERAUTH_DOSETPAG) setpag();
205 if (flags & KA_USERAUTH_DOSETPAG2) dosetpag = 1;
206 #ifdef AFS_KERBEROS_ENV
207 if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag) ktc_newpag();
209 if (lifetime == 0) lifetime = MAXKTCTICKETLIFETIME;
210 code = GetTickets (name, instance, realm, &key, lifetime, password_expires, dosetpag);
211 if (code == KABADREQUEST) {
212 des_string_to_key(password, &key);
213 code = GetTickets(name, instance, realm, &key, lifetime, password_expires, dosetpag);
216 /* By the time 3.3 comes out, these "old-style" passwd programs should be
217 * well and truly obsolete. Any passwords set with such a program
218 * OUGHT to have been changed years ago. Having 2 -or- 3
219 * authentication RPCs generated for every klog plays hob with the
220 * "failed login limits" code in the kaserver, and it's hard to
221 * explain to admins just how to set the limit properly. By removing
222 * this function, we can just double it internally in the kaserver, and
223 * not document anything. kpasswd had the TRUNCATEPASSWORD "feature"
224 * disabled on 10/02/90.
227 if ((code == KABADREQUEST) && (strlen (password) > 8)) {
228 /* try with only the first 8 characters incase they set their password
229 * with an old style passwd program. */
231 strncpy (pass8, password, 8);
233 ka_StringToKey (pass8, realm, &key);
234 bzero (pass8, sizeof(pass8));
235 code = GetTickets (name, instance, realm, &key, lifetime,
236 password_expires, dosetpag);
238 fprintf (stderr, "%s %s\n%s %s\n%s\n",
239 "Warning: you have typed a password longer than 8",
240 "characters, but only the",
241 "first 8 characters were actually significant. If",
242 "you change your password",
243 "again this warning message will go away.\n");
246 #endif /* OLDCRUFT */
253 alarm(remainingTime); /* restore timer, if any */
257 if (code && reasonP) switch (code) {
259 *reasonP = "password was incorrect";
262 *reasonP = "Authentication Server was unavailable";
265 *reasonP = (char *)error_message (code);
270 /* For backward compatibility */
271 afs_int32 ka_UserAuthenticate (
279 return ka_UserAuthenticateGeneral
280 (KA_USERAUTH_VERSION + ((doSetPAG) ? KA_USERAUTH_DOSETPAG : 0),
281 name, instance, realm, password, /*lifetime*/0, /*spare1,2*/0,0,
285 #if !defined(UKERNEL)
286 afs_int32 ka_UserReadPassword (
294 if (reasonP) *reasonP = "";
296 if (code) return code;
297 code = read_pw_string (password, plen, prompt, 0);
298 if (code) code = KAREADPW;
299 else if (strlen(password) == 0) code = KANULLPASSWORD;
303 *reasonP = (char *)error_message (code);
307 #endif /* !defined(UKERNEL) */
309 afs_int32 ka_VerifyUserPassword(
320 version &= KA_USERAUTH_VERSION_MASK;
321 return ka_UserAuthenticateGeneral(version | KA_USERAUTH_ONLY_VERIFY,
322 name, instance, realm, password,
323 0, &pwexpires, spare, reasonP);