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