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
13 #include <afsconfig.h>
15 #include "afs/param.h"
17 #include <afs/param.h>
22 #include "afs/sysincludes.h"
23 #include "afsincludes.h"
25 #include "afs/com_err.h"
26 #include "afs/cellconfig.h"
28 #include "afs/ptint.h"
29 #include "afs/pterror.h"
30 #include "afs/ptserver.h"
32 #include "rx/rx_globals.h"
34 #include "afs/kauth.h"
35 #include "afs/kautils.h"
36 #include "afs/afsutil.h"
37 #else /* defined(UKERNEL) */
40 #include <afs/com_err.h>
44 #include <netinet/in.h>
48 #include <afs/cellconfig.h>
50 #include <afs/ptint.h>
51 #include <afs/pterror.h>
52 #include <afs/ptuser.h>
53 #include <afs/ptserver.h>
54 #include <afs/afsutil.h>
56 #include <rx/rx_globals.h>
57 #include <rx/rxkad.h> /* max ticket lifetime */
59 #include <des_prototypes.h>
62 #endif /* defined(UKERNEL) */
66 GetTickets(char *name, char *instance, char *realm,
67 struct ktc_encryptionKey * key, Date lifetime,
68 afs_int32 * pwexpires, afs_int32 flags)
72 code = ka_GetAuthToken(name, instance, realm, key, lifetime, pwexpires);
73 memset(key, 0, sizeof(*key));
76 code = ka_GetAFSTicket(name, instance, realm, lifetime, flags);
81 * Requires that you already possess a TGT.
84 ka_GetAFSTicket(char *name, char *instance, char *realm, Date lifetime,
88 struct ktc_token token;
89 struct ktc_principal server, client;
91 code = ka_GetServerToken("afs", "", realm, lifetime, &token, /*new */ 1,
95 if (ktc_OldPioctl()) {
97 char username[MAXKTCNAMELEN];
100 char *whoami = "UserAuthenticate: ptserver";
102 strcpy(server.name, "afs");
103 strcpy(server.instance, "");
104 code = ka_ExpandCell(realm, server.cell, &local);
107 code = pr_Initialize(0, AFSDIR_CLIENT_ETC_DIRPATH, server.cell);
109 afs_com_err(whoami, code, "initializing ptserver in cell '%s'",
115 len += strlen(instance) + 1;
116 if (len >= sizeof(username)) {
117 fprintf(stderr, "user's name '%s'.'%s' would be too large\n",
121 strcpy(username, name);
123 strcat(username, ".");
124 strcat(username, instance);
126 code = pr_SNameToId(username, &viceId);
127 /* Before going further, shutdown the pr ubik connection */
129 if ((code == 0) && (viceId == ANONYMOUSID))
132 afs_com_err(whoami, code, "translating %s to id", username);
136 sprintf(client.name, "AFS ID %d", viceId);
137 strcpy(client.instance, "");
138 strcpy(client.cell, server.cell);
139 code = ktc_SetToken(&server, &token, &client, /*dosetpag */ 0);
146 #ifdef ka_UserAuthenticate
147 #undef ka_UserAuthenticate
151 ka_UserAuthenticateGeneral(afs_int32 flags, char *name, char *instance,
152 char *realm, char *password, Date lifetime,
153 afs_int32 * password_expires, /* days 'til, or don't change if not set */
154 afs_int32 spare2, char **reasonP)
156 int remainingTime = 0;
157 struct ktc_encryptionKey key;
158 afs_int32 code, dosetpag = 0;
159 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && !defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV)
165 if ((flags & KA_USERAUTH_VERSION_MASK) != KA_USERAUTH_VERSION)
166 return KAOLDINTERFACE;
167 if ((strcmp(name, "root") == 0) && (instance == 0)) {
169 *reasonP = "root is only authenticated locally";
176 ka_StringToKey(password, realm, &key);
179 * alarm is set by klogin and kpasswd only so ignore for
184 { /* Rx uses timers, save to be safe */
186 /* don't reset alarms, rx already running */
189 remainingTime = alarm(0);
193 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && (!defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV))
194 /* handle smoothly the case where no AFS system calls exists (yet) */
195 old = signal(SIGSYS, SIG_IGN);
197 #ifdef AFS_DECOSF_ENV
198 (void)signal(SIGTRAP, SIG_IGN);
199 #endif /* AFS_DECOSF_ENV */
202 if (flags & KA_USERAUTH_ONLY_VERIFY) {
203 code = ka_VerifyUserToken(name, instance, realm, &key);
204 if (code == KABADREQUEST) {
205 des_string_to_key(password, &key);
206 code = ka_VerifyUserToken(name, instance, realm, &key);
210 if (flags & KA_USERAUTH_DOSETPAG)
213 #if !defined(UKERNEL) && !defined(AFS_NT40_ENV)
214 if (flags & KA_USERAUTH_DOSETPAG)
218 if (flags & KA_USERAUTH_DOSETPAG2)
220 #ifdef AFS_KERBEROS_ENV
221 if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag)
225 lifetime = MAXKTCTICKETLIFETIME;
227 GetTickets(name, instance, realm, &key, lifetime,
228 password_expires, dosetpag);
229 if (code == KABADREQUEST) {
230 des_string_to_key(password, &key);
232 GetTickets(name, instance, realm, &key, lifetime,
233 password_expires, dosetpag);
236 /* By the time 3.3 comes out, these "old-style" passwd programs should be
237 * well and truly obsolete. Any passwords set with such a program
238 * OUGHT to have been changed years ago. Having 2 -or- 3
239 * authentication RPCs generated for every klog plays hob with the
240 * "failed login limits" code in the kaserver, and it's hard to
241 * explain to admins just how to set the limit properly. By removing
242 * this function, we can just double it internally in the kaserver, and
243 * not document anything. kpasswd had the TRUNCATEPASSWORD "feature"
244 * disabled on 10/02/90.
247 if ((code == KABADREQUEST) && (strlen(password) > 8)) {
248 /* try with only the first 8 characters incase they set their password
249 * with an old style passwd program. */
251 strncpy(pass8, password, 8);
253 ka_StringToKey(pass8, realm, &key);
254 memset(pass8, 0, sizeof(pass8));
256 GetTickets(name, instance, realm, &key, lifetime,
257 password_expires, dosetpag);
259 fprintf(stderr, "%s %s\n%s %s\n%s\n",
260 "Warning: you have typed a password longer than 8",
261 "characters, but only the",
262 "first 8 characters were actually significant. If",
263 "you change your password",
264 "again this warning message will go away.\n");
267 #endif /* OLDCRUFT */
274 alarm(remainingTime); /* restore timer, if any */
281 *reasonP = "password was incorrect";
284 *reasonP = "Authentication Server was unavailable";
287 *reasonP = (char *)afs_error_message(code);
292 /* For backward compatibility */
294 ka_UserAuthenticate(char *name, char *instance, char *realm, char *password,
295 int doSetPAG, char **reasonP)
297 return ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION +
298 ((doSetPAG) ? KA_USERAUTH_DOSETPAG : 0),
299 name, instance, realm, password,
300 /*lifetime */ 0, /*spare1,2 */ 0, 0,
304 #if !defined(UKERNEL)
306 ka_UserReadPassword(char *prompt, char *password, int plen, char **reasonP)
315 code = read_pw_string(password, plen, prompt, 0);
318 else if (strlen(password) == 0)
319 code = KANULLPASSWORD;
324 *reasonP = (char *)afs_error_message(code);
328 #endif /* !defined(UKERNEL) */
331 ka_VerifyUserPassword(afs_int32 version, char *name, char *instance,
332 char *realm, char *password, int spare, char **reasonP)
336 version &= KA_USERAUTH_VERSION_MASK;
337 return ka_UserAuthenticateGeneral(version | KA_USERAUTH_ONLY_VERIFY, name,
338 instance, realm, password, 0,
339 &pwexpires, spare, reasonP);