.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "PAM::FAQ 3pm" .TH PAM::FAQ 3pm "2014-03-15" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Authen::PAM::FAQ \- Frequently\-Asked Questions about Authen::PAM. .SH "SYNOPSIS" .IX Header "SYNOPSIS" perldoc Authen::PAM::FAQ .SH "VERSION" .IX Header "VERSION" This document is currently at version \fI0.05\fR, as of \fIMay 4, 2005\fR .SH "DESCRIPTION" .IX Header "DESCRIPTION" .SS "1. Can I authenticate a user non interactively?" .IX Subsection "1. Can I authenticate a user non interactively?" Yes, you can although not in a very clean way. The \s-1PAM\s0 library has a mechanism, in a form of a conversation function, to send and receive text data from the user. For details of the format of the conversation function consult the Authen::PAM manual. This function receives a list of code/string pairs. There are two codes (\s-1PAM_TEXT_INFO\s0 and \s-1PAM_ERROR_MSG\s0) for displaying the associated string to the user and two codes (\s-1PAM_ECHO_ON\s0 and \s-1PAM_ECHO_OFF\s0) for getting input from the user. As you can see the codes are rather general and you can not be completely sure when you are asked for a user name and when for a password. However, the common practice is that \s-1PAM_ECHO_ON\s0 is used for a user name and \s-1PAM_ECHO_OFF\s0 is used for a password. So, what you can do is to write your own conversation function which ignores the \s-1PAM_TEXT_INFO\s0 and \s-1PAM_ERROR_MSG\s0 codes and returns the user name for the code \s-1PAM_ECHO_ON\s0 and the password for the code \&\s-1PAM_ECHO_OFF.\s0 If you pass the user name in the initialization function then usually you will not be asked for it. Here is a simple example how to do this: .PP .Vb 2 \& 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, \e&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),"\en" unless $res == PAM_SUCCESS(); .Ve .PP The Authen::PAM module comes with a default conversation function which you can find in the file \fI\s-1PAM\s0.pm\fR. .SS "2. Can I change a password non interactively?" .IX Subsection "2. Can I change a password non interactively?" All the discussion of the previous question also applies here. There is however one serious complication. When changing a password it is quite possible that the \s-1PAM\s0 library will send you at lest two \&\s-1PAM_ECHO_OFF\s0 prompts \- one for the old password and one or two for the new one. Therefore, the first thing you should do is to see what sequence of prompts is produced by your service. Then the conversation function should include some state variable to distinguish the different prompts. Here is an example: .PP .Vb 1 \& 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, \e&my_conv_func)) || \& die "Error code $pamh during PAM init!"; \& \& $state = 0; \& $res = $pamh\->pam_chauthtok; \& print $pamh\->pam_strerror($res),"\en" unless $res == PAM_SUCCESS(); .Ve .PP If you are running the script as root then most likely you will not be prompted for an old password. In this case you can simply return the new password at the \s-1ECHO_OFF\s0 prompt. .PP The \f(CW$msg\fR variable contains the text of the input prompt which you can use for additional test or for debugging purposes, e.g. .PP .Vb 8 \& 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++; \& } .Ve .SS "3. Why are the constants \s-1PAM_AUTHTOK\s0 and \s-1PAM_OLDAUTHTOK\s0 not available?" .IX Subsection "3. Why are the constants PAM_AUTHTOK and PAM_OLDAUTHTOK not available?" The \s-1PAM_AUTHTOK\s0 and \s-1PAM_OLDAUTHTOK\s0 items can be used to pass authentication tokens (passwords) from one module to another. However, they are available only to \s-1PAM\s0 modules and not to \s-1PAM\s0 applicatinos. 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 . .SH "SEE ALSO" .IX Header "SEE ALSO" Authen::PAM .SH "AUTHOR" .IX Header "AUTHOR" Nikolay Pelov <\s-1NIKIP\s0 at cpan.org> .SH "COPYRIGHT" .IX Header "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.