Perforce auth-check trigger for Unix passwd file

I just installed Perforce (what a hassle!) and discovered that it won’t authenticate to the local Unix accounts out of the box.  The nice folks at Perforce let you call an external trigger, and provide a complex sample that will handle talking to Active Directory, but don’t have one do handle ordinary Unix passwd access.

Totally annoying.  A simple Perl script fixed it.  Don’t know why they didn’t put it in their samples, though.

#!/usr/bin/perl

use strict;
use warnings;

=head1 NAME p4_check_passwd

Called with the user name on the command line and the password on standard
input, this program returns a success or failure depending on that password's
correctness.

Uses getpwnam to do so, and must run as root on in shadow group to access
/etc/shadow and password data.

This should be configured in p4 triggers as an auth-check trigger:

Triggers:
unixpw auth-check auth "/home/perforce/bin/p4_check_passwd.pl %user%"

This uses the crypt system call, which should handle any variants of encryption
in your password file. It also uses the getpwnam() function to access
the password data, so should be able to access data from NIS or other
configured password system.

=cut

# Perforce wants all messages on stdout. Guarantee that.
open(STDERR, ">&STDOUT") or die "Can't redirect to stdout\n";

# Get the user name
my $username = shift;
die "Need user name on command line\n" unless $username;

# Get the password
my $password = <STDIN>;
chomp $password;

# Get username and password from the system
my ($name, $passwd) = getpwnam($username);

die "Can't log in as $username\n" unless ($name and $username eq $name);
die "Can't access encrypted passwords\n" if(not defined $passwd or $passwd eq ''
or $passwd eq 'x');

# Check password and return correct exit code or die.
if(crypt($password, $passwd) eq $passwd) {
	exit 0; # Silent, successful exit worked!
} else {
	die "Can't log in as $username\n";
}

Works for me, anyway.

Tags:

Leave a Reply