Setting Up External Authentication Triggers
How can Perforce users be authenticated against external data?
Task
Enabling Perforce user authentication against external data
Solution
This technical note is for administrators who want to authenticate Perforce users against an external data source, for example LDAP. Support for trigger types enabling external authentication was first made available in the 2005.2 release of the Perforce Server.
WARNING: Make sure you spell the trigger name correctly when adding the trigger with 'p4 triggers' because a misspelling can result in all users being locked out of Perforce. Also, be sure to fully test your trigger and trigger table invocation prior to deployment in a production environment. Please contact support@perforce.com if you need assistance with restoring access to your server.
To implement external authentication, you must understand:
- Triggers (Perforce System Administrator's Guide).
- Using Triggers in Perforce (Technical Note #28).
- Perforce tickets, 'p4 login' and 'p4 logout'.
To implement external authentication, you create an authentication trigger. The trigger connects to a remote password database and delivers the username and password for verification.
There are two authentication triggers that can be configured:
auth-check: verifies a password for the 'p4 login' command.
auth-set: sets a password for the 'p4 passwd' command.
The auth-check trigger is run by the Perforce Server after the user issues the 'p4 login' command. If the trigger runs successfully, the user
will be issued a Perforce ticket. If the trigger encounters an error, the login is rejected.
The auth-set trigger is unlikely to be required
since the users will already have a way of setting their password
external to Perforce; however, it is described here for completeness'
sake. The auth-set trigger is run by the Perforce
Server after the user issues the 'p4 passwd' command. Note the auth-check
trigger is also required to check old passwords before new external passwords
can be set.
One important difference between authentication triggers and other Perforce
triggers is the way authentication triggers receive the passwords. Passwords are sent to the auth-check and auth-set
triggers on the standard input (STDIN). The first thing the trigger
must do is read the password from STDIN. As with all triggers, success
is indicated by execution exit status of 0.
Here is a small Perl script example of how the password is read from the standard input. This simple case just checks that the password is 'secret'.
testauth-checkauth "/script/checkpass"
#!/usr/bin/perl
##
## Perforce requires messages on stdout
##
open(STDERR, ">&STDOUT") or die "Can't dup stdout";
##
## read the password from <stdin< and truncate the newline
##
chomp (my $password = <STDIN>);
$password =~ s/r$//;
##
## success
##
if($password eq "secret"){
exit 0;
}
##
## failure
##
die "You got the password wrong!n";
In this example, when a 'p4 login' request is issued with the correct password supplied (note this is totally independent of username), the server displays the following output:
% p4 login
Password: secret
User joeb logged in.
By contrast, when the wrong password is entered, you will see the following output:
% p4 login
Password: foobar
Password invalid.
'test' validation failed: You got the password wrong!
If you write an auth-set trigger, the only difference from an auth-check trigger is that the auth-set trigger gets the old password followed by the new password on STDIN.
Below is an example auth-check trigger definition
that authenticates against an LDAP server. Note that the LDAP
distinguished name (DN) is being passed to the trigger as a trigger
argument.
ldap auth-check auth "/script/checkpass uid=%user%,cn=users,dc=myco,dc=com"
After adding or removing an auth-check or auth-set
trigger you must restart the server for your change to take effect.
Making changes to the parameters of these triggers once they've been
added can be done without a server restart.
Once an auth-check trigger is in place, the
Perforce security counter is ignored. Perforce will no longer try to do
such things as enforce strong passwords.
For examples of authentication triggers (Perl/C++), see the following code in the Public Depot:
How does connecting to an Active Directory server differ from connecting to an LDAP server?
Active Directory differs from most LDAP servers in that it supports secure authentication but not secure communication.
Please note that the provided AD scripts work by using the cn for authentication. They expect the cn to be equal to the sAMAccountID. That is to say the short name without spaces that users generally use to log into their machine. If cn fields on your AD server have been changed to include spaces you will need to modify the below scripts to do a lookup on the sAMAccountID and retrieve the cn before attempting the AD authentication component.
Below is a small program that authenticates against an Active Directory server and compiles readily on Windows. Also included is an already compiled copy that should work on all Windows platforms and a Linux 24x86 binary.
An example of how p4auth_ad should be called from a Perforce trigger is:
ad auth-check auth "c:/p4auth_ad.exe localhost 389 CN=Users,DC=test,DC=perforce,DC=com %user%"
We've received reports that in some environments the above trigger does not properly handle users with null passwords. Use the below trigger in cases where the above trigger does not work. It operates in a similar fashion to the above trigger but does not allow users to login if they have no Active Directory password set.
- Windows binary p4auth_ad-no_null.exe
- Linux 24x86 binary p4auth_ad-no_null
- Windows p4auth_ad-no_null.cpp
- Unix p4auth_ad-no_null.cpp
The above auth trigger is called slightly differently. It does not require the domain. Here is an example of how it should be called from a Perforce trigger:
ad auth-check auth "c:/p4auth_ad-no_null.exe localhost 389 %user%"
Please report any issues encountered with these scripts to support@perforce.com .
