use std::collections::HashSet; use ldap3::result::Result; use ldap3::{LdapConn, Scope, SearchEntry, Mod}; use base64::{Engine as _, engine::general_purpose}; use crypto::{sha2::Sha512, digest::Digest}; //https://stackoverflow.com/a/44532957 pub fn hex_to_base64(hex: &str) -> String { // Make vector of bytes from octets let mut bytes = Vec::new(); for i in 0..(hex.len()/2) { let res = u8::from_str_radix(&hex[2*i .. 2*i+2], 16); match res { Ok(v) => bytes.push(v), Err(e) => println!("Problem with hex: {}", e), }; }; general_purpose::STANDARD.encode(&bytes) // now convert from Vec to b64-encoded String } fn main() -> Result<()> { let mut ldap = LdapConn::new("ldaps://sso.skynet.ie")?; let user = "silver"; let pass = ""; let field = "sshPublicKey"; let value = "em232323232323"; let dn = format!("uid={},ou=users,dc=skynet,dc=ie", user); ldap.simple_bind(&dn, pass)?.success()?; // always assume insecure let mut secure = false; // get the users current password hash let (rs, _res) = ldap.search(&dn,Scope::Base,"(objectClass=*)",vec!["userPassword"])?.success()?; if !rs.is_empty() { let tmp = SearchEntry::construct(rs[0].clone()); if !tmp.attrs["userPassword"].is_empty() && tmp.attrs["userPassword"][0].starts_with("{SHA512}") { secure = true; } } let mut mods = vec![ Mod::Replace(field, HashSet::from([value])) ]; let mut pw_hashset = HashSet::new(); let pass_tmp; if !secure { let mut hasher = Sha512::new(); hasher.input_str(pass); // get it as hex string let hex = hasher.result_str(); // convert it to b64 pass_tmp = format!("{{SHA512}}{}", hex_to_base64(&hex)); pw_hashset.insert(pass_tmp.as_str()); mods.push(Mod::Replace("userPassword", pw_hashset)); }; let res = ldap.modify(&dn, mods)?.success()?; println!("{:?}", res); Ok(ldap.unbind()?) }