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>
21 #include <sys/types.h>
28 #include <sys/ioctl.h>
39 #include <afs/afsutil.h>
42 extern struct cmd_syndesc *cmd_CreateSyntax();
47 29 Oct 1992 Patch GetTokens to print something reasonable when there are no tokens.
51 /* this is a structure used to communicate with the afs cache mgr, but is
52 * otherwise irrelevant, or worse.
58 afs_int32 BeginTimestamp;
59 afs_int32 EndTimestamp;
63 static SetSysname(ahost, auid, sysname)
70 char space[1200], *tp;
71 struct ViceIoctl blob;
74 /* otherwise we've got the token, now prepare to build the pioctl args */
77 pheader[2] = 0; /* group low */
78 pheader[3] = 0; /* group high */
79 pheader[4] = 38/*VIOC_AFS_SYSNAME*/;/* sysname pioctl index */
80 pheader[5] = 1; /* NFS protocol exporter # */
83 memcpy(space, pheader, sizeof(pheader));
84 tp = space + sizeof(pheader);
86 /* finally setup the pioctl call's parameters */
87 blob.in_size = sizeof(pheader);
91 memcpy(tp, &setp, sizeof(afs_int32));
92 tp += sizeof(afs_int32);
94 blob.in_size += sizeof(afs_int32) + strlen(sysname) + 1;
95 tp += strlen(sysname);
97 code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
105 static GetTokens(ahost, auid)
109 struct ViceIoctl iob;
110 afs_int32 pheader[6];
112 register afs_int32 code;
114 char *stp; /* secret token ptr */
115 struct ClearToken ct;
117 afs_int32 temp, gotit = 0;
118 int maxLen; /* biggest ticket we can copy */
119 int tktLen; /* server ticket length */
120 time_t tokenExpireTime;
122 struct ktc_token token;
123 struct ktc_principal clientName;
127 current_time = time(0);
129 /* otherwise we've got the token, now prepare to build the pioctl args */
132 pheader[2] = 0; /* group low */
133 pheader[3] = 0; /* group high */
134 pheader[4] = 8; /* gettoken pioctl index */
135 pheader[5] = 1; /* NFS protocol exporter # */
137 for (index=0; index<200; index++) { /* sanity check in case pioctl fails */
138 code = ktc_ListTokens(index, &newIndex, &clientName);
140 if (code == KTC_NOENT) {
143 printf("knfs: there are no tokens here.\n");
146 break; /* done, but failed */
148 if (strcmp(clientName.name, "afs") != 0) continue; /* wrong ticket service */
151 memcpy(tbuffer, pheader, sizeof(pheader));
152 tp = tbuffer + sizeof(pheader);
153 memcpy(tp, &index, sizeof(afs_int32));
154 tp += sizeof(afs_int32);
156 iob.in_size = sizeof(afs_int32) + sizeof(pheader);
158 iob.out_size = sizeof(tbuffer);
159 code = pioctl(NULL, _VICEIOCTL(99), &iob, 0);
160 if (code < 0 && errno == EDOM) return KTC_NOENT;
161 else if (code == 0) {
162 /* check to see if this is the right cell/realm */
164 memcpy(&temp, tp, sizeof(afs_int32)); /* get size of secret token */
165 tktLen = temp; /* remember size of ticket */
166 tp += sizeof(afs_int32);
167 stp = tp; /* remember where ticket is, for later */
168 tp += temp; /* skip ticket for now */
169 memcpy(&temp, tp, sizeof(afs_int32)); /* get size of clear token */
170 if (temp != sizeof(struct ClearToken)) return KTC_ERROR;
171 tp += sizeof(afs_int32); /* skip length */
172 memcpy(&ct, tp, temp); /* copy token for later use */
173 tp += temp; /* skip clear token itself */
174 tp += sizeof(afs_int32); /* skip primary flag */
175 /* tp now points to the cell name */
176 if (strcmp(tp, clientName.cell) == 0) {
177 /* closing in now, we've got the right cell */
179 maxLen = sizeof(token) - sizeof(struct ktc_token) + MAXKTCTICKETLEN;
180 if (maxLen < tktLen) return KTC_TOOBIG;
181 memcpy(token.ticket, stp, tktLen);
182 token.startTime = ct.BeginTimestamp;
183 token.endTime = ct.EndTimestamp;
184 if (ct.AuthHandle == -1) ct.AuthHandle = 999;
185 token.kvno = ct.AuthHandle;
186 memcpy(&token.sessionKey, ct.HandShakeKey, sizeof(struct ktc_encryptionKey));
187 token.ticketLen = tktLen;
188 if ((token.kvno == 999) || /* old style bcrypt ticket */
189 (ct.BeginTimestamp && /* new w/ prserver lookup */
190 (((ct.EndTimestamp - ct.BeginTimestamp) & 1) == 1))) {
191 sprintf(clientName.name, "AFS ID %d", ct.ViceId);
192 clientName.instance[0] = 0;
194 sprintf(clientName.name, "Unix UID %d", ct.ViceId);
195 clientName.instance[0] = 0;
197 strcpy(clientName.cell, tp);
199 tokenExpireTime = token.endTime;
200 strcpy(UserName, clientName.name);
201 if (clientName.instance[0] != 0) {
202 strcat(UserName, ".");
203 strcat(UserName, clientName.instance);
205 if (UserName[0] == 0)
207 else if (strncmp(UserName, "AFS ID", 6) == 0) {
208 printf("User's (%s) tokens", UserName);
210 else if (strncmp(UserName, "Unix UID", 8) == 0) {
213 printf("User %s's tokens", UserName);
214 printf(" for %s%s%s@%s ",
216 clientName.instance[0] ? "." : "",
219 if (tokenExpireTime <= current_time)
220 printf("[>> Expired <<]\n");
222 expireString = ctime(&tokenExpireTime);
223 expireString += 4; /*Move past the day of week*/
224 expireString[12] = '\0';
225 printf("[Expires %s]\n", expireString);
235 static NFSUnlog(ahost, auid)
239 afs_int32 pheader[6];
241 struct ViceIoctl blob;
243 /* otherwise we've got the token, now prepare to build the pioctl args */
246 pheader[2] = 0; /* group low */
247 pheader[3] = 0; /* group high */
248 pheader[4] = 9; /* unlog pioctl index */
249 pheader[5] = 1; /* NFS protocol exporter # */
252 memcpy(space, pheader, sizeof(pheader));
254 /* finally setup the pioctl call's parameters */
255 blob.in_size = sizeof(pheader);
259 code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
266 /* Copy the AFS service token into the kernel for a particular host and user */
267 static NFSCopyToken(ahost, auid)
270 struct ktc_principal client, server;
271 struct ktc_token theTicket;
273 afs_int32 pheader[6];
275 struct ClearToken ct;
276 afs_int32 index, newIndex;
277 afs_int32 temp; /* for bcopy */
279 struct ViceIoctl blob;
281 for(index = 0;; index = newIndex) {
282 code = ktc_ListTokens(index, &newIndex, &server);
284 if (code == KTC_NOENT) {
288 break; /* done, but failed */
290 if (strcmp(server.name, "afs") != 0) continue; /* wrong ticket service */
291 code = ktc_GetToken(&server, &theTicket, sizeof(theTicket), &client);
292 if (code) return code;
294 /* otherwise we've got the token, now prepare to build the pioctl args */
297 pheader[2] = 0; /* group low */
298 pheader[3] = 0; /* group high */
299 pheader[4] = 3; /* set token pioctl index */
300 pheader[5] = 1; /* NFS protocol exporter # */
302 /* copy in the header */
303 memcpy(space, pheader, sizeof(pheader));
304 tp = space + sizeof(pheader);
305 /* copy in the size of the encrypted part */
306 memcpy(tp, &theTicket.ticketLen, sizeof(afs_int32));
307 tp += sizeof(afs_int32);
308 /* copy in the ticket itself */
309 memcpy(tp, theTicket.ticket, theTicket.ticketLen);
310 tp += theTicket.ticketLen;
311 /* copy in "clear token"'s size */
312 temp = sizeof(struct ClearToken);
313 memcpy(tp, &temp, sizeof(afs_int32));
314 tp += sizeof(afs_int32);
315 /* create the clear token and copy *it* in */
316 ct.AuthHandle = theTicket.kvno; /* where we hide the key version # */
317 memcpy(ct.HandShakeKey, &theTicket.sessionKey, sizeof(ct.HandShakeKey));
320 ct.BeginTimestamp = theTicket.startTime;
321 ct.EndTimestamp = theTicket.endTime;
322 memcpy(tp, &ct, sizeof(ct));
324 /* copy in obsolete primary flag */
326 memcpy(tp, &temp, sizeof(afs_int32));
327 tp += sizeof(afs_int32);
328 /* copy in cell name, null terminated */
329 strcpy(tp, server.cell);
330 tp += strlen(server.cell)+1;
332 /* finally setup the pioctl call's parameters */
333 blob.in_size = tp-space;
337 code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
346 static cmdproc(as, arock)
347 register struct cmd_syndesc *as;
349 register struct hostent *the;
350 char *tp, *sysname = 0;
352 register afs_int32 code;
354 the = (struct hostent *)
355 hostutil_GetHostByName(tp = as->parms[0].items->data);
357 printf("knfs: unknown host '%s'.\n", tp);
360 memcpy(&addr, the->h_addr, sizeof(afs_int32));
362 if (as->parms[1].items) {
363 code = util_GetInt32(tp = as->parms[1].items->data, &uid);
365 printf("knfs: can't parse '%s' as a number (UID)\n", tp);
369 else uid = -1; /* means wildcard: match any user on this host */
372 * If not "-id" is passed then we use the getuid() id, unless it's root
373 * that is doing it in which case we only authenticate as "system:anyuser"
374 * as it's appropriate for root. (The cm handles conversions from 0 to
381 if (as->parms[2].items) {
382 sysname = as->parms[2].items->data;
385 if (as->parms[4].items) {
386 /* tokens specified */
387 code = GetTokens(addr, uid);
390 printf("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
392 printf("knfs: failed to get tokens for uid %d (code %d)\n", uid, code);
397 /* finally, parsing is done, make the call */
398 if (as->parms[3].items) {
399 /* unlog specified */
400 code = NFSUnlog(addr, uid);
403 printf("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
405 printf("knfs: failed to unlog (code %d)\n", code);
409 code = NFSCopyToken(addr, uid);
412 printf("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
414 printf("knfs: failed to copy tokens (code %d)\n", code);
417 code = SetSysname(addr, uid, sysname);
419 printf("knfs: failed to set client's @sys to %s (code %d)\n", sysname, code);
426 #include "AFS_component_version_number.c"
431 register struct cmd_syndesc *ts;
432 register afs_int32 code;
436 * The following signal action for AIX is necessary so that in case of a
437 * crash (i.e. core is generated) we can include the user's data section
438 * in the core dump. Unfortunately, by default, only a partial core is
439 * generated which, in many cases, isn't too useful.
441 struct sigaction nsa;
443 sigemptyset(&nsa.sa_mask);
444 nsa.sa_handler = SIG_DFL;
445 nsa.sa_flags = SA_FULLDUMP;
446 sigaction(SIGABRT, &nsa, NULL);
447 sigaction(SIGSEGV, &nsa, NULL);
450 ts = cmd_CreateSyntax(NULL, cmdproc, 0, "copy tickets for NFS");
451 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_REQUIRED, "host name");
452 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "user ID (decimal)");
453 cmd_AddParm(ts, "-sysname", CMD_SINGLE, CMD_OPTIONAL, "host's '@sys' value");
454 cmd_AddParm(ts, "-unlog", CMD_FLAG, CMD_OPTIONAL, "unlog remote user");
455 cmd_AddParm(ts, "-tokens", CMD_FLAG, CMD_OPTIONAL, "display all tokens for remote [host,id]");
457 code = cmd_Dispatch(argc, argv);