-
-sub authenticate_user_shadow {
- my ($userid, $password) = @_;
-
- die "no password\n" if !$password;
-
- my $shadow_cfg = cfs_read_file($shadowconfigfile);
-
- if ($shadow_cfg->{users}->{$userid}) {
- my $encpw = crypt($password, $shadow_cfg->{users}->{$userid}->{shadow});
- die "invalid credentials\n" if ($encpw ne $shadow_cfg->{users}->{$userid}->{shadow});
- } else {
- die "no password set\n";
- }
-}
-
-sub authenticate_user_pam {
- my ($userid, $password) = @_;
-
- # user (www-data) need to be able to read /etc/passwd /etc/shadow
-
- die "no password\n" if !$password;
-
- my $pamh = new Authen::PAM ('common-auth', $userid, sub {
- my @res;
- while(@_) {
- my $msg_type = shift;
- my $msg = shift;
- push @res, (0, $password);
- }
- push @res, 0;
- return @res;
- });
-
- if (!ref ($pamh)) {
- my $err = $pamh->pam_strerror($pamh);
- die "error during PAM init: $err";
- }
-
- my $res;
-
- if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS) {
- my $err = $pamh->pam_strerror($res);
- die "$err\n";
- }
-
- if (($res = $pamh->pam_acct_mgmt (0)) != PAM_SUCCESS) {
- my $err = $pamh->pam_strerror($res);
- die "$err\n";
- }
-
- $pamh = 0; # call destructor
-}
-
-sub authenticate_user_ad {
-
- my ($entry, $server, $userid, $password) = @_;
-
- my $default_port = $entry->{secure} ? 636: 389;
- my $port = $entry->{port} ? $entry->{port} : $default_port;
- my $scheme = $entry->{secure} ? 'ldaps' : 'ldap';
- my $conn_string = "$scheme://${server}:$port";
-
- my $ldap = Net::LDAP->new($server) || die "$@\n";
-
- $userid = "$userid\@$entry->{domain}"
- if $userid !~ m/@/ && $entry->{domain};
-
- my $res = $ldap->bind($userid, password => $password);
-
- my $code = $res->code();
- my $err = $res->error;
-
- $ldap->unbind();
-
- die "$err\n" if ($code);
-}
-
-sub authenticate_user_ldap {
-
- my ($entry, $server, $userid, $password) = @_;
-
- my $default_port = $entry->{secure} ? 636: 389;
- my $port = $entry->{port} ? $entry->{port} : $default_port;
- my $scheme = $entry->{secure} ? 'ldaps' : 'ldap';
- my $conn_string = "$scheme://${server}:$port";
-
- my $ldap = Net::LDAP->new($conn_string, verify => 'none') || die "$@\n";
- my $search = $entry->{user_attr} . "=" . $userid;
- my $result = $ldap->search( base => "$entry->{base_dn}",
- scope => "sub",
- filter => "$search",
- attrs => ['dn']
- );
- die "no entries returned\n" if !$result->entries;
- my @entries = $result->entries;
- my $res = $ldap->bind($entries[0]->dn, password => $password);
-
- my $code = $res->code();
- my $err = $res->error;
-
- $ldap->unbind();
-
- die "$err\n" if ($code);
-}
-
-sub authenticate_user_domain {
- my ($realm, $userid, $password) = @_;
-
- my $domain_cfg = cfs_read_file($domainconfigfile);
-
- die "no auth domain specified" if !$realm;
-
- if ($realm eq 'pam') {
- authenticate_user_pam($userid, $password);
- return;
- }
-
- eval {
- if ($realm eq 'pve') {
- authenticate_user_shadow($userid, $password);
- } else {
-
- my $cfg = $domain_cfg->{$realm};
- die "auth domain '$realm' does not exists\n" if !$cfg;
-
- if ($cfg->{type} eq 'ad') {
- eval { authenticate_user_ad($cfg, $cfg->{server1}, $userid, $password); };
- my $err = $@;
- return if !$err;
- die $err if !$cfg->{server2};
- authenticate_user_ad($cfg, $cfg->{server2}, $userid, $password);
- } elsif ($cfg->{type} eq 'ldap') {
- eval { authenticate_user_ldap($cfg, $cfg->{server1}, $userid, $password); };
- my $err = $@;
- return if !$err;
- die $err if !$cfg->{server2};
- authenticate_user_ldap($cfg, $cfg->{server2}, $userid, $password);
- } else {
- die "unknown auth type '$cfg->{type}'\n";
- }
- }
- };
- if (my $err = $@) {
- sleep(2); # timeout after failed auth
- die $err;
- }
-}
-