07fb001608e94306af1937f2e6300843f53b6bb3
[openafs.git] / src / kauth / token.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 /* These routines provide an interface to the token cache maintained by the
11    kernel.  Principally it handles cache misses by requesting the desired token
12    from the AuthServer. */
13
14 #include <afsconfig.h>
15 #if defined(UKERNEL)
16 #include "../afs/param.h"
17 #else
18 #include <afs/param.h>
19 #endif
20
21 RCSID("$Header$");
22
23 #if defined(UKERNEL)
24 #include "../afs/sysincludes.h"
25 #include "../afs/afsincludes.h"
26 #include "../afs/stds.h"
27 #include "../rx/xdr.h"
28 #include "../afs/pthread_glock.h"
29 #include "../afs/lock.h"
30 #include "../afs/ubik.h"
31 #include "../afsint/kauth.h"
32 #include "../afs/kautils.h"
33 #include "../afs/auth.h"
34 #include "../afs/pthread_glock.h"
35 #else /* defined(UKERNEL) */
36 #include <afs/stds.h>
37 #include <sys/types.h>
38 #include <rx/xdr.h>
39 #include <afs/pthread_glock.h>
40 #ifdef AFS_NT40_ENV
41 #include <winsock2.h>
42 #else
43 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #endif
46 /* netinet/in.h and cellconfig.h  are needed together */
47 #include <afs/cellconfig.h>
48     /* these are needed together */
49 #include <lock.h>
50 #include <ubik.h>
51
52 #include "kauth.h"
53 #include "kautils.h"
54 #include <afs/auth.h>
55 #endif /* defined(UKERNEL) */
56
57
58 afs_int32 ka_GetAuthToken (
59   char *name,
60   char *instance,
61   char *cell,
62   struct ktc_encryptionKey *key,
63   afs_int32  lifetime,
64   afs_int32  *pwexpires)
65
66     afs_int32                code;
67     struct ubik_client *conn;
68     afs_int32           now = time(0);
69     struct ktc_token    token;
70     char                cellname[MAXKTCREALMLEN];
71     char                realm[MAXKTCREALMLEN];
72     struct ktc_principal client, server;
73
74     LOCK_GLOBAL_MUTEX
75     code = ka_ExpandCell (cell, cellname, 0/*local*/);
76     if (code) {
77         UNLOCK_GLOBAL_MUTEX
78         return code;
79     }
80     cell = cellname;
81
82     /* get an unauthenticated connection to desired cell */
83     code = ka_AuthServerConn (cell, KA_AUTHENTICATION_SERVICE, 0, &conn);
84     if (code) {
85         UNLOCK_GLOBAL_MUTEX
86         return code;
87     }
88     code = ka_Authenticate (name, instance, cell, conn,
89                             KA_TICKET_GRANTING_SERVICE,
90                             key, now, now+lifetime, &token, pwexpires);
91     if (code) {
92         UNLOCK_GLOBAL_MUTEX
93         return code;
94     }
95     code = ubik_ClientDestroy (conn);
96     if (code) {
97         UNLOCK_GLOBAL_MUTEX
98         return code;
99     }
100
101     code = ka_CellToRealm (cell, realm, 0/*local*/);
102     if (code) {
103         UNLOCK_GLOBAL_MUTEX
104         return code;
105     }
106     strcpy (client.name, name);
107     strcpy (client.instance, instance);
108     strncpy (client.cell, cell, sizeof(client.cell));
109     strcpy (server.name, KA_TGS_NAME);
110     strcpy (server.instance, realm);
111     strcpy (server.cell, cell);
112     code = ktc_SetToken (&server, &token, &client, 0);
113     UNLOCK_GLOBAL_MUTEX
114     return code;
115 }
116
117 afs_int32 ka_GetServerToken (
118   char *name,
119   char *instance,
120   char *cell,
121   Date  lifetime,
122   struct ktc_token *token,
123   int   new,
124   int   dosetpag)
125 {
126     afs_int32                code;
127     struct ubik_client *conn;
128     afs_int32           now = time(0);
129     struct ktc_token    auth_token;
130     struct ktc_token    cell_token;
131     struct ktc_principal server, auth_server, client;
132     char               *localCell = ka_LocalCell();
133     char                cellname[MAXKTCREALMLEN];
134     char                realm[MAXKTCREALMLEN];
135     char                authDomain[MAXKTCREALMLEN];
136     int                 local;
137
138     LOCK_GLOBAL_MUTEX
139     code = ka_ExpandCell (cell, cellname, 0/*local*/);
140     if (code) {
141         UNLOCK_GLOBAL_MUTEX
142         return code;
143     }
144     cell = cellname;
145
146     strcpy (server.name, name);
147     strcpy (server.instance, instance);
148     lcstring (server.cell, cell, sizeof(server.cell));
149     if (!new) {
150         code = ktc_GetToken (&server, token, sizeof(struct ktc_token), &client);
151         if (!code) {
152             UNLOCK_GLOBAL_MUTEX
153             return 0;
154         }
155     }
156     
157     code = ka_CellToRealm (cell, realm, &local);
158     if (code) {
159         UNLOCK_GLOBAL_MUTEX
160         return code;
161     }
162
163     /* get TGS ticket for proper realm */
164     strcpy (auth_server.name, KA_TGS_NAME);
165     strcpy (auth_server.instance, realm);
166     lcstring (auth_server.cell, realm, sizeof(auth_server.cell));
167     strcpy (authDomain, realm);
168     code = ktc_GetToken (&auth_server, &auth_token, sizeof(auth_token), &client);
169     if (code && !local) {               /* try for remotely authenticated ticket */
170         strcpy (auth_server.cell, localCell);
171         strcpy (authDomain, "");
172         code = ktc_GetToken (&auth_server, &auth_token, sizeof(auth_token), &client);
173     }
174
175     if (code && local) {
176         UNLOCK_GLOBAL_MUTEX
177         return code;
178     }
179     else if (code) {
180         /* here we invoke the inter-cell mechanism */
181
182         /* get local auth ticket */
183         ucstring (auth_server.instance, localCell, sizeof(auth_server.instance));
184         strcpy (auth_server.cell, localCell);
185         code = ktc_GetToken (&auth_server, &cell_token, sizeof(cell_token), &client);
186         if (code) {
187             UNLOCK_GLOBAL_MUTEX
188             return code;
189         }
190         /* get a connection to the local cell */
191         if (code = ka_AuthServerConn (localCell, KA_TICKET_GRANTING_SERVICE, 0, &conn)) {
192             UNLOCK_GLOBAL_MUTEX
193             return code;
194         }
195         /* get foreign auth ticket */
196         if (code = ka_GetToken (KA_TGS_NAME, realm, localCell, client.name,
197                                 client.instance, conn, now, now+lifetime,
198                                 &cell_token, "" /* local auth domain */,
199                                 &auth_token)) {
200             UNLOCK_GLOBAL_MUTEX
201             return code;
202         }
203         code = ubik_ClientDestroy (conn);
204         if (code) {
205             UNLOCK_GLOBAL_MUTEX
206             return code;
207         }
208         conn = 0;
209
210         /* save foreign auth ticket */
211         strcpy (auth_server.instance, realm);
212         lcstring (auth_server.cell, localCell, sizeof(auth_server.cell));
213         ucstring (authDomain, localCell, sizeof(authDomain));
214         if (code = ktc_SetToken (&auth_server, &auth_token, &client, 0)) {
215             UNLOCK_GLOBAL_MUTEX
216             return code;
217         }
218     }
219
220     if (code = ka_AuthServerConn (cell, KA_TICKET_GRANTING_SERVICE, 0, &conn)) {
221         UNLOCK_GLOBAL_MUTEX
222         return code;
223     }
224     if (code = ka_GetToken (name, instance, cell, client.name,
225                             client.instance, conn, now, now+lifetime,
226                             &auth_token, authDomain, token)) {
227         UNLOCK_GLOBAL_MUTEX
228         return code;
229     }
230     code = ubik_ClientDestroy (conn);
231     if (code) {
232         UNLOCK_GLOBAL_MUTEX
233         return code;
234     }
235
236     if (code = ktc_SetToken (&server, token, &client,
237                              dosetpag ? AFS_SETTOK_SETPAG : 0)) {
238         UNLOCK_GLOBAL_MUTEX
239         return code;
240     }
241     UNLOCK_GLOBAL_MUTEX
242     return 0;
243 }
244
245 afs_int32 ka_GetAdminToken (
246   char *name,
247   char *instance,
248   char *cell,
249   struct ktc_encryptionKey *key,
250   afs_int32  lifetime,
251   struct ktc_token *token,
252   int   new)
253 {
254     int                  code;
255     struct ubik_client  *conn;
256     afs_int32            now = time(0);
257     struct ktc_principal server, client;
258     struct ktc_token     localToken;
259     char                 cellname[MAXKTCREALMLEN];
260
261     LOCK_GLOBAL_MUTEX
262     code = ka_ExpandCell (cell, cellname, 0/*local*/);
263     if (code) {
264         UNLOCK_GLOBAL_MUTEX
265         return code;
266     }
267     cell = cellname;
268
269     if (token == 0) token = &localToken; /* in case caller doesn't want token */
270
271     strcpy (server.name, KA_ADMIN_NAME);
272     strcpy (server.instance, KA_ADMIN_INST);
273     strncpy (server.cell, cell, sizeof(server.cell));
274     if (!new) {
275         code = ktc_GetToken (&server,
276                              token, sizeof(struct ktc_token), &client);
277         if (code == 0) {
278             UNLOCK_GLOBAL_MUTEX
279             return 0;
280         }
281     }
282
283     if ((name == 0) || (key == 0)) {
284         /* just lookup in cache don't get new one */
285         UNLOCK_GLOBAL_MUTEX
286         return KANOTICKET;
287     }
288
289     /* get an unauthenticated connection to desired cell */
290     code = ka_AuthServerConn (cell, KA_AUTHENTICATION_SERVICE, 0, &conn);
291     if (code) {
292         UNLOCK_GLOBAL_MUTEX
293         return code;
294     }
295     code = ka_Authenticate (name, instance, cell, conn, KA_MAINTENANCE_SERVICE,
296                             key, now, now+lifetime, token, 0);
297     (void) ubik_ClientDestroy (conn);
298     if (code) {
299         UNLOCK_GLOBAL_MUTEX
300         return code;
301     }
302
303     strcpy (client.name, name);
304     strcpy (client.instance, instance);
305     strncpy (client.cell, cell, sizeof(client.cell));
306     code = ktc_SetToken (&server, token, &client, 0);
307     UNLOCK_GLOBAL_MUTEX
308     return code;
309 }
310
311
312 afs_int32 ka_VerifyUserToken(
313   char *name,
314   char *instance,
315   char *cell,
316   struct ktc_encryptionKey *key)
317 {
318     afs_int32 code;
319     struct ubik_client *conn;
320     afs_int32           now = time(0);
321     struct ktc_token    token;
322     char                cellname[MAXKTCREALMLEN];
323     char                realm[MAXKTCREALMLEN];
324     struct ktc_principal client, server;
325     afs_int32 pwexpires;
326
327     LOCK_GLOBAL_MUTEX
328     code = ka_ExpandCell (cell, cellname, 0/*local*/);
329     if (code) {
330         UNLOCK_GLOBAL_MUTEX
331         return code;
332     }
333
334     cell = cellname;
335
336     /* get an unauthenticated connection to desired cell */
337     code = ka_AuthServerConn (cell, KA_AUTHENTICATION_SERVICE, 0, &conn);
338     if (code) {
339         UNLOCK_GLOBAL_MUTEX
340         return code;
341     }
342
343     code = ka_Authenticate (name, instance, cell, conn,
344                             KA_TICKET_GRANTING_SERVICE,
345                             key, now, now+MAXKTCTICKETLIFETIME, &token, &pwexpires);
346     if (code) {
347         UNLOCK_GLOBAL_MUTEX
348         return code;
349     }
350     code = ubik_ClientDestroy (conn);
351     UNLOCK_GLOBAL_MUTEX
352     return code;
353 }