#include <afsconfig.h>
#include <afs/param.h>
-#if defined(UKERNEL)
-#include "afsincludes.h"
-#endif
+#include <roken.h>
-#ifdef AFS_SUN5_ENV
-#include <unistd.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
#include <afs/stds.h>
+#include <afs/opr.h>
#include <afs/pthread_glock.h>
-#include <sys/types.h>
#include <ctype.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <afs/vice.h>
+
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+
+#if defined(UKERNEL)
+#include "afsincludes.h"
+#endif
+
#ifdef AFS_AIX_ENV
#include <sys/lockf.h>
#ifdef AFS_AIX51_ENV
#endif
#endif
#endif
+
#ifdef HAVE_CRT_EXTERNS_H
#include <crt_externs.h>
#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+
+#include <afs/vice.h>
#include <afs/auth.h>
#include <afs/venus.h>
#include <afs/afsutil.h>
#include <afs/sys_prototypes.h>
#endif
-#include "token.h"
-
-#if defined(LINUX_KEYRING_SUPPORT) && defined(HAVE_SESSION_TO_PARENT)
+#if defined(AFS_LINUX26_ENV)
#include <sys/syscall.h>
+#if defined(SYS_keyctl)
+/* Open code this value to avoid a dependency on keyutils */
#define KEYCTL_SESSION_TO_PARENT 18
#endif
+#endif
-/* For malloc() */
-#include <stdlib.h>
+#include "token.h"
#include "ktc.h"
-#ifdef notdef
-/* AFS_KERBEROS_ENV is now conditionally defined in the Makefile */
-#define AFS_KERBEROS_ENV
-#endif
-
#ifdef AFS_KERBEROS_ENV
-#include <fcntl.h>
-#include <sys/file.h>
#include <afs/cellconfig.h>
static char lcell[MAXCELLCHARS];
#ifdef AFS_DUX40_ENV
#define PIOCTL afs_pioctl
#elif defined(UKERNEL)
-#define PIOCTL(A,B,C,D) call_syscall(AFSCALL_PIOCTL,A,B,C,D)
+#define PIOCTL(A,B,C,D) (errno = (call_syscall(AFSCALL_PIOCTL,A,B,C,D)), errno?-1:0)
#else
#define PIOCTL pioctl
#endif
0}, {
0}};
+static int
+GetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
+ int atokenLen, struct ktc_principal *alicnet, afs_int32 *aviceid);
+
#define MAXPIOCTLTOKENLEN \
(3*sizeof(afs_int32)+MAXKTCTICKETLEN+sizeof(struct ClearToken)+MAXKTCREALMLEN)
}
#else /* NO_AFS_CLIENT */
code = PIOCTL(0, VIOCSETTOK, &iob, 0);
-#if defined(LINUX_KEYRING_SUPPORT) && defined(HAVE_SESSION_TO_PARENT)
- /*
- * If we're using keyring based PAGs and the SESSION_TO_PARENT keyctl
- * is available, use it to copy the session keyring to the parent process
- */
- if (flags & AFS_SETTOK_SETPAG)
- syscall(SYS_keyctl, KEYCTL_SESSION_TO_PARENT);
-#endif
#endif /* NO_AFS_CLIENT */
if (code)
return KTC_PIOCTLFAIL;
if (code)
return KTC_PIOCTLFAIL;
+#if defined(AFS_LINUX26_ENV) && defined(SYS_keyctl)
+ else
+ /*
+ * If we're using keyring based PAGs and the SESSION_TO_PARENT keyctl
+ * is available, use it to copy the session keyring to the parent process
+ */
+ if (token->flags & AFS_SETTOK_SETPAG)
+ syscall(SYS_keyctl, KEYCTL_SESSION_TO_PARENT);
+#endif
return 0;
}
*/
if (code == -1 && errno == EINVAL) {
struct ktc_principal server;
- struct ktc_principal client;
struct ktc_tokenUnion token;
struct ktc_token *ktcToken; /* too huge for the stack */
+ afs_int32 viceid;
memset(&server, 0, sizeof(server));
ktcToken = malloc(sizeof(struct ktc_token));
strcpy(server.name, "afs");
strcpy(server.cell, cellName);
- code = ktc_GetToken(&server, ktcToken, sizeof(struct ktc_token),
- &client);
+ code = GetToken(&server, ktcToken, sizeof(struct ktc_token),
+ NULL /*client*/, &viceid);
if (code == 0) {
*tokenSet = token_buildTokenJar(cellName);
token.at_type = AFSTOKEN_UNION_KAD;
= ktcToken->ticketLen;
token.ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_val
= ktcToken->ticket;
+ token.ktc_tokenUnion_u.at_kad.rk_viceid = viceid;
token_addToken(*tokenSet, &token);
memset(ktcToken, 0, sizeof(struct ktc_token));
}
free(ktcToken);
+ return code;
}
if (code)
return KTC_PIOCTLFAIL;
ktc_GetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
int atokenLen, struct ktc_principal *aclient)
{
+ return GetToken(aserver, atoken, atokenLen, aclient, NULL);
+}
+
+static int
+GetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
+ int atokenLen, struct ktc_principal *aclient, afs_int32 *aviceid)
+{
struct ViceIoctl iob;
char tbuffer[MAXPIOCTLTOKENLEN];
afs_int32 code = 0;
#ifdef AFS_KERBEROS_ENV
char found = 0;
#endif
+ if (aviceid) {
+ *aviceid = 0;
+ }
LOCK_GLOBAL_MUTEX;
sizeof(struct ktc_encryptionKey));
atoken->ticketLen = tktLen;
- if (aclient) {
- strcpy(aclient->cell, cellp);
- aclient->instance[0] = 0;
+ if (aclient || aviceid) {
+ if (aclient) {
+ strcpy(aclient->cell, cellp);
+ aclient->instance[0] = 0;
+ }
if ((atoken->kvno == 999) || /* old style bcrypt ticket */
(ct.BeginTimestamp && /* new w/ prserver lookup */
(((ct.EndTimestamp - ct.BeginTimestamp) & 1) == 1))) {
- sprintf(aclient->name, "AFS ID %d", ct.ViceId);
- } else {
+ if (aclient) {
+ sprintf(aclient->name, "AFS ID %d", ct.ViceId);
+ }
+ if (aviceid) {
+ *aviceid = ct.ViceId;
+ }
+ } else if (aclient) {
sprintf(aclient->name, "Unix UID %d", ct.ViceId);
}
}
}
#endif /* NO_AFS_CLIENT */
+/*!
+ * An iterator which can list all cells with tokens in the cache
+ *
+ * This function may be used to list the names of all cells for which
+ * tokens exist in the current cache. The first time that it is called,
+ * prevIndex should be set to 0. On all subsequent calls, prevIndex
+ * should be set to the value returned in newIndex by the last call
+ * to the function. Note that there is no guarantee that the index value
+ * is monotonically increasing.
+ *
+ * @param prevIndex
+ * The index returned by the last call, or 0 if this is the first
+ * call in an iteration
+ * @param newIndex
+ * A pointer to an int which, upon return, will hold the next value
+ * to be used.
+ * @param cellName
+ * A pointer to a char * which, upon return, will hold a cellname.
+ * This must be freed by the caller using free()
+ */
+
+int
+ktc_ListTokensEx(int prevIndex, int *newIndex, char **cellName) {
+ struct ViceIoctl iob;
+ char tbuffer[MAXPIOCTLTOKENLEN];
+ afs_int32 code;
+ afs_int32 index;
+ struct ktc_setTokenData tokenSet;
+ XDR xdrs;
+
+ memset(&tokenSet, 0, sizeof(tokenSet));
+
+ *cellName = NULL;
+ *newIndex = prevIndex;
+
+ index = prevIndex;
+
+ while (index<100) { /* Safety, incase of pioctl failure */
+ memset(tbuffer, 0, sizeof(tbuffer));
+ iob.in = tbuffer;
+ memcpy(tbuffer, &index, sizeof(afs_int32));
+ iob.in_size = sizeof(afs_int32);
+ iob.out = tbuffer;
+ iob.out_size = sizeof(tbuffer);
+
+ code = PIOCTL(0, VIOC_GETTOK2, &iob, 0);
+
+ /* Can't use new pioctl, so must use old one */
+ if (code == -1 && errno == EINVAL) {
+ struct ktc_principal server;
+
+ code = ktc_ListTokens(index, newIndex, &server);
+ if (code == 0)
+ *cellName = strdup(server.cell);
+ return code;
+ }
+
+ if (code == 0) {
+ /* Got a token from the pioctl. Now we throw it away,
+ * so we can return just a cellname. This is rather wasteful,
+ * but it's what the old API does. Ho hum. */
+
+ xdrmem_create(&xdrs, iob.out, iob.out_size, XDR_DECODE);
+ if (!xdr_ktc_setTokenData(&xdrs, &tokenSet)) {
+ xdr_destroy(&xdrs);
+ return EINVAL;
+ }
+ xdr_destroy(&xdrs);
+ *cellName = strdup(tokenSet.cell);
+ xdr_free((xdrproc_t)xdr_ktc_setTokenData, &tokenSet);
+ *newIndex = index + 1;
+ return 0;
+ }
+ index++;
+ }
+ return KTC_PIOCTLFAIL;
+}
+
/* ktc_ListTokens - list all tokens. start aprevIndex at 0, it returns the
* next rock in (*aindex). (*aserver) is set to the relevant ticket on
* success. */