Re: PAM Pass through authentication only one threaded

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Rich,

On 11/01/2013 02:22 PM, Rich Megginson wrote:
All ldapsearch scripts are executed in background = in parallel way.
But server process them in serial way. I can tell that by increasing
time needed to process ldapsearches. Increment around 2sec is caused
by pam_unix delay because of wrong password.

Is 389 bind process really serialized? Or have I just overlooked some
limit?

PAM is not thread safe, in our experience, so we have to serialize calls
into PAM.

thank you for confirmation of my observation.

In fact I'm able to put my 389 server into deadlock.

I've written simple auth script for libpam-script [1] It's purpose is to check pasword of user in other than main entry, attached.

Content of /etc/pam.d/ldapserver:
auth required /lib/security/pam_script.so onerr=fail dir=/usr/share/libpam-script account required /lib/security/pam_script.so onerr=fail dir=/usr/share/libpam-script

[root@pdap 8445]# ls -l /usr/share/libpam-script
total 8
lrwxrwxrwx 1 root root   11 Oct 31 17:52 pam_script_acct -> perlauth.pl
lrwxrwxrwx 1 root root   11 Oct 31 17:52 pam_script_auth -> perlauth.pl
-rwxr-xr-x 1 root root 2450 Oct 31 19:45 perlauth.pl

It works fine in it's serialized way - until there is maximum 29 parallel connections.

If there is 30 or more parallel connections 389 hangs for ever. Very often killing process ldapsearch process does not help. Server is very often unable to restart so I have to kill it with -9.

My question is if there is any limit related to number of parallel bind operations. I guess there is something to related to 30 or more likely to 60 - my plugin itself open next connection to the same LDAP server.

Thanks

[1]  http://sourceforge.net/projects/pam-script/--
-----------------------
Jan Tomasek aka Semik
http://www.tomasek.cz/
#!/usr/bin/perl -w

use strict;
use Net::LDAPS;
use Net::LDAP::Constant qw(LDAP_SUCCESS);
use Sys::Syslog qw(:standard :macros);
use Net::LDAP::Util qw(escape_filter_value);


my $prg_name = $0;
$prg_name =~ s/.*\///;

my $ldap_host = 'localhost';
my $ldap_port = 636;

my $pam_user = 'PAM_USER';
my $pam_type = 'PAM_TYPE';
my $pam_password = 'PAM_AUTHTOK';

sub syslog_escape {
  my $str = shift;
  my @chr = split(//, $str);

  for(my $i=0; $i<@chr; $i++) {
    if (ord($chr[$i])>127) {
      $chr[$i] = sprintf('\0x%X', ord($chr[$i]));
    };
  };

  return join('', @chr);
};

sub logger {
  my $priority = shift;
  my $msg = shift;

  openlog($prg_name, 'pid', LOG_LOCAL0);
  syslog($priority, syslog_escape($msg));
  closelog;
};

sub local_die {
  logger(LOG_ERR, @_);
  die;
};

sub log_pam_env {
  my @out;

  foreach my $key (keys %ENV) {
    next unless ($key =~ /^PAM_/);

    if ($key eq 'PAM_AUTHTOK') {
      if (exists $ENV{$key}) {
	if ($ENV{$pam_password} eq '') {
	  push @out, "$key=";
        } else {
	  push @out, "$key=*hidden*" ;
	};
      };
    } else {
      push @out, "$key=".$ENV{$key};
    };
  };

  logger(LOG_ERR, 'PAM env: '.join(' ', @out));
};

# Log all PAM_* env variables we got from LDAP server
log_pam_env();

my $ldaps = Net::LDAPS->new($ldap_host,
			    port => $ldap_port) or die "$@";
my $conn = $ldaps->bind;    # TODO an anonymous bind


unless ($ENV{$pam_user}) {
  local_die "Missing $pam_user in environment";
};

unless ($ENV{$pam_type}) {
  local_die "Missing $pam_type in environment";
};

unless ($ENV{$pam_password}) {
  if ($ENV{$pam_type} eq 'auth') {
    local_die "Missing $pam_password in environment";
  };
};

my $filter = '(objectClass=appPassword)';
if ($ENV{$pam_type} eq 'auth') {
  $filter = "(&$filter(altUserPassword=".escape_filter_value($ENV{$pam_password})."))";
};
logger(LOG_ERR, $filter);
my $mesg = $ldaps->search( # perform a search
			  base   => $ENV{$pam_user},
			  filter => $filter,
			 );

if ($mesg->code == LDAP_SUCCESS) {
  foreach my $entry ($mesg->entries) {
    # todo pridat popisku hesla ktera matchla
    logger(LOG_ERR, 'Matched: '.$entry->dn);
    exit 0;
  };
  local_die('Invalid password.');
} else {
  local_die $mesg->error;
};

# K tomuhle bychom se nikdy nemeli dostat
local_die('This should not happen.');
--
389 users mailing list
389-users@xxxxxxxxxxxxxxxxxxxxxxx
https://admin.fedoraproject.org/mailman/listinfo/389-users

[Index of Archives]     [Fedora User Discussion]     [Older Fedora Users]     [Fedora Announce]     [Fedora Package Announce]     [EPEL Announce]     [Fedora News]     [Fedora Cloud]     [Fedora Advisory Board]     [Fedora Education]     [Fedora Security]     [Fedora Scitech]     [Fedora Robotics]     [Fedora Maintainers]     [Fedora Infrastructure]     [Fedora Websites]     [Anaconda Devel]     [Fedora Devel Java]     [Fedora Legacy]     [Fedora Desktop]     [Fedora Fonts]     [ATA RAID]     [Fedora Marketing]     [Fedora Management Tools]     [Fedora Mentors]     [Fedora Package Review]     [Fedora R Devel]     [Fedora PHP Devel]     [Kickstart]     [Fedora Music]     [Fedora Packaging]     [Centos]     [Fedora SELinux]     [Fedora Legal]     [Fedora Kernel]     [Fedora QA]     [Fedora Triage]     [Fedora OCaml]     [Coolkey]     [Virtualization Tools]     [ET Management Tools]     [Yum Users]     [Tux]     [Yosemite News]     [Yosemite Photos]     [Linux Apps]     [Maemo Users]     [Gnome Users]     [KDE Users]     [Fedora Tools]     [Fedora Art]     [Fedora Docs]     [Maemo Users]     [Asterisk PBX]     [Fedora Sparc]     [Fedora Universal Network Connector]     [Fedora ARM]

  Powered by Linux