AFS-PAG

 view release on metacpan or  search on metacpan

.gitignore  view on Meta::CPAN

/Build
/MANIFEST.bak
/MYMETA.json
/MYMETA.yml
/_build/
/blib/
/config.log
/cover_db
/glue/
/lib/AFS/PAG.c
*.o

Build.PL  view on Meta::CPAN

    # the relevant function name.
    my $return = 1;
    for my $function (@{$functions_ref}) {
        my $found_ref    = sub { $func_found_ref->($function) };
        my $notfound_ref = sub { $user_notfound_ref->($function) };
        $return &= check_func($self, $function, $found_ref, $notfound_ref);
    }
    return $return;
}

# Returns C code that includes the given headers.  Used to construct prologues
# for check functions.
#
# @headers - The headers to include
#
# Returns: C source as a string that includes those headers
sub include {
    my @headers = @_;
    my $result  = q{};
    for my $header (@headers) {
        $result .= "#include <$header>\n";

Build.PL  view on Meta::CPAN

    return @files;
}

# Basic package configuration.
my $build = Module::Build->new(
    module_name          => 'AFS::PAG',
    dist_version_from    => 'lib/AFS/PAG.pm',
    dist_author          => 'Russ Allbery <rra@cpan.org>',
    license              => 'mit',
    recursive_test_files => 1,
    add_to_cleanup       => [qw(config.log cover_db glue/*.o)],

    # XS configuration.
    c_source             => 'glue',
    extra_compiler_flags => ['-I.'],

    # Additional package metadata.
    meta_merge => {
        resources => {
            repository => 'git://git.eyrie.org/afs/afs-pag.git',
            bugtracker =>

Changes  view on Meta::CPAN

AFS::PAG 1.02 (2014-07-27)

    Rename NEWS to Changes to match the normal Perl convention.

    Add repository and bugtracker information in the distribution
    metadata.

    Update to rra-c-util 5.5:

    * Use Lancaster Consensus environment variables to control tests.
    * Work around perltidy bug that leaves behind stray log files.
    * Use calloc or reallocarray for protection against integer overflows.

AFS::PAG 1.01 (2013-10-06)

    Define the correct preprocessor symbols to build properly if a libkafs
    or libkopenafs library was found.

    Mark autodie required for configure and use for correct automated
    testing behavior on Perl 5.10.0.  (autodie was added to core in
    5.10.1.)

AFS::PAG 1.00 (2013-09-12)

    Initial public release with support for libkafs, libkopenafs, and
    Linux systems with no support library.  pioctl is not yet supported,
    only hasafs, haspag, setpag, and unlog.  The build system has only
    been tested on Debian.

MANIFEST.SKIP  view on Meta::CPAN

# -*- conf -*-

# Avoid version control files.
^\.git/

# Avoid generated build files.
\bblib/
^config\.log$
^glue/
^lib/AFS/PAG\.c$
\.o$

# Avoid Module::Build generated and utility files.
\bBuild$
\b_build/
\bBuild.bat$
\bBuild.COM$
\bBUILD.COM$

README  view on Meta::CPAN


                  Written by Russ Allbery <rra@cpan.org>

  Copyright 2013, 2014 The Board of Trustees of the Leland Stanford Junior
  University.  This software is distributed under a BSD-style license.
  Please see the section LICENSE below for more information.

BLURB

  AFS::PAG provides the standard PAG and token manipulation functions
  setpag and unlog to Perl programs as a native module.  It also provides
  the hasafs and haspag functions to detect whether AFS is running and
  whether the current process is in a PAG.  Unlike the more general AFS
  module, it will build with any recent OpenAFS, Heimdal's libkafs, or on
  Linux without any AFS libraries at all.

DESCRIPTION

  AFS is a distributed file system allowing cross-platform sharing of
  files among multiple computers.  It associates client credentials
  (called AFS tokens) with a Process Authentication Group, or PAG.

kafs/kafs.c  view on Meta::CPAN

/*
 * kafs replacement, main API.
 *
 * This is a simple implementation of the k_hasafs, k_setpag, and k_unlog
 * functions.  It is for use on systems that don't have libkafs or
 * libkopenafs, or where a dependency on those libraries is not desirable for
 * some reason.
 *
 * A more robust implementation of the full kafs interface would have a
 * separate header file with the various system call constants and would
 * support more operations and the k_pioctl interface.  Since this is a
 * stripped-down implementation with only the few functions to do PAG
 * management, various interface constants and system call numbers are
 * hard-coded here.

kafs/kafs.c  view on Meta::CPAN

    int err, rval;

    rval = k_syscall(21, 0, 0, 0, 0, &err);
    if (rval != 0)
        err = rval;
    return err;
}


/*
 * The unlog system call.  This destroys any tokens in the current PAG.
 */
int
k_unlog(void)
{
    struct ViceIoctl iob;

    iob.in = NULL;
    iob.in_size = 0;
    iob.out = NULL;
    iob.out_size = 0;
    return k_pioctl(NULL, _IOW('V', 9, struct ViceIoctl), &iob, 0);
}

lib/AFS/PAG.pm  view on Meta::CPAN

use warnings;

use base qw(DynaLoader);

use Exporter qw(import);

our (@EXPORT_OK, $VERSION);

# Set all import-related variables in a BEGIN block for robustness.
BEGIN {
    @EXPORT_OK = qw(hasafs haspag setpag unlog);
    $VERSION   = '1.02';
}

# Load the binary module.
bootstrap AFS::PAG $VERSION;

1;
__END__

=for stopwords
Allbery AFS PAG libkafs libkopenafs Kerberos aklog UID kdestroy

=head1 NAME

AFS::PAG - Perl bindings for AFS PAG manipulation

=head1 SYNOPSIS

    use AFS::PAG qw(hasafs setpag unlog);

    if (hasafs()) {
        setpag();
        system('aklog') == 0
          or die "cannot get tokens\n";
        do_afs_things();
        unlog();
    }

=head1 DESCRIPTION

AFS is a distributed file system allowing cross-platform sharing of files
among multiple computers.  It associates client credentials (called AFS
tokens) with a Process Authentication Group, or PAG.  AFS::PAG makes
available in Perl the PAG manipulation functions provided by the libkafs
or libkopenafs libraries.

With the functions provided by this module, a Perl program can detect
whether AFS is available on the local system (hasafs()) and whether it is
currently running inside a PAG (haspag()).  It can also create a new PAG
and put the current process in it (setpag()) and remove any AFS tokens in
the current PAG (unlog()).

Note that this module doesn't provide a direct way to obtain new AFS
tokens.  Programs that need AFS tokens should normally obtain Kerberos
tickets (via whatever means) and then run the program B<aklog>, which
comes with most AFS distributions.  This program will create AFS tokens
from the current Kerberos ticket cache and store them in the current PAG.
To isolate those credentials from the rest of the system, call setpag()
before running B<aklog>.

=head1 FUNCTIONS

This module provides the following functions, none of which are exported
by default:

=over 4

=item hasafs()

lib/AFS/PAG.pm  view on Meta::CPAN

tokens obtained inside a PAG are visible to any process in the same PAG,
regardless of UID.

=item setpag()

Creates a new, empty PAG and put the current process in it.  This should
normally be called before obtaining new AFS tokens to isolate those tokens
from other processes on the system.  Returns true on success and throws
an exception on failure.

=item unlog()

Deletes all AFS tokens in the current PAG, similar to the action of
B<kdestroy> on a Kerberos ticket cache.  Returns true on success and
throws an exception on failure.

=back

=head1 DIAGNOSTICS

=over 4

=item PAG creation failed: %s

setpag() failed.  The end of the error message will be a translation of
the system call error number.

=item Token deletion failed: %s

unlog() failed.  The end of the error message will be a translation of
the system call error number.

=back

=head1 RESTRICTIONS

This module currently doesn't provide the k_pioctl() or pioctl() function
to make lower-level AFS system calls.  It also doesn't provide the libkafs
functions to obtain AFS tokens from Kerberos tickets directly without using
an external ticket cache.  This prevents use of internal Kerberos ticket
caches (such as memory caches), since the Kerberos tickets used to generate
AFS tokens have to be visible to an external B<aklog> program.

=head1 AUTHOR

Russ Allbery <rra@cpan.org>

=head1 SEE ALSO

aklog(1)

The current version of this module is always available from its web site
at L<http://www.eyrie.org/~eagle/software/afs-pag/>.

=cut

lib/AFS/PAG.xs  view on Meta::CPAN

void
setpag()
  PPCODE:
    if (k_setpag() == 0)
        XSRETURN_YES;
    else
        croak("PAG creation failed: %s", strerror(errno));


void
unlog()
  PPCODE:
    if (k_unlog() == 0)
        XSRETURN_YES;
    else
        croak("Token deletion failed: %s", strerror(errno));

portable/kafs.h  view on Meta::CPAN

/*
 * Portability wrapper around the kafs API.
 *
 * This header includes kafs.h if it's available, prototypes k_hasafs,
 * k_setpag, and k_unlog replacements (generally provided by the kafs
 * replacement library) imlemented in terms of our system call layer or
 * lsetpag if it is available and libkafs isn't, and as a last resort provides
 * a k_hasafs function that always fails and k_setpag and k_unlog functions
 * that always succeed.
 *
 * It also defines the HAVE_KAFS macro to 1 if some AFS support was available,
 * in case programs that use it want to handle the case of no AFS support
 * differently (such as in help output).
 *
 * 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>

portable/kafs.h  view on Meta::CPAN

#  include <kopenafs.h>
# else
struct ViceIoctl {
    void *in, *out;
    short in_size;
    short out_size;
};
int k_hasafs(void);
int k_pioctl(char *, struct ViceIoctl *, void *, int);
int k_setpag(void);
int k_unlog(void);
# endif
# ifdef HAVE_K_HASPAG
#  if !defined(HAVE_KAFS_H) && !defined(HAVE_KOPENAFS_H)
int k_haspag(void);
#  endif
# else
int k_haspag(void) __attribute__((__visibility__("hidden")));
# endif

/* We're linking directly to the OpenAFS libraries. */
#elif HAVE_LSETPAG
# if HAVE_AFS_AFSSYSCALLS_H
#  include <afs/afssyscalls.h>
# else
int lsetpag(void);
int lpioctl(char *, int, void *, int);
# endif
# define k_hasafs()           (1)
# define k_pioctl(p, c, a, f) lpioctl((p), (c), (a), (f))
# define k_setpag()           lsetpag()
# define k_unlog()            (errno = ENOSYS, -1)

int k_haspag(void) __attribute__((__visibility__("hidden")));

/* We're using our local kafs replacement. */
#elif HAVE_KAFS_REPLACEMENT
# define HAVE_K_PIOCTL 1

struct ViceIoctl {
    void *in, *out;
    short in_size;
    short out_size;
};

/* Default to a hidden visibility for all portability functions. */
#pragma GCC visibility push(hidden)

int k_hasafs(void);
int k_haspag(void);
int k_pioctl(char *, int, struct ViceIoctl *, int);
int k_setpag(void);
int k_unlog(void);

/* Undo default visibility change. */
#pragma GCC visibility pop

/* We have no kafs implementation available. */
#else
# undef HAVE_KAFS
# define k_hasafs()           (0)
# define k_haspag()           (0)
# define k_pioctl(p, c, a, f) (errno = ENOSYS, -1)
# define k_setpag()           (errno = ENOSYS, -1)
# define k_unlog()            (errno = ENOSYS, -1)
#endif

END_DECLS

#endif /* PORTABLE_KAFS_H */

portable/stdbool.h  view on Meta::CPAN

/*
 * Portability wrapper around <stdbool.h>.
 *
 * Provides the bool and _Bool types and the true and false constants,
 * following the C99 specification, on hosts that don't have stdbool.h.  This
 * logic is based heavily on the example in the Autoconf manual.
 *
 * 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

t/data/perlcriticrc  view on Meta::CPAN


severity = 1
verbose  = %f:%l:%c: [%p] %m (%e, Severity: %s)\n

# I prefer this policy (a lot, actually), but other people in my group at
# Stanford really didn't like it, so this is my compromise to agree with a
# group coding style.
[-CodeLayout::ProhibitParensWithBuiltins]

# Stanford's coding style allows postfix unless for flow control.  There
# doesn't appear to be any way to allow it only for flow control (the logic
# for "if" and "when" appears to be special-cased), so we have to allow unless
# globally.
[ControlStructures::ProhibitPostfixControls]
allow = unless

# This is handled with a separate test case that uses Test::Spelling.
[-Documentation::PodSpelling]

# Pod::Man and Pod::Text fixed this bug years ago.  I know, I maintain them.
[-Documentation::RequirePodLinksIncludeText]

t/lib/Test/RRA.pm  view on Meta::CPAN

    }
    plan skip_all => "$description normally skipped";
    return;
}

# Attempt to load a module and skip the test if the module could not be
# loaded.  If the module could be loaded, call its import function manually.
# If the module could not be loaded, calls plan skip_all, which will terminate
# the program.
#
# The special logic here is based on Test::More and is required to get the
# imports to happen in the caller's namespace.
#
# $module  - Name of the module to load
# @imports - Any arguments to import, possibly including a version
#
# Returns: undef
sub use_prereq {
    my ($module, @imports) = @_;

    # If the first import looks like a version, pass it as a bare string.

t/pag/basic.t  view on Meta::CPAN


use lib 't/lib';

use Test::RRA qw(use_prereq);
BEGIN { use_prereq('IPC::System::Simple', qw(capturex systemx)) }

# Establish the plan now that we know we're continuing.
use Test::More tests => 6;

# Load the module.
BEGIN { use_ok('AFS::PAG', qw(hasafs haspag setpag unlog)) }

# Determines if the user has valid tokens by running tokens.
#
# Returns: True if the user has valid tokens, false if not or if tokens fails
sub has_tokens {
    my $tokens = eval { capturex('tokens') };
    if (!$@ && $tokens =~ m{ [ ] tokens [ ] for [ ] }xmsi) {
        return 1;
    } else {
        return;

t/pag/basic.t  view on Meta::CPAN

    ok(haspag(), '...and we are now in a PAG');

    # If we had tokens, check to see if k_setpag hides them.
  SKIP: {
        if (!$had_tokens) {
            skip 'cannot check token hiding without existing tokens', 1;
        }
        ok(!has_tokens(), '...and hides existing tokens');
    }

    # Try to obtain tokens with aklog and test unlog.
    my $status = eval { systemx('aklog') };
  SKIP: {
        if ($@ || $status != 0 || !has_tokens()) {
            skip 'aklog cannot obtain tokens, cannot test unlog', 2;
        }
        ok(unlog(),       'unlog succeeds');
        ok(!has_tokens(), '...and we no longer have tokens');
    }
}

t/pag/isolation.t  view on Meta::CPAN


use lib 't/lib';

use Test::RRA qw(use_prereq);
BEGIN { use_prereq('IPC::System::Simple', qw(capturex systemx)) }

# Establish the plan now that we know we're continuing.
use Test::More tests => 3;

# Load the module.
BEGIN { use_ok('AFS::PAG', qw(hasafs setpag unlog)) }

# Determines if the user has valid tokens by running tokens.
#
# Returns: True if the user has valid tokens, false if not or if tokens fails
sub has_tokens {
    my $tokens = eval { capturex('tokens') };
    if (!$@ && $tokens =~ m{ [ ] tokens [ ] for [ ] }xmsi) {
        return 1;
    } else {
        return;
    }
}

# We need AFS support and existing tokens to run this test.
SKIP: {
    if (!hasafs() || !has_tokens()) {
        skip 'AFS tokens not available', 2;
    }

    # Fork off a child that creates a new PAG and then runs unlog.  This
    # should not affect the tokens in our parent process.
    my $pid = fork;
    if ($pid == 0) {
        setpag();
        unlog();
        exit(0);
    } else {
        waitpid($pid, 0);
    }

    # Check that the child calls succeeded.
    is($?, 0, 'Child setpag and unlog succeeded');

    # Check that we still have tokens.
    ok(has_tokens(), 'Parent process still has tokens');
}



( run in 0.898 second using v1.01-cache-2.11-cpan-49f99fa48dc )