Setting Up External Authentication Triggers
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.
TASK
How can I authenticate Perforce users against external data?
SOLUTION
This article is for administrators who want to authenticate Perforce users against an external data source such as LDAP. Support for trigger types enabling external authentication was first made available in the 2005.2 release of the Perforce Server. You need to update your Perforce Server version to 2005.2 or later to use any of the following triggers with Perforce.
To implement external authentication, you must understand:
- Triggers (Perforce System Administrator's Guide).
- Using Triggers in Perforce (KB Article #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 types of 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 is issued a Perforce ticket. If the trigger encounters an error, the login is rejected. Note that the
P4PASSWD environment variable that you might have set (allowed up
to security level 2) will no longer work.
The auth-set trigger is unlikely to be required
since the users already have a way of setting their password
external to Perforce; however, to be thorough it is described here. 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 an execution exit status of 0.
The following 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".
test auth-check auth "/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!";
In the above 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 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 have been
added can be done without a server restart.
When an auth-check trigger is in place, the
Perforce security counter is ignored; Perforce no longer tries to enforce strong passwords or other such security measures.
For examples of authentication triggers (Perl/C), see the following code in the Public Depot. A detailed description of each script's function is explained in the comment sections of that script:
Active Directory vs. 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. It expects the cn to be equal to the sAMAccountID, 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 need to modify the scripts below 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. Before adding the script to the p4 triggers table, first run the script from a command line replacing %user% with an Active Directory username to make sure there are no errors and the script returns a zero exit code.
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%"
Sometimes a Windows domain name must be appended to the user such as:
ad auth-check auth "c:/p4auth_ad.exe localhost 389 CN=Users,DC=test,DC=perforce,DC=com foobar\%user%"Other times forward slashes are not allowed and backslashes must be used:
ad auth-check auth "c:\p4auth_ad.exe localhost 389 CN=Users,DC=test,DC=perforce,DC=com foobar\%user%"
To find the proper parameters to use, download the Port Query tool from Microsoft at
http://support.microsoft.com/kb/31009.
Look at serverName:
currentdate: 03/23/2010 22:22:59 (unadjusted GMT) subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=foo,DC=com dsServiceName: CN=NTDS Settings,CN=SVR-DC1,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=foo,DC=com namingContexts: DC=foo,DC=com defaultNamingContext: DC=foo,DC=com schemaNamingContext: CN=Schema,CN=Configuration,DC=foo,DC=com configurationNamingContext: CN=Configuration,DC=foo,DC=com rootDomainNamingContext: DC=foo,DC=com supportedControl: 1.2.840.113556.1.4.319 supportedLDAPVersion: 3 supportedLDAPPolicies: MaxPoolThreads highestCommittedUSN: 1715777 supportedSASLMechanisms: GSSAPI dnsHostName: SVR.foo.com ldapServiceName: foo.com:svr$@FOO.COM serverName: CN=SVR,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=foo,DC=com supportedCapabilities: 1.2.840.113556.1.4.800 isSynchronized: TRUE isGlobalCatalogReady: TRUE domainFunctionality: 4 forestFunctionality: 4 domainControllerFunctionality: 4
The trigger syntax would become
ad auth-check auth "C:\Program Files\Perforce\p4auth_ad.exe SVR.foo.com 389 CN=SVR,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=foo,DC=com foo\%user%"
Users reported 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 it does not allow users to login if they have not set an Active Directory password.
- 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 where %user% might need to be replaced with %user%@<domainname>
ad auth-check auth "c:\p4auth_ad-no_null.exe localhost 389 %user@server.domainname.com"
Please report any issues encountered with these scripts to support@perforce.com. See Authentication Troubleshooting for help in debugging external authentication triggers.
