tvlserver_depinstall: config rxgen ubik_depinstall auth_depinstall
+${COMPILE_PART1} tvlserver ${COMPILE_DEPINSTALL}
-auth_depinstall: config comerr
+auth_depinstall: config rxgen comerr
+${COMPILE_PART1} auth ${COMPILE_DEPINSTALL}
fsint_depinstall: config rxgen
# libafs build targets
#
libafs: config export lwp_depinstall rx_depinstall vlserver_depinstall tvlserver_depinstall rxkad_depinstall fsint_depinstall \
- libacl_depinstall afs_depinstall dir_depinstall rxstat_depinstall sys_depinstall
+ libacl_depinstall afs_depinstall dir_depinstall rxstat_depinstall sys_depinstall auth_depinstall
src/config/config src/libafs/MakefileProto.${MKAFS_OSTYPE} src/libafs/Makefile ${SYS_NAME}
+${COMPILE_PART1} libafs ${COMPILE_PART2}
libafs_tree: export lwp_depinstall rx_depinstall vlserver_depinstall tvlserver_depinstall rxkad_depinstall fsint_depinstall \
- libacl_depinstall afs_depinstall dir_depinstall rxstat_depinstall sys_depinstall
+ libacl_depinstall afs_depinstall dir_depinstall rxstat_depinstall sys_depinstall auth_depinstall
${TOP_SRCDIR}/config/make_libafs_tree.pl \
-sn $(SYS_NAME) \
-os $(MKAFS_OSTYPE) \
#include "afs/vice.h"
#include "afs/afs_bypasscache.h"
#include "rx/rx_globals.h"
+#include "token.h"
struct VenusFid afs_rootFid;
afs_int32 afs_waitForever = 0;
return ret;
}
+static_inline void
+afs_pd_xdrStart(struct afs_pdata *apd, XDR *xdrs, enum xdr_op op) {
+ xdrmem_create(xdrs, apd->ptr, apd->remaining, op);
+}
+
+static_inline void
+afs_pd_xdrEnd(struct afs_pdata *apd, XDR *xdrs) {
+ size_t pos;
+
+ pos = xdr_getpos(xdrs);
+ apd->ptr += pos;
+ apd->remaining -= pos;
+ xdr_destroy(xdrs);
+}
+
+
+
static_inline int
afs_pd_getString(struct afs_pdata *apd, char *str, size_t maxLen)
{
DECL_PIOCTL(PGetWSCell);
DECL_PIOCTL(PGetUserCell);
DECL_PIOCTL(PSetTokens);
+DECL_PIOCTL(PSetTokens2);
DECL_PIOCTL(PGetVolumeStatus);
DECL_PIOCTL(PSetVolumeStatus);
DECL_PIOCTL(PFlush);
PDiscon, /* 5 -- get/set discon mode */
PBogus, /* 6 */
PBogus, /* 7 */
- PBogus, /* 8 */
+ PSetTokens2, /* 8 */
PNewUuid, /* 9 */
PBogus, /* 10 */
PBogus, /* 11 */
return 0;
}
+/* Work out which cell we're changing tokens for */
+static_inline int
+_settok_tokenCell(char *cellName, int *cellNum, int *primary) {
+ int t1;
+ struct cell *cell;
+
+ if (cellName && strlen(cellName) > 0) {
+ cell = afs_GetCellByName(cellName, READ_LOCK);
+ } else {
+ cell = afs_GetPrimaryCell(READ_LOCK);
+ if (primary)
+ *primary = 1;
+ }
+ if (!cell) {
+ t1 = afs_initState;
+ if (t1 < 101)
+ return EIO;
+ else
+ return ESRCH;
+ }
+ *cellNum = cell->cellNum;
+ afs_PutCell(cell, READ_LOCK);
+
+ return 0;
+}
+
+
+static_inline int
+_settok_setParentPag(afs_ucred_t **cred) {
+ afs_uint32 pag;
+#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+ char procname[256];
+ osi_procname(procname, 256);
+ afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
+ MyPidxx2Pid(MyPidxx), procname);
+ return setpag(osi_curporc(), cred, -1, &pag, 1);
+#else
+ return setpag(cred, -1, &pag, 1);
+#endif
+}
+
/*!
* VIOCSETTOK (3) - Set authentication tokens
*
*/
DECL_PIOCTL(PSetTokens)
{
- afs_int32 i;
+ afs_int32 cellNum;
+ afs_int32 size;
+ afs_int32 code;
struct unixuser *tu;
struct ClearToken clear;
- struct cell *tcell;
char *stp;
char *cellName;
int stLen;
if (afs_pd_skip(ain, stLen) != 0)
return EINVAL;
- if (afs_pd_getInt(ain, &i) != 0)
+ if (afs_pd_getInt(ain, &size) != 0)
return EINVAL;
- if (i != sizeof(struct ClearToken))
+ if (size != sizeof(struct ClearToken))
return EINVAL;
if (afs_pd_getBytes(ain, &clear, sizeof(struct ClearToken)) !=0)
if (afs_pd_getStringPtr(ain, &cellName) != 0)
return EINVAL;
- /* rest is cell name, look it up */
- tcell = afs_GetCellByName(cellName, READ_LOCK);
- if (!tcell)
- goto nocell;
+ code = _settok_tokenCell(cellName, &cellNum, NULL);
+ if (code)
+ return code;
} else {
/* default to primary cell, primary id */
- flag = 1; /* primary id */
- tcell = afs_GetPrimaryCell(READ_LOCK);
- if (!tcell)
- goto nocell;
+ code = _settok_tokenCell(NULL, &cellNum, &flag);
+ if (code)
+ return code;
}
- i = tcell->cellNum;
- afs_PutCell(tcell, READ_LOCK);
+
if (set_parent_pag) {
- afs_uint32 pag;
-#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
- char procname[256];
- osi_procname(procname, 256);
- afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
- MyPidxx2Pid(MyPidxx), procname);
- if (!setpag(osi_curproc(), acred, -1, &pag, 1)) {
-#else
- if (!setpag(acred, -1, &pag, 1)) {
-#endif
+ if (_settok_setParentPag(acred) == 0) {
afs_InitReq(&treq, *acred);
areq = &treq;
}
}
+
/* now we just set the tokens */
- tu = afs_GetUser(areq->uid, i, WRITE_LOCK); /* i has the cell # */
+ tu = afs_GetUser(areq->uid, cellNum, WRITE_LOCK);
/* Set tokens destroys any that are already there */
afs_FreeTokens(&tu->tokens);
afs_AddRxkadToken(&tu->tokens, stp, stLen, &clear);
afs_PutUser(tu, WRITE_LOCK);
return 0;
-
- nocell:
- {
- int t1;
- t1 = afs_initState;
- if (t1 < 101)
- return EIO;
- else
- return ESRCH;
- }
}
/*!
return afs_pd_putInt(aout, mode);
}
+#define MAX_PIOCTL_TOKENS 10
+
+DECL_PIOCTL(PSetTokens2)
+{
+ int code =0;
+ int i, cellNum, primaryFlag;
+ XDR xdrs;
+ struct unixuser *tu;
+ struct vrequest treq;
+ struct ktc_setTokenData tokenSet;
+ struct ktc_tokenUnion decodedToken;
+
+ memset(&tokenSet, 0, sizeof(tokenSet));
+
+ AFS_STATCNT(PSetTokens2);
+ if (!afs_resourceinit_flag)
+ return EIO;
+
+ afs_pd_xdrStart(ain, &xdrs, XDR_DECODE);
+
+ if (!xdr_ktc_setTokenData(&xdrs, &tokenSet)) {
+ afs_pd_xdrEnd(ain, &xdrs);
+ return EINVAL;
+ }
+
+ afs_pd_xdrEnd(ain, &xdrs);
+
+ /* We limit each PAG to 10 tokens to prevent a malicous (or runaway)
+ * process from using up the whole of the kernel memory by allocating
+ * tokens.
+ */
+ if (tokenSet.tokens.tokens_len > MAX_PIOCTL_TOKENS) {
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+ return E2BIG;
+ }
+
+ code = _settok_tokenCell(tokenSet.cell, &cellNum, &primaryFlag);
+ if (code) {
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+ return code;
+ }
+
+ if (tokenSet.flags & AFSTOKEN_EX_SETPAG) {
+ if (_settok_setParentPag(acred) == 0) {
+ afs_InitReq(&treq, *acred);
+ areq = &treq;
+ }
+ }
+
+ tu = afs_GetUser(areq->uid, cellNum, WRITE_LOCK);
+ /* Free any tokens that we've already got */
+ afs_FreeTokens(&tu->tokens);
+
+ /* Iterate across the set of tokens we've received, and stuff them
+ * into this user's tokenJar
+ */
+ for (i=0; i < tokenSet.tokens.tokens_len; i++) {
+ xdrmem_create(&xdrs,
+ tokenSet.tokens.tokens_val[i].token_opaque_val,
+ tokenSet.tokens.tokens_val[i].token_opaque_len,
+ XDR_DECODE);
+
+ memset(&decodedToken, 0, sizeof(decodedToken));
+ if (!xdr_ktc_tokenUnion(&xdrs, &decodedToken)) {
+ xdr_destroy(&xdrs);
+ code = EINVAL;
+ goto out;
+ }
+
+ xdr_destroy(&xdrs);
+
+ afs_AddTokenFromPioctl(&tu->tokens, &decodedToken);
+ /* This is untidy - the old token interface supported passing
+ * the primaryFlag as part of the token interface. Current
+ * OpenAFS userland never sets this, but it's specified as being
+ * part of the XG interface, so we should probably still support
+ * it. Rather than add it to our AddToken interface, just handle
+ * it here.
+ */
+ if (decodedToken.at_type == AFSTOKEN_UNION_KAD) {
+ if (decodedToken.ktc_tokenUnion_u.at_kad.rk_primary_flag)
+ primaryFlag = 1;
+ }
+
+ /* XXX - We should think more about destruction here. It's likely that
+ * there is key material in what we're about to throw away, which
+ * we really should zero out before giving back to the allocator */
+ xdr_free((xdrproc_t) xdr_ktc_tokenUnion, &decodedToken);
+ }
+
+ tu->states |= UHasTokens;
+ tu->states &= ~UTokensBad;
+ afs_SetPrimary(tu, primaryFlag);
+ tu->tokenTime = osi_Time();
+
+ xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);
+
+out:
+ afs_ResetUserConns(tu);
+ afs_PutUser(tu, WRITE_LOCK);
+
+ return code;
+}
+
DECL_PIOCTL(PNFSNukeCreds)
{
afs_uint32 addr;
#endif
/* afs_tokens.c */
+struct ktc_tokenUnion;
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 int afs_HasUsableTokens(struct tokenJar *, afs_int32);
extern void afs_AddRxkadToken(struct tokenJar **, char *, int,
struct ClearToken *);
+extern int afs_AddTokenFromPioctl(struct tokenJar **, struct ktc_tokenUnion *);
/* UKERNEL/afs_usrops.c */
#ifdef UKERNEL
afs_int32 C_SRXAFSCB_GetCellByNum; /* afs_callback.c */
afs_int32 C_BPrefetchNoCache; /* afs_daemons.c */
afs_int32 C_afs_ReadNoCache; /* osi_vnodeops.c */
+ afs_int32 C_PSetTokens2; /* afs_pioctl.c */
};
struct afs_CMMeanStats {
#include "afs/param.h"
#include "afs/sysincludes.h"
#include "afsincludes.h"
+#include "token.h"
/* A jar for storing tokens in */
rxkad->clearToken = *clearToken;
}
+static int
+afs_AddRxkadTokenFromPioctl(struct tokenJar **tokens,
+ struct ktc_tokenUnion *pioctlToken) {
+ struct ClearToken clear;
+
+ clear.AuthHandle = pioctlToken->ktc_tokenUnion_u.at_kad.rk_kvno;
+ clear.ViceId = pioctlToken->ktc_tokenUnion_u.at_kad.rk_viceid;
+ clear.BeginTimestamp = pioctlToken->ktc_tokenUnion_u.at_kad.rk_begintime;
+ clear.EndTimestamp = pioctlToken->ktc_tokenUnion_u.at_kad.rk_endtime;
+ memcpy(clear.HandShakeKey, pioctlToken->ktc_tokenUnion_u.at_kad.rk_key, 8);
+ afs_AddRxkadToken(tokens,
+ pioctlToken->ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_val,
+ pioctlToken->ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_len,
+ &clear);
+
+ /* Security means never having to say you're sorry */
+ memset(clear.HandShakeKey, 0, 8);
+
+ return 0;
+}
+
+
+/*!
+ * Add a token to a token jar based on the input from a new-style
+ * SetToken pioctl
+ *
+ * @param[in] tokens
+ * Pointer to the address of a token jar
+ * @param[in] pioctlToken
+ * The token structure obtained through the pioctl (note this
+ * is a single, XDR decoded, token)
+ *
+ * @returns
+ * 0 on success, an error code on failure
+ */
+int
+afs_AddTokenFromPioctl(struct tokenJar **tokens,
+ struct ktc_tokenUnion *pioctlToken) {
+
+ switch (pioctlToken->at_type) {
+ case RX_SECIDX_KAD:
+ return afs_AddRxkadTokenFromPioctl(tokens, pioctlToken);
+ }
+
+ return EINVAL;
+}
/copyauth
/ktc_errors.c
/setkey
+/token.h
INSTALL_SCRIPT = @INSTALL_SCRIPT@
OBJS= cellconfig.o ktc.o userok.o writeconfig.o authcon.o \
- acfg_errors.o ktc_errors.o
+ acfg_errors.o ktc_errors.o token.xdr.o token.o
KOBJS= cellconfig.o ktc.krb.o userok.o writeconfig.o authcon.o \
- acfg_errors.o ktc_errors.o
+ acfg_errors.o ktc_errors.o token.xdr.o token.o
LIBS=libauth.a \
${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libdes.a \
depinstall: ${TOP_INCDIR}/afs/keys.h \
${TOP_INCDIR}/afs/cellconfig.h \
${TOP_INCDIR}/afs/auth.h \
- ${TOP_INCDIR}/afs/ktc.h
+ ${TOP_INCDIR}/afs/ktc.h \
+ ${TOP_INCDIR}/afs/token.h \
+ token.h \
+ token.xdr.c
+
+${TOP_INCDIR}/afs/token.h: token.h
+ ${INSTALL_DATA} $? $@
generated: acfg_errors.c cellconfig.h ktc_errors.c auth.h
ktc_errors.o: ktc_errors.c
+ktc.o: token.h
+
ktc_errors.c auth.h: ktc_errors.et auth.p.h
$(RM) -f auth.h ktc_errors.c
${COMPILE_ET} -p ${srcdir} ktc_errors -h auth
+token.xdr.c: token.xg
+ $(RXGEN) -A -x -c -o $@ ${srcdir}/token.xg
+
+token.h : token.xg
+ $(RXGEN) -A -x -h -o $@ ${srcdir}/token.xg
+
#
# Install targets
#
cd test; $(MAKE)
clean:
- $(RM) -f *.o *.a copyauth setkey auth.h cellconfig.h acfg_errors.c ktc_errors.c core \
- AFS_component_version_number.c
+ $(RM) -f *.o *.a copyauth setkey auth.h cellconfig.h acfg_errors.c \
+ ktc_errors.c token.h token.xdr.c core \
+ AFS_component_version_number.c
include ../config/Makefile.version
struct ktc_principal *, afs_int32);
int ktc_GetToken(struct ktc_principal *, struct ktc_token *,
int, struct ktc_principal *);
+
+struct ktc_setTokenData;
+int ktc_SetTokenEx(struct ktc_setTokenData *);
+
int ktc_ListTokens(int, int *, struct ktc_principal *);
int ktc_ForgetToken(struct ktc_principal *);
int ktc_ForgetAllTokens(void);
#include <afs/sys_prototypes.h>
#endif
+#include "token.h"
+
#if defined(LINUX_KEYRING_SUPPORT) && defined(HAVE_SESSION_TO_PARENT)
#include <sys/syscall.h>
#define KEYCTL_SESSION_TO_PARENT 18
}
int
+ktc_SetTokenEx(struct ktc_setTokenData *token) {
+ struct ViceIoctl iob;
+ afs_int32 code;
+ XDR xdrs;
+
+ xdrlen_create(&xdrs);
+ if (!xdr_ktc_setTokenData(&xdrs, token))
+ return EINVAL;
+ iob.in_size = xdr_getpos(&xdrs);
+ xdr_destroy(&xdrs);
+
+ iob.in = malloc(iob.in_size);
+ if (iob.in == NULL)
+ return ENOMEM;
+
+ xdrmem_create(&xdrs, iob.in, iob.in_size, XDR_ENCODE);
+ if (!xdr_ktc_setTokenData(&xdrs, token))
+ return KTC_INVAL;
+ xdr_destroy(&xdrs);
+
+ iob.out = NULL;
+ iob.out_size = 0;
+
+ code = PIOCTL(0, VIOC_SETTOK2, &iob, 0);
+
+ free(iob.in);
+
+ /* If we can't use the new pioctl, then fallback to using the old
+ * one, with just the rxkad portion of the token we're being asked to
+ * set
+ */
+ if (code == -1 && errno == EINVAL) {
+ struct ktc_principal server, client;
+ struct ktc_token *rxkadToken;
+ afs_int32 flags;
+
+ /* With the growth of ticket sizes, a ktc_token is now 12k. Don't
+ * allocate it on the stack! */
+ rxkadToken = malloc(sizeof(*rxkadToken));
+ if (rxkadToken == NULL)
+ return ENOMEM;
+
+ code = token_extractRxkad(token, rxkadToken, &flags, &client);
+ if (code) {
+ free(rxkadToken);
+ return KTC_INVAL;
+ }
+
+ memset(&server, 0, sizeof(server));
+ strcpy(server.name, "afs");
+ strcpy(server.cell, token->cell);
+ code = ktc_SetToken(&server, rxkadToken, &client, flags);
+ free(rxkadToken);
+ return code;
+ }
+
+ if (code)
+ return KTC_PIOCTLFAIL;
+
+ return 0;
+}
+
+int
ktc_SetToken(struct ktc_principal *aserver,
struct ktc_token *atoken,
struct ktc_principal *aclient,
* directory or online at http://www.openafs.org/dl/license10.html
*/
-#ifndef _AFS_AUTH_KTC_H
-#define _AFS_AUTH_KTC_H
+#ifndef AFS_SRC_AUTH_KTC_H
+#define AFS_SRC_AUTH_KTC_H
extern char * ktc_tkt_string(void);
extern char * ktc_tkt_string_uid(afs_uint32);
extern void ktc_set_tkt_string(char *);
extern int ktc_OldPioctl(void);
-#endif /* _AFS_AUTH_KTC_H */
+struct ktc_setTokenData;
+struct ktc_tokenUnion;
+extern int token_findByType(struct ktc_setTokenData *, int,
+ struct ktc_tokenUnion *);
+extern struct ktc_setTokenData *token_buildTokenJar(char *);
+extern int token_addToken(struct ktc_setTokenData *, struct ktc_tokenUnion *);
+extern int token_replaceToken(struct ktc_setTokenData *,
+ struct ktc_tokenUnion *);
+extern void token_setPag(struct ktc_setTokenData *, int);
+
+struct ktc_token;
+struct ktc_principal;
+extern int token_extractRxkad(struct ktc_setTokenData *, struct ktc_token *,
+ int *, struct ktc_principal *);
+#endif /* AFS_SRC_AUTH_KTC_H */
--- /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 <sys/errno.h>
+
+#include <afsconfig.h>
+#include <afs/param.h>
+#include <afs/auth.h>
+#include <rx/rxkad.h>
+#include "ktc.h"
+#include "token.h"
+
+
+/* Routines for processing tokens in the new XDR format
+ *
+ * The code here is inspired by work done by Jeffrey Hutzelman et al
+ * at the AFSSIG.se hackathon and further refined by Matt
+ * Benjamin and Marcus Watts as part of rxk5. However, unless
+ * otherwise noted, the implementation is new
+ */
+
+/* Given a token type, return the entry number of the first token of that
+ * type */
+static int
+findTokenEntry(struct ktc_setTokenData *token,
+ int targetType)
+{
+ XDR xdrs;
+ int i, type;
+
+ for (i = 0; i < token->tokens.tokens_len; i++) {
+ xdrmem_create(&xdrs,
+ token->tokens.tokens_val[i].token_opaque_val,
+ token->tokens.tokens_val[i].token_opaque_len,
+ XDR_DECODE);
+ /* Take a peak at the discriminator. */
+ if (!xdr_enum(&xdrs, &type)) {
+ type = -1;
+ }
+ xdr_destroy(&xdrs);
+
+ if (type == targetType)
+ return i;
+ }
+ return -1;
+}
+
+/* XDR encode a token union structure, and return data and length information
+ * suitable for stuffing into a token_opaque structure
+ */
+static int
+encodeTokenUnion(struct ktc_tokenUnion *token,
+ char **dataPtr, size_t *lenPtr) {
+ char *data = NULL;
+ size_t len;
+ XDR xdrs;
+ int code = 0;
+
+ *dataPtr = NULL;
+ *lenPtr = 0;
+
+ xdrlen_create(&xdrs);
+ if (!xdr_ktc_tokenUnion(&xdrs, token)) {
+ code = EINVAL;
+ goto out;
+ }
+
+ len = xdr_getpos(&xdrs);
+ data = malloc(len);
+ if (data == NULL) {
+ code = ENOMEM;
+ goto out;
+ }
+ xdr_destroy(&xdrs);
+
+ xdrmem_create(&xdrs, data, len, XDR_ENCODE);
+ if (!xdr_ktc_tokenUnion(&xdrs, token)) {
+ code = EINVAL;
+ goto out;
+ }
+
+ *dataPtr = data;
+ *lenPtr = len;
+
+out:
+ xdr_destroy(&xdrs);
+ if (code) {
+ if (data)
+ free(data);
+ }
+
+ return code;
+}
+
+static void
+addOpaque(struct ktc_setTokenData *jar, char *data, size_t len)
+{
+ int entry;
+
+ entry = jar->tokens.tokens_len;
+ jar->tokens.tokens_val = realloc(jar->tokens.tokens_val,
+ entry + 1 * sizeof(token_opaque));
+ jar->tokens.tokens_len++;
+ jar->tokens.tokens_val[entry].token_opaque_val = data;
+ jar->tokens.tokens_val[entry].token_opaque_len = len;
+}
+
+/*!
+ * Extract a specific token element from a unified token structure
+ *
+ * This routine extracts an afsTokenUnion structure from the tokenData
+ * structure used by the SetTokenEx and GetTokenEx pioctls
+ *
+ * @param[in] token
+ * A ktc_setTokenData structure containing the token to extract from
+ * @param[in] targetType
+ * The securityClass index of the token to be extracted
+ * @param[out] output
+ * The decoded token. On entry, this must point to a block of memory
+ * of sufficient size to contain an afsTokenUnion structure. Upon
+ * completion, this block must be passed to xdr_free(), using the
+ * xdr_afsTokenUnion xdrproc_t.
+ */
+int
+token_findByType(struct ktc_setTokenData *token,
+ int targetType,
+ struct ktc_tokenUnion *output)
+{
+ XDR xdrs;
+ int entry;
+ int code = EINVAL;
+
+ memset(output, 0, sizeof *output);
+ entry = findTokenEntry(token, targetType);
+ if (entry == -1)
+ goto out;
+
+ xdrmem_create(&xdrs,
+ token->tokens.tokens_val[entry].token_opaque_val,
+ token->tokens.tokens_val[entry].token_opaque_len,
+ XDR_DECODE);
+
+ if (!xdr_ktc_tokenUnion(&xdrs, output)) {
+ xdr_destroy(&xdrs);
+ goto out;
+ }
+
+ xdr_destroy(&xdrs);
+ if (output->at_type != targetType) {
+ xdr_free((xdrproc_t)xdr_ktc_tokenUnion, output);
+ goto out;
+ }
+
+ code = 0;
+
+out:
+ return code;
+}
+
+/*!
+ * Given an unified token, populate an rxkad token from it
+ *
+ * This routine populates an rxkad token using information contained
+ * in the tokenData structure used by the SetTokenEx and GetTokenEX
+ * pioctls.
+ *
+ * @param[in] token
+ * The new format token to extract information from.
+ * @param[out] rxkadToken
+ * The old-style rxkad token. This must be a pointer to an existing
+ * data block of sufficient size
+ * @param[out] flags
+ * The set of token flags
+ * @param[out] aclient
+ * The client owning the token. This must be a pointer to an existing
+ * data block of sufficient size, or NULL.
+ */
+
+int
+token_extractRxkad(struct ktc_setTokenData *token,
+ struct ktc_token *rxkadToken,
+ int *flags,
+ struct ktc_principal *aclient)
+{
+ struct ktc_tokenUnion uToken;
+ int code;
+
+ memset(&uToken, 0, sizeof(uToken));
+ if (aclient)
+ memset(aclient, 0, sizeof(*aclient));
+
+ code = token_findByType(token, AFSTOKEN_UNION_KAD, &uToken);
+ if (code)
+ return code;
+
+ rxkadToken->kvno = uToken.ktc_tokenUnion_u.at_kad.rk_kvno;
+ memcpy(rxkadToken->sessionKey.data,
+ uToken.ktc_tokenUnion_u.at_kad.rk_key, 8);
+ rxkadToken->startTime = uToken.ktc_tokenUnion_u.at_kad.rk_begintime;
+ rxkadToken->endTime = uToken.ktc_tokenUnion_u.at_kad.rk_endtime;
+ rxkadToken->ticketLen = uToken.ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_len;
+
+ if (rxkadToken->ticketLen > MAXKTCTICKETLEN) {
+ code = E2BIG;
+ goto out;
+ }
+
+ memcpy(rxkadToken->ticket,
+ uToken.ktc_tokenUnion_u.at_kad.rk_ticket.rk_ticket_val,
+ rxkadToken->ticketLen);
+
+ if (flags)
+ *flags = uToken.ktc_tokenUnion_u.at_kad.rk_primary_flag & ~0x8000;
+
+ if (aclient) {
+ strncpy(aclient->cell, token->cell, MAXKTCREALMLEN-1);
+ aclient->cell[MAXKTCREALMLEN-1] = '\0';
+
+ if ((rxkadToken->kvno == 999) || /* old style bcrypt ticket */
+ (rxkadToken->startTime && /* new w/ prserver lookup */
+ (((rxkadToken->endTime - rxkadToken->startTime) & 1) == 1))) {
+ sprintf(aclient->name, "AFS ID %d",
+ uToken.ktc_tokenUnion_u.at_kad.rk_viceid);
+ } else {
+ sprintf(aclient->name, "Unix UID %d",
+ uToken.ktc_tokenUnion_u.at_kad.rk_viceid);
+ }
+ }
+
+out:
+ xdr_free((xdrproc_t) xdr_ktc_tokenUnion, &uToken);
+ return code;
+}
+
+struct ktc_setTokenData *
+token_buildTokenJar(char * cellname) {
+ struct ktc_setTokenData *jar;
+
+ jar = malloc(sizeof(struct ktc_setTokenData));
+ if (jar == NULL)
+ return NULL;
+
+ memset(jar, 0, sizeof(struct ktc_setTokenData));
+
+ jar->cell = strdup(cellname);
+
+ return jar;
+}
+
+/*!
+ * Add a token to an existing set of tokens. This will always add the token,
+ * regardless of whether an entry for the security class already exists
+ */
+int
+token_addToken(struct ktc_setTokenData *jar, struct ktc_tokenUnion *token) {
+ int code;
+ char *data;
+ size_t len;
+
+ code = encodeTokenUnion(token, &data, &len);
+ if (code)
+ goto out;
+
+ addOpaque(jar, data, len);
+
+out:
+ return code;
+}
+
+/*!
+ * Replace at token in an existing set of tokens. This replaces the first
+ * token stored of a matching type. If no matching tokens are found, then
+ * the new token is added at the end of the list
+ */
+int
+token_replaceToken(struct ktc_setTokenData *jar,
+ struct ktc_tokenUnion *token) {
+ int entry;
+ char *data;
+ size_t len;
+ int code;
+
+ entry = findTokenEntry(jar, token->at_type);
+ if (entry == -1)
+ return token_addToken(jar, token);
+
+ code = encodeTokenUnion(token, &data, &len);
+ if (code)
+ goto out;
+
+ free(jar->tokens.tokens_val[entry].token_opaque_val);
+ jar->tokens.tokens_val[entry].token_opaque_val = data;
+ jar->tokens.tokens_val[entry].token_opaque_len = len;
+
+out:
+ return code;
+}
+
+void
+token_setPag(struct ktc_setTokenData *jar, int setpag) {
+ if (setpag)
+ jar->flags |= AFSTOKEN_EX_SETPAG;
+ else
+ jar->flags &= ~AFSTOKEN_EX_SETPAG;
+}
--- /dev/null
+/*
+ * afstoken - pioctl interface for new common token data structures.
+ *
+ * revised following suggestions from lha@kth.se 20070511, 20070513
+ */
+
+/* this file is in the public domain. Do what thou wilt. */
+
+const AFSTOKEN_RK_TIX_MAX = 12000; /* Matches entry in rxkad.h */
+
+struct token_rxkad {
+ afs_int32 rk_viceid;
+ afs_int32 rk_kvno;
+ opaque rk_key[8];
+ afs_int32 rk_begintime;
+ afs_int32 rk_endtime;
+ afs_int32 rk_primary_flag;
+ opaque rk_ticket<AFSTOKEN_RK_TIX_MAX>;
+};
+
+const AFSTOKEN_UNION_NOAUTH = 0;
+const AFSTOKEN_UNION_KAD = 2;
+union ktc_tokenUnion switch (afs_int32 at_type) {
+ case AFSTOKEN_UNION_KAD:
+ token_rxkad at_kad;
+};
+
+const AFSTOKEN_LENGTH_MAX = 16384;
+typedef opaque token_opaque<AFSTOKEN_LENGTH_MAX>;
+
+const AFSTOKEN_EX_SETPAG = 0x00000001; /* set tokens in new pag */
+const AFSTOKEN_MAX = 8;
+const AFSTOKEN_CELL_MAX = 64;
+
+struct ktc_setTokenData {
+ afs_int32 flags;
+ string cell<AFSTOKEN_CELL_MAX>;
+ token_opaque tokens<AFSTOKEN_MAX>;
+};
#define VIOC_GETALIAS _CVICEIOCTL(2) /* get alias info */
#define VIOC_CBADDR _CVICEIOCTL(3) /* push callback addr */
#define VIOC_DISCON _CVICEIOCTL(5) /* set/get discon mode */
+#define VIOC_GETTOK2 _CVICEIOCTL(7) /* extended fetch tokens */
+#define VIOC_SETTOK2 _CVICEIOCTL(8) /* extended set tokens */
#define VIOC_NEWUUID _CVICEIOCTL(9) /* new uuid */
#define VIOCPRECACHE _CVICEIOCTL(12) /* precache size */
#define VIOC_GETPAG _CVICEIOCTL(13) /* get pag value */
-I${TOP_OBJDIR}/src/config \
-I${TOP_OBJDIR}/src/fsint \
-I${TOP_OBJDIR}/src/vlserver \
+ -I${TOP_OBJDIR}/src/auth \
-I${TOP_INCDIR} \
-I${TOP_INCDIR}/afs
rxkad_common.o \
xdr_afsuuid.o \
xdr.o \
+ token.xdr.o \
afs_uuid.o $(AFS_OS_OBJS)
# These next two allow nfs and nonfs builds to occur in the same directory.
AFS_component_version_number.o\
xdr_afsuuid.o \
xdr.o \
+ token.xdr.o \
afs_uuid.o $(AFS_OS_PAGOBJS)
$(CRULE_OPT)
xdr_len.o: $(TOP_SRCDIR)/rx/xdr_len.c
$(CRULE_OPT)
+token.xdr.o: $(TOP_OBJDIR)/src/auth/token.xdr.c
+ $(CRULE_OPT)
# these files are not to be optimized - subject to change.
afs_cbqueue.o: $(TOP_SRC_AFS)/afs_cbqueue.c
writeconfig.o \
authcon.o \
ktc_errors.o \
- acfg_errors.o
+ acfg_errors.o \
+ token.o \
+ token.xdr.o
KAUTHOBJS = \
kauth.xdr.o \
kaaux.o \
client.o \
authclient.o \
- token.o \
+ katoken.o \
kautils.o \
kalocalcell.o \
kaerrors.o \
${CCRULE} -I../auth
ktc.o: ${AUTH}/ktc.c
- ${CCRULE}
+ ${CCRULE} -I../auth
+
+token.o: ${AUTH}/token.c
+ ${CCRULE} -I../auth
+
+token.xdr.o: ${AUTH}/token.xdr.c
+ ${CCRULE} -I../auth
userok.o: ${AUTH}/userok.c
${CCRULE} -I../auth
authclient.o: ${KAUTH}/authclient.c
${CCRULE} -I../kauth
-token.o: ${KAUTH}/token.c
- ${CCRULE} -I../kauth
+katoken.o: ${KAUTH}/token.c
+ ${CCRULE} -o katoken.o -I../kauth
kautils.o: ${KAUTH}/kautils.c
${CCRULE} -I../kauth
LIB =../lib
NS_INCL =SRC/../afsweb/netscape_includes
+TOP_OBJ_AUTH = ${TOP_OBJDIR}/src/auth
TOP_OBJ_FSINT = ${TOP_OBJDIR}/src/fsint
TOP_OBJ_RXSTAT = ${TOP_OBJDIR}/src/rxstat
TOP_OBJ_VLSERVER = ${TOP_OBJDIR}/src/vlserver
TOP_SRC_AFS = ${TOP_SRCDIR}/afs
+TOP_SRC_AUTH = ${TOP_SRCDIR}/auth
TOP_SRC_RXSTAT = ${TOP_SRCDIR}/rxstat
TOP_SRC_FSINT = ${TOP_SRCDIR}/fsint
TOP_SRC_RX = ${TOP_SRCDIR}/rx
-I${TOP_OBJDIR}/src/fsint \
-I${TOP_OBJDIR}/src/vlserver \
-I${TOP_OBJDIR}/src/libuafs \
+ -I${TOP_OBJDIR}/src/auth \
-I${TOP_INCDIR} \
-I${TOP_INCDIR}/afs @INCLUDE_libintl@
$(UOBJ)/ptuser.o \
$(UOBJ)/pterror.o \
$(UOBJ)/ticket.o \
- $(UOBJ)/token.o \
+ $(UOBJ)/katoken.o \
$(UOBJ)/ubik_int.cs.o \
$(UOBJ)/ubik_int.xdr.o \
$(UOBJ)/ubikclient.o \
$(UOBJ)/rxstat.o \
$(UOBJ)/xdr_int32.o \
$(UOBJ)/xdr_int64.o \
+ $(UOBJ)/token.xdr.o \
+ $(UOBJ)/token.o \
$(UOBJ)/xdr_mem.o \
$(UOBJ)/xdr_len.o
$(WEBOBJ)/pterror.o \
$(WEBOBJ)/securehash.o \
$(WEBOBJ)/ticket.o \
- $(WEBOBJ)/token.o \
+ $(WEBOBJ)/katoken.o \
$(WEBOBJ)/ubik_int.cs.o \
$(WEBOBJ)/ubik_int.xdr.o \
$(WEBOBJ)/ubikclient.o \
$(WEBOBJ)/Krxstat.ss.o \
$(WEBOBJ)/Krxstat.xdr.o \
$(WEBOBJ)/rxstat.o \
+ $(WEBOBJ)/token.xdr.o \
+ $(WEBOBJ)/token.o \
$(WEBOBJ)/xdr_mem.o \
$(WEBOBJ)/xdr_len.o
$(WEBOBJ)/pterror.o \
$(WEBOBJ)/securehash.o \
$(WEBOBJ)/ticket.o \
- $(WEBOBJ)/token.o \
+ $(WEBOBJ)/katoken.o \
$(WEBOBJ)/ubik_int.cs.o \
$(WEBOBJ)/ubik_int.xdr.o \
$(WEBOBJ)/ubikclient.o \
$(WEBOBJ)/Krxstat.ss.o \
$(WEBOBJ)/Krxstat.xdr.o \
$(WEBOBJ)/rxstat.o \
+ $(WEBOBJ)/token.xdr.o \
+ $(WEBOBJ)/token.o \
$(WEBOBJ)/xdr_mem.o \
$(WEBOBJ)/xdr_len.o
$(JUAFS)/ptuser.o \
$(JUAFS)/pterror.o \
$(JUAFS)/ticket.o \
- $(JUAFS)/token.o \
+ $(JUAFS)/katoken.o \
$(JUAFS)/ubik_int.cs.o \
$(JUAFS)/ubik_int.xdr.o \
$(JUAFS)/ubikclient.o \
$(JUAFS)/Krxstat.xdr.o \
$(JUAFS)/rxstat.o \
$(JUAFS)/xdr_int64.o \
+ $(JUAFS)/token.xdr.o \
+ $(JUAFS)/token.o \
$(JUAFS)/xdr_mem.o \
$(JUAFS)/xdr_len.o
$(CRULE1)
$(UOBJ)/hostparse.o: $(TOP_SRCDIR)/util/hostparse.c
$(CRULE1)
-$(UOBJ)/token.o: $(TOP_SRCDIR)/kauth/token.c
- $(CRULE1)
+$(UOBJ)/katoken.o: $(TOP_SRCDIR)/kauth/token.c
+ $(CRULE1) -o katoken.o
$(UOBJ)/acfg_errors.o: $(TOP_OBJDIR)/src/auth/acfg_errors.c
$(CRULE1)
$(UOBJ)/kaaux.o: $(TOP_SRCDIR)/kauth/kaaux.c
$(CRULE1)
$(UOBJ)/Krxstat.xdr.o: $(TOP_OBJ_RXSTAT)/Krxstat.xdr.c
$(CRULE1)
+$(UOBJ)/token.xdr.o: $(TOP_OBJ_AUTH)/token.xdr.c
+ $(CRULE1)
+$(UOBJ)/token.o: $(TOP_SRCDIR)/auth/token.c
+ $(CRULE1)
$(UOBJ)/xdr_mem.o: $(TOP_SRC_RX)/xdr_mem.c
$(CRULE1)
$(UOBJ)/xdr_len.o: $(TOP_SRC_RX)/xdr_len.c
$(CRULE2)
$(WEBOBJ)/hostparse.o: $(TOP_SRCDIR)/util/hostparse.c
$(CRULE2)
-$(WEBOBJ)/token.o: $(TOP_SRCDIR)/kauth/token.c
- $(CRULE2)
+$(WEBOBJ)/katoken.o: $(TOP_SRCDIR)/kauth/token.c
+ $(CRULE2) -o katoken.o
$(WEBOBJ)/acfg_errors.o: $(TOP_OBJDIR)/src/auth/acfg_errors.c
$(CRULE2)
$(WEBOBJ)/kaaux.o: $(TOP_SRCDIR)/kauth/kaaux.c
$(CRULE2)
$(WEBOBJ)/Krxstat.xdr.o: $(TOP_OBJ_RXSTAT)/Krxstat.xdr.c
$(CRULE2)
+$(WEBOBJ)/token.xdr.o: $(TOP_OBJ_AUTH)/token.xdr.c
+ $(CRULE2)
+$(WEBOBJ)/token.o: $(TOP_SRCDIR)/auth/token.c
+ $(CRULE1)
$(WEBOBJ)/xdr_mem.o: $(TOP_SRC_RX)/xdr_mem.c
$(CRULE2)
$(WEBOBJ)/xdr_len.o: $(TOP_SRC_RX)/xdr_len.c
$(CRULE1)
$(JUAFS)/hostparse.o: $(TOP_SRCDIR)/util/hostparse.c
$(CRULE1)
-$(JUAFS)/token.o: $(TOP_SRCDIR)/kauth/token.c
- $(CRULE1)
+$(JUAFS)/katoken.o: $(TOP_SRCDIR)/kauth/token.c
+ $(CRULE1) -o katoken.o
$(JUAFS)/acfg_errors.o: $(TOP_OBJDIR)/src/auth/acfg_errors.c
$(CRULE1)
$(JUAFS)/kaaux.o: $(TOP_SRCDIR)/kauth/kaaux.c
$(CRULE1)
$(JUAFS)/Krxstat.xdr.o: $(TOP_OBJ_RXSTAT)/Krxstat.xdr.c
$(CRULE1)
+$(JUAFS)/token.xdr.o: $(TOP_OBJ_AUTH)/token.xdr.c
+ $(CRULE1)
+$(JUAFS)/token.o: $(TOP_SRCDIR)/auth/token.c
+ $(CRULE1)
$(JUAFS)/xdr_mem.o: $(TOP_SRC_RX)/xdr_mem.c
$(CRULE1)
$(JUAFS)/xdr_len.o: $(TOP_SRC_RX)/xdr_len.c
ktc_krb.o: ${srcdir}/../auth/ktc.c ${TOP_INCDIR}/afs/cellconfig.h \
${TOP_INCDIR}/afs/auth.h ${srcdir}/../auth/keys.h \
${TOP_INCDIR}/afs/vice.h
- ${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/../auth/ktc.c -o $@
+ ${CC} ${CFLAGS} -DAFS_KERBEROS_ENV -c ${srcdir}/../auth/ktc.c -I../auth -o $@
pam_afs.so.1: $(SHOBJS) afs_setcred.o afs_auth.o afs_util.o \
${TOP_LIBDIR}/libafsauthent_pic.a \
writeconfig.o \
authcon.o \
ktc_errors.o \
- acfg_errors.o
+ acfg_errors.o \
+ token.xdr.o \
+ token.o
KAUTHOBJS = \
kauth.xdr.o \
kaaux.o \
client.o \
authclient.o \
- token.o \
+ katoken.o \
kautils.o \
kalocalcell.o \
kaerrors.o \
acfg_errors.o: ${AUTH}/acfg_errors.c
${CCRULE}
+token.xdr.o: ${AUTH}/token.xdr.c
+ ${CCRULE}
+
+token.o :${AUTH}/token.c
+ ${CCRULE}
+
kauth.xdr.o: ${KAUTH}/kauth.xdr.c
${CCRULE}
authclient.o: ${KAUTH}/authclient.c
${CCRULE}
-token.o: ${KAUTH}/token.c
- ${CCRULE}
+katoken.o: ${KAUTH}/token.c
+ ${CCRULE} -o katoken.o
kautils.o: ${KAUTH}/kautils.c
${CCRULE}