1 /* Copyright (C) 1998 Transarc Corporation - All rights reserved */
3 * (C) COPYRIGHT TRANSARC CORPORATION 1989
4 * LICENSED MATERIALS - PROPERTY OF TRANSARC
11 #include <sys/types.h>
18 #include <sys/ioctl.h>
22 #include <afs/afsutil.h>
25 extern struct cmd_syndesc *cmd_CreateSyntax();
30 29 Oct 1992 Patch GetTokens to print something reasonable when there are no tokens.
34 /* this is a structure used to communicate with the afs cache mgr, but is
35 * otherwise irrelevant, or worse.
41 afs_int32 BeginTimestamp;
42 afs_int32 EndTimestamp;
46 static SetSysname(ahost, auid, sysname)
53 char space[1200], *tp;
54 struct ViceIoctl blob;
57 /* otherwise we've got the token, now prepare to build the pioctl args */
60 pheader[2] = 0; /* group low */
61 pheader[3] = 0; /* group high */
62 pheader[4] = 38/*VIOC_AFS_SYSNAME*/;/* sysname pioctl index */
63 pheader[5] = 1; /* NFS protocol exporter # */
66 bcopy(pheader, space, sizeof(pheader));
67 tp = space + sizeof(pheader);
69 /* finally setup the pioctl call's parameters */
70 blob.in_size = sizeof(pheader);
73 blob.out = (char *) 0;
74 bcopy(&setp, tp, sizeof(afs_int32));
75 tp += sizeof(afs_int32);
77 blob.in_size += sizeof(afs_int32) + strlen(sysname) + 1;
78 tp += strlen(sysname);
80 code = pioctl((char *) 0, _VICEIOCTL(99), &blob, 0);
88 static GetTokens(ahost, auid)
95 register afs_int32 code;
97 char *stp; /* secret token ptr */
100 afs_int32 temp, gotit = 0;
101 int maxLen; /* biggest ticket we can copy */
102 int tktLen; /* server ticket length */
103 time_t tokenExpireTime;
105 struct ktc_token token;
106 struct ktc_principal clientName;
110 current_time = time(0);
112 /* otherwise we've got the token, now prepare to build the pioctl args */
115 pheader[2] = 0; /* group low */
116 pheader[3] = 0; /* group high */
117 pheader[4] = 8; /* gettoken pioctl index */
118 pheader[5] = 1; /* NFS protocol exporter # */
120 for (index=0; index<200; index++) { /* sanity check in case pioctl fails */
121 code = ktc_ListTokens(index, &newIndex, &clientName);
123 if (code == KTC_NOENT) {
126 printf("knfs: there are no tokens here.\n");
129 break; /* done, but failed */
131 if (strcmp(clientName.name, "afs") != 0) continue; /* wrong ticket service */
134 bcopy(pheader, tbuffer, sizeof(pheader));
135 tp = tbuffer + sizeof(pheader);
136 bcopy(&index, tp, sizeof(afs_int32));
137 tp += sizeof(afs_int32);
139 iob.in_size = sizeof(afs_int32) + sizeof(pheader);
141 iob.out_size = sizeof(tbuffer);
142 code = pioctl((char *)0, _VICEIOCTL(99), &iob, 0);
143 if (code < 0 && errno == EDOM) return KTC_NOENT;
144 else if (code == 0) {
145 /* check to see if this is the right cell/realm */
147 bcopy(tp, &temp, sizeof(afs_int32)); /* get size of secret token */
148 tktLen = temp; /* remember size of ticket */
149 tp += sizeof(afs_int32);
150 stp = tp; /* remember where ticket is, for later */
151 tp += temp; /* skip ticket for now */
152 bcopy(tp, &temp, sizeof(afs_int32)); /* get size of clear token */
153 if (temp != sizeof(struct ClearToken)) return KTC_ERROR;
154 tp += sizeof(afs_int32); /* skip length */
155 bcopy(tp, &ct, temp); /* copy token for later use */
156 tp += temp; /* skip clear token itself */
157 tp += sizeof(afs_int32); /* skip primary flag */
158 /* tp now points to the cell name */
159 if (strcmp(tp, clientName.cell) == 0) {
160 /* closing in now, we've got the right cell */
162 maxLen = sizeof(token) - sizeof(struct ktc_token) + MAXKTCTICKETLEN;
163 if (maxLen < tktLen) return KTC_TOOBIG;
164 bcopy(stp, token.ticket, tktLen);
165 token.startTime = ct.BeginTimestamp;
166 token.endTime = ct.EndTimestamp;
167 if (ct.AuthHandle == -1) ct.AuthHandle = 999;
168 token.kvno = ct.AuthHandle;
169 bcopy(ct.HandShakeKey, &token.sessionKey, sizeof(struct ktc_encryptionKey));
170 token.ticketLen = tktLen;
171 if ((token.kvno == 999) || /* old style bcrypt ticket */
172 (ct.BeginTimestamp && /* new w/ prserver lookup */
173 (((ct.EndTimestamp - ct.BeginTimestamp) & 1) == 1))) {
174 sprintf(clientName.name, "AFS ID %d", ct.ViceId);
175 clientName.instance[0] = 0;
177 sprintf(clientName.name, "Unix UID %d", ct.ViceId);
178 clientName.instance[0] = 0;
180 strcpy(clientName.cell, tp);
182 tokenExpireTime = token.endTime;
183 strcpy(UserName, clientName.name);
184 if (clientName.instance[0] != 0) {
185 strcat(UserName, ".");
186 strcat(UserName, clientName.instance);
188 if (UserName[0] == 0)
190 else if (strncmp(UserName, "AFS ID", 6) == 0) {
191 printf("User's (%s) tokens", UserName);
193 else if (strncmp(UserName, "Unix UID", 8) == 0) {
196 printf("User %s's tokens", UserName);
197 printf(" for %s%s%s@%s ",
199 clientName.instance[0] ? "." : "",
202 if (tokenExpireTime <= current_time)
203 printf("[>> Expired <<]\n");
205 expireString = ctime(&tokenExpireTime);
206 expireString += 4; /*Move past the day of week*/
207 expireString[12] = '\0';
208 printf("[Expires %s]\n", expireString);
218 static NFSUnlog(ahost, auid)
222 afs_int32 pheader[6];
224 struct ViceIoctl blob;
226 /* otherwise we've got the token, now prepare to build the pioctl args */
229 pheader[2] = 0; /* group low */
230 pheader[3] = 0; /* group high */
231 pheader[4] = 9; /* unlog pioctl index */
232 pheader[5] = 1; /* NFS protocol exporter # */
235 bcopy(pheader, space, sizeof(pheader));
237 /* finally setup the pioctl call's parameters */
238 blob.in_size = sizeof(pheader);
241 blob.out = (char *) 0;
242 code = pioctl((char *) 0, _VICEIOCTL(99), &blob, 0);
249 /* Copy the AFS service token into the kernel for a particular host and user */
250 static NFSCopyToken(ahost, auid)
253 struct ktc_principal client, server;
254 struct ktc_token theTicket;
256 afs_int32 pheader[6];
258 struct ClearToken ct;
259 afs_int32 index, newIndex;
260 afs_int32 temp; /* for bcopy */
262 struct ViceIoctl blob;
264 for(index = 0;; index = newIndex) {
265 code = ktc_ListTokens(index, &newIndex, &server);
267 if (code == KTC_NOENT) {
271 break; /* done, but failed */
273 if (strcmp(server.name, "afs") != 0) continue; /* wrong ticket service */
274 code = ktc_GetToken(&server, &theTicket, sizeof(theTicket), &client);
275 if (code) return code;
277 /* otherwise we've got the token, now prepare to build the pioctl args */
280 pheader[2] = 0; /* group low */
281 pheader[3] = 0; /* group high */
282 pheader[4] = 3; /* set token pioctl index */
283 pheader[5] = 1; /* NFS protocol exporter # */
285 /* copy in the header */
286 bcopy(pheader, space, sizeof(pheader));
287 tp = space + sizeof(pheader);
288 /* copy in the size of the encrypted part */
289 bcopy(&theTicket.ticketLen, tp, sizeof(afs_int32));
290 tp += sizeof(afs_int32);
291 /* copy in the ticket itself */
292 bcopy(theTicket.ticket, tp, theTicket.ticketLen);
293 tp += theTicket.ticketLen;
294 /* copy in "clear token"'s size */
295 temp = sizeof(struct ClearToken);
296 bcopy(&temp, tp, sizeof(afs_int32));
297 tp += sizeof(afs_int32);
298 /* create the clear token and copy *it* in */
299 ct.AuthHandle = theTicket.kvno; /* where we hide the key version # */
300 bcopy(&theTicket.sessionKey, ct.HandShakeKey, sizeof(ct.HandShakeKey));
303 ct.BeginTimestamp = theTicket.startTime;
304 ct.EndTimestamp = theTicket.endTime;
305 bcopy(&ct, tp, sizeof(ct));
307 /* copy in obsolete primary flag */
309 bcopy(&temp, tp, sizeof(afs_int32));
310 tp += sizeof(afs_int32);
311 /* copy in cell name, null terminated */
312 strcpy(tp, server.cell);
313 tp += strlen(server.cell)+1;
315 /* finally setup the pioctl call's parameters */
316 blob.in_size = tp-space;
319 blob.out = (char *) 0;
320 code = pioctl((char *) 0, _VICEIOCTL(99), &blob, 0);
329 static cmdproc(as, arock)
330 register struct cmd_syndesc *as;
332 register struct hostent *the;
333 char *tp, *sysname = 0;
335 register afs_int32 code;
337 the = (struct hostent *)
338 hostutil_GetHostByName(tp = as->parms[0].items->data);
340 printf("knfs: unknown host '%s'.\n", tp);
343 bcopy(the->h_addr, &addr, sizeof(afs_int32));
345 if (as->parms[1].items) {
346 code = util_GetInt32(tp = as->parms[1].items->data, &uid);
348 printf("knfs: can't parse '%s' as a number (UID)\n", tp);
352 else uid = -1; /* means wildcard: match any user on this host */
355 * If not "-id" is passed then we use the getuid() id, unless it's root
356 * that is doing it in which case we only authenticate as "system:anyuser"
357 * as it's appropriate for root. (The cm handles conversions from 0 to
364 if (as->parms[2].items) {
365 sysname = as->parms[2].items->data;
368 if (as->parms[4].items) {
369 /* tokens specified */
370 code = GetTokens(addr, uid);
373 printf("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
375 printf("knfs: failed to get tokens for uid %d (code %d)\n", uid, code);
380 /* finally, parsing is done, make the call */
381 if (as->parms[3].items) {
382 /* unlog specified */
383 code = NFSUnlog(addr, uid);
386 printf("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
388 printf("knfs: failed to unlog (code %d)\n", code);
392 code = NFSCopyToken(addr, uid);
395 printf("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
397 printf("knfs: failed to copy tokens (code %d)\n", code);
400 code = SetSysname(addr, uid, sysname);
402 printf("knfs: failed to set client's @sys to %s (code %d)\n", sysname, code);
409 #include "AFS_component_version_number.c"
414 register struct cmd_syndesc *ts;
415 register afs_int32 code;
419 * The following signal action for AIX is necessary so that in case of a
420 * crash (i.e. core is generated) we can include the user's data section
421 * in the core dump. Unfortunately, by default, only a partial core is
422 * generated which, in many cases, isn't too useful.
424 struct sigaction nsa;
426 sigemptyset(&nsa.sa_mask);
427 nsa.sa_handler = SIG_DFL;
428 nsa.sa_flags = SA_FULLDUMP;
429 sigaction(SIGABRT, &nsa, NULL);
430 sigaction(SIGSEGV, &nsa, NULL);
433 ts = cmd_CreateSyntax((char *) 0, cmdproc, 0, "copy tickets for NFS");
434 cmd_AddParm(ts, "-host", CMD_SINGLE, CMD_REQUIRED, "host name");
435 cmd_AddParm(ts, "-id", CMD_SINGLE, CMD_OPTIONAL, "user ID (decimal)");
436 cmd_AddParm(ts, "-sysname", CMD_SINGLE, CMD_OPTIONAL, "host's '@sys' value");
437 cmd_AddParm(ts, "-unlog", CMD_FLAG, CMD_OPTIONAL, "unlog remote user");
438 cmd_AddParm(ts, "-tokens", CMD_FLAG, CMD_OPTIONAL, "display all tokens for remote [host,id]");
440 code = cmd_Dispatch(argc, argv);