From: Dominik Csapak Date: Wed, 8 Apr 2020 07:00:53 +0000 (+0200) Subject: auth ldap/ad: make password a parameter for the api X-Git-Url: https://git.proxmox.com/?p=pve-access-control.git;a=commitdiff_plain;h=782b702dbbad6cb28db86f2701af76ded5813191;hp=89338e4d9c5f9a0795e6df057c0fa24f1c1a180b 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 --- 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;