Newer
Older
/* Copyright 2021 Dominik George <dominik.george@teckids.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use crate::config::{
get_config,
get_optional,
get_or_error
use crate::oauth::{get_access_token_client, get_data_jq};
use serde::{Serialize, Deserialize};
use libc::{getpwuid, geteuid};
use std::ffi::CStr;
use libnss::interop::Response;
#[derive(Serialize, Deserialize)]
#[serde(remote = "Passwd")]
struct PasswdDef {
name: String,
passwd: String,
uid: libc::uid_t,
gid: libc::gid_t,
gecos: String,
dir: String,
shell: String
}
#[derive(Deserialize)] struct PasswdHelper(#[serde(with = "PasswdDef")] Passwd);
fn nss_hook_prepare() -> Config {
let conf = get_config(None);
let mut log_level = log::LevelFilter::Error;
if get_optional(&conf, "nss.debug").unwrap_or_default() {
log_level = log::LevelFilter::Debug;
}
setup_log(log_level);
return conf;
}
fn get_current_user() -> String {
let euid;
let euser;
unsafe {
euid = geteuid();
euser = CStr::from_ptr((*getpwuid(euid)).pw_name);
};
euser.to_str().ok().unwrap().to_string()
}
struct OidcPasswd;
impl PasswdHooks for OidcPasswd {
fn get_all_entries() -> Response<Vec<Passwd>> {
let conf = nss_hook_prepare();
let mut cache = get_cache();
let token = match cache.load_user_token(&user) {
// FIXME Implement caching of system token
debug!("Could not find a user token for {} to request NSS data; trying client credentials", user);
match get_access_token_client(&conf, "nss", "", "") {
Ok(ct) => {
ctc = ct.clone();
&ctc
},
Err(_) => {
error!("Failed to get access token with client credentials");
return Response::Unavail;
}
}
let data: Vec<PasswdHelper> = match get_data_jq(&conf, "nss", "passwd", &token, true) {
Err(_) => {
error!("Could not load JSON data for passwd");
return Response::Unavail;
}
Response::Success(data.into_iter().map(|p| p.0).collect())
fn get_entry_by_uid(uid: libc::uid_t) -> Response<Passwd> {
return Response::Success(Passwd {
name: "test".to_string(),
passwd: "x".to_string(),
uid: 1005,
gid: 1005,
gecos: "Test Account".to_string(),
dir: "/home/test".to_string(),
shell: "/bin/bash".to_string(),
});
}
Response::NotFound
fn get_entry_by_name(name: String) -> Response<Passwd> {
return Response::Success(Passwd {
name: "test".to_string(),
passwd: "x".to_string(),
uid: 1005,
gid: 1005,
gecos: "Test Account".to_string(),
dir: "/home/test".to_string(),
shell: "/bin/bash".to_string(),
});
}
Response::NotFound
}
}
libnss_passwd_hooks!(oidc, OidcPasswd);