Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / kauth / token.c
blob0680b6c6e1b5ade33baf30c762f777b4c9f7fe31
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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 */
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. */
14 #include <afsconfig.h>
15 #include <afs/param.h>
17 #ifdef UKERNEL
18 # include "afsincludes.h"
19 #endif
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>
38 #include "kauth.h"
39 #include "kautils.h"
40 #include <afs/auth.h>
43 afs_int32
44 ka_GetAuthToken(char *name, char *instance, char *cell,
45 struct ktc_encryptionKey * key, afs_int32 lifetime,
46 afs_int32 * pwexpires)
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;
56 LOCK_GLOBAL_MUTEX;
57 code = ka_ExpandCell(cell, cellname, 0 /*local */ );
58 if (code) {
59 UNLOCK_GLOBAL_MUTEX;
60 return code;
62 cell = cellname;
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;
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;
78 code = ubik_ClientDestroy(conn);
79 if (code) {
80 UNLOCK_GLOBAL_MUTEX;
81 return code;
84 code = ka_CellToRealm(cell, realm, 0 /*local */ );
85 if (code) {
86 UNLOCK_GLOBAL_MUTEX;
87 return code;
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;
100 afs_int32
101 ka_GetServerToken(char *name, char *instance, char *cell, Date lifetime,
102 struct ktc_token * token, int new, int dosetpag)
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;
116 LOCK_GLOBAL_MUTEX;
117 code = ka_ExpandCell(cell, cellname, 0 /*local */ );
118 if (code) {
119 UNLOCK_GLOBAL_MUTEX;
120 return code;
122 cell = cellname;
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;
136 code = ka_CellToRealm(cell, realm, &local);
137 if (code) {
138 UNLOCK_GLOBAL_MUTEX;
139 return code;
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);
157 if (code && local) {
158 UNLOCK_GLOBAL_MUTEX;
159 return code;
160 } else if (code) {
161 /* here we invoke the inter-cell mechanism */
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;
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;
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;
190 code = ubik_ClientDestroy(conn);
191 if (code) {
192 UNLOCK_GLOBAL_MUTEX;
193 return code;
195 conn = 0;
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;
207 if ((code =
208 ka_AuthServerConn(cell, KA_TICKET_GRANTING_SERVICE, 0, &conn))) {
209 UNLOCK_GLOBAL_MUTEX;
210 return code;
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;
218 code = ubik_ClientDestroy(conn);
219 if (code) {
220 UNLOCK_GLOBAL_MUTEX;
221 return code;
224 if ((code =
225 ktc_SetToken(&server, token, &client,
226 dosetpag ? AFS_SETTOK_SETPAG : 0))) {
227 UNLOCK_GLOBAL_MUTEX;
228 return code;
230 UNLOCK_GLOBAL_MUTEX;
231 return 0;
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)
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];
246 LOCK_GLOBAL_MUTEX;
247 code = ka_ExpandCell(cell, cellname, 0 /*local */ );
248 if (code) {
249 UNLOCK_GLOBAL_MUTEX;
250 return code;
252 cell = cellname;
254 if (token == 0)
255 token = &localToken; /* in case caller doesn't want token */
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;
269 if ((name == 0) || (key == 0)) {
270 /* just lookup in cache don't get new one */
271 UNLOCK_GLOBAL_MUTEX;
272 return KANOTICKET;
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;
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;
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;
299 afs_int32
300 ka_VerifyUserToken(char *name, char *instance, char *cell,
301 struct ktc_encryptionKey * key)
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;
310 LOCK_GLOBAL_MUTEX;
311 code = ka_ExpandCell(cell, cellname, 0 /*local */ );
312 if (code) {
313 UNLOCK_GLOBAL_MUTEX;
314 return code;
317 cell = cellname;
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;
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;
334 code = ubik_ClientDestroy(conn);
335 UNLOCK_GLOBAL_MUTEX;
336 return code;