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