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