From 782b702dbbad6cb28db86f2701af76ded5813191 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Wed, 8 Apr 2020 09:00:53 +0200 Subject: [PATCH] auth ldap/ad: make password a parameter for the api Allows us to add it in the gui, until now the admin needed to create the file themself. Mirrored after credential handling from CIFS and PBS in their pve-storage plugins Signed-off-by: Dominik Csapak [Thomas: don't differ from storage one unnecessarily, keep comments and behavior] Signed-off-by: Thomas Lamprecht --- PVE/Auth/AD.pm | 1 + PVE/Auth/LDAP.pm | 85 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/PVE/Auth/AD.pm b/PVE/Auth/AD.pm index 4f40be3..24b0e9f 100755 --- a/PVE/Auth/AD.pm +++ b/PVE/Auth/AD.pm @@ -83,6 +83,7 @@ sub options { certkey => { optional => 1 }, base_dn => { optional => 1 }, bind_dn => { optional => 1 }, + password => { optional => 1 }, user_attr => { optional => 1 }, filter => { optional => 1 }, sync_attributes => { optional => 1 }, diff --git a/PVE/Auth/LDAP.pm b/PVE/Auth/LDAP.pm index 905cc47..6b6b184 100755 --- a/PVE/Auth/LDAP.pm +++ b/PVE/Auth/LDAP.pm @@ -37,6 +37,11 @@ sub properties { optional => 1, maxLength => 256, }, + password => { + description => "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.", + type => 'string', + optional => 1, + }, verify => { description => "Verify the server's SSL certificate", type => 'boolean', @@ -126,6 +131,7 @@ sub options { server2 => { optional => 1 }, base_dn => {}, bind_dn => { optional => 1 }, + password => { optional => 1 }, user_attr => {}, port => { optional => 1 }, secure => { optional => 1 }, @@ -185,7 +191,7 @@ sub connect_and_bind { if ($config->{bind_dn}) { $bind_dn = $config->{bind_dn}; - $bind_pass = PVE::Tools::file_read_firstline("/etc/pve/priv/ldap/${realm}.pw"); + $bind_pass = ldap_get_credentials($realm); die "missing password for realm $realm\n" if !defined($bind_pass); } @@ -343,4 +349,81 @@ sub authenticate_user { return 1; } +my $ldap_pw_dir = "/etc/pve/priv/realm"; + +sub ldap_cred_file_name { + my ($realmid) = @_; + return "${ldap_pw_dir}/${realmid}.pw"; +} + +sub get_cred_file { + my ($realmid) = @_; + + my $cred_file = ldap_cred_file_name($realmid); + if (-e $cred_file) { + return $cred_file; + } elsif (-e "/etc/pve/priv/ldap/${realmid}.pw") { + # FIXME: remove fallback with 7.0 by doing a rename on upgrade from 6.x + return "/etc/pve/priv/ldap/${realmid}.pw"; + } + + return $cred_file; +} + +sub ldap_set_credentials { + my ($password, $realmid) = @_; + + my $cred_file = ldap_cred_file_name($realmid); + mkdir $ldap_pw_dir; + + PVE::Tools::file_set_contents($cred_file, $password); + + return $cred_file; +} + +sub ldap_get_credentials { + my ($realmid) = @_; + + if (my $cred_file = get_cred_file($realmid)) { + return PVE::Tools::file_read_firstline($cred_file); + } + return undef; +} + +sub ldap_delete_credentials { + my ($realmid) = @_; + + if (my $cred_file = get_cred_file($realmid)) { + unlink($cred_file) or warn "removing LDAP credentials '$cred_file' failed: $!\n"; + } +} + +sub on_add_hook { + my ($class, $realm, $config, %param) = @_; + + if (defined($param{password})) { + ldap_set_credentials($param{password}, $realm); + } else { + ldap_delete_credentials($realm); + } +} + +sub on_update_hook { + my ($class, $realm, $config, %param) = @_; + + return if !exists($param{password}); + + if (defined($param{password})) { + ldap_set_credentials($param{password}, $realm); + } else { + ldap_delete_credentials($realm); + } +} + +sub on_delete_hook { + my ($class, $realm, $config) = @_; + + ldap_delete_credentials($realm); +} + 1; -- 2.39.2