6166433806d2ef554760df0ac2a4266df6a769e8
[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 code = ka_ExpandCell(cell, cellname, 0 /*local */ );
80     if (code) {
81         UNLOCK_GLOBAL_MUTEX return code;
82     }
83     cell = cellname;
84
85     /* get an unauthenticated connection to desired cell */
86     code = ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn);
87     if (code) {
88         UNLOCK_GLOBAL_MUTEX return code;
89     }
90     code =
91         ka_Authenticate(name, instance, cell, conn,
92                         KA_TICKET_GRANTING_SERVICE, key, now, now + lifetime,
93                         &token, pwexpires);
94     if (code) {
95         UNLOCK_GLOBAL_MUTEX return code;
96     }
97     code = ubik_ClientDestroy(conn);
98     if (code) {
99         UNLOCK_GLOBAL_MUTEX return code;
100     }
101
102     code = ka_CellToRealm(cell, realm, 0 /*local */ );
103     if (code) {
104         UNLOCK_GLOBAL_MUTEX 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 return code;
114 }
115
116 afs_int32
117 ka_GetServerToken(char *name, char *instance, char *cell, Date lifetime,
118                   struct ktc_token * token, int new, int dosetpag)
119 {
120     afs_int32 code;
121     struct ubik_client *conn;
122     afs_int32 now = time(0);
123     struct ktc_token auth_token;
124     struct ktc_token cell_token;
125     struct ktc_principal server, auth_server, client;
126     char *localCell = ka_LocalCell();
127     char cellname[MAXKTCREALMLEN];
128     char realm[MAXKTCREALMLEN];
129     char authDomain[MAXKTCREALMLEN];
130     int local;
131
132     LOCK_GLOBAL_MUTEX code = ka_ExpandCell(cell, cellname, 0 /*local */ );
133     if (code) {
134         UNLOCK_GLOBAL_MUTEX return code;
135     }
136     cell = cellname;
137
138     strcpy(server.name, name);
139     strcpy(server.instance, instance);
140     lcstring(server.cell, cell, sizeof(server.cell));
141     if (!new) {
142         code =
143             ktc_GetToken(&server, token, sizeof(struct ktc_token), &client);
144         if (!code) {
145             UNLOCK_GLOBAL_MUTEX return 0;
146         }
147     }
148
149     code = ka_CellToRealm(cell, realm, &local);
150     if (code) {
151         UNLOCK_GLOBAL_MUTEX return code;
152     }
153
154     /* get TGS ticket for proper realm */
155     strcpy(auth_server.name, KA_TGS_NAME);
156     strcpy(auth_server.instance, realm);
157     lcstring(auth_server.cell, realm, sizeof(auth_server.cell));
158     strcpy(authDomain, realm);
159     code =
160         ktc_GetToken(&auth_server, &auth_token, sizeof(auth_token), &client);
161     if (code && !local) {       /* try for remotely authenticated ticket */
162         strcpy(auth_server.cell, localCell);
163         strcpy(authDomain, "");
164         code =
165             ktc_GetToken(&auth_server, &auth_token, sizeof(auth_token),
166                          &client);
167     }
168
169     if (code && local) {
170         UNLOCK_GLOBAL_MUTEX return code;
171     } else if (code) {
172         /* here we invoke the inter-cell mechanism */
173
174         /* get local auth ticket */
175         ucstring(auth_server.instance, localCell,
176                  sizeof(auth_server.instance));
177         strcpy(auth_server.cell, localCell);
178         code =
179             ktc_GetToken(&auth_server, &cell_token, sizeof(cell_token),
180                          &client);
181         if (code) {
182             UNLOCK_GLOBAL_MUTEX return code;
183         }
184         /* get a connection to the local cell */
185         if ((code =
186              ka_AuthServerConn(localCell, KA_TICKET_GRANTING_SERVICE, 0,
187                                &conn))) {
188             UNLOCK_GLOBAL_MUTEX return code;
189         }
190         /* get foreign auth ticket */
191         if ((code =
192              ka_GetToken(KA_TGS_NAME, realm, localCell, client.name,
193                          client.instance, conn, now, now + lifetime,
194                          &cell_token, "" /* local auth domain */ ,
195                          &auth_token))) {
196             UNLOCK_GLOBAL_MUTEX return code;
197         }
198         code = ubik_ClientDestroy(conn);
199         if (code) {
200             UNLOCK_GLOBAL_MUTEX return code;
201         }
202         conn = 0;
203
204         /* save foreign auth ticket */
205         strcpy(auth_server.instance, realm);
206         lcstring(auth_server.cell, localCell, sizeof(auth_server.cell));
207         ucstring(authDomain, localCell, sizeof(authDomain));
208         if ((code = ktc_SetToken(&auth_server, &auth_token, &client, 0))) {
209             UNLOCK_GLOBAL_MUTEX return code;
210         }
211     }
212
213     if ((code =
214          ka_AuthServerConn(cell, KA_TICKET_GRANTING_SERVICE, 0, &conn))) {
215         UNLOCK_GLOBAL_MUTEX return code;
216     }
217     if ((code =
218          ka_GetToken(name, instance, cell, client.name, client.instance, conn,
219                      now, now + lifetime, &auth_token, authDomain, token))) {
220         UNLOCK_GLOBAL_MUTEX return code;
221     }
222     code = ubik_ClientDestroy(conn);
223     if (code) {
224         UNLOCK_GLOBAL_MUTEX return code;
225     }
226
227     if ((code =
228          ktc_SetToken(&server, token, &client,
229                       dosetpag ? AFS_SETTOK_SETPAG : 0))) {
230         UNLOCK_GLOBAL_MUTEX return code;
231     }
232     UNLOCK_GLOBAL_MUTEX return 0;
233 }
234
235 afs_int32
236 ka_GetAdminToken(char *name, char *instance, char *cell,
237                  struct ktc_encryptionKey * key, afs_int32 lifetime,
238                  struct ktc_token * token, int new)
239 {
240     int code;
241     struct ubik_client *conn;
242     afs_int32 now = time(0);
243     struct ktc_principal server, client;
244     struct ktc_token localToken;
245     char cellname[MAXKTCREALMLEN];
246
247     LOCK_GLOBAL_MUTEX code = ka_ExpandCell(cell, cellname, 0 /*local */ );
248     if (code) {
249         UNLOCK_GLOBAL_MUTEX return code;
250     }
251     cell = cellname;
252
253     if (token == 0)
254         token = &localToken;    /* in case caller doesn't want token */
255
256     strcpy(server.name, KA_ADMIN_NAME);
257     strcpy(server.instance, KA_ADMIN_INST);
258     strncpy(server.cell, cell, sizeof(server.cell));
259     if (!new) {
260         code =
261             ktc_GetToken(&server, token, sizeof(struct ktc_token), &client);
262         if (code == 0) {
263             UNLOCK_GLOBAL_MUTEX return 0;
264         }
265     }
266
267     if ((name == 0) || (key == 0)) {
268         /* just lookup in cache don't get new one */
269         UNLOCK_GLOBAL_MUTEX return KANOTICKET;
270     }
271
272     /* get an unauthenticated connection to desired cell */
273     code = ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn);
274     if (code) {
275         UNLOCK_GLOBAL_MUTEX return code;
276     }
277     code =
278         ka_Authenticate(name, instance, cell, conn, KA_MAINTENANCE_SERVICE,
279                         key, now, now + lifetime, token, 0);
280     (void)ubik_ClientDestroy(conn);
281     if (code) {
282         UNLOCK_GLOBAL_MUTEX return code;
283     }
284
285     strcpy(client.name, name);
286     strcpy(client.instance, instance);
287     strncpy(client.cell, cell, sizeof(client.cell));
288     code = ktc_SetToken(&server, token, &client, 0);
289     UNLOCK_GLOBAL_MUTEX return code;
290 }
291
292
293 afs_int32
294 ka_VerifyUserToken(char *name, char *instance, char *cell,
295                    struct ktc_encryptionKey * key)
296 {
297     afs_int32 code;
298     struct ubik_client *conn;
299     afs_int32 now = time(0);
300     struct ktc_token token;
301     char cellname[MAXKTCREALMLEN];
302     afs_int32 pwexpires;
303
304     LOCK_GLOBAL_MUTEX code = ka_ExpandCell(cell, cellname, 0 /*local */ );
305     if (code) {
306         UNLOCK_GLOBAL_MUTEX return code;
307     }
308
309     cell = cellname;
310
311     /* get an unauthenticated connection to desired cell */
312     code = ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn);
313     if (code) {
314         UNLOCK_GLOBAL_MUTEX return code;
315     }
316
317     code =
318         ka_Authenticate(name, instance, cell, conn,
319                         KA_TICKET_GRANTING_SERVICE, key, now,
320                         now + MAXKTCTICKETLIFETIME, &token, &pwexpires);
321     if (code) {
322         UNLOCK_GLOBAL_MUTEX return code;
323     }
324     code = ubik_ClientDestroy(conn);
325     UNLOCK_GLOBAL_MUTEX return code;
326 }