2 * Copyright 2000, International Business Machines Corporation and others.
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
14 #include <afsconfig.h>
15 #include <afs/param.h>
22 #include <sys/types.h>
29 #include <sys/ioctl.h>
40 #include <afs/afsutil.h>
43 extern struct cmd_syndesc *cmd_CreateSyntax();
48 29 Oct 1992 Patch GetTokens to print something reasonable when there are no tokens.
52 /* this is a structure used to communicate with the afs cache mgr, but is
53 * otherwise irrelevant, or worse.
59 afs_int32 BeginTimestamp;
60 afs_int32 EndTimestamp;
65 SetSysname(ahost, auid, sysname)
72 char space[1200], *tp;
73 struct ViceIoctl blob;
76 /* otherwise we've got the token, now prepare to build the pioctl args */
79 pheader[2] = 0; /* group low */
80 pheader[3] = 0; /* group high */
81 pheader[4] = 38 /*VIOC_AFS_SYSNAME */ ; /* sysname pioctl index */
82 pheader[5] = 1; /* NFS protocol exporter # */
85 memcpy(space, pheader, sizeof(pheader));
86 tp = space + sizeof(pheader);
88 /* finally setup the pioctl call's parameters */
89 blob.in_size = sizeof(pheader);
93 memcpy(tp, &setp, sizeof(afs_int32));
94 tp += sizeof(afs_int32);
96 blob.in_size += sizeof(afs_int32) + strlen(sysname) + 1;
97 tp += strlen(sysname);
99 code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
108 GetTokens(ahost, auid)
112 struct ViceIoctl iob;
113 afs_int32 pheader[6];
115 register afs_int32 code;
117 char *stp; /* secret token ptr */
118 struct ClearToken ct;
120 afs_int32 temp, gotit = 0;
121 int maxLen; /* biggest ticket we can copy */
122 int tktLen; /* server ticket length */
123 time_t tokenExpireTime;
125 struct ktc_token token;
126 struct ktc_principal clientName;
130 current_time = time(0);
132 /* otherwise we've got the token, now prepare to build the pioctl args */
135 pheader[2] = 0; /* group low */
136 pheader[3] = 0; /* group high */
137 pheader[4] = 8; /* gettoken pioctl index */
138 pheader[5] = 1; /* NFS protocol exporter # */
140 for (index = 0; index < 200; index++) { /* sanity check in case pioctl fails */
141 code = ktc_ListTokens(index, &newIndex, &clientName);
143 if (code == KTC_NOENT) {
146 printf("knfs: there are no tokens here.\n");
149 break; /* done, but failed */
151 if (strcmp(clientName.name, "afs") != 0)
152 continue; /* wrong ticket service */
155 memcpy(tbuffer, pheader, sizeof(pheader));
156 tp = tbuffer + sizeof(pheader);
157 memcpy(tp, &index, sizeof(afs_int32));
158 tp += sizeof(afs_int32);
160 iob.in_size = sizeof(afs_int32) + sizeof(pheader);
162 iob.out_size = sizeof(tbuffer);
163 code = pioctl(NULL, _VICEIOCTL(99), &iob, 0);
164 if (code < 0 && errno == EDOM)
166 else if (code == 0) {
167 /* check to see if this is the right cell/realm */
169 memcpy(&temp, tp, sizeof(afs_int32)); /* get size of secret token */
170 tktLen = temp; /* remember size of ticket */
171 tp += sizeof(afs_int32);
172 stp = tp; /* remember where ticket is, for later */
173 tp += temp; /* skip ticket for now */
174 memcpy(&temp, tp, sizeof(afs_int32)); /* get size of clear token */
175 if (temp != sizeof(struct ClearToken))
177 tp += sizeof(afs_int32); /* skip length */
178 memcpy(&ct, tp, temp); /* copy token for later use */
179 tp += temp; /* skip clear token itself */
180 tp += sizeof(afs_int32); /* skip primary flag */
181 /* tp now points to the cell name */
182 if (strcmp(tp, clientName.cell) == 0) {
183 /* closing in now, we've got the right cell */
186 sizeof(token) - sizeof(struct ktc_token) +
190 memcpy(token.ticket, stp, tktLen);
191 token.startTime = ct.BeginTimestamp;
192 token.endTime = ct.EndTimestamp;
193 if (ct.AuthHandle == -1)
195 token.kvno = ct.AuthHandle;
196 memcpy(&token.sessionKey, ct.HandShakeKey,
197 sizeof(struct ktc_encryptionKey));
198 token.ticketLen = tktLen;
199 if ((token.kvno == 999) || /* old style bcrypt ticket */
200 (ct.BeginTimestamp && /* new w/ prserver lookup */
201 (((ct.EndTimestamp - ct.BeginTimestamp) & 1) == 1))) {
202 sprintf(clientName.name, "AFS ID %d", ct.ViceId);
203 clientName.instance[0] = 0;
205 sprintf(clientName.name, "Unix UID %d", ct.ViceId);
206 clientName.instance[0] = 0;
208 strcpy(clientName.cell, tp);
210 tokenExpireTime = token.endTime;
211 strcpy(UserName, clientName.name);
212 if (clientName.instance[0] != 0) {
213 strcat(UserName, ".");
214 strcat(UserName, clientName.instance);
216 if (UserName[0] == 0)
218 else if (strncmp(UserName, "AFS ID", 6) == 0) {
219 printf("User's (%s) tokens", UserName);
220 } else if (strncmp(UserName, "Unix UID", 8) == 0) {
223 printf("User %s's tokens", UserName);
224 printf(" for %s%s%s@%s ", clientName.name,
225 clientName.instance[0] ? "." : "", clientName.instance,
227 if (tokenExpireTime <= current_time)
228 printf("[>> Expired <<]\n");
230 expireString = ctime(&tokenExpireTime);
231 expireString += 4; /*Move past the day of week */
232 expireString[12] = '\0';
233 printf("[Expires %s]\n", expireString);
244 NFSUnlog(ahost, auid)
249 afs_int32 pheader[6];
251 struct ViceIoctl blob;
253 /* otherwise we've got the token, now prepare to build the pioctl args */
256 pheader[2] = 0; /* group low */
257 pheader[3] = 0; /* group high */
258 pheader[4] = 9; /* unlog pioctl index */
259 pheader[5] = 1; /* NFS protocol exporter # */
262 memcpy(space, pheader, sizeof(pheader));
264 /* finally setup the pioctl call's parameters */
265 blob.in_size = sizeof(pheader);
269 code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
276 /* Copy the AFS service token into the kernel for a particular host and user */
278 NFSCopyToken(ahost, auid)
282 struct ktc_principal client, server;
283 struct ktc_token theTicket;
285 afs_int32 pheader[6];
287 struct ClearToken ct;
288 afs_int32 index, newIndex;
289 afs_int32 temp; /* for bcopy */
291 struct ViceIoctl blob;
293 for (index = 0;; index = newIndex) {
294 code = ktc_ListTokens(index, &newIndex, &server);
296 if (code == KTC_NOENT) {
300 break; /* done, but failed */
302 if (strcmp(server.name, "afs") != 0)
303 continue; /* wrong ticket service */
304 code = ktc_GetToken(&server, &theTicket, sizeof(theTicket), &client);
308 /* otherwise we've got the token, now prepare to build the pioctl args */
311 pheader[2] = 0; /* group low */
312 pheader[3] = 0; /* group high */
313 pheader[4] = 3; /* set token pioctl index */
314 pheader[5] = 1; /* NFS protocol exporter # */
316 /* copy in the header */
317 memcpy(space, pheader, sizeof(pheader));
318 tp = space + sizeof(pheader);
319 /* copy in the size of the encrypted part */
320 memcpy(tp, &theTicket.ticketLen, sizeof(afs_int32));
321 tp += sizeof(afs_int32);
322 /* copy in the ticket itself */
323 memcpy(tp, theTicket.ticket, theTicket.ticketLen);
324 tp += theTicket.ticketLen;
325 /* copy in "clear token"'s size */
326 temp = sizeof(struct ClearToken);
327 memcpy(tp, &temp, sizeof(afs_int32));
328 tp += sizeof(afs_int32);
329 /* create the clear token and copy *it* in */
330 ct.AuthHandle = theTicket.kvno; /* where we hide the key version # */
331 memcpy(ct.HandShakeKey, &theTicket.sessionKey,
332 sizeof(ct.HandShakeKey));
335 ct.BeginTimestamp = theTicket.startTime;
336 ct.EndTimestamp = theTicket.endTime;
337 memcpy(tp, &ct, sizeof(ct));
339 /* copy in obsolete primary flag */
341 memcpy(tp, &temp, sizeof(afs_int32));
342 tp += sizeof(afs_int32);
343 /* copy in cell name, null terminated */
344 strcpy(tp, server.cell);
345 tp += strlen(server.cell) + 1;
347 /* finally setup the pioctl call's parameters */
348 blob.in_size = tp - space;
352 code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
363 register struct cmd_syndesc *as;
366 register struct hostent *the;
367 char *tp, *sysname = 0;
369 register afs_int32 code;
371 the = (struct hostent *)
372 hostutil_GetHostByName(tp = as->parms[0].items->data);
374 printf("knfs: unknown host '%s'.\n", tp);
377 memcpy(&addr, the->h_addr, sizeof(afs_int32));
379 if (as->parms[1].items) {
380 code = util_GetInt32(tp = as->parms[1].items->data, &uid);
382 printf("knfs: can't parse '%s' as a number (UID)\n", tp);
386 uid = -1; /* means wildcard: match any user on this host */
389 * If not "-id" is passed then we use the getuid() id, unless it's root
390 * that is doing it in which case we only authenticate as "system:anyuser"
391 * as it's appropriate for root. (The cm handles conversions from 0 to
398 if (as->parms[2].items) {
399 sysname = as->parms[2].items->data;
402 if (as->parms[4].items) {
403 /* tokens specified */
404 code = GetTokens(addr, uid);
408 ("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
410 printf("knfs: failed to get tokens for uid %d (code %d)\n",
416 /* finally, parsing is done, make the call */
417 if (as->parms[3].items) {
418 /* unlog specified */
419 code = NFSUnlog(addr, uid);
423 ("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
425 printf("knfs: failed to unlog (code %d)\n", code);
428 code = NFSCopyToken(addr, uid);
432 ("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
434 printf("knfs: failed to copy tokens (code %d)\n", code);
437 code = SetSysname(addr, uid, sysname);
439 printf("knfs: failed to set client's @sys to %s (code %d)\n",
447 #include "AFS_component_version_number.c"
453 register struct cmd_syndesc *ts;
454 register afs_int32 code;
458 * The following signal action for AIX is necessary so that in case of a
459 * crash (i.e. core is generated) we can include the user's data section
460 * in the core dump. Unfortunately, by default, only a partial core is
461 * generated which, in many cases, isn't too useful.
463 struct sigaction nsa;
465 sigemptyset(&nsa.sa_mask);
466 nsa.sa_handler = SIG_DFL;
467 nsa.sa_flags = SA_FULLDUMP;
468 sigaction(SIGABRT, &nsa, NULL);
469 sigaction(SIGSEGV, &nsa, NULL);
472 ts = cmd_CreateSyntax(NULL, cmdproc, 0, "copy tickets for NFS");
473 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_REQUIRED, "host name");
474 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "user ID (decimal)");
475 cmd_AddParm(ts, "-sysname", CMD_SINGLE, CMD_OPTIONAL,
476 "host's '@sys' value");
477 cmd_AddParm(ts, "-unlog", CMD_FLAG, CMD_OPTIONAL, "unlog remote user");
478 cmd_AddParm(ts, "-tokens", CMD_FLAG, CMD_OPTIONAL,
479 "display all tokens for remote [host,id]");
481 code = cmd_Dispatch(argc, argv);