Skip to content

Commit 9eb64dc

Browse files
author
CommanderKeynes
committed
Got LDAP working
1 parent 85c0a49 commit 9eb64dc

File tree

4 files changed

+75
-12
lines changed

4 files changed

+75
-12
lines changed

pgcat.minimal.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ admin_auth_ldapurl = "ldap://127.0.0.1:3893"
1212
admin_auth_ldapsuffix = "@example.com"
1313

1414
[pools.pgml.users.0]
15-
username = "postgres"
15+
username = "jdoe"
1616
password = "postgres"
17-
auth_type = "md5"
17+
auth_type = "ldap"
18+
auth_ldapurl = "ldap://127.0.0.1:3893"
19+
auth_ldapsuffix = "@example.com"
1820
pool_size = 10
1921
min_pool_size = 1
2022
pool_mode = "transaction"

src/auth_passthrough.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ impl AuthPassthrough {
7272
let auth_user = crate::config::User {
7373
username: self.user.clone(),
7474
auth_type: "".to_string(),
75+
auth_ldapsuffix: None,
76+
auth_ldapurl: None,
7577
password: Some(self.password.clone()),
7678
server_username: None,
7779
server_password: None,

src/client.rs

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -416,20 +416,20 @@ pub async fn startup_tls(
416416

417417

418418
// Pass in username and password to authenticate against LDAP
419-
async fn authenticate_ldap(username: &str, password: &str) -> bool {
419+
async fn authenticate_ldap(username: &str, password: &str, ldapurl: &str, ldapsuffix: &str) -> bool {
420420
// Connection to the LDAP Server
421421
let ldap_conn_settings = LdapConnSettings::new();
422422
let (conn, mut ldap) =
423423
LdapConnAsync::with_settings(
424-
ldap_conn_settings, "ldap://127.0.0.1:3893").await.unwrap();
424+
ldap_conn_settings, ldapurl).await.unwrap();
425425
ldap3::drive!(conn);
426426

427427
// Takes the username provided and converts it into an email for validation
428428
// This is required because LDAP uses either the Distinguished name or Email in order to bind. Username alone will not work :/
429-
let email = format!("{}@example.com", username);
429+
let email = format!("{}{}", username, ldapsuffix);
430430

431431
// Attempts a simple bind using the passed in values of username and Password
432-
println!("{}", password);
432+
println!("{:?}", password);
433433
let result = ldap.simple_bind(email.as_str(), &password).await.unwrap().success();
434434
ldap.unbind().await.unwrap();
435435

@@ -617,15 +617,14 @@ where
617617
))
618618
}
619619
};
620-
let str_password = std::str::from_utf8(&password_response).unwrap();
620+
let str_password = String::from_utf8(password_response).unwrap();
621+
let str_password = str_password.trim_matches(char::from(0));
621622
let unsuccessful_auth = !authenticate_ldap(
622623
&config.general.admin_username,
623-
str_password,
624-
// "dogood",
625-
// config.general.admin_auth_ldapurl.expect("ldapurl not set").as_str(),
626-
// config.general.admin_auth_ldapsuffix.expect("ldapsuffix not set").as_str(),
624+
&str_password,
625+
&config.general.admin_auth_ldapurl.unwrap(),
626+
&config.general.admin_auth_ldapsuffix.unwrap(),
627627
).await;
628-
println!("{}", unsuccessful_auth);
629628
if unsuccessful_auth {
630629
wrong_password(&mut write, username).await?;
631630

@@ -794,6 +793,62 @@ where
794793
}
795794

796795
else if let "ldap" = pool.settings.user.auth_type.as_str() {
796+
clear_text_challenge(&mut write).await?;
797+
let code = match read.read_u8().await {
798+
Ok(p) => p,
799+
Err(_) => {
800+
return Err(Error::ClientSocketError(
801+
"password code".into(),
802+
client_identifier,
803+
))
804+
}
805+
};
806+
807+
// PasswordMessage
808+
if code as char != 'p' {
809+
return Err(Error::ProtocolSyncError(format!(
810+
"Expected p, got {}",
811+
code as char
812+
)));
813+
}
814+
815+
let len = match read.read_i32().await {
816+
Ok(len) => len,
817+
Err(_) => {
818+
return Err(Error::ClientSocketError(
819+
"password message length".into(),
820+
client_identifier,
821+
))
822+
}
823+
};
824+
825+
let mut password_response = vec![0u8; (len - 4) as usize];
826+
827+
match read.read_exact(&mut password_response).await {
828+
Ok(_) => (),
829+
Err(_) => {
830+
return Err(Error::ClientSocketError(
831+
"password message".into(),
832+
client_identifier,
833+
))
834+
}
835+
};
836+
let str_password = String::from_utf8(password_response).unwrap();
837+
let str_password = str_password.trim_matches(char::from(0));
838+
let unsuccessful_auth = !authenticate_ldap(
839+
&pool.settings.user.username.as_str(),
840+
&str_password,
841+
&pool.settings.user.auth_ldapurl.clone().unwrap(),
842+
&pool.settings.user.auth_ldapsuffix.clone().unwrap(),
843+
).await;
844+
if unsuccessful_auth {
845+
wrong_password(&mut write, username).await?;
846+
847+
return Err(Error::ClientGeneralError(
848+
"Invalid password".into(),
849+
client_identifier,
850+
));
851+
}
797852

798853
}
799854
let transaction_mode = pool.settings.pool_mode == PoolMode::Transaction;

src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ pub struct User {
209209
pub username: String,
210210
pub password: Option<String>,
211211
pub auth_type: String,
212+
pub auth_ldapsuffix: Option<String>,
213+
pub auth_ldapurl: Option<String>,
212214
pub server_username: Option<String>,
213215
pub server_password: Option<String>,
214216
pub pool_size: u32,
@@ -227,6 +229,8 @@ impl Default for User {
227229
username: String::from("postgres"),
228230
password: None,
229231
auth_type: "md5".to_string(),
232+
auth_ldapsuffix: None,
233+
auth_ldapurl: None,
230234
server_username: None,
231235
server_password: None,
232236
pool_size: 15,

0 commit comments

Comments
 (0)