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