AFS-PAG

 view release on metacpan or  search on metacpan

portable/k_haspag.c  view on Meta::CPAN

/*
 * Replacement for missing k_haspag kafs function.
 *
 * k_haspag is a relatively new addition to the kafs interface (implemented by
 * Heimdal's libkafs and OpenAFS's libkopenafs).  It returns true if the
 * current process is in a PAG and false otherwise.  This is a replacement
 * function for libraries that don't have it or for use with a replacement
 * kafs layer.  It falls back on looking at the current process's supplemental
 * groups if the system call isn't supported or if k_pioctl isn't available.
 *
 * The canonical version of this file is maintained in the rra-c-util package,
 * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 *
 * The authors hereby relinquish any claim to any copyright that they may have
 * in this work, whether granted under contract or by operation of law or
 * international treaty, and hereby commit to the public, at large, that they
 * shall not, at any time in the future, seek to enforce any copyright in this
 * work against any person or entity, or prevent any person or entity from
 * copying, publishing, distributing or creating derivative works of this
 * work.
 */

#include <config.h>
#include <portable/kafs.h>
#include <portable/system.h>

#ifdef HAVE_SYS_IOCCOM_H
# include <sys/ioccom.h>
#endif
#include <sys/ioctl.h>


/*
 * The haspag function.  Returns true if the current process is in a PAG,
 * false otherwise.  This attempts a system call, and if that fails, falls
 * back on looking for supplemental groups that match the AFS groups.
 */
int
k_haspag(void)
{
    int ngroups, i;
    gid_t *groups;
    uint32_t pag, g0, g1, hi, lo;

    /* First, try the system call if k_pioctl is available. */
#ifdef HAVE_K_PIOCTL
    int result;
    struct ViceIoctl iob;

    iob.in = NULL;
    iob.in_size = 0;
    iob.out = (void *) &pag;
    iob.out_size = sizeof(pag);
    result = k_pioctl(NULL, _IOW('C', 13, struct ViceIoctl), &iob, 0);
    if (result == 0)
        return pag != (uint32_t) -1;
#endif

    /*
     * If that failed, the cache manager may not support the VIOC_GETPAG
     * system call.  Fall back on analyzing the groups.
     */
    ngroups = getgroups(0, NULL);
    groups = calloc(ngroups, sizeof(*groups));
    if (groups == NULL)
        return 0;
    ngroups = getgroups(ngroups, groups);

    /*
     * Strictly speaking, the single group PAG is only used on Linux, but
     * check it everywhere anyway to simplify life.
     */
    for (i = 0; i < ngroups; i++)
        if (((groups[i] >> 24) & 0xff) == 'A') {
            free(groups);
            return 1;
        }



( run in 2.509 seconds using v1.01-cache-2.11-cpan-b9db842bd85 )