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>
25 #include <afs/afsutil.h>
26 #include <afs/sys_prototypes.h>
31 29 Oct 1992 Patch GetTokens to print something reasonable when there are no tokens.
35 /* this is a structure used to communicate with the afs cache mgr, but is
36 * otherwise irrelevant, or worse.
42 afs_int32 BeginTimestamp
;
43 afs_int32 EndTimestamp
;
48 SetSysname(afs_int32 ahost
, afs_int32 auid
, char *sysname
)
52 char space
[1200], *tp
;
53 struct ViceIoctl blob
;
56 /* otherwise we've got the token, now prepare to build the pioctl args */
59 pheader
[2] = 0; /* group low */
60 pheader
[3] = 0; /* group high */
61 pheader
[4] = 38 /*VIOC_AFS_SYSNAME */ ; /* sysname pioctl index */
62 pheader
[5] = 1; /* NFS protocol exporter # */
65 memcpy(space
, pheader
, sizeof(pheader
));
66 tp
= space
+ sizeof(pheader
);
68 /* finally setup the pioctl call's parameters */
69 blob
.in_size
= sizeof(pheader
);
73 memcpy(tp
, &setp
, sizeof(afs_int32
));
74 tp
+= sizeof(afs_int32
);
76 blob
.in_size
+= sizeof(afs_int32
) + strlen(sysname
) + 1;
77 tp
+= strlen(sysname
);
79 code
= pioctl(NULL
, _VICEIOCTL(99), &blob
, 0);
88 GetTokens(afs_int32 ahost
, afs_int32 auid
)
95 char *stp
; /* secret token ptr */
98 afs_int32 temp
, gotit
= 0;
99 int maxLen
; /* biggest ticket we can copy */
100 int tktLen
; /* server ticket length */
101 time_t tokenExpireTime
;
102 char UserName
[MAXKTCNAMELEN
+ MAXKTCNAMELEN
];
103 struct ktc_token token
;
104 struct ktc_principal clientName
;
108 current_time
= time(0);
110 /* otherwise we've got the token, now prepare to build the pioctl args */
113 pheader
[2] = 0; /* group low */
114 pheader
[3] = 0; /* group high */
115 pheader
[4] = 8; /* gettoken pioctl index */
116 pheader
[5] = 1; /* NFS protocol exporter # */
118 for (index
= 0; index
< 200; index
++) { /* sanity check in case pioctl fails */
119 code
= ktc_ListTokens(index
, &newIndex
, &clientName
);
121 if (code
== KTC_NOENT
) {
124 printf("knfs: there are no tokens here.\n");
127 break; /* done, but failed */
129 if (strcmp(clientName
.name
, "afs") != 0)
130 continue; /* wrong ticket service */
133 memcpy(tbuffer
, pheader
, sizeof(pheader
));
134 tp
= tbuffer
+ sizeof(pheader
);
135 memcpy(tp
, &index
, sizeof(afs_int32
));
136 tp
+= sizeof(afs_int32
);
138 iob
.in_size
= sizeof(afs_int32
) + sizeof(pheader
);
140 iob
.out_size
= sizeof(tbuffer
);
141 code
= pioctl(NULL
, _VICEIOCTL(99), &iob
, 0);
142 if (code
< 0 && errno
== EDOM
)
144 else if (code
== 0) {
145 /* check to see if this is the right cell/realm */
147 memcpy(&temp
, tp
, 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 memcpy(&temp
, tp
, sizeof(afs_int32
)); /* get size of clear token */
153 if (temp
!= sizeof(struct ClearToken
))
155 tp
+= sizeof(afs_int32
); /* skip length */
156 memcpy(&ct
, tp
, temp
); /* copy token for later use */
157 tp
+= temp
; /* skip clear token itself */
158 tp
+= sizeof(afs_int32
); /* skip primary flag */
159 /* tp now points to the cell name */
160 if (strcmp(tp
, clientName
.cell
) == 0) {
161 /* closing in now, we've got the right cell */
164 sizeof(token
) - sizeof(struct ktc_token
) +
166 if (tktLen
< 0 || tktLen
> maxLen
)
168 memcpy(token
.ticket
, stp
, tktLen
);
169 token
.startTime
= ct
.BeginTimestamp
;
170 token
.endTime
= ct
.EndTimestamp
;
171 if (ct
.AuthHandle
== -1)
173 token
.kvno
= ct
.AuthHandle
;
174 memcpy(&token
.sessionKey
, ct
.HandShakeKey
,
175 sizeof(struct ktc_encryptionKey
));
176 token
.ticketLen
= tktLen
;
177 if ((token
.kvno
== 999) || /* old style bcrypt ticket */
178 (ct
.BeginTimestamp
&& /* new w/ prserver lookup */
179 (((ct
.EndTimestamp
- ct
.BeginTimestamp
) & 1) == 1))) {
180 sprintf(clientName
.name
, "AFS ID %d", ct
.ViceId
);
181 clientName
.instance
[0] = 0;
183 sprintf(clientName
.name
, "Unix UID %d", ct
.ViceId
);
184 clientName
.instance
[0] = 0;
186 strlcpy(clientName
.cell
, tp
, sizeof(clientName
.cell
));
188 tokenExpireTime
= token
.endTime
;
189 strlcpy(UserName
, clientName
.name
, sizeof(UserName
));
190 if (clientName
.instance
[0] != 0) {
191 strlcat(UserName
, ".", sizeof(UserName
));
192 strlcat(UserName
, clientName
.instance
, sizeof(UserName
));
194 if (UserName
[0] == 0)
196 else if (strncmp(UserName
, "AFS ID", 6) == 0) {
197 printf("User's (%s) tokens", UserName
);
198 } else if (strncmp(UserName
, "Unix UID", 8) == 0) {
201 printf("User %s's tokens", UserName
);
202 printf(" for %s%s%s@%s ", clientName
.name
,
203 clientName
.instance
[0] ? "." : "", clientName
.instance
,
205 if (tokenExpireTime
<= current_time
)
206 printf("[>> Expired <<]\n");
208 expireString
= ctime(&tokenExpireTime
);
209 expireString
+= 4; /*Move past the day of week */
210 expireString
[12] = '\0';
211 printf("[Expires %s]\n", expireString
);
222 NFSUnlog(afs_int32 ahost
, afs_int32 auid
)
225 afs_int32 pheader
[6];
227 struct ViceIoctl blob
;
229 /* otherwise we've got the token, now prepare to build the pioctl args */
232 pheader
[2] = 0; /* group low */
233 pheader
[3] = 0; /* group high */
234 pheader
[4] = 9; /* unlog pioctl index */
235 pheader
[5] = 1; /* NFS protocol exporter # */
238 memcpy(space
, pheader
, sizeof(pheader
));
240 /* finally setup the pioctl call's parameters */
241 blob
.in_size
= sizeof(pheader
);
245 code
= pioctl(NULL
, _VICEIOCTL(99), &blob
, 0);
252 /* Copy the AFS service token into the kernel for a particular host and user */
254 NFSCopyToken(afs_int32 ahost
, afs_int32 auid
)
256 struct ktc_principal client
, server
;
257 struct ktc_token theTicket
;
259 afs_int32 pheader
[6];
261 struct ClearToken ct
;
262 afs_int32 index
, newIndex
;
263 afs_int32 temp
; /* for bcopy */
265 struct ViceIoctl blob
;
267 for (index
= 0;; index
= newIndex
) {
268 code
= ktc_ListTokens(index
, &newIndex
, &server
);
270 if (code
== KTC_NOENT
) {
274 break; /* done, but failed */
276 if (strcmp(server
.name
, "afs") != 0)
277 continue; /* wrong ticket service */
278 code
= ktc_GetToken(&server
, &theTicket
, sizeof(theTicket
), &client
);
282 /* otherwise we've got the token, now prepare to build the pioctl args */
285 pheader
[2] = 0; /* group low */
286 pheader
[3] = 0; /* group high */
287 pheader
[4] = 3; /* set token pioctl index */
288 pheader
[5] = 1; /* NFS protocol exporter # */
290 /* copy in the header */
291 memcpy(space
, pheader
, sizeof(pheader
));
292 tp
= space
+ sizeof(pheader
);
293 /* copy in the size of the encrypted part */
294 memcpy(tp
, &theTicket
.ticketLen
, sizeof(afs_int32
));
295 tp
+= sizeof(afs_int32
);
296 /* copy in the ticket itself */
297 memcpy(tp
, theTicket
.ticket
, theTicket
.ticketLen
);
298 tp
+= theTicket
.ticketLen
;
299 /* copy in "clear token"'s size */
300 temp
= sizeof(struct ClearToken
);
301 memcpy(tp
, &temp
, sizeof(afs_int32
));
302 tp
+= sizeof(afs_int32
);
303 /* create the clear token and copy *it* in */
304 ct
.AuthHandle
= theTicket
.kvno
; /* where we hide the key version # */
305 memcpy(ct
.HandShakeKey
, &theTicket
.sessionKey
,
306 sizeof(ct
.HandShakeKey
));
309 ct
.BeginTimestamp
= theTicket
.startTime
;
310 ct
.EndTimestamp
= theTicket
.endTime
;
311 memcpy(tp
, &ct
, sizeof(ct
));
313 /* copy in obsolete primary flag */
315 memcpy(tp
, &temp
, sizeof(afs_int32
));
316 tp
+= sizeof(afs_int32
);
317 /* copy in cell name, null terminated */
318 strcpy(tp
, server
.cell
);
319 tp
+= strlen(server
.cell
) + 1;
321 /* finally setup the pioctl call's parameters */
322 blob
.in_size
= tp
- space
;
326 code
= pioctl(NULL
, _VICEIOCTL(99), &blob
, 0);
336 cmdproc(struct cmd_syndesc
*as
, void *arock
)
339 char *tp
, *sysname
= 0;
343 the
= (struct hostent
*)
344 hostutil_GetHostByName(tp
= as
->parms
[0].items
->data
);
346 printf("knfs: unknown host '%s'.\n", tp
);
349 memcpy(&addr
, the
->h_addr
, sizeof(afs_int32
));
351 if (as
->parms
[1].items
) {
352 code
= util_GetInt32(tp
= as
->parms
[1].items
->data
, &uid
);
354 printf("knfs: can't parse '%s' as a number (UID)\n", tp
);
358 uid
= -1; /* means wildcard: match any user on this host */
361 * If not "-id" is passed then we use the getuid() id, unless it's root
362 * that is doing it in which case we only authenticate as "system:anyuser"
363 * as it's appropriate for root. (The cm handles conversions from 0 to
370 if (as
->parms
[2].items
) {
371 sysname
= as
->parms
[2].items
->data
;
374 if (as
->parms
[4].items
) {
375 /* tokens specified */
376 code
= GetTokens(addr
, uid
);
380 ("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
382 printf("knfs: failed to get tokens for uid %d (code %d)\n",
388 /* finally, parsing is done, make the call */
389 if (as
->parms
[3].items
) {
390 /* unlog specified */
391 code
= NFSUnlog(addr
, uid
);
395 ("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
397 printf("knfs: failed to unlog (code %d)\n", code
);
400 code
= NFSCopyToken(addr
, uid
);
404 ("knfs: Translator in 'passwd sync' mode; remote uid must be the same as local uid\n");
406 printf("knfs: failed to copy tokens (code %d)\n", code
);
409 code
= SetSysname(addr
, uid
, sysname
);
411 printf("knfs: failed to set client's @sys to %s (code %d)\n",
419 #include "AFS_component_version_number.c"
422 main(int argc
, char **argv
)
424 struct cmd_syndesc
*ts
;
429 * The following signal action for AIX is necessary so that in case of a
430 * crash (i.e. core is generated) we can include the user's data section
431 * in the core dump. Unfortunately, by default, only a partial core is
432 * generated which, in many cases, isn't too useful.
434 struct sigaction nsa
;
436 sigemptyset(&nsa
.sa_mask
);
437 nsa
.sa_handler
= SIG_DFL
;
438 nsa
.sa_flags
= SA_FULLDUMP
;
439 sigaction(SIGABRT
, &nsa
, NULL
);
440 sigaction(SIGSEGV
, &nsa
, NULL
);
443 ts
= cmd_CreateSyntax(NULL
, cmdproc
, NULL
, 0, "copy tickets for NFS");
444 cmd_AddParm(ts
, "-host", CMD_SINGLE
, CMD_REQUIRED
, "host name");
445 cmd_AddParm(ts
, "-id", CMD_SINGLE
, CMD_OPTIONAL
, "user ID (decimal)");
446 cmd_AddParm(ts
, "-sysname", CMD_SINGLE
, CMD_OPTIONAL
,
447 "host's '@sys' value");
448 cmd_AddParm(ts
, "-unlog", CMD_FLAG
, CMD_OPTIONAL
, "unlog remote user");
449 cmd_AddParm(ts
, "-tokens", CMD_FLAG
, CMD_OPTIONAL
,
450 "display all tokens for remote [host,id]");
452 code
= cmd_Dispatch(argc
, argv
);