Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / kauth / user.c
blobe9b32e6c86d878a9fba6bac7563c9fbb90409cc5
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
10 /* This file provides the easiest, turn-key interface to the authication
11 * package. */
13 #include <afsconfig.h>
14 #include <afs/param.h>
17 #include <afs/stds.h>
18 #include <signal.h>
19 #include <afs/com_err.h>
20 #ifdef AFS_NT40_ENV
21 #include <winsock2.h>
22 #else
23 #include <netinet/in.h>
24 #include <unistd.h>
25 #endif
26 #include <string.h>
27 #include <stdio.h>
28 #include <afs/cellconfig.h>
29 #include <afs/auth.h>
30 #include <afs/ptint.h>
31 #include <afs/pterror.h>
32 #include <afs/ptuser.h>
33 #include <afs/ptserver.h>
34 #include <afs/afsutil.h>
36 #ifndef UKERNEL
37 #include <afs/sys_prototypes.h>
38 #endif
40 #include <des.h>
41 #include <des_prototypes.h>
42 #include <rx/rx.h>
43 #include <rx/rx_globals.h>
44 #include <rx/rxkad.h> /* max ticket lifetime */
45 #include "kauth.h"
46 #include "kautils.h"
47 #include <afs/ktc.h>
50 afs_int32
51 GetTickets(char *name, char *instance, char *realm,
52 struct ktc_encryptionKey * key, Date lifetime,
53 afs_int32 * pwexpires, afs_int32 flags)
55 afs_int32 code;
57 code = ka_GetAuthToken(name, instance, realm, key, lifetime, pwexpires);
58 memset(key, 0, sizeof(*key));
59 if (code)
60 return code;
61 code = ka_GetAFSTicket(name, instance, realm, lifetime, flags);
62 return code;
66 * Requires that you already possess a TGT.
68 afs_int32
69 ka_GetAFSTicket(char *name, char *instance, char *realm, Date lifetime,
70 afs_int32 flags)
72 afs_int32 code;
73 struct ktc_token token;
74 struct ktc_principal server, client;
76 code = ka_GetServerToken("afs", "", realm, lifetime, &token, /*new */ 1,
77 /*dosetpag */ flags);
78 if (code)
79 return code;
80 if (ktc_OldPioctl()) {
81 int local;
82 char username[MAXKTCNAMELEN];
83 afs_int32 viceId;
84 int len;
85 char *whoami = "UserAuthenticate: ptserver";
87 strcpy(server.name, "afs");
88 strcpy(server.instance, "");
89 code = ka_ExpandCell(realm, server.cell, &local);
90 if (code)
91 return code;
92 code = pr_Initialize(0, AFSDIR_CLIENT_ETC_DIRPATH, server.cell);
93 if (code) {
94 afs_com_err(whoami, code, "initializing ptserver in cell '%s'",
95 server.cell);
96 return 0;
98 len = strlen(name);
99 if (instance[0])
100 len += strlen(instance) + 1;
101 if (len >= sizeof(username)) {
102 fprintf(stderr, "user's name '%s'.'%s' would be too large\n",
103 name, instance);
104 return 0;
106 strcpy(username, name);
107 if (instance[0]) {
108 strcat(username, ".");
109 strcat(username, instance);
111 code = pr_SNameToId(username, &viceId);
112 /* Before going further, shutdown the pr ubik connection */
113 pr_End();
114 if ((code == 0) && (viceId == ANONYMOUSID))
115 code = PRNOENT;
116 if (code) {
117 afs_com_err(whoami, code, "translating %s to id", username);
118 return 0;
121 sprintf(client.name, "AFS ID %d", viceId);
122 strcpy(client.instance, "");
123 strcpy(client.cell, server.cell);
124 code = ktc_SetToken(&server, &token, &client, /*dosetpag */ 0);
125 if (code)
126 return code;
128 return code;
131 #ifdef ka_UserAuthenticate
132 #undef ka_UserAuthenticate
133 #endif
135 afs_int32
136 ka_UserAuthenticateGeneral(afs_int32 flags, char *name, char *instance,
137 char *realm, char *password, Date lifetime,
138 afs_int32 * password_expires, /* days 'til, or don't change if not set */
139 afs_int32 spare2, char **reasonP)
141 int remainingTime = 0;
142 struct ktc_encryptionKey key;
143 afs_int32 code, dosetpag = 0;
144 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && !defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV)
145 void (*old)(int);
146 #endif
148 if (reasonP)
149 *reasonP = "";
150 if ((flags & KA_USERAUTH_VERSION_MASK) != KA_USERAUTH_VERSION)
151 return KAOLDINTERFACE;
152 if ((strcmp(name, "root") == 0) && (instance == 0)) {
153 if (reasonP)
154 *reasonP = "root is only authenticated locally";
155 return KANOENT;
157 code = ka_Init(0);
158 if (code)
159 return code;
161 ka_StringToKey(password, realm, &key);
164 * alarm is set by klogin and kpasswd only so ignore for
165 * NT
168 #ifndef AFS_NT40_ENV
169 { /* Rx uses timers, save to be safe */
170 if (rx_socket) {
171 /* don't reset alarms, rx already running */
172 remainingTime = 0;
173 } else
174 remainingTime = alarm(0);
176 #endif
178 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && (!defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV))
179 /* handle smoothly the case where no AFS system calls exists (yet) */
180 old = signal(SIGSYS, SIG_IGN);
181 #endif
182 #ifdef AFS_DECOSF_ENV
183 (void)signal(SIGTRAP, SIG_IGN);
184 #endif /* AFS_DECOSF_ENV */
185 if (instance == 0)
186 instance = "";
187 if (flags & KA_USERAUTH_ONLY_VERIFY) {
188 code = ka_VerifyUserToken(name, instance, realm, &key);
189 if (code == KABADREQUEST) {
190 des_string_to_key(password, ktc_to_cblockptr(&key));
191 code = ka_VerifyUserToken(name, instance, realm, &key);
193 } else {
194 #ifdef AFS_DUX40_ENV
195 if (flags & KA_USERAUTH_DOSETPAG)
196 afs_setpag();
197 #else
198 #if !defined(UKERNEL) && !defined(AFS_NT40_ENV)
199 if (flags & KA_USERAUTH_DOSETPAG)
200 setpag();
201 #endif
202 #endif
203 if (flags & KA_USERAUTH_DOSETPAG2)
204 dosetpag = 1;
205 #ifdef AFS_KERBEROS_ENV
206 if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag)
207 ktc_newpag();
208 #endif
209 if (lifetime == 0)
210 lifetime = MAXKTCTICKETLIFETIME;
211 code =
212 GetTickets(name, instance, realm, &key, lifetime,
213 password_expires, dosetpag);
214 if (code == KABADREQUEST) {
215 des_string_to_key(password, ktc_to_cblockptr(&key));
216 code =
217 GetTickets(name, instance, realm, &key, lifetime,
218 password_expires, dosetpag);
222 #ifndef AFS_NT40_ENV
223 if (remainingTime) {
224 pr_End();
225 rx_Finalize();
226 alarm(remainingTime); /* restore timer, if any */
228 #endif
230 if (code && reasonP)
231 switch (code) {
232 case KABADREQUEST:
233 *reasonP = "password was incorrect";
234 break;
235 case KAUBIKCALL:
236 *reasonP = "Authentication Server was unavailable";
237 break;
238 default:
239 *reasonP = (char *)afs_error_message(code);
241 return code;
244 /* For backward compatibility */
245 afs_int32
246 ka_UserAuthenticate(char *name, char *instance, char *realm, char *password,
247 int doSetPAG, char **reasonP)
249 return ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION +
250 ((doSetPAG) ? KA_USERAUTH_DOSETPAG : 0),
251 name, instance, realm, password,
252 /*lifetime */ 0, /*spare1,2 */ 0, 0,
253 reasonP);
256 #if !defined(UKERNEL)
257 afs_int32
258 ka_UserReadPassword(char *prompt, char *password, int plen, char **reasonP)
260 afs_int32 code = 0;
262 if (reasonP)
263 *reasonP = "";
264 code = ka_Init(0);
265 if (code)
266 return code;
267 code = read_pw_string(password, plen, prompt, 0);
268 if (code)
269 code = KAREADPW;
270 else if (strlen(password) == 0)
271 code = KANULLPASSWORD;
272 else
273 return 0;
275 if (reasonP) {
276 *reasonP = (char *)afs_error_message(code);
278 return code;
280 #endif /* !defined(UKERNEL) */
282 afs_int32
283 ka_VerifyUserPassword(afs_int32 version, char *name, char *instance,
284 char *realm, char *password, int spare, char **reasonP)
286 afs_int32 pwexpires;
288 version &= KA_USERAUTH_VERSION_MASK;
289 return ka_UserAuthenticateGeneral(version | KA_USERAUTH_ONLY_VERIFY, name,
290 instance, realm, password, 0,
291 &pwexpires, spare, reasonP);