]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Add k_haspag to libkopenafs
authorRuss Allbery <rra@stanford.edu>
Thu, 27 May 2010 04:23:10 +0000 (23:23 -0500)
committerDerrick Brashear <shadow@dementia.org>
Fri, 28 May 2010 02:52:07 +0000 (19:52 -0700)
Add the k_haspag function to libkopenafs, which returns true if the
current process is in a PAG and false otherwise.

The implementation currently duplicates code from the ktc_curpag
function since the latter calls the regular pioctl() interface and
hence introduces an Rx dependency that we're avoiding for libkopenafs.
This should be refactored to avoid the code duplication at some point,
but that will require building a utility library that can be reasonably
linked into libkopenafs and is therefore deferred for future work.

Change-Id: Ib97322ef24dc3a4e48cb45090c516c95b71e9fc7
Reviewed-on: http://gerrit.openafs.org/2041
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>
src/kopenafs/Makefile.in
src/kopenafs/kopenafs.c
src/kopenafs/kopenafs.h
src/kopenafs/libkopenafs.map
src/kopenafs/test-setpag.c

index dceeb16422be27613288a4378dd76548d9cdd61f..25a5f03afdbfcb32f997c87d43e3a1ed0e01d8ad 100644 (file)
@@ -17,7 +17,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
 # API version. When something changes, increment as appropriate. 
 # Ignore at your own risk.
 MAJOR          = 1
-MINOR          = 0
+MINOR          = 1
 
 CC             = ${MT_CC}
 INCLUDES       = -I. -I${srcdir} -I../sys
index 727e05a617266268f4a75d9cd936935f5c7abdf6..746a4b55499c14aa3f051cfb09e775c3120482dd 100644 (file)
  * included in the libsys code.
  */
 
-#include <sys/param.h>
-#include <netinet/in.h>
 #include <errno.h>
-#include <stdlib.h>
+#include <netinet/in.h>
 #include <signal.h>
+#include <stdlib.h>
+#ifdef AFS_AIX51_ENV
+# include <sys/cred.h>
+# ifdef HAVE_SYS_PAG_H
+#  include <sys/pag.h>
+# endif
+#endif
+#include <sys/param.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include <afsconfig.h>
 #include <afs/afssyscalls.h>
+#include <afs/param.h>
 #include <kopenafs.h>
 
 static volatile sig_atomic_t syscall_okay = 1;
@@ -87,3 +96,99 @@ k_unlog(void)
     iob.out_size = 0;
     return lpioctl(NULL, VIOCUNLOG, &iob, 0);
 }
+
+
+/*
+ * If we don't have the VIOC_GETPAG pioctl, we try to determine whether we're
+ * in a PAG by using either a special OS call (AIX 5.2 and later) or by
+ * walking the group list, which works differently for current versions of
+ * Linux.
+ *
+ * These OS differences are encapsulated in the following OS-specific haspag
+ * helper functions.
+ *
+ * This is largely copied from auth/ktc.c and should be merged with that
+ * version, but that version calls through the pioctl() interface right now
+ * and therefore pulls in Rx for NFS translator support.  This avoids an Rx
+ * dependency in the standalone libkopenafs interface.
+ */
+#if defined(AFS_AIX52_ENV)
+static int
+os_haspag(void)
+{
+    return (getpagvalue("afs") < 0) ? 0 : 1;
+}
+#elif defined(AFS_AIX51_ENV)
+static int
+os_haspag(void)
+{
+    return 0;
+}
+#else
+static int
+os_haspag(void)
+{
+    int ngroups;
+    gid_t *groups;
+    afs_uint32 g0, g1;
+    afs_uint32 h, l, pag;
+# ifdef AFS_LINUX26_ENV
+    int i;
+# endif
+
+    ngroups = getgroups(0, NULL);
+    groups = malloc(sizeof(*groups) * ngroups);
+    if (groups == NULL)
+        return 0;
+    ngroups = getgroups(ngroups, groups);
+
+    /* Check for AFS_LINUX26_ONEGROUP_ENV PAGs. */
+# ifdef AFS_LINUX26_ENV
+    for (i = 0; i < ngroups; i++)
+        if (((groups[i] >> 24) & 0xff) == 'A') {
+            free(groups);
+            return 1;
+        }
+# endif
+
+    /* Check for the PAG group pair. */
+    if (ngroups < 2) {
+        free(groups);
+        return 0;
+    }
+    g0 = groups[0] & 0xffff;
+    g1 = groups[1] & 0xffff;
+    free(groups);
+    g0 -= 0x3f00;
+    g1 -= 0x3f00;
+    if (g0 < 0xc000 && g1 < 0xc000) {
+        l = ((g0 & 0x3fff) << 14) | (g1 & 0x3fff);
+        h = (g0 >> 14);
+        h = (g1 >> 14) + h + h + h;
+        pag = ((h << 28) | l);
+        if (((pag >> 24) & 0xff) == 'A')
+            return 1;
+        else
+            return 0;
+    }
+    return 0;
+}
+#endif /* !AFS_AIX51_ENV */
+
+int
+k_haspag(void)
+{
+    int code;
+    struct ViceIoctl iob;
+    afs_uint32 pag;
+
+    iob.in = NULL;
+    iob.in_size = 0;
+    iob.out = (caddr_t) &pag;
+    iob.out_size = sizeof(afs_uint32);
+    code = lpioctl(NULL, VIOC_GETPAG, &iob, 0);
+    if (code == 0)
+        return pag != (afs_uint32) -1;
+    else
+        return os_haspag();
+}
index cfa2aa43efdf16acb1024fc12414a0fc3563071a..3bdbc19974226953df690b0695d91d25cb9e1921 100644 (file)
@@ -37,6 +37,12 @@ int k_hasafs(void);
  */
 int k_setpag(void);
 
+/*
+ * Returns true if the current process is in a PAG and false if it is not or
+ * if an error was encountered in determining whether it is in a PAG.
+ */
+int k_haspag(void);
+
 /*
  * Remove the tokens in the current PAG.  Returns 0 on success, non-zero on
  * system call failure.
index 2220a046eb5972a7e038aa427b7781228e06b1f0..0bc3f66a136f9ffebd7d4d2e739b4796b0cddcd3 100644 (file)
@@ -6,6 +6,7 @@ KOPENAFS_1.0 {
     global:
         k_hasafs;
         k_setpag;
+        k_haspag;
         k_unlog;
         k_pioctl;
     local:
index dc11673bcbb38ff61dbe7585a6335069269951da..fa3a5fffc06a3cec75e463ed98e952550318fd26 100644 (file)
@@ -13,6 +13,9 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <unistd.h>
+
+#include <kopenafs.h>
 
 int
 main(int argc, char *argv[])
@@ -20,9 +23,12 @@ main(int argc, char *argv[])
     int status;
 
     if (k_hasafs()) {
+        printf("%s in a PAG\n", k_haspag() ? "Currently" : "Not currently");
         printf("Running k_setpag\n");
         status = k_setpag();
         printf("Status: %d, errno: %d\n", status, errno);
+        if (!k_haspag())
+            printf("Error: not in a PAG after k_setpag()\n");
         if (argc > 1) {
             argv++;
             execvp(argv[0], argv);
@@ -30,4 +36,5 @@ main(int argc, char *argv[])
     } else {
         printf("AFS apparently not running\n");
     }
+    return 0;
 }