Skip to content

Commit

Permalink
Merge branch 'kanidm:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
irvingoujAtDevolution authored Jan 16, 2024
2 parents 3f11052 + 015917a commit 2635899
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 46 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/rust_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: "Linux Build and Test"
# Trigger the workflow on push to master or pull request
"on":
push:
branches:
- master
pull_request:

env:
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
rust_build:
runs-on: ubuntu-latest
env:
SCCACHE_GHA_ENABLED: true
RUSTC_WRAPPER: sccache
CARGO_INCREMENTAL: 0
CARGO_TERM_COLOR: always
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup sccache
uses: mozilla-actions/[email protected]
with:
version: "v0.4.2"
- name: "Build the workspace"
run: cargo build --workspace

- name: "Run cargo test"
run: cargo test

- name: "Run cargo test --release"
run: cargo test --release
10 changes: 6 additions & 4 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Contributors

## Author

* William Brown (Firstyear): [email protected]
* William Brown (Firstyear): <[email protected]>

## Contributors
## Thanks to the contributors

* Hiroyuki Wada (wadahiro)
* James Hodgkinson (yaleman)
* Jiegec
* Nitnelave
* Hiroyuki Wada (wadahiro)

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = ["proto", "client", "cli"]


[workspace.package]
version = "0.4.2"
version = "0.4.3"
authors = ["William Brown <[email protected]>"]
rust-version = "1.74"
edition = "2021"
Expand All @@ -28,8 +28,8 @@ futures-util = "^0.3.21"
lber = "^0.4.0"
# Must match lber
nom = "7"
ldap3_client = { path = "./client", version = "0.4.1" }
ldap3_proto = { path = "./proto", version = "0.4.1" }
ldap3_client = { path = "./client", version = "^0.4.3" }
ldap3_proto = { path = "./proto", version = "^0.4.3" }
peg = "0.8.1"
openssl = "^0.10.38"
ron = "^0.8.0"
Expand All @@ -45,4 +45,4 @@ tracing = { version = "^0.1.34", features = ["attributes"] }
tracing-subscriber = "^0.3.11"
url = "^2.2.2"
uuid = "^1.1.2"
sspi = "0.11.0"
sspi = "^0.11.1"
19 changes: 19 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Doing a release

Make sure you've done all the tests and clippying and things.

## Checks

Fix (what you can) for outdated packages:

```shell
cargo audit
```

## Release order

```shell
cargo publish -p "ldap3_proto"
cargo publish -p "ldap3_client"
cargo publish -p "ldap3_cli"
```
9 changes: 3 additions & 6 deletions cli/src/ldap_debug_opt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use std::fmt;
use std::str::FromStr;

Expand Down Expand Up @@ -39,7 +38,7 @@ struct BerDumpOptions {

#[clap(short, long)]
/// the path to the dump
path: PathBuf
path: PathBuf,
}

#[derive(Debug, clap::Subcommand)]
Expand All @@ -48,16 +47,14 @@ enum LdapDebugAction {
BerDump(BerDumpOptions),
}


#[derive(Debug, clap::Parser)]
#[clap(about = "Ldap Debugging Utility")]
struct LdapDebugOpt {
#[clap(short, long)]
/// Display extended infomation during runtime.
/// Display extended information during runtime.
verbose: bool,

#[clap(subcommand)]
/// The ldap action to perform
action: LdapDebugAction
action: LdapDebugAction,
}

7 changes: 2 additions & 5 deletions cli/src/ldap_opt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/*
#[derive(clap::ValueEnum, Debug, Clone)]
enum SyncRequestMode {
Expand All @@ -22,7 +21,6 @@ enum LdapAction {

// /// scope
// scope

/// Execute this query
filter: String,
},
Expand Down Expand Up @@ -56,7 +54,7 @@ enum LdapAction {
#[clap(about = "Ldap Client Utility")]
struct LdapOpt {
#[structopt(short, long)]
/// Display extended infomation during runtime.
/// Display extended information during runtime.
verbose: bool,

#[clap(short = 'H', long = "url")]
Expand All @@ -76,6 +74,5 @@ struct LdapOpt {

#[clap(subcommand)]
/// The ldap action to perform
action: LdapAction
action: LdapAction,
}

62 changes: 49 additions & 13 deletions client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#![deny(clippy::unimplemented)]
#![deny(clippy::unwrap_used)]
#![deny(clippy::panic)]
#![deny(clippy::unreachable)]
#![deny(clippy::await_holding_lock)]
#![deny(clippy::needless_pass_by_value)]
#![deny(clippy::trivially_copy_pass_by_ref)]
Expand Down Expand Up @@ -105,17 +104,17 @@ impl fmt::Display for LdapError {
write!(f, "The LDAP server sent a response we did not expect")
}
LdapError::FileIOError => {
write!(f, "An error occured while accessing a file")
write!(f, "An error occurred while accessing a file")
}
LdapError::TransportReadError => {
write!(f, "An error occured reading from the transport")
write!(f, "An error occurred reading from the transport")
}
LdapError::TransportWriteError => {
write!(f, "An error occured writing to the transport")
write!(f, "An error occurred writing to the transport")
}
LdapError::UnavailableCriticalExtension => write!(f, "An extension marked as critical was not available"),
LdapError::InvalidCredentials => write!(f, "Invalid DN or Password"),
LdapError::InsufficentAccessRights => write!(f, "Insufficent Access"),
LdapError::InsufficentAccessRights => write!(f, "Insufficient Access"),
LdapError::UnwillingToPerform => write!(f, "Too many failures, server is unwilling to perform the operation."),
LdapError::EsyncRefreshRequired => write!(f, "An initial content sync is required. The current cookie should be considered invalid."),
LdapError::NotImplemented => write!(f, "An error occurred, but we haven't implemented code to handle this error yet.")
Expand Down Expand Up @@ -261,6 +260,8 @@ pub struct LdapClientBuilder<'a> {
timeout: Duration,
cas: Vec<&'a Path>,
verify: bool,
/// The maximum LDAP packet size parsed during decoding.
max_ber_size: Option<usize>,
}

impl<'a> LdapClientBuilder<'a> {
Expand All @@ -270,12 +271,12 @@ impl<'a> LdapClientBuilder<'a> {
timeout: Duration::from_secs(30),
cas: Vec::new(),
verify: true,
max_ber_size: None,
}
}

pub fn set_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
pub fn set_timeout(self, timeout: Duration) -> Self {
Self { timeout, ..self }
}

pub fn add_tls_ca<T>(mut self, ca: &'a T) -> Self
Expand All @@ -286,9 +287,19 @@ impl<'a> LdapClientBuilder<'a> {
self
}

pub fn danger_accept_invalid_certs(mut self, accept_invalid_certs: bool) -> Self {
self.verify = accept_invalid_certs;
self
pub fn danger_accept_invalid_certs(self, accept_invalid_certs: bool) -> Self {
Self {
verify: !accept_invalid_certs,
..self
}
}

/// Set the maximum size of a decoded message
pub fn max_ber_size(self, max_ber_size: Option<usize>) -> Self {
Self {
max_ber_size,
..self
}
}

#[tracing::instrument(level = "debug", skip_all)]
Expand All @@ -298,6 +309,7 @@ impl<'a> LdapClientBuilder<'a> {
timeout,
cas,
verify,
max_ber_size,
} = self;

info!(%url);
Expand Down Expand Up @@ -363,6 +375,9 @@ impl<'a> LdapClientBuilder<'a> {
}
};

// If they didn't set it in the builder then set it to the default
let max_ber_size = max_ber_size.unwrap_or(ldap3_proto::DEFAULT_MAX_BER_SIZE);

// If ldaps - start openssl
let (write_transport, read_transport) = if need_tls {
let mut tls_parms = SslConnector::builder(SslMethod::tls_client()).map_err(|e| {
Expand Down Expand Up @@ -420,16 +435,17 @@ impl<'a> LdapClientBuilder<'a> {
})?;

info!("tls configured");

let (r, w) = tokio::io::split(tlsstream);
(
LdapWriteTransport::Tls(FramedWrite::new(w, LdapCodec::default())),
LdapReadTransport::Tls(FramedRead::new(r, LdapCodec::new(Some(32768)))),
LdapReadTransport::Tls(FramedRead::new(r, LdapCodec::new(Some(max_ber_size)))),
)
} else {
let (r, w) = tokio::io::split(tcpstream);
(
LdapWriteTransport::Plain(FramedWrite::new(w, LdapCodec::default())),
LdapReadTransport::Plain(FramedRead::new(r, LdapCodec::new(Some(32768)))),
LdapReadTransport::Plain(FramedRead::new(r, LdapCodec::new(Some(max_ber_size)))),
)
};

Expand Down Expand Up @@ -521,3 +537,23 @@ impl LdapClient {
})
}
}

/// Doesn't test the actual *build* step because that requires a live LDAP server.
#[test]
fn test_ldapclient_builder() {
let url = Url::parse("ldap://ldap.example.com:389").unwrap();
let client = LdapClientBuilder::new(&url).max_ber_size(Some(1234567));
assert_eq!(client.timeout, Duration::from_secs(30));
let client = client.set_timeout(Duration::from_secs(60));
assert_eq!(client.timeout, Duration::from_secs(60));
assert_eq!(client.cas.len(), 0);
assert_eq!(client.max_ber_size, Some(1234567));
assert_eq!(client.verify, true);

let ca_path = "test.pem".to_string();
let client = client.add_tls_ca(&ca_path);
assert_eq!(client.cas.len(), 1);

let badssl_client = client.danger_accept_invalid_certs(true);
assert_eq!(badssl_client.verify, false);
}
4 changes: 2 additions & 2 deletions client/src/syncrepl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl LdapClient {
done: false,
}) => {
// These are no-ops that are skipped for our purposes
// They are intended to deliniate the seperate phases, but we actually don't
// They are intended to deliniate the separate phases, but we actually don't
// care until we get the search result done.
let _d_uuids = delete_uuids.get_or_insert_with(Vec::default);
}
Expand All @@ -157,7 +157,7 @@ impl LdapClient {
},
) => {
// These are no-ops that are skipped for our purposes
// They are intended to deliniate the seperate phases, but we actually don't
// They are intended to deliniate the separate phases, but we actually don't
// care until we get the search result done.
let _p_uuids = present_uuids.get_or_insert_with(Vec::default);
}
Expand Down
2 changes: 1 addition & 1 deletion proto/examples/search/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
loop {
let res = framed.next().await.expect("no meg")?;
if let LdapOp::SearchResultDone(..) = &res.op {
info!("search sucessfull");
info!("search successful");
break;
}
}
Expand Down
26 changes: 23 additions & 3 deletions proto/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use uuid::Uuid;
use crate::{
bytes_to_string,
error::LdapProtoError,
proto::{ber_bool_to_bool, ber_integer_to_i64, SyncRequestMode, SyncStateValue}, LdapResultCode,
proto::{ber_bool_to_bool, ber_integer_to_i64, SyncRequestMode, SyncStateValue},
LdapResultCode,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -56,13 +57,15 @@ pub enum LdapControl {
ServerSort {
sort_requests: Vec<ServerSortRequet>,
},

ServerSortResult {
sort_result: ServerSortResult,
},
PasswordPolicyRequest {
criticality: bool,
},
}

#[derive(Debug, Clone, PartialEq,Hash, Eq, PartialOrd, Ord)]
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub struct ServerSortResult {
Expand Down Expand Up @@ -150,6 +153,10 @@ impl fmt::Debug for LdapControl {
.debug_struct("LdapControl::ServerSortResult")
.field("sort_result", &sort_result)
.finish(),
LdapControl::PasswordPolicyRequest { criticality } => f
.debug_struct("LdapControl::PasswordPolicyRequest")
.field("criticality", &criticality)
.finish(),
}
}
}
Expand Down Expand Up @@ -487,6 +494,16 @@ impl TryFrom<StructureTag> for LdapControl {
},
})
}
"1.3.6.1.4.1.42.2.27.8.5.1" => {
let criticality = criticality_tag
.and_then(|t| t.match_class(TagClass::Universal))
.and_then(|t| t.match_id(Types::Boolean as u64))
.and_then(|t| t.expect_primitive())
.and_then(ber_bool_to_bool)
.unwrap_or(false);

Ok(LdapControl::PasswordPolicyRequest { criticality })
}
oid => {
warn!(%oid, "Unsupported control oid");
Err(LdapProtoError::ControlUnknown)
Expand Down Expand Up @@ -705,6 +722,9 @@ impl From<LdapControl> for Tag {
})),
)
}
LdapControl::PasswordPolicyRequest { criticality } => {
("1.3.6.1.4.1.42.2.27.8.5.1", criticality, None)
}
};

let mut inner = Vec::with_capacity(3);
Expand Down
Loading

0 comments on commit 2635899

Please sign in to comment.