ktc: fix up initializer for local_tokens
[openafs.git] / src / auth / ktc.c
index 3e0e0a7..002f53b 100644 (file)
 #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];
 
@@ -100,9 +88,6 @@ static char lcell[MAXCELLCHARS];
 #define BUFSIZ 4096
 #endif
 
-#ifdef AFS_HPUX_ENV
-#include <unistd.h>
-#endif
 #if    defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
 static struct flock fileWlock = { F_WRLCK, 0, 0, 0, 0, 0 };
 static struct flock fileRlock = { F_RDLCK, 0, 0, 0, 0, 0 };
@@ -136,7 +121,7 @@ static void ktc_LocalCell(void);
 #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
@@ -160,11 +145,11 @@ static struct {
     struct ktc_principal server;
     struct ktc_principal client;
     struct ktc_token token;
-} local_tokens[MAXLOCALTOKENS] = { {
-0}, {
-0}, {
-0}, {
-0}};
+} local_tokens[MAXLOCALTOKENS];
+
+static int
+GetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
+          int atokenLen, struct ktc_principal *alicnet, afs_int32 *aviceid);
 
 
 #define MAXPIOCTLTOKENLEN \
@@ -310,14 +295,6 @@ SetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
     }
 #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;
@@ -375,7 +352,11 @@ ktc_SetTokenEx(struct ktc_setTokenData *token) {
 
        memset(&server, 0, sizeof(server));
        strcpy(server.name, "afs");
-       strcpy(server.cell, token->cell);
+       if (strlcpy(server.cell, token->cell, sizeof(server.cell))
+               >= sizeof(server.cell)) {
+           free(rxkadToken);
+           return KTC_INVAL;
+       }
        code = ktc_SetToken(&server, rxkadToken, &client, flags);
        free(rxkadToken);
        return code;
@@ -383,6 +364,15 @@ ktc_SetTokenEx(struct ktc_setTokenData *token) {
 
     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;
 }
@@ -486,9 +476,9 @@ ktc_GetTokenEx(char *cellName, struct ktc_setTokenData **tokenSet) {
      */
     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));
@@ -497,9 +487,12 @@ ktc_GetTokenEx(char *cellName, struct ktc_setTokenData **tokenSet) {
        memset(ktcToken, 0, sizeof(struct ktc_token));
 
        strcpy(server.name, "afs");
-       strcpy(server.cell, cellName);
-       code = ktc_GetToken(&server, ktcToken, sizeof(struct ktc_token),
-                           &client);
+
+       if (cellName != NULL)
+           strcpy(server.cell, cellName);
+
+       code = GetToken(&server, ktcToken, sizeof(struct ktc_token),
+                        NULL /*client*/, &viceid);
        if (code == 0) {
            *tokenSet = token_buildTokenJar(cellName);
            token.at_type = AFSTOKEN_UNION_KAD;
@@ -513,12 +506,14 @@ ktc_GetTokenEx(char *cellName, struct ktc_setTokenData **tokenSet) {
                = 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;
@@ -546,6 +541,13 @@ int
 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;
@@ -559,6 +561,9 @@ ktc_GetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
 #ifdef AFS_KERBEROS_ENV
     char found = 0;
 #endif
+    if (aviceid) {
+       *aviceid = 0;
+    }
 
     LOCK_GLOBAL_MUTEX;
 
@@ -694,15 +699,22 @@ ktc_GetToken(struct ktc_principal *aserver, struct ktc_token *atoken,
                       sizeof(struct ktc_encryptionKey));
                atoken->ticketLen = tktLen;
 
-               if (aclient) {
-                   strcpy(aclient->cell, cellp);
-                   aclient->instance[0] = 0;
+               if (aclient || aviceid) {
+                   if (aclient) {
+                       strlcpy(aclient->cell, cellp, sizeof(aclient->cell));
+                       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);
                    }
                }
@@ -736,6 +748,27 @@ ktc_ForgetToken(struct ktc_principal *aserver)
 }
 #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;
@@ -936,7 +969,7 @@ ktc_ListTokens(int aprevIndex,
     tp += temp;                        /* skip clear token itself */
     tp += sizeof(afs_int32);   /* skip primary flag */
     /* tp now points to the cell name */
-    strcpy(aserver->cell, tp);
+    strlcpy(aserver->cell, tp, sizeof(aserver->cell));
     aserver->instance[0] = 0;
     strcpy(aserver->name, "afs");
 #endif /* NO_AFS_CLIENT */
@@ -1076,10 +1109,6 @@ ktc_curpag(void)
   */
 
 #if 0
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <sys/file.h>
 #include <krb.h>
 #endif
@@ -1794,7 +1823,7 @@ extern char **environ;
 
     for (senv = environ, numenv = 0; *senv; senv++)
        numenv++;
-    newenv = (char **)malloc((numenv + 2) * sizeof(char *));
+    newenv = malloc((numenv + 2) * sizeof(char *));
 
     for (senv = environ, denv = newenv; *senv; senv++) {
        if (strncmp(*senv, "KRBTKFILE=", 10) != 0 &&