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