--- /dev/null
+/Build
+/MANIFEST.bak
+/MYMETA.json
+/MYMETA.yml
+/_build/
+/blib/
+/cover_db
+/lib/Authen/Kerberos/Kadmin.c
+*.o
--- /dev/null
+#!/usr/bin/perl
+#
+# Build script for the Authen::Kerberos distribution.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.010;
+use autodie;
+use strict;
+use warnings;
+
+use Module::Build;
+
+# Basic package configuration.
+my $build = Module::Build->new(
+ module_name => 'Authen::Kerberos',
+ dist_abstract => 'Perl bindings for Kerberos libraries',
+ dist_author => 'Russ Allbery <eagle@eyrie.org>',
+ dist_version => '0.01',
+ license => 'mit',
+ recursive_test_files => 1,
+
+ # XS configuration.
+ extra_linker_flags => ['-lkadm5srv'],
+
+ # Other package relationships.
+ configure_requires => {
+ 'Module::Build' => '0.28',
+ autodie => 0,
+ perl => '5.010',
+ },
+ requires => {
+ autodie => 0,
+ perl => '5.010',
+ },
+);
+
+# Generate the build script.
+$build->create_build_script;
--- /dev/null
+Build.PL
+lib/Authen/Kerberos/Exception.pm
+lib/Authen/Kerberos/Kadmin.pm
+lib/Authen/Kerberos/Kadmin.xs
+MANIFEST This list of files
+MANIFEST.SKIP
+t/data/perl.conf
+t/docs/pod-coverage.t
+t/docs/pod-spelling.t
+t/docs/pod.t
+t/docs/synopsis.t
+t/kadmin/basic.t
+t/misc/exception.t
+t/style/coverage.t
+t/style/critic.t
+t/style/minimum-version.t
+t/style/strict.t
+typemap
--- /dev/null
+# -*- conf -*-
+
+# Avoid version control files.
+^\.git/
+
+# Avoid generated build files.
+\bblib/
+^lib/Authen/Kerberos/Kadmin\.c$
+\.o$
+
+# Avoid Module::Build generated and utility files.
+\bBuild$
+\b_build/
+\bBuild.bat$
+\bBuild.COM$
+\bBUILD.COM$
+\bbuild.com$
+
+# Avoid temp and backup files.
+~$
+\.old$
+\#$
+\b\.#
+\.bak$
+\.tmp$
+\.#
+\.rej$
+
+# Avoid OS-specific files/dirs
+# Mac OSX metadata
+\B\.DS_Store
+# Mac OSX SMB mount metadata files
+\B\._
+
+# Avoid Devel::Cover and Devel::CoverX::Covered files.
+\bcover_db\b
+\bcovered\b
+
+# Avoid MYMETA files
+^MYMETA\.
+
+# Avoid archives of this distribution
+\bAuthen-Kerberos-[\d\.\_]+
--- /dev/null
+# Rich exception object for Kerberos operations.
+#
+# All Kerberos APIs, including ones on some subsidiary objects, throw an
+# Authen::Kerberos::Exception on any failure of the underlying Kerberos API
+# call. This is a rich exception object that carries the Kerberos library
+# error message, failure code, and additional information. This Perl class
+# defines the object and provides accessor methods to extract information from
+# it.
+#
+# These objects are constructed in the static kadmin_croak function defined in
+# Kadmin.xs. Any changes to the code here should be reflected there and vice
+# versa.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+package Authen::Kerberos::Exception;
+
+use 5.010;
+use strict;
+use warnings;
+
+use overload '""' => \&to_string, 'cmp' => \&spaceship;
+
+our $VERSION;
+
+# Set $VERSION in a BEGIN block for robustness.
+BEGIN {
+ $VERSION = '0.01';
+}
+
+# There is intentionally no constructor. This object is thrown by the
+# Kerberos C API.
+
+# Basic accessors.
+sub function { my $self = shift; return $self->{function} }
+sub message { my $self = shift; return $self->{message} }
+sub code { my $self = shift; return $self->{code} }
+
+# A full verbose message with all the information from the exception.
+#
+# $self - Authen::Kerberos::Exception object
+#
+# Returns: A string version of the exception information.
+sub to_string {
+ my ($self) = @_;
+ my $message = $self->{message};
+ my $function = $self->{function};
+ my $file = $self->{file};
+ my $line = $self->{line};
+
+ # Construct the verbose message, trying to follow the normal Perl text
+ # exception format.
+ my $result = q{};
+ if (defined($function)) {
+ $result .= "$function: ";
+ }
+ $result .= $message;
+ if (defined $line) {
+ $result .= " at $file line $line";
+ }
+ return $result;
+}
+
+# The cmp implmenetation converts the exception to a string and then compares
+# it to the other argument.
+#
+# $self - Authen::Kerberos::Exception object
+# $other - The other object (generally a string) to which to compare it
+# $swap - True if the order needs to be swapped for a proper comparison
+#
+# Returns: -1, 0, or 1 per the cmp interface contract
+sub spaceship {
+ my ($self, $other, $swap) = @_;
+ my $string = $self->to_string;
+ if ($swap) {
+ return ($other cmp $string);
+ } else {
+ return ($string cmp $other);
+ }
+}
+
+1;
+
+__END__
+
+=for stopwords
+Allbery
+
+=head1 NAME
+
+Authen::Kerberos::Exception - Rich exception for Kerberos API method errors
+
+=head1 SYNOPSIS
+
+ my $kadmin = Authen::Kerberos::Kadmin->new;
+ if (!eval { $kadmin->chpass('foo', 'password') }) {
+ if (ref($@) eq 'Authen::Kerberos::Exception') {
+ my $e = $@;
+ print 'function: ', $e->function, "\n";
+ print 'code: ', $e->code, "\n";
+ print 'message: ', $e->message, "\n";
+ print "$e\n";
+ die $e->to_string;
+ }
+ }
+
+=head1 DESCRIPTION
+
+All Authen::Kerberos::Kadmin methods will throw an exception on error.
+Exceptions produced by the underlying C API call will be represented by a
+Authen::Kerberos::Exception object.
+
+You can use this object like you would normally use $@, including printing
+it out and doing string comparisons with it, and it will convert to the
+string representation of the complete error message. But you can also
+access the structured data stored inside the exception by treating it as
+an object and using the methods defined below.
+
+=head1 METHODS
+
+=over 4
+
+=item code()
+
+Returns the Kerberos status code for the exception.
+
+=item function()
+
+Returns the name of the Kerberos C API function that failed and caused the
+exception to be raised.
+
+=item message()
+
+Returns the Kerberos error message. This uses the underlying Kerberos API
+calls to try to recover additional data about the cause of the error.
+
+=item spaceship([STRING], [SWAP])
+
+This method is called if the exception object is compared to a string via
+cmp. It will compare the given string to the verbose error message and
+return the result. If SWAP is set, it will reverse the order to compare
+the given string to the verbose error. (This is the normal interface
+contract for an overloaded C<cmp> implementation.)
+
+=item to_string()
+
+This method is called if the exception is interpolated into a string. It
+can also be called directly to retrieve the default string form of the
+exception.
+
+=back
+
+=head1 AUTHOR
+
+Russ Allbery <eagle@eyrie.org>
+
+=cut
--- /dev/null
+# Perl bindings for the kadmin API.
+#
+# This is the Perl boostrap file for the Authen::Kerberos::Kadmin module,
+# nearly all of which is implemented in XS. For the actual source, see
+# Kadmin.xs. This file contains the bootstrap and export code and the
+# documentation.
+#
+# Currently, this only provides an interface to the Heimdal libkadm5srv
+# library. This module will eventually become a level of indirection that can
+# select from several XS modules to support both MIT Kerberos and Heimdal, and
+# both the libkadm5clnt and libkadm5srv libraries.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+package Authen::Kerberos::Kadmin;
+
+use 5.010;
+use strict;
+use warnings;
+
+use base qw(DynaLoader);
+
+use Exporter qw(import);
+
+our $VERSION;
+
+# Set $VERSION in a BEGIN block for robustness.
+BEGIN {
+ $VERSION = '0.01';
+}
+
+# Load the binary module.
+bootstrap Authen::Kerberos::Kadmin $VERSION;
+
+1;
+__END__
+
+=for stopwords
+Allbery Heimdal KDC kadmin libkadm5srv
+
+=head1 NAME
+
+Authen::Kerberos::Kadmin - Perl bindings for Kerberos administration
+
+=head1 SYNOPSIS
+
+ use Authen::Kerberos::Kadmin;
+
+ my $kadmin = Authen::Kerberos::Kadmin->new(
+ {
+ password_quality => 1,
+ realm => 'EXAMPLE.COM',
+ server => 1,
+ }
+ );
+ my ($principal, $password);
+ $kadmin->chpass($principal, $password);
+
+=head1 REQUIREMENTS
+
+Perl 5.10 or later, a Heimdal KDC, and the Heimdal libkadm5srv library.
+
+=head1 DESCRIPTION
+
+Authen::Kerberos::Kadmin provides Perl bindings for the kadmin library
+API, used to perform Kerberos administrative actions such as creating and
+deleting principals or changing their keys or flags.
+
+Currently, this module only supports Heimdal and only supports the server
+mode, where the program is run on the KDC and makes changes directly to
+the Kerberos KDC database. It also only supports the password change
+operation currently. More functionality will be added later.
+
+=head1 CLASS METHODS
+
+All class methods throw exceptions on any error.
+
+=over 4
+
+=item new([ARGS])
+
+Create a new Authen::Kerberos::Kadmin object, which holds the internal
+library state. All further operations must be done with this object.
+ARGS, if present, is an anonymous hash of configuration options.
+Supported options are:
+
+=over 4
+
+=item password_quality
+
+If set to a true value, the password quality check configuration will be
+loaded and password quality checking will be enabled. If set to a false
+value or not present, passwords passed to chpass() will not be checked for
+quality. Be aware that, with a Heimdal KDC, password history is normally
+done via the password quality interface, so not setting this option may
+also lead to bypassing history checks.
+
+=item realm
+
+The Kerberos realm in which to take administrative actions.
+
+=item server
+
+If set to a true value, use the server kadmin API instead of the client
+API. This mode opens the Kerberos KDC database directly to make changes
+instead of using the kadmin network protocol. Currently, this option must
+be present and set to a true value.
+
+=back
+
+=back
+
+=head1 INSTANCE METHODS
+
+All instance methods throw exceptions on any error.
+
+=over 4
+
+=item chpass(PRINCIPAL, PASSWORD)
+
+Change the Kerberos password for PRINCIPAL to PASSWORD.
+
+=back
+
+=cut
+
+=head1 AUTHOR
+
+Russ Allbery <eagle@eyrie.org>
+
+=cut
--- /dev/null
+/* -*- c -*-
+ * Perl bindings for the kadmin API
+ *
+ * This is an XS source file, suitable for processing by xsubpp, that
+ * generates Perl bindings for the Kerberos kadmin API (libkadm5srv or
+ * libkadm5clnt). It also provides enough restructuring so that the C
+ * function calls can be treated as method calls on a kadmin connection
+ * object.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2014
+ * The Board of Trustees of the Leland Stanford Junior University
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <EXTERN.h>
+#include <perl.h>
+#include <XSUB.h>
+
+#include <krb5.h>
+#include <kadm5/admin.h>
+
+/*
+ * Define a struct that wraps the kadmin API handle so that we can include
+ * some other data structures that we need to use.
+ */
+typedef struct {
+ void *handle;
+ krb5_context ctx;
+} *Authen__Kerberos__Kadmin;
+
+/* Used to check that an object argument to a function is not NULL. */
+#define CROAK_NULL(o, t, f) \
+ do { \
+ if ((o) == NULL) \
+ croak(t " object is undef in " f); \
+ } while (0);
+#define CROAK_NULL_SELF(o, t, f) CROAK_NULL((o), t, t "::" f)
+
+
+/*
+ * Turn a Kerberos error into a Perl exception. If the destroy argument is
+ * true, free the Kerberos context after setting up the exception. This is
+ * used in cases where we're croaking inside the constructor.
+ */
+static void __attribute__((__noreturn__))
+kadmin_croak(krb5_context ctx, krb5_error_code code, const char *function,
+ bool destroy)
+{
+ HV *hv;
+ SV *rv;
+ const char *message;
+
+ hv = newHV();
+ (void) hv_store(hv, "code", 6, newSViv(code), 0);
+ message = krb5_get_error_message(ctx, code);
+ (void) hv_store(hv, "message", 7, newSVpv(message, 0), 0);
+ krb5_free_error_message(ctx, message);
+ if (destroy)
+ krb5_free_context(ctx);
+ if (function != NULL)
+ (void) hv_store(hv, "function", 6, newSVpv(function, 0), 0);
+ if (CopLINE(PL_curcop)) {
+ (void) hv_store(hv, "line", 4, newSViv(CopLINE(PL_curcop)), 0);
+ (void) hv_store(hv, "file", 4, newSVpv(CopFILE(PL_curcop), 0), 0);
+ }
+ rv = newRV_noinc((SV *) hv);
+ sv_bless(rv, gv_stashpv("Authen::Kerberos::Exception", TRUE));
+ sv_setsv(get_sv("@", TRUE), sv_2mortal(rv));
+ croak(Nullch);
+}
+
+
+/* XS code below this point. */
+
+MODULE = Authen::Kerberos::Kadmin PACKAGE = Authen::Kerberos::Kadmin
+
+PROTOTYPES: DISABLE
+
+
+Authen::Kerberos::Kadmin
+new(class, args)
+ const char *class
+ HV *args
+ PREINIT:
+ krb5_context ctx;
+ krb5_error_code code;
+ kadm5_config_params params;
+ SV **value = NULL;
+ void *handle;
+ Authen__Kerberos__Kadmin self;
+ bool quality = FALSE;
+ CODE:
+{
+ code = krb5_init_context(&ctx);
+ if (code != 0)
+ kadmin_croak(NULL, code, "krb5_init_context", FALSE);
+
+ /* Parse the arguments to the function, if any. */
+ memset(¶ms, 0, sizeof(params));
+ if (args != NULL) {
+ value = hv_fetchs(args, "realm", 0);
+ if (value != NULL) {
+ params.realm = SvPV_nolen(*value);
+ params.mask = KADM5_CONFIG_REALM;
+ }
+ value = hv_fetchs(args, "server", 0);
+ if (value == NULL || !SvTRUE(*value))
+ croak("server mode required in Authen::Kerberos::Kadmin::new");
+ value = hv_fetchs(args, "password_quality", 0);
+ if (value != NULL && SvTRUE(*value))
+ quality = TRUE;
+ }
+
+ /* Create the kadmin server handle. */
+ code = kadm5_init_with_password_ctx(ctx, "kadmin/admin", NULL, NULL,
+ ¶ms, KADM5_STRUCT_VERSION,
+ KADM5_API_VERSION_2, &handle);
+ if (code != 0)
+ kadmin_croak(ctx, code, "kadm5_init_with_password_ctx", TRUE);
+
+ /* Set up password quality checking if desired. */
+ if (quality)
+ kadm5_setup_passwd_quality_check(ctx, NULL, NULL);
+
+ /* Flesh out our internal data structure. */
+ self = malloc(sizeof(*self));
+ if (self == NULL) {
+ kadm5_destroy(handle);
+ krb5_free_context(ctx);
+ croak("cannot allocate memory");
+ }
+ self->ctx = ctx;
+ self->handle = handle;
+ RETVAL = self;
+}
+ OUTPUT:
+ RETVAL
+
+
+void
+DESTROY(self)
+ Authen::Kerberos::Kadmin self
+ CODE:
+{
+ if (self == NULL)
+ return;
+ kadm5_destroy(self->handle);
+ krb5_free_context(self->ctx);
+ free(self);
+}
+
+
+void
+chpass(self, principal, password)
+ Authen::Kerberos::Kadmin self
+ const char *principal
+ const char *password
+ PREINIT:
+ krb5_error_code code;
+ krb5_principal princ = NULL;
+ CODE:
+{
+ code = krb5_parse_name(self->ctx, principal, &princ);
+ if (code != 0)
+ kadmin_croak(self->ctx, code, "krb5_parse_name", FALSE);
+ code = kadm5_chpass_principal(self->handle, princ, password);
+ krb5_free_principal(self->ctx, princ);
+ if (code != 0)
+ kadmin_croak(self->ctx, code, "kadm5_chpass_principal", FALSE);
+ XSRETURN_YES;
+}
--- /dev/null
+# Configuration for Perl tests. -*- perl -*-
+
+# The level of coverage achieved by the test suite.
+$COVERAGE_LEVEL = 100;
+
+# Default minimum version requirement.
+$MINIMUM_VERSION = '5.010';
+
+# File must end with this line.
+1;
--- /dev/null
+# -*- conf -*-
+#
+# Default configuration for perlcritic. Be sure to copy this into the source
+# for packages that run perlcritic tests automatically during the build for
+# reproducible test results.
+#
+# This file has been updated to match perlcritic 1.118.
+#
+# 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>
+# Copyright 2011, 2012, 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+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]
+
+# The POD sections Perl::Critic wants are incompatible with the POD template
+# from perlpodstyle, which is what I use for my POD documentation.
+[-Documentation::RequirePodSections]
+
+# This problem was fixed in Perl 5.14, which now properly preserves the value
+# of $@ even if destructors run at exit from the eval block.
+[-ErrorHandling::RequireCheckingReturnValueOfEval]
+
+# The default of 9 is too small and forces weird code contortions.
+[InputOutput::RequireBriefOpen]
+lines = 25
+
+# This is correct 80% of the time, but it isn't correct for a lot of scripts
+# inside packages, where maintaining $VERSION isn't worth the effort.
+# Unfortunately, there's no way to override it, so it gets turned off
+# globally.
+[-Modules::RequireVersionVar]
+
+# This sounds interesting but is actually useless. Any large blocks of
+# literal text, which does not add to the complexity of the regex, will set it
+# off.
+[-RegularExpressions::ProhibitComplexRegexes]
+
+# I generally don't want to require Readonly as a prerequisite for all my Perl
+# modules.
+[-ValuesAndExpressions::ProhibitConstantPragma]
+
+# A good idea, but there are too many places where this would be more
+# confusing than helpful. Pull out numbers if one might change them
+# independent of the algorithm, but don't do so for mathematical formulae.
+[-ValuesAndExpressions::ProhibitMagicNumbers]
+
+# Increase this to six digits so that I'm not told to add underscores to
+# port numbers (which is just silly).
+[ValuesAndExpressions::RequireNumberSeparators]
+min_value = 100000
+
+# Text::Wrap has a broken interface that requires use of package variables.
+[Variables::ProhibitPackageVars]
+add_packages = Text::Wrap
+
+# use English was one of the worst ideas in the history of Perl. It makes the
+# code slightly more readable for amateurs at the cost of confusing
+# experienced Perl programmers and sending people in futile quests for where
+# these magical global variables are defined.
+[-Variables::ProhibitPunctuationVars]
--- /dev/null
+# -*- conf -*-
+#
+# Default options for perltidy for proper Perl code reformatting.
+#
+# 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/>.
+
+-bbao # put line breaks before any operator
+-nbbc # don't force blank lines before comments (bad for else blocks)
+-ce # cuddle braces around else
+-l=79 # usually use 78, but don't want 79-long lines reformatted
+-pt=2 # don't add extra whitespace around parentheses
+-sbt=2 # ...or square brackets
+-sfs # no space before semicolon in for (not that I use this form)
--- /dev/null
+#!/usr/bin/perl
+#
+# Test that all methods are documented in POD.
+#
+# 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>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(use_prereq);
+use Test::RRA::Config qw(@POD_COVERAGE_EXCLUDE);
+
+use_prereq('Test::Pod::Coverage');
+
+# Test everything found in the distribution.
+all_pod_coverage_ok({ also_private => [@POD_COVERAGE_EXCLUDE] });
--- /dev/null
+#!/usr/bin/perl
+#
+# Check for spelling errors in POD documentation.
+#
+# Checks all POD files in a Perl distribution using Test::Spelling. This test
+# is disabled unless RRA_MAINTAINER_TESTS is set, since spelling dictionaries
+# vary too much between environments.
+#
+# 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>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(skip_unless_maintainer use_prereq);
+
+# Only run this test for the maintainer.
+skip_unless_maintainer('Spelling tests');
+
+# Load prerequisite modules.
+use_prereq('Test::Spelling');
+
+# Check all POD in the Perl distribution. Add the examples directory if it
+# exists. Also add any files in usr/bin or usr/sbin, which are widely used in
+# Stanford-internal packages.
+my @files = all_pod_files();
+if (-d 'examples') {
+ push(@files, all_pod_files('examples'));
+}
+for my $dir (qw(usr/bin usr/sbin)) {
+ if (-d $dir) {
+ push(@files, glob("$dir/*"));
+ }
+}
+
+# We now have a list of all files to check, so output a plan and run the
+# tests. We can't use all_pod_files_spelling_ok because it refuses to check
+# non-Perl files and Stanford-internal packages have a lot of shell scripts
+# with POD documentation.
+plan tests => scalar(@files);
+for my $file (@files) {
+ pod_file_spelling_ok($file);
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Check all POD documents for POD formatting errors.
+#
+# 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>
+# Copyright 2012, 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(use_prereq);
+
+use_prereq('Test::Pod');
+
+# Check all POD in the Perl distribution. Add the examples directory if it
+# exists. Also add any files in usr/bin or usr/sbin, which are widely used in
+# Stanford-internal packages.
+my @files = all_pod_files();
+if (-d 'examples') {
+ push(@files, all_pod_files('examples'));
+}
+for my $dir (qw(usr/bin usr/sbin)) {
+ if (-d $dir) {
+ push(@files, glob("$dir/*"));
+ }
+}
+
+# We now have a list of all files to check, so output a plan and run the
+# tests. We can't use all_pod_files_ok because it refuses to check non-Perl
+# files and Stanford-internal packages have a lot of shell scripts with POD
+# documentation.
+plan tests => scalar(@files);
+for my $file (@files) {
+ pod_file_ok($file);
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Check the SYNOPSIS section of the documentation for syntax errors.
+#
+# 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>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(use_prereq);
+
+use_prereq('Perl::Critic::Utils');
+use_prereq('Test::Synopsis');
+
+# The default Test::Synopsis all_synopsis_ok() function requires that the
+# module be in a lib directory. Use Perl::Critic::Utils to find the modules
+# in blib, or lib if it doesn't exist. However, strip out anything in
+# blib/script, since scripts use a different SYNOPSIS syntax.
+my @files = Perl::Critic::Utils::all_perl_files('blib');
+@files = grep { !m{blib/script/}xms } @files;
+if (!@files) {
+ @files = Perl::Critic::Utils::all_perl_files('lib');
+}
+plan tests => scalar @files;
+
+# Run the actual tests.
+for my $file (@files) {
+ synopsis_ok($file);
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Test suite for Authen::Kerberos::Kadmin basic functionality.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+use 5.010;
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+BEGIN {
+ use_ok('Authen::Kerberos::Kadmin');
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Test suite for Authen::Kerberos::Exception
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+use 5.010;
+use strict;
+use warnings;
+
+use Test::More tests => 12;
+
+BEGIN {
+ use_ok('Authen::Kerberos::Exception');
+}
+
+# We have to create an exception by hand, since there is (intentionally) no
+# Perl interface to create one and currently we don't support any functions
+# that let us easily generate a real exception.
+my $exception = {
+ code => -1_765_328_383,
+ message => 'A Kerberos error message',
+ function => 'krb5_foo',
+ file => 'exception.t',
+ line => 10,
+};
+bless($exception, 'Authen::Kerberos::Exception');
+
+# Check the accessors.
+is($exception->code, -1_765_328_383, 'code');
+is($exception->message, 'A Kerberos error message', 'message');
+is($exception->function, 'krb5_foo', 'function');
+
+# Check the string representation.
+is($exception->to_string,
+ 'krb5_foo: A Kerberos error message at exception.t line 10', 'to_string');
+is("$exception", 'krb5_foo: A Kerberos error message at exception.t line 10',
+ 'stringify');
+
+# The function, file, and line are optional. Try without them.
+delete $exception->{function};
+delete $exception->{file};
+delete $exception->{line};
+is($exception->to_string, 'A Kerberos error message', 'to_string short');
+is("$exception", 'A Kerberos error message', 'stringify short');
+
+# Check cmp.
+my $string = "$exception";
+is($exception cmp $string, 0, 'cmp equal');
+is($string cmp $exception, 0, 'cmp equal reversed');
+is($exception cmp 'Test', -1, 'cmp unequal');
+is('Test' cmp $exception, 1, 'cmp unequal reversed');
--- /dev/null
+#!/usr/bin/perl
+#
+# Test Perl code for test coverage.
+#
+# Test coverage checking is disabled unless RRA_MAINTAINER_TESTS is set since
+# it takes a long time, is sensitive to the versions of various libraries,
+# and will not interfere with functionality.
+#
+# 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>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::More;
+use Test::RRA qw(skip_unless_maintainer use_prereq);
+use Test::RRA::Config qw($COVERAGE_LEVEL @COVERAGE_SKIP_TESTS);
+
+# Skip code coverage unless doing maintainer testing.
+skip_unless_maintainer('Coverage testing');
+
+# Load required modules.
+use_prereq('Devel::Cover');
+use_prereq('Test::Strict');
+
+# Build a list of test directories to use for coverage.
+my %ignore = map { $_ => 1 } qw(docs style), @COVERAGE_SKIP_TESTS;
+opendir(my $testdir, 't') or BAIL_OUT("cannot open t: $!");
+my @t_dirs = readdir($testdir) or BAIL_OUT("cannot read t: $!");
+closedir($testdir) or BAIL_OUT("cannot close t: $!");
+
+# Filter out ignored and system directories.
+@t_dirs = grep { !$ignore{$_} } File::Spec->no_upwards(@t_dirs);
+
+# Prepend the t directory name to the directories.
+@t_dirs = map { File::Spec->catfile('t', $_) } @t_dirs;
+
+# Disable POD coverage; that's handled separately and is confused by
+# autoloading.
+$Test::Strict::DEVEL_COVER_OPTIONS
+ = '-coverage,statement,branch,condition,subroutine';
+
+# Do the coverage analysis.
+all_cover_ok($COVERAGE_LEVEL, @t_dirs);
+
+# Hack to suppress "used only once" warnings.
+END { $Test::Strict::DEVEL_COVER_OPTIONS = q{} }
--- /dev/null
+#!/usr/bin/perl
+#
+# Check for perlcritic errors in all code.
+#
+# Checks all Perl code in blib/lib, t, and Makefile.PL for problems uncovered
+# by perlcritic. This test is disabled unless RRA_MAINTAINER_TESTS is set,
+# since coding style will not interfere with functionality and newer versions
+# of perlcritic may introduce new checks.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(skip_unless_maintainer use_prereq);
+use Test::RRA::Config qw(@CRITIC_IGNORE);
+
+# Skip tests unless we're running the test suite in maintainer mode.
+skip_unless_maintainer('Coding style tests');
+
+# Load prerequisite modules.
+use_prereq('Perl::Critic::Utils');
+use_prereq('Test::Perl::Critic');
+
+# Force the embedded Perl::Tidy check to use the correct configuration.
+local $ENV{PERLTIDY} = 't/data/perltidyrc';
+
+# Import the configuration file and run Perl::Critic.
+Test::Perl::Critic->import(-profile => 't/data/perlcriticrc');
+
+# By default, Test::Perl::Critic only checks blib. We also want to check t,
+# Build.PL, and examples.
+my @files = Perl::Critic::Utils::all_perl_files('blib');
+if (!@files) {
+ @files = Perl::Critic::Utils::all_perl_files('lib');
+}
+if (-f 'Build.PL') {
+ push(@files, 'Build.PL');
+}
+for my $dir (qw(examples usr t)) {
+ if (-d $dir) {
+ push(@files, Perl::Critic::Utils::all_perl_files($dir));
+ }
+}
+
+# Strip out Autoconf templates or left-over perltidy files.
+@files = grep { !m{ [.](?:in|tdy) }xms } @files;
+
+# Strip out ignored files.
+my %ignore = map { $_ => 1 } @CRITIC_IGNORE;
+@files = grep { !$ignore{$_} } @files;
+
+# Declare a plan now that we know what we're testing.
+plan tests => scalar @files;
+
+# Run the actual tests.
+for my $file (@files) {
+ critic_ok($file);
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Check that too-new features of Perl are not being used.
+#
+# 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>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use Test::More;
+use Test::RRA qw(use_prereq);
+use Test::RRA::Config qw($MINIMUM_VERSION);
+
+use_prereq('Test::MinimumVersion');
+
+# Check all files in the Perl distribution.
+all_minimum_version_ok($MINIMUM_VERSION);
--- /dev/null
+#!/usr/bin/perl
+#
+# Test Perl code for strict, warnings, and syntax.
+#
+# 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>
+# Copyright 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+use 5.006;
+use strict;
+use warnings;
+
+use lib 't/lib';
+
+use File::Spec;
+use Test::RRA qw(use_prereq);
+
+use_prereq('Test::Strict');
+
+# Test everything in the distribution directory except the Build and
+# Makefile.PL scripts generated by Module::Build. We also want to check use
+# warnings.
+$Test::Strict::TEST_SKIP = ['Build', 'Makefile.PL'];
+$Test::Strict::TEST_WARNINGS = 1;
+all_perl_files_ok(File::Spec->curdir);
+
+# Hack to suppress "used only once" warnings.
+END {
+ $Test::Strict::TEST_SKIP = [];
+ $Test::Strict::TEST_WARNINGS = 0;
+}
--- /dev/null
+# Typemap file for the Perl bindings to the Kerberos library.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2014
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+TYPEMAP
+
+Authen::Kerberos::Kadmin T_PTROBJ_NU
+
+INPUT
+
+T_PTROBJ_NU
+ if ($arg == &PL_sv_undef) {
+ $var = NULL;
+ } else if (sv_isa($arg, \"${ntype}\")) {
+ IV tmp = SvIV((SV *) SvRV($arg));
+ $var = INT2PTR($type, tmp);
+ } else {
+ croak(\"$var is not of type ${ntype}\");
+ }
+
+OUTPUT
+
+T_PTROBJ_NU
+ if ($var == NULL)
+ $arg = &PL_sv_undef;
+ else
+ sv_setref_pv($arg, \"${ntype}\", (void *) $var);