static void
idbg_pruser(struct unixuser *tu)
{
+ union tokenUnion *token;
+
+ token = afs_FindToken(tu->tokens, RX_SECIDX_KAD);
+
qprintf("@0x%x nxt 0x%x uid %d (0x%x) cell 0x%x vid 0x%x ref %d\n", tu,
tu->next, tu->uid, tu->uid, tu->cell, tu->vid, tu->refCount);
- qprintf("time %d stLen %d stp 0x%x exp 0x%x ", tu->tokenTime, tu->stLen,
- tu->stp, tu->exporter);
+ qprintf("time %dRX_SECIDX_KADstLen %d stp 0x%x exp 0x%x ", tu->tokenTime,
+ (token != NULL)?token->rxkad.ticketLen:0,
+ (token != NULL)?token->rxkad.ticket:NULL,
+ tu->exporter);
printflags(tu->states, tab_userstates);
qprintf("\n");
qprintf("ClearToken: handle 0x%x ViceID 0x%x Btime %d Etime %d\n",
- tu->ct.AuthHandle, tu->ct.ViceId, tu->ct.BeginTimestamp,
- tu->ct.EndTimestamp);
+ (token != NULL)?token->rxkad.clearToken.AuthHandle:0,
+ tu->vid,
+ (token != NULL)?token->rxkad.clearToken.BeginTimestamp:0,
+ (token != NULL)?token->rxkad.clearToken.EndTimestamp:0);
}
extern struct unixuser *afs_users[NUSERS];
{
struct cell *tc = 0;
struct unixuser *tu = p;
+ union tokenUnion *token;
char *cellname;
if (p == (void *)1) {
if (tc) afs_PutCell(tc, READ_LOCK);
if (tu->states & UHasTokens) {
+ token = afs_FindToken(tu->tokens, RX_SECIDX_KAD);
seq_printf(m, " %10d %10d %10d %3d",
- tu->tokenTime, tu->ct.BeginTimestamp, tu->ct.EndTimestamp,
- tu->ct.AuthHandle);
+ tu->tokenTime,
+ (token!=NULL)?token->rxkad.clearToken.BeginTimestamp:0,
+ (token!=NULL)?token->rxkad.clearToken.EndTimestamp:0,
+ (token!=NULL)?token->rxkad.clearToken.AuthHandle:0);
} else {
seq_printf(m, " %-36s", "Tokens Not Set");
}
{
struct cell *tc = 0;
struct unixuser *tu = p;
+ union tokenUnion *token;
char *cellname;
if (p == (void *)1) {
if (tc) afs_PutCell(tc, READ_LOCK);
if (tu->states & UHasTokens) {
+ token = afs_FindToken(tu->tokens, RX_SECIDX_KAD);
seq_printf(m, " %10d %10d %10d %3d",
- tu->tokenTime, tu->ct.BeginTimestamp, tu->ct.EndTimestamp,
- tu->ct.AuthHandle);
+ tu->tokenTime,
+ (token != NULL)?token->rxkad.clearToken.BeginTimestamp:0,
+ (token != NULL)?token->rxkad.clearToken.EndTimestamp:0,
+ (token != NULL)?token->rxkad.clearToken.AuthHandle:0);
} else {
seq_printf(m, " %-36s", "Tokens Not Set");
}
extern afs_int32 afs_numcachefiles;
extern afs_int32 afs_numfilesperdir;
+struct rxkadToken {
+ afs_int32 ticketLen;
+ char * ticket;
+ struct ClearToken clearToken;
+};
+
+union tokenUnion {
+ struct rxkadToken rxkad;
+};
+
+struct tokenJar {
+ struct tokenJar *next;
+ int type;
+ union tokenUnion u;
+};
+
struct unixuser {
struct unixuser *next; /* next hash pointer */
afs_int32 uid; /* search based on uid and cell */
short refCount; /* reference count for allocation */
char states; /* flag info */
afs_int32 tokenTime; /* last time tokens were set, used for timing out conn data */
- afs_int32 stLen; /* ticket length (if kerberos, includes kvno at head) */
- char *stp; /* pointer to ticket itself */
- struct ClearToken ct;
+ struct tokenJar *tokens;
struct afs_exporter *exporter; /* more info about the exporter for the remote user */
void *cellinfo; /* pointer to cell info (PAG manager only) */
};
afs_pickSecurityObject(struct afs_conn *conn, int *secLevel)
{
struct rx_securityClass *secObj = NULL;
+ union tokenUnion *token;
/* Do we have tokens ? */
if (conn->user->vid != UNDEFVID) {
- *secLevel = 2;
- /* kerberos tickets on channel 2 */
- secObj = rxkad_NewClientSecurityObject(
- cryptall ? rxkad_crypt : rxkad_clear,
- (struct ktc_encryptionKey *)conn->user->ct.HandShakeKey,
- conn->user->ct.AuthHandle,
- conn->user->stLen, conn->user->stp);
+ token = afs_FindToken(conn->user->tokens, RX_SECIDX_KAD);
+ if (token) {
+ *secLevel = RX_SECIDX_KAD;
+ /* kerberos tickets on channel 2 */
+ secObj = rxkad_NewClientSecurityObject(
+ cryptall ? rxkad_crypt : rxkad_clear,
+ (struct ktc_encryptionKey *)
+ token->rxkad.clearToken.HandShakeKey,
+ token->rxkad.clearToken.AuthHandle,
+ token->rxkad.ticketLen, token->rxkad.ticket);
+ }
}
if (secObj == NULL) {
*secLevel = 0;
for (i = 0; i < NUSERS; i++) {
for (tu = afs_users[i]; tu; tu = ntu) {
ntu = tu->next;
- if (tu->stp)
- afs_osi_Free(tu->stp, tu->stLen);
+ if (tu->tokens)
+ afs_FreeTokens(&tu->tokens);
if (tu->exporter)
EXP_RELE(tu->exporter);
afs_osi_Free(tu, sizeof(struct unixuser));
struct nfsclientpag *np = (struct nfsclientpag *)(au->exporter);
struct rx_securityClass *csec;
struct rx_connection *tconn;
+ struct tokenUnion *tokenPtr;
+ struct rkxadToken *token;
SysNameList tsysnames;
CredInfos tcreds;
CredInfo *tcred;
tu->exporter = (struct afs_exporter *)np;
}
- /* free any old secret token, and keep the new one */
- if (tu->stp != NULL) {
- afs_osi_Free(tu->stp, tu->stLen);
- }
- tu->stp = tcred->st.st_val;
- tu->stLen = tcred->st.st_len;
+ afs_FreeTokens(&tu->tokens);
+
+ /* Add a new rxkad token. Using the afs_AddRxkadToken interface
+ * would require another copy, so we do this the hard way */
+ tokenptr = afs_AddToken(&tu->tokens, 2);
+ token = &tokenptr->rxkad;
+ token->ticket = tcred->st.st_val;
+ token->ticketLen = tcred->st.st_len;
/* copy the clear token */
- memset(&tu->ct, 0, sizeof(tu->ct));
- memcpy(tu->ct.HandShakeKey, tcred->ct.HandShakeKey, 8);
+ memset(&token->clearToken, 0, sizeof(token->clearToken));
+ memcpy(token->clearToken.HandShakeKey, tcred->ct.HandShakeKey, 8);
memset(tcred->ct.HandShakeKey, 0, 8);
- tu->ct.AuthHandle = tcred->ct.AuthHandle;
- tu->ct.ViceId = tcred->ct.ViceId;
- tu->ct.BeginTimestamp = tcred->ct.BeginTimestamp;
- tu->ct.EndTimestamp = tcred->ct.EndTimestamp;
+ token->clearToken.AuthHandle = tcred->ct.AuthHandle;
+ token->clearToken.ViceId = tcred->ct.ViceId;
+ token->clearToken.BeginTimestamp = tcred->ct.BeginTimestamp;
+ token->clearToken.EndTimestamp = tcred->ct.EndTimestamp;
/* Set everything else, reset connections, and move on. */
tu->vid = tcred->vid;
if (tu->uid == uid) {
tu->vid = UNDEFVID;
tu->states &= ~UHasTokens;
- /* security is not having to say you're sorry */
- memset(&tu->ct, 0, sizeof(struct ClearToken));
+ afs_FreeTokens(&tu->tokens);
#ifdef UKERNEL
/* set the expire times to 0, causes
* afs_GCUserData to remove this entry
*/
- tu->ct.EndTimestamp = 0;
tu->tokenTime = 0;
#endif /* UKERNEL */
}
if (!tu->cellinfo)
tu->cellinfo = (void *)tcell;
tu->vid = clear.ViceId;
- if (tu->stp != NULL) {
- afs_osi_Free(tu->stp, tu->stLen);
- }
- tu->stp = (char *)afs_osi_Alloc(stLen);
- tu->stLen = stLen;
- memcpy(tu->stp, stp, stLen);
- tu->ct = clear;
+ afs_FreeTokens(&tu->tokens);
+ afs_AddRxkadToken(&tu->tokens, stp, stLen, &clear);
#ifndef AFS_NOSTATS
afs_stats_cmfullperf.authent.TicketUpdates++;
afs_ComputePAGStats();
CredInfos *a_creds)
{
struct unixuser *tu;
+ union tokenUnion *token;
CredInfo *tci;
int bucket, count, i = 0, clen;
char *cellname;
if (tu->uid == a_uid && tu->cellinfo &&
(tu->states & UHasTokens) && !(tu->states & UTokensBad)) {
+ token = afs_FindToken(tu->tokens, RX_SECIDX_KAD);
+
tci = &a_creds->CredInfos_val[i];
tci->vid = tu->vid;
- tci->ct.AuthHandle = tu->ct.AuthHandle;
- memcpy(tci->ct.HandShakeKey, tu->ct.HandShakeKey, 8);
- tci->ct.ViceId = tu->ct.ViceId;
- tci->ct.BeginTimestamp = tu->ct.BeginTimestamp;
- tci->ct.EndTimestamp = tu->ct.EndTimestamp;
+ tci->ct.AuthHandle = token->rxkad.clearToken.AuthHandle;
+ memcpy(tci->ct.HandShakeKey,
+ token->rxkad.clearToken.HandShakeKey, 8);
+ tci->ct.ViceId = token->rxkad.clearToken.ViceId;
+ tci->ct.BeginTimestamp = token->rxkad.clearToken.BeginTimestamp;
+ tci->ct.EndTimestamp = token->rxkad.clearToken.EndTimestamp;
cellname = ((struct afspag_cell *)(tu->cellinfo))->cellname;
clen = strlen(cellname) + 1;
goto out;
memcpy(tci->cellname, cellname, clen);
- tci->st.st_len = tu->stLen;
- tci->st.st_val = afs_osi_Alloc(tu->stLen);
+ tci->st.st_len = token->rxkad.ticketLen;
+ tci->st.st_val = afs_osi_Alloc(token->rxkad.ticketLen);
if (!tci->st.st_val) {
afs_osi_Free(tci->cellname, clen);
goto out;
}
- memcpy(tci->st.st_val, tu->stp, tu->stLen);
+ memcpy(tci->st.st_val,
+ token->rxkad.ticket, token->rxkad.ticketLen);
if (tu->states & UPrimary)
tci->states |= UPrimary;
}
/* now we just set the tokens */
tu = afs_GetUser(areq->uid, i, WRITE_LOCK); /* i has the cell # */
tu->vid = clear.ViceId;
- if (tu->stp != NULL) {
- afs_osi_Free(tu->stp, tu->stLen);
- }
- tu->stp = (char *)afs_osi_Alloc(stLen);
- if (tu->stp == NULL) {
- return ENOMEM;
- }
- tu->stLen = stLen;
- memcpy(tu->stp, stp, stLen);
- tu->ct = clear;
+ /* Set tokens destroys any that are already there */
+ afs_FreeTokens(&tu->tokens);
+ afs_AddRxkadToken(&tu->tokens, stp, stLen, &clear);
#ifndef AFS_NOSTATS
afs_stats_cmfullperf.authent.TicketUpdates++;
afs_ComputePAGStats();
struct cell *tcell;
afs_int32 i;
struct unixuser *tu;
+ union tokenUnion *token;
afs_int32 iterator = 0;
int newStyle;
int code = E2BIG;
return EDOM;
}
if (((tu->states & UHasTokens) == 0)
- || (tu->ct.EndTimestamp < osi_Time())) {
+ || !afs_HasUsableTokens(tu->tokens, osi_Time())) {
tu->states |= (UTokensBad | UNeedsReset);
afs_NotifyUser(tu, UTokensDropped);
afs_PutUser(tu, READ_LOCK);
return ENOTCONN;
}
- iterator = tu->stLen; /* for compat, we try to return 56 byte tix if they fit */
+ token = afs_FindToken(tu->tokens, RX_SECIDX_KAD);
+
+ /* for compat, we try to return 56 byte tix if they fit */
+ iterator = token->rxkad.ticketLen;
if (iterator < 56)
iterator = 56; /* # of bytes we're returning */
if (afs_pd_putInt(aout, iterator) != 0)
goto out;
- if (afs_pd_putBytes(aout, tu->stp, tu->stLen) != 0)
+ if (afs_pd_putBytes(aout, token->rxkad.ticket, token->rxkad.ticketLen) != 0)
goto out;
- if (tu->stLen < 56) {
+ if (token->rxkad.ticketLen < 56) {
/* Tokens are always 56 bytes or larger */
- if (afs_pd_skip(aout, iterator - tu->stLen) != 0) {
+ if (afs_pd_skip(aout, iterator - token->rxkad.ticketLen) != 0) {
goto out;
}
}
if (afs_pd_putInt(aout, sizeof(struct ClearToken)) != 0)
goto out;
- if (afs_pd_putBytes(aout, &tu->ct, sizeof(struct ClearToken)) != 0)
+ if (afs_pd_putBytes(aout, &token->rxkad.clearToken,
+ sizeof(struct ClearToken)) != 0)
goto out;
if (newStyle) {
if (tu->uid == areq->uid) {
tu->vid = UNDEFVID;
tu->states &= ~UHasTokens;
- /* security is not having to say you're sorry */
- memset(&tu->ct, 0, sizeof(struct ClearToken));
+ afs_FreeTokens(&tu->tokens);
tu->refCount++;
ReleaseWriteLock(&afs_xuser);
afs_NotifyUser(tu, UTokensDropped);
/* set the expire times to 0, causes
* afs_GCUserData to remove this entry
*/
- tu->ct.EndTimestamp = 0;
tu->tokenTime = 0;
#endif /* UKERNEL */
}
if (tu->exporter && EXP_CHECKHOST(tu->exporter, addr)) {
tu->vid = UNDEFVID;
tu->states &= ~UHasTokens;
- /* security is not having to say you're sorry */
- memset(&tu->ct, 0, sizeof(struct ClearToken));
+ afs_FreeTokens(&tu->tokens);
tu->refCount++;
ReleaseWriteLock(&afs_xuser);
afs_ResetUserConns(tu);
/* set the expire times to 0, causes
* afs_GCUserData to remove this entry
*/
- tu->ct.EndTimestamp = 0;
tu->tokenTime = 0;
#endif /* UKERNEL */
}
extern int Afs_syscall(void);
#endif
+/* afs_tokens.c */
+extern union tokenUnion *afs_FindToken(struct tokenJar *, rx_securityIndex);
+extern void afs_FreeTokens(struct tokenJar **);
+extern union tokenUnion *afs_AddToken(struct tokenJar **, rx_securityIndex);
+extern void afs_DiscardExpiredTokens(struct tokenJar **, afs_int32);
+extern int afs_HasUsableTokens(struct tokenJar *, afs_int32);
+extern void afs_AddRxkadToken(struct tokenJar **, char *, int,
+ struct ClearToken *);
+
/* UKERNEL/afs_usrops.c */
#ifdef UKERNEL
extern void uafs_Shutdown(void);
--- /dev/null
+/*
+ * Copyright (c) 2010 Your Filesystem Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+#include "afs/sysincludes.h"
+#include "afsincludes.h"
+
+/* A jar for storing tokens in */
+
+/*!
+ * Return a token of the specified type from the selected tokenjar.
+ *
+ * @param[in] tokens
+ * The tokenjar in which to search
+ * @param[in] type
+ * The type of token to return
+ *
+ * @return
+ * A tokenUnion structure, from which the desired token can be
+ * accessed using the appropriate element of the union.
+ */
+union tokenUnion *
+afs_FindToken(struct tokenJar *tokens, rx_securityIndex type) {
+ while (tokens != NULL) {
+ if (tokens->type == type) {
+ return &tokens->u;
+ }
+ tokens = tokens->next;
+ }
+ return NULL;
+}
+
+/*!
+ * Free a single token
+ *
+ * This will free the given token. No attempt is made to unlink
+ * the token from its container, and it is an error to attempt to
+ * free a token which is still linked.
+ *
+ * This performs a secure free, setting all token information to 0
+ * before returning allocated data blocks to the kernel.
+ *
+ * Intended primarily for internal use.
+ *
+ * @param[in] token
+ * The token to free
+ */
+
+void
+afs_FreeOneToken(struct tokenJar *token) {
+ if (token->next != NULL)
+ osi_Panic("Freeing linked token");
+
+ switch (token->type) {
+ case RX_SECIDX_KAD:
+ if (token->u.rxkad.ticket != NULL) {
+ memset(token->u.rxkad.ticket, 0, token->u.rxkad.ticketLen);
+ afs_osi_Free(token->u.rxkad.ticket,
+ token->u.rxkad.ticketLen);
+ }
+ break;
+ default:
+ break;
+ }
+ memset(token, 0, sizeof(struct tokenJar));
+ afs_osi_Free(token, sizeof(struct tokenJar));
+}
+
+/*!
+ * Free a token jar
+ *
+ * Free all of the tokens in a given token jar. This will also set the
+ * pointer to the jar to NULL, to indicate that it has been freed.
+ *
+ * @param[in] tokenPtr
+ * A pointer to the address of the tokenjar to free.
+ */
+void
+afs_FreeTokens(struct tokenJar **tokenPtr) {
+ struct tokenJar *next, *tokens;
+
+ tokens = *tokenPtr;
+ *tokenPtr = NULL;
+ while(tokens != NULL) {
+ next = tokens->next;
+ tokens->next = NULL; /* Unlink from chain */
+ afs_FreeOneToken(tokens);
+ tokens = next;
+ }
+}
+
+/*!
+ * Add a token to a token jar
+ *
+ * Add a new token to a token jar. If the jar already exists,
+ * then this token becomes the first in the jar. If it doesn't
+ * exist, then a new jar is created. The contents of the new
+ * token are initialised to 0 upon creation.
+ *
+ * @param[in] tokens
+ * A pointer to the address of the token jar to populate
+ * @param[in] type
+ * The type of token to create
+ *
+ * @return
+ * A pointer to the tokenUnion of the newly created token,
+ * which may then be used to populate the token.
+ */
+union tokenUnion *
+afs_AddToken(struct tokenJar **tokens, rx_securityIndex type) {
+ struct tokenJar *newToken;
+
+ newToken = afs_osi_Alloc(sizeof(struct tokenJar));
+ memset(newToken, 0, sizeof(*newToken));
+
+ newToken->type = type;
+ newToken->next = *tokens;
+ *tokens = newToken;
+
+ return &newToken->u;
+}
+
+/*!
+ * Indicate if a single token is expired
+ *
+ * @param[in] token
+ * The token to check
+ * @param[in] now
+ * The time to check against for expiry (typically the results of
+ * calling osi_Time())
+ *
+ * @returns
+ * True if the token has expired, false otherwise
+ */
+int
+afs_IsTokenExpired(struct tokenJar *token, afs_int32 now) {
+ switch (token->type) {
+ case RX_SECIDX_KAD:
+ if (token->u.rxkad.clearToken.EndTimestamp < now - NOTOKTIMEOUT)
+ return 1;
+ break;
+ default:
+ return 0;
+ }
+ return 0; /* not reached, but keep gcc happy */
+}
+
+/*!
+ * Indicate if a token is usable by the kernel module
+ *
+ * This determines whether a token is usable. A usable token is one that
+ * has not expired, and which is otherwise suitable for use.
+ *
+ * @param[in] token
+ * The token to check
+ * @param[in] now
+ * The time to use for the expiry check
+ *
+ * @returns
+ * True if the token is usable, false otherwise
+ */
+int
+afs_IsTokenUsable(struct tokenJar *token, afs_int32 now) {
+
+ if (afs_IsTokenExpired(token, now))
+ return 0;
+
+ switch (token->type) {
+ case RX_SECIDX_KAD:
+ /* We assume that all non-expired rxkad tokens are usable by us */
+ return 1;
+ default :
+ return 0;
+ }
+}
+
+/*!
+ * Discard all expired tokens from a token jar
+ *
+ * This permanently removes all tokens which have expired from the token
+ * jar. Note that tokens which are not usable, but which have not expired,
+ * will not be deleted.
+ *
+ * @param[in] tokenPtr
+ * A pointer to the address of the token jar to check
+ * @param[in] now
+ * The time to use for the expiry check
+ */
+
+void
+afs_DiscardExpiredTokens(struct tokenJar **tokenPtr, afs_int32 now) {
+ struct tokenJar *next;
+
+ while (*tokenPtr != NULL) {
+ if (afs_IsTokenExpired(*tokenPtr, now)) {
+ next = (*tokenPtr)->next;
+ (*tokenPtr)->next = NULL;
+ afs_FreeOneToken(*tokenPtr);
+ *tokenPtr = next;
+ } else {
+ tokenPtr = &(*tokenPtr)->next;
+ }
+ }
+}
+
+/*!
+ * Indicate whether a token jar contains one, or more usable tokens
+ *
+ * @param[in] token
+ * The token jar to check
+ * @param[in] now
+ * The cime to use for the expiry check
+ *
+ * @returns
+ * True if the jar contains usable tokens, otherwise false
+ */
+int
+afs_HasUsableTokens(struct tokenJar *token, afs_int32 now) {
+ while (token != NULL) {
+ if (afs_IsTokenUsable(token, now))
+ return 1;
+ token = token->next;
+ }
+ return 0;
+}
+
+/*!
+ * Add an rxkad token to the token jar
+ *
+ * @param[in] tokens
+ * A pointer to the address of the jar to add the token to
+ * @param[in] ticket
+ * A data block containing the token's opaque ticket
+ * @param[in] ticketLen
+ * The length of the ticket data block
+ * @param[in] clearToken
+ * The cleartext token information
+ */
+void
+afs_AddRxkadToken(struct tokenJar **tokens, char *ticket, int ticketLen,
+ struct ClearToken *clearToken) {
+ union tokenUnion *tokenU;
+ struct rxkadToken *rxkad;
+
+ tokenU = afs_AddToken(tokens, RX_SECIDX_KAD);
+ rxkad = &tokenU->rxkad;
+
+ rxkad->ticket = afs_osi_Alloc(ticketLen);
+ rxkad->ticketLen = ticketLen;
+ memcpy(rxkad->ticket, ticket, ticketLen);
+ rxkad->clearToken = *clearToken;
+}
+
/* Don't garbage collect users in use now (refCount) */
if (tu->refCount == 0) {
if (tu->states & UHasTokens) {
- /*
- * Give ourselves a little extra slack, in case we
- * reauthenticate
- */
- if (tu->ct.EndTimestamp < now - NOTOKTIMEOUT)
+ /* Need to walk the token stack, and dispose of
+ * all expired tokens */
+ afs_DiscardExpiredTokens(&tu->tokens, now);
+ if (!afs_HasUsableTokens(tu->tokens, now))
delFlag = 1;
} else {
if (aforce || (tu->tokenTime < now - NOTOKTIMEOUT))
#ifndef AFS_PAG_MANAGER
RemoveUserConns(tu);
#endif
- if (tu->stp)
- afs_osi_Free(tu->stp, tu->stLen);
+ afs_FreeTokens(&tu->tokens);
+
if (tu->exporter)
EXP_RELE(tu->exporter);
afs_osi_Free(tu, sizeof(struct unixuser));
* check expiration
*/
if (!(tu->states & UTokensBad) && tu->vid != UNDEFVID) {
- if (tu->ct.EndTimestamp < now) {
+ if (!afs_HasUsableTokens(tu->tokens, now)) {
/*
* This token has expired, warn users and reset access
* cache.
ObtainWriteLock(&afs_xuser, 9);
for (tu = afs_users[i]; tu; tu = tu->next) {
if (tu->uid == pag) {
- tu->ct.EndTimestamp = 0;
+ tu->states &= ~UHasTokens;
tu->tokenTime = 0;
}
}
* i.e. nfs translator, etc.
*/
if (!pu->exporter && afs_gcpags == AFS_GCPAGS_OK) {
- /* set the expire times to 0, causes
- * afs_GCUserData to remove this entry
- */
- pu->ct.EndTimestamp = 0;
+ /* make afs_GCUserData remove this entry */
+ pu->states &= ~UHasTokens;
pu->tokenTime = 0;
(*ReleasedCount)++; /* remember how many we marked (info only) */
afs_server.o \
afs_stat.o \
afs_syscall.o \
+ afs_tokens.o \
afs_user.o \
afs_util.o \
afs_vcache.o \
afs_pag_user.o \
afs_stat.o \
afs_syscall.o \
+ afs_tokens.o \
afs_warn.o \
afsaux.o \
xdr_arrayn.o \
$(CRULE_OPT)
afs_server.o: $(TOP_SRC_AFS)/afs_server.c
$(CRULE_OPT)
+afs_tokens.o: $(TOP_SRC_AFS)/afs_tokens.c
+ $(CRULE_OPT)
afs_user.o: $(TOP_SRC_AFS)/afs_user.c
$(CRULE_OPT)
afs_util.o: $(TOP_SRC_AFS)/afs_util.c
$(UOBJ)/afs_server.o \
$(UOBJ)/afs_stat.o \
$(UOBJ)/afs_syscall.o \
+ $(UOBJ)/afs_tokens.o \
$(UOBJ)/afs_user.o \
$(UOBJ)/afs_util.o \
$(UOBJ)/afs_vcache.o \
$(WEBOBJ)/afs_server.o \
$(WEBOBJ)/afs_stat.o \
$(WEBOBJ)/afs_syscall.o \
+ $(WEBOBJ)/afs_tokens.o \
$(WEBOBJ)/afs_user.o \
$(WEBOBJ)/afs_util.o \
$(WEBOBJ)/afs_vcache.o \
$(WEBOBJ)/afs_server.o \
$(WEBOBJ)/afs_stat.o \
$(WEBOBJ)/afs_syscall.o \
+ $(WEBOBJ)/afs_tokens.o \
$(WEBOBJ)/afs_user.o \
$(WEBOBJ)/afs_util.o \
$(WEBOBJ)/afs_vcache.o \
$(JUAFS)/afs_server.o \
$(JUAFS)/afs_stat.o \
$(JUAFS)/afs_syscall.o \
+ $(JUAFS)/afs_tokens.o \
$(JUAFS)/afs_user.o \
$(JUAFS)/afs_util.o \
$(JUAFS)/afs_vcache.o \
$(CRULE1)
$(UOBJ)/afs_server.o: $(TOP_SRC_AFS)/afs_server.c
$(CRULE1)
+$(UOBJ)/afs_tokens.o: $(TOP_SRC_AFS)/afs_tokens.c
+ $(CRULE1)
$(UOBJ)/afs_user.o: $(TOP_SRC_AFS)/afs_user.c
$(CRULE1)
$(UOBJ)/afs_util.o: $(TOP_SRC_AFS)/afs_util.c
$(CRULE2)
$(WEBOBJ)/afs_server.o: $(TOP_SRC_AFS)/afs_server.c
$(CRULE2)
+$(WEBOBJ)/afs_tokens.o: $(TOP_SRC_AFS)/afs_tokens.c
+ $(CRULE2)
$(WEBOBJ)/afs_user.o: $(TOP_SRC_AFS)/afs_user.c
$(CRULE2)
$(WEBOBJ)/afs_util.o: $(TOP_SRC_AFS)/afs_util.c
$(CRULE1)
$(JUAFS)/afs_server.o: $(TOP_SRC_AFS)/afs_server.c
$(CRULE1)
+$(JUAFS)/afs_tokens.o: $(TOP_SRC_AFS)/afs_tokens.c
+ $(CRULE1)
$(JUAFS)/afs_user.o: $(TOP_SRC_AFS)/afs_user.c
$(CRULE1)
$(JUAFS)/afs_util.o: $(TOP_SRC_AFS)/afs_util.c