mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 23:10:58 +00:00
Add k_haspag to libkopenafs
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>
This commit is contained in:
parent
e29bd1f8d1
commit
5f2c6bd341
@ -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
|
||||
|
@ -12,14 +12,23 @@
|
||||
* 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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -6,6 +6,7 @@ KOPENAFS_1.0 {
|
||||
global:
|
||||
k_hasafs;
|
||||
k_setpag;
|
||||
k_haspag;
|
||||
k_unlog;
|
||||
k_pioctl;
|
||||
local:
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user