Remove DUX/OSF code
[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     if (instance == 0)
171         instance = "";
172     if (flags & KA_USERAUTH_ONLY_VERIFY) {
173         code = ka_VerifyUserToken(name, instance, realm, &key);
174         if (code == KABADREQUEST) {
175             DES_string_to_key(password, ktc_to_cblockptr(&key));
176             code = ka_VerifyUserToken(name, instance, realm, &key);
177         }
178     } else {
179 #if !defined(AFS_NT40_ENV)
180         if (flags & KA_USERAUTH_DOSETPAG)
181             setpag();
182 #endif
183         if (flags & KA_USERAUTH_DOSETPAG2)
184             dosetpag = 1;
185 #ifdef AFS_KERBEROS_ENV
186         if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag)
187             ktc_newpag();
188 #endif
189         if (lifetime == 0)
190             lifetime = MAXKTCTICKETLIFETIME;
191         code =
192             GetTickets(name, instance, realm, &key, lifetime,
193                        password_expires, dosetpag);
194         if (code == KABADREQUEST) {
195             DES_string_to_key(password, ktc_to_cblockptr(&key));
196             code =
197                 GetTickets(name, instance, realm, &key, lifetime,
198                            password_expires, dosetpag);
199         }
200     }
201
202 #ifndef AFS_NT40_ENV
203     if (remainingTime) {
204         pr_End();
205         rx_Finalize();
206         alarm(remainingTime);   /* restore timer, if any */
207     }
208 #endif
209
210     if (code && reasonP)
211         switch (code) {
212         case KABADREQUEST:
213             *reasonP = "password was incorrect";
214             break;
215         case KAUBIKCALL:
216             *reasonP = "Authentication Server was unavailable";
217             break;
218         default:
219             *reasonP = (char *)afs_error_message(code);
220         }
221     return code;
222 }
223
224 /* For backward compatibility */
225 afs_int32
226 ka_UserAuthenticate(char *name, char *instance, char *realm, char *password,
227                     int doSetPAG, char **reasonP)
228 {
229     return ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION +
230                                       ((doSetPAG) ? KA_USERAUTH_DOSETPAG : 0),
231                                       name, instance, realm, password,
232                                       /*lifetime */ 0, /*spare1,2 */ 0, 0,
233                                       reasonP);
234 }
235
236 afs_int32
237 ka_UserReadPassword(char *prompt, char *password, int plen, char **reasonP)
238 {
239     afs_int32 code = 0;
240
241     if (reasonP)
242         *reasonP = "";
243     code = ka_Init(0);
244     if (code)
245         return code;
246     code = UI_UTIL_read_pw_string(password, plen, prompt, 0);
247     if (code)
248         code = KAREADPW;
249     else if (strlen(password) == 0)
250         code = KANULLPASSWORD;
251     else
252         return 0;
253
254     if (reasonP) {
255         *reasonP = (char *)afs_error_message(code);
256     }
257     return code;
258 }
259
260 afs_int32
261 ka_VerifyUserPassword(afs_int32 version, char *name, char *instance,
262                       char *realm, char *password, int spare, char **reasonP)
263 {
264     afs_int32 pwexpires;
265
266     version &= KA_USERAUTH_VERSION_MASK;
267     return ka_UserAuthenticateGeneral(version | KA_USERAUTH_ONLY_VERIFY, name,
268                                       instance, realm, password, 0,
269                                       &pwexpires, spare, reasonP);
270 }