Integrate better with systemd + better logs and protocol usage

This commits adds the following:

- Better systemd integration and usage:
  - More hardening
  - A watchdog thread
  - Journald native logging

as well as

- Better logs
- Some protocol usage fixes
This commit is contained in:
2024-08-20 17:46:40 +02:00
parent a4067975b6
commit cdb1fb4181
9 changed files with 292 additions and 87 deletions

View File

@@ -7,6 +7,7 @@ use tokio::net::{UnixListener, UnixStream};
use sqlx::prelude::*;
use sqlx::MySqlConnection;
use crate::core::protocol::SetPasswordError;
use crate::server::sql::database_operations::list_databases;
use crate::{
core::{
@@ -56,7 +57,7 @@ pub async fn listen_for_incoming_connections(
let listener = UnixListener::bind(socket_path)?;
sd_notify::notify(true, &[sd_notify::NotifyState::Ready]).ok();
sd_notify::notify(false, &[sd_notify::NotifyState::Ready]).ok();
while let Ok((conn, _addr)) = listener.accept().await {
let uid = match conn.peer_cred() {
@@ -78,7 +79,7 @@ pub async fn listen_for_incoming_connections(
}
};
log::trace!("Accepted connection from uid {}", uid);
log::debug!("Accepted connection from uid {}", uid);
let unix_user = match UnixUser::from_uid(uid) {
Ok(user) => user,
@@ -173,47 +174,47 @@ pub async fn handle_requests_for_single_session_with_db_connection(
}
};
log::trace!("Received request: {:?}", request);
// TODO: don't clone the request
let request_to_display = match &request {
Request::PasswdUser(db_user, _) => {
Request::PasswdUser(db_user.to_owned(), "<REDACTED>".to_string())
}
request => request.to_owned(),
};
log::info!("Received request: {:#?}", request_to_display);
match request {
let response = match request {
Request::CreateDatabases(databases_names) => {
let result = create_databases(databases_names, unix_user, db_connection).await;
stream.send(Response::CreateDatabases(result)).await?;
Response::CreateDatabases(result)
}
Request::DropDatabases(databases_names) => {
let result = drop_databases(databases_names, unix_user, db_connection).await;
stream.send(Response::DropDatabases(result)).await?;
}
Request::ListDatabases(database_names) => {
let response = match database_names {
Some(database_names) => {
let result = list_databases(database_names, unix_user, db_connection).await;
Response::ListDatabases(result)
}
None => {
let result = list_all_databases_for_user(unix_user, db_connection).await;
Response::ListAllDatabases(result)
}
};
stream.send(response).await?;
}
Request::ListPrivileges(database_names) => {
let response = match database_names {
Some(database_names) => {
let privilege_data =
get_databases_privilege_data(database_names, unix_user, db_connection)
.await;
Response::ListPrivileges(privilege_data)
}
None => {
let privilege_data =
get_all_database_privileges(unix_user, db_connection).await;
Response::ListAllPrivileges(privilege_data)
}
};
stream.send(response).await?;
Response::DropDatabases(result)
}
Request::ListDatabases(database_names) => match database_names {
Some(database_names) => {
let result = list_databases(database_names, unix_user, db_connection).await;
Response::ListDatabases(result)
}
None => {
let result = list_all_databases_for_user(unix_user, db_connection).await;
Response::ListAllDatabases(result)
}
},
Request::ListPrivileges(database_names) => match database_names {
Some(database_names) => {
let privilege_data =
get_databases_privilege_data(database_names, unix_user, db_connection)
.await;
Response::ListPrivileges(privilege_data)
}
None => {
let privilege_data =
get_all_database_privileges(unix_user, db_connection).await;
Response::ListAllPrivileges(privilege_data)
}
},
Request::ModifyPrivileges(database_privilege_diffs) => {
let result = apply_privilege_diffs(
BTreeSet::from_iter(database_privilege_diffs),
@@ -221,50 +222,58 @@ pub async fn handle_requests_for_single_session_with_db_connection(
db_connection,
)
.await;
stream.send(Response::ModifyPrivileges(result)).await?;
Response::ModifyPrivileges(result)
}
Request::CreateUsers(db_users) => {
let result = create_database_users(db_users, unix_user, db_connection).await;
stream.send(Response::CreateUsers(result)).await?;
Response::CreateUsers(result)
}
Request::DropUsers(db_users) => {
let result = drop_database_users(db_users, unix_user, db_connection).await;
stream.send(Response::DropUsers(result)).await?;
Response::DropUsers(result)
}
Request::PasswdUser(db_user, password) => {
let result =
set_password_for_database_user(&db_user, &password, unix_user, db_connection)
.await;
stream.send(Response::PasswdUser(result)).await?;
}
Request::ListUsers(db_users) => {
let response = match db_users {
Some(db_users) => {
let result = list_database_users(db_users, unix_user, db_connection).await;
Response::ListUsers(result)
}
None => {
let result =
list_all_database_users_for_unix_user(unix_user, db_connection).await;
Response::ListAllUsers(result)
}
};
stream.send(response).await?;
Response::PasswdUser(result)
}
Request::ListUsers(db_users) => match db_users {
Some(db_users) => {
let result = list_database_users(db_users, unix_user, db_connection).await;
Response::ListUsers(result)
}
None => {
let result =
list_all_database_users_for_unix_user(unix_user, db_connection).await;
Response::ListAllUsers(result)
}
},
Request::LockUsers(db_users) => {
let result = lock_database_users(db_users, unix_user, db_connection).await;
stream.send(Response::LockUsers(result)).await?;
Response::LockUsers(result)
}
Request::UnlockUsers(db_users) => {
let result = unlock_database_users(db_users, unix_user, db_connection).await;
stream.send(Response::UnlockUsers(result)).await?;
Response::UnlockUsers(result)
}
Request::Exit => {
break;
}
}
};
// TODO: don't clone the response
let response_to_display = match &response {
Response::PasswdUser(Err(SetPasswordError::MySqlError(_))) => {
Response::PasswdUser(Err(SetPasswordError::MySqlError("<REDACTED>".to_string())))
}
response => response.to_owned(),
};
log::info!("Response: {:#?}", response_to_display);
stream.send(response).await?;
stream.flush().await?;
log::debug!("Successfully processed request");
}
Ok(())