# Rust and Python bindings for the Kerberos administration interface (kadm5) This repository contains both a work-in-progress safe, idiomatic Rust bindings for libkadm5, the library to administrate a Kerberos realm that supports the Kerberos administration interface (mainly Heimdal and MIT Kerberos 5), and the underlying "unsafe" bindings generated by bindgen in kadmin-sys. It also contains a Python API to those bindings. ### Kerberos implementations compatibility These libraries will only compile against MIT krb5. However, they will allow you to communicate with an MIT krb5 KDC as well as a Heimdal KDC. In fact, these libraries are tested against both! ## kadmin-sys ![Crates.io Version](https://img.shields.io/crates/v/kadmin-sys) ![docs.rs](https://img.shields.io/docsrs/kadmin-sys) These are the raw bindings to libkadm5. This crate offers two features, `client` and `server`. You must choose one of them depending on how your application is going to interact with the KDC. By default, `client` is enabled. - `client`: links against `kadm5clnt`. Use this is you plan to remotely access the KDC, using kadmind's GSS-API RPC interface, like the CLI tool `kadmin` does. - `server`: links against `kadm5srv`. Use this is you plan to directly edit the KDB from the machine where the KDC is running, like the CLI tool `kadmin.local` does. ## kadmin ![Crates.io Version](https://img.shields.io/crates/v/kadmin) ![docs.rs](https://img.shields.io/docsrs/kadmin) This is a safe, idiomatic Rust interface to libkadm5. This crate offers two features, `client` and `local`. They are similar to how kadmin-sys behaves. You should only enable one of them. With the `client` feature: ```rust use kadmin::{KAdmin, KAdminImpl}; let princ = "user/admin@EXAMPLE.ORG"; let password = "vErYsEcUrE"; let kadmin = KAdmin::builder().with_password(&princ, &password).unwrap(); dbg!("{}", kadmin.list_principals("*").unwrap()); ``` With the `local` feature: ```rust use kadmin::{KAdmin, KAdminImpl}; let princ = "user/admin@EXAMPLE.ORG"; let password = "vErYsEcUrE"; let kadmin = KAdmin::builder().with_local().unwrap(); dbg!("{}", kadmin.list_principals("*").unwrap()); ``` #### About thread safety As far as I can tell, libkadm5 APIs are **not** thread safe. As such, the types provided by this crate are neither `Send` nor `Sync`. You _must not_ use those with threads. You can either create a `KAdmin` instance per thread, or use the `kadmin::sync::KAdmin` interface that spawns a thread and sends the various commands to it. The API is not exactly the same as the non-thread-safe one, but should be close enough that switching between one or the other is easy enough. Read more about this in the documentation of the crate. ## python-kadmin-rs ![PyPI - Version](https://img.shields.io/pypi/v/python-kadmin-rs) ![Read the Docs](https://img.shields.io/readthedocs/python-kadmin-rs) These are Python bindings to the above Rust library, using the `kadmin::sync` interface to ensure thread safety. It provides two Python modules: `kadmin` for remote operations, and `kadmin_local` for local operations. With `kadmin`: ```python import kadmin princ = "user/admin@EXAMPLE.ORG" password = "vErYsEcUrE" kadm = kadmin.KAdmin.with_password(princ, password) print(kadm.list_principals("*")) ``` With `kadmin_local`: ```python import kadmin kadm = kadmin.KAdmin.with_local() print(kadm.list_principals("*")) ``` ## License Licensed under the [MIT License](./LICENSE). ## Contributing Just open a PR. ### Releasing 1. Go to [Actions > Create release PR](https://github.com/authentik-community/kadmin-rs/actions/workflows/release-pr.yml) 2. Click "Run workflow" and select what you need to release and input the new version. 3. Wait for the PR to be opened and the CI to pass 4. Merge the PR. 5. Go to [Releases](https://github.com/authentik-community/kadmin-rs/releases) 6. Edit the created release. 7. Click "Generate release notes" 8. Publish