PAM::FAQ(3pm)
π PAM::FAQ β the Authen::PAM hot goss π
okay bestie, so this is PAM::FAQ(3pm), the Frequently-Asked Questions about Authen::PAM page, and honestly? it's giving "the group chat pinned message of Perl PAM lore." we're gonna go through every question, every code block, every tiny detail, no skipping. periodt. β¨
πΈ SYNOPSIS πΈ
perldoc Authen::PAM::FAQ
that's it. that's the synopsis. iconic minimalism. π
π VERSION π
so this doc is currently at version 0.05, as of May 4, 2005. vintage. a classic. no cap. π¦
β¨ DESCRIPTION β¨
1. Can I authenticate a user non interactively? π
short answer: yes, long answer: yes but it's not in a very clean way, and we love a messy queen. π
so here's the tea: the PAM library has a mechanism β in the form of a conversation function β that sends and receives text data from the user. for the full format spec of the conversation function, go consult the Authen::PAM manual, bestie, that's where the real details live.
this function receives a list of code/string pairs. there are four codes you need to know:
PAM_TEXT_INFOandPAM_ERROR_MSGβ these ones just display the associated string to the user π’PAM_ECHO_ONandPAM_ECHO_OFFβ these ones actually get input from the user β¨οΈ
and here's the awkward part: the codes are rather general, so you can't be completely sure when you're being asked for a user name vs. when you're being asked for a password. however β and this is the common practice β PAM_ECHO_ON is used for a user name, and PAM_ECHO_OFF is used for a password. iykyk. π«Ά
so what you do is: write your own conversation function that ignores PAM_TEXT_INFO and PAM_ERROR_MSG, and returns the user name for PAM_ECHO_ON and the password for PAM_ECHO_OFF. and if you pass the user name in the initialization function, then usually you will not be asked for it at all. slay.
here's a simple example of how to do this:
use Authen::PAM;
use POSIX qw(ttyname);
$service = "login";
$username = "foo";
$password = "bar";
$tty_name = ttyname(fileno(STDIN));
sub my_conv_func {
my @res;
while ( @_ ) {
my $code = shift;
my $msg = shift;
my $ans = "";
$ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
$ans = $password if ($code == PAM_PROMPT_ECHO_OFF() );
push @res, (PAM_SUCCESS(),$ans);
}
push @res, PAM_SUCCESS();
return @res;
}
ref($pamh = new Authen::PAM($service, $username, \&my_conv_func)) ||
die "Error code $pamh during PAM init!";
$res = $pamh->pam_set_item(PAM_TTY(), $tty_name);
$res = $pamh->pam_authenticate;
print $pamh->pam_strerror($res),"\n" unless $res == PAM_SUCCESS();
and fun fact: the Authen::PAM module actually comes with a default conversation function, which you can find in the file PAM.pm. go peek at it. π
2. Can I change a password non interactively? π
so basically all the discussion of the previous question also applies here, but there's one serious complication that you need to know about before you go feral. π
when changing a password, it is quite possible that the PAM library will send you at least two PAM_ECHO_OFF prompts β one for the old password, and one or two for the new one. because of course it does. so the first thing you should do is see what sequence of prompts your service actually produces. then your conversation function should include some state variable to distinguish the different prompts. here's an example:
use Authen::PAM;
$service = "passwd";
$username = "foo";
$oldpassword = "old_pass";
$newpassword = "new_pass";
sub my_conv_func {
my @res;
while ( @_ ) {
my $code = shift;
my $msg = shift;
my $ans = "";
$ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
if ($code == PAM_PROMPT_ECHO_OFF() ) {
$ans = $oldpassword if ($state == 0);
$ans = $newpassword if ($state == 1);
$ans = $newpassword if ($state == 2);
$state++;
}
push @res, (PAM_SUCCESS(),$ans);
}
push @res, PAM_SUCCESS();
return @res;
}
ref($pamh = new Authen::PAM($service, $username, \&my_conv_func)) ||
die "Error code $pamh during PAM init!";
$state = 0;
$res = $pamh->pam_chauthtok;
print $pamh->pam_strerror($res),"\n" unless $res == PAM_SUCCESS();
heads up bestie: if you are running the script as root, then most likely you will not be prompted for an old password. in that case you can simply return the new password at the ECHO_OFF prompt. easy. π
also, the $msg variable contains the text of the input prompt, which you can use for additional test or for debugging purposes. like so:
if ($code == PAM_PROMPT_ECHO_OFF() ) {
if ($state>=1 || $msg=~/new/i) { # are we asked for a new password
$ans = $newpassword;
} else {
$ans = $oldpassword;
}
$state++;
}
3. Why are the constants PAM_AUTHTOK and PAM_OLDAUTHTOK not available? π€
okay so the PAM_AUTHTOK and PAM_OLDAUTHTOK items can be used to pass authentication tokens (passwords) from one module to another. cute, right? but here's the catch β they are available only to PAM modules and not to PAM applications. sorry bestie, it's a modules-only party. π
but!! if you have a special setup in which you really need to preset the password from the application (e.g. using a radius server), then you can use the pam_set_authtok module, available from:
<http://www.uni-hohenheim.de/~schaefer/linux/pam/pam_set_authtok.html>
go get it. π₯
π SEE ALSO π
Authen::PAM
π«Ά AUTHOR π«Ά
Nikolay Pelov <NIKIP at cpan.org>
β COPYRIGHT β
Copyright (c) 1998-2005 Nikolay Pelov. All rights reserved. This file is part of the Authen::PAM library. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
okay that's the whole page, mwah! π this was perl v5.42.3, dated 2026-08-19, and you read it top to bottom like a good little Unix gremlin. go authenticate something. no cap. π¦πβ¨
π¦ where this page comes from
- ubuntu stonking: libauthen-pam-perl 0.16-6build5 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms