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