Improving logging and docs around unixd/PAM/NSS (#577)

This commit is contained in:
James Hodgkinson 2021-09-06 07:48:37 +10:00 committed by GitHub
parent 0c1ad4e5fe
commit ea8801f23d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 18 deletions

View file

@ -241,6 +241,35 @@ edit the content.
## Troubleshooting
### Check POSIX-status of group and config
If authentication is failing via PAM, make sure that a list of groups is configured in `/etc/kanidm/unixd`:
```
pam_allowed_login_groups = ["example_group"]
```
Check the status of the group with `kanidm group posix show example_group`. If you get something similar to the below:
```shell
> kanidm group posix show example_group
Using cached token for name idm_admin
Error -> Http(500, Some(InvalidAccountState("Missing class: account && posixaccount OR group && posixgroup")), "b71f137e-39f3-4368-9e58-21d26671ae24")
```
POSIX-enable the group with `kanidm group posix set example_group`. You should get a result similar to this when you search for your group name:
```shell
> kanidm group posix show example_group
[ spn: example_group@kanidm.example.com, gidnumber: 3443347205 name: example_group, uuid: b71f137e-39f3-4368-9e58-21d26671ae24 ]
```
Also, ensure the target user is in the group by running:
```
> kanidm group list_members example_group
```
### Increase logging
For the unixd daemon, you can increase the logging with:
@ -262,10 +291,10 @@ To debug the pam module interactions add `debug` to the module arguments such as
### Check the socket permissions
Check that the /var/run/kanidm-unixd/sock is 777, and that non-root readers can see it with
Check that the `/var/run/kanidm-unixd/sock` is 777, and that non-root readers can see it with
ls or other tools.
Ensure that /var/run/kanidm-unixd/task_sock is 700, and that it is owned by the kanidm unixd
Ensure that `/var/run/kanidm-unixd/task_sock` is 700, and that it is owned by the kanidm unixd
process user.
### Check you can access the kanidm server
@ -279,6 +308,15 @@ You can check this with the client tools:
You should have:
/usr/lib64/libnss_kanidm.so.2
/usr/lib64/security/pam_kanidm.so
The exact path *may* change depending on your distribution, `pam_unixd.so` should be co-located with pam_kanidm.so so looking for it findable with:
```
find /usr/ -name 'pam_unix.so'
```
For example, on a Debian machine, it's located in `/usr/lib/x86_64-linux-gnu/security/`.
### Increase connection timeout

View file

@ -94,31 +94,42 @@ impl PamHooks for PamKanidm {
match call_daemon_blocking(cfg.sock_path.as_str(), &req) {
Ok(r) => match r {
ClientResponse::PamStatus(Some(true)) => {
// println!("PAM_SUCCESS");
if opts.debug {
println!("PamResultCode::PAM_SUCCESS");
}
PamResultCode::PAM_SUCCESS
}
ClientResponse::PamStatus(Some(false)) => {
// println!("PAM_IGNORE");
if opts.debug {
println!("PamResultCode::PAM_AUTH_ERR");
}
PamResultCode::PAM_AUTH_ERR
}
ClientResponse::PamStatus(None) => {
if opts.ignore_unknown_user {
if opts.debug {
println!("PamResultCode::PAM_IGNORE");
}
PamResultCode::PAM_IGNORE
} else {
if opts.debug {
println!("PamResultCode::PAM_USER_UNKNOWN");
}
PamResultCode::PAM_USER_UNKNOWN
}
}
_ => {
// unexpected response.
if opts.debug {
println!("PAM_IGNORE -> {:?}", r);
println!("PamResultCode::PAM_IGNORE -> {:?}", r);
}
PamResultCode::PAM_IGNORE
}
},
Err(e) => {
if opts.debug {
println!("PAM_IGNORE -> {:?}", e);
println!("PamResultCode::PAM_IGNORE -> {:?}", e);
}
PamResultCode::PAM_IGNORE
}

View file

@ -80,6 +80,10 @@ impl CacheLayer {
dbtxn.commit()?;
}
if pam_allow_groups.len() == 0 {
eprintln!("Will not be able to authenticate users, pam_allow_groups config is not configured.");
}
// We assume we are offline at start up, and we mark the next "online check" as
// being valid from "now".
Ok(CacheLayer {
@ -858,21 +862,30 @@ impl CacheLayer {
pub async fn pam_account_allowed(&self, account_id: &str) -> Result<Option<bool>, ()> {
let token = self.get_usertoken(Id::Name(account_id.to_string())).await?;
Ok(token.map(|tok| {
let user_set: BTreeSet<_> = tok
.groups
.iter()
.map(|g| vec![g.name.clone(), g.spn.clone(), g.uuid.clone()])
.flatten()
.collect();
if self.pam_allow_groups.len() == 0 {
// can't allow anything if the group list is zero...
eprintln!("Cannot authenticate users, no allowed groups in configuration!");
Ok(Some(false))
} else {
Ok(token.map(|tok| {
let user_set: BTreeSet<_> = tok
.groups
.iter()
.map(|g| vec![g.name.clone(), g.spn.clone(), g.uuid.clone()])
.flatten()
.collect();
debug!(
"Checking if -> {:?} & {:?}",
user_set, self.pam_allow_groups
);
debug!(
"Checking if user is in allowed groups ({:?}) -> {:?}",
self.pam_allow_groups, user_set,
);
let intersection_count = user_set.intersection(&self.pam_allow_groups).count();
debug!("Number of intersecting groups: {}", intersection_count);
debug!("User has valid token: {}", tok.valid);
user_set.intersection(&self.pam_allow_groups).count() > 0 && tok.valid
}))
intersection_count > 0 && tok.valid
}))
}
}
pub async fn pam_account_authenticate(