# ldap-acis
Parse, evaluate, generate, and transform LDAP Access Control Instructions
(ACIs) in Rust. Supports both 389 Directory Server and OpenLDAP ACI syntaxes,
and can convert between the two.
## What it does
- **Parse** ACIs from 389 DS or OpenLDAP text format into a common model
- **Evaluate** access requests against a set of ACIs, with LRU caching
- **Generate** ACI text from programmatic definitions
- **Transform** between 389 DS and OpenLDAP formats
- Full ACI model: target DN patterns, attribute sets, target filters,
operation types (read, write, search, compare, add, delete, selfwrite),
and bind rules (userdn, groupdn, IP, DNS, time of day, day of week, SSF)
- Uses [`acls-rs`](https://forge.fedoraproject.org/freeipa/bac-rules) for permission
composition
## Quick start
### Parsing
```rust
use ldap_acis::prelude::*;
let aci_text = r#"(targetattr="cn || sn || givenName")
(version 3.0; acl "Allow read"; allow (read, search, compare)
userdn = "ldap:///anyone";)"#;
let acis = parse::<Ds389>(aci_text).unwrap();
assert_eq!(acis[0].name(), "Allow read");
```
### Building ACIs programmatically
```rust
use ldap_acis::prelude::*;
let aci = AciBuilder::new("Allow self-modify")
.target_attributes(vec![
"telephoneNumber".into(),
"mobile".into(),
])
.permission(OperationType::Modify)
.bind_rule(BindRule::SelfUser)
.grant(true)
.build();
```
### Converting between formats
```rust
use ldap_acis::prelude::*;
let ds389_text = r#"(version 3.0; acl "test"; allow (read)
userdn = "ldap:///anyone";)"#;
let acis = parse::<Ds389>(ds389_text).unwrap();
let openldap_text = generate::<OpenLdapGen>(&acis).unwrap();
```
## Features
- `bloom` *(default)* — Bloom-filter pre-screening during evaluation
- `serde` — serialization support
## Documentation
Full API reference and usage guide:
<https://forge.fedoraproject.org/freeipa/bac-rules>
## License
Licensed under either of Apache License 2.0 or MIT license, at your option.