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