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