diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f69055a0..72fe9f0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,16 +27,16 @@ jobs: account required pam_permit.so session [success=1 default=ignore] pam_permit.so session requisite pam_permit.so - session required pam_permit.so" | tee /etc/pam.d/dosr' + session required pam_permit.so" | tee /etc/pam.d/sr' - name: Install RootAsRole run: cargo xtask install -bip sudo - name: print config - run: dosr cat /etc/security/rootasrole.json + run: sr cat /etc/security/rootasrole.json - name: getenv run: env - - name: Run dosr + - name: Run Sr env: RUST_LOG: debug - run: /usr/bin/dosr -h - - name: Run Chsr with dosr - run: dosr /usr/bin/chsr -h + run: /usr/bin/sr -h + - name: Run Chsr with sr + run: sr /usr/bin/chsr -h diff --git a/.vscode/launch.json b/.vscode/launch.json index 40c2e5c8..a3f110d6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "type": "lldb", "request": "launch", "name": "Launch", - "program": "${workspaceFolder}/target/debug/dosr", + "program": "${workspaceFolder}/target/debug/sr", "args": ["ls"], "cwd": "${workspaceFolder}" } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index db39d329..c1707c71 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -14,7 +14,7 @@ "args": [ "/usr/bin/setcap", "=p", - "${cwd}/bin/dosr" + "${cwd}/bin/sr" ], "options": { "cwd": "${cwd}" diff --git a/Cargo.toml b/Cargo.toml index ae8584f1..015acb8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,11 @@ members = ["xtask", "rar-common"] [package] name = "rootasrole" # The project version is managed on json file in resources/rootasrole.json -version = "3.1.2" +version = "3.1.1" rust-version = "1.76.0" authors = ["Eddie Billoir "] edition = "2021" -default-run = "dosr" +default-run = "sr" description = "An alternative to sudo that uses Linux capabilities and Role based access control." license = "LGPL-3.0-or-later" repository = "https://github.com/LeChatP/RootAsRole" @@ -41,7 +41,7 @@ debug = true #srlibs = [ "pam-client", "bitflags" ] [[bin]] -name = "dosr" +name = "sr" path = "src/sr/main.rs" required-features = ["finder"] @@ -64,7 +64,7 @@ serde_json = "1.0" toml = "0.8" [dependencies] -rar-common = { path = "rar-common", version = "3.1.2", package = "rootasrole-core" } +rar-common = { path = "rar-common", version = "3.1.0", package = "rootasrole-core" } log = "0.4" libc = "0.2" strum = { version = "0.26", features = ["derive"] } @@ -76,7 +76,8 @@ serde = { version = "1.0", features=["rc", "derive"] } serde_json = "1.0" cbor4ii = { version = "1.0.0", features = ["serde", "serde1", "use_std"] } glob = "0.3" -bitflags = { version = "2.9" } +pam-client2 = "0.5" +bitflags = { version = "2.6" } shell-words = "1.1" linked_hash_set = { version = "0.1" } derivative = "2.2" @@ -88,11 +89,9 @@ pest = "2.7" pest_derive = "2.7" const_format = "0.2" hex = "0.4" -bon = "3" -serde_json_borrow = "0.8" -konst = "0.3" -nonstick = "0.1.1" -libpam-sys = "0.2.0" +bon = "3.5.1" +serde_json_borrow = "0.7.1" +konst = "0.3.16" [dev-dependencies] log = "0.4" @@ -122,7 +121,7 @@ changelog = "target/debian/changelog" [package.metadata.generate-rpm] assets = [ - { source = "target/release/dosr", dest = "/usr/bin/dosr", user = "root", group = "root", mode = "0555", caps = "=p" }, + { source = "target/release/sr", dest = "/usr/bin/sr", user = "root", group = "root", mode = "0555", caps = "=p" }, { source = "target/release/chsr", dest = "/usr/bin/chsr", user = "root", group = "root", mode = "0555" }, { source = "resources/rh/rh_sr_pam.conf", dest = "/etc/pam.d/sr", user = "root", group = "root", mode = "0644", config = true }, { source = "resources/rootasrole.json", dest = "/etc/security/rootasrole.json", user = "root", group = "root", mode = "0644", config = true }, diff --git a/README.md b/README.md index b95a7584..b026c00e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ -# RootAsRole (V3.1.2) — A better alternative to `sudo(-rs +# RootAsRole (V3.1.1) — A better alternative to `sudo(-rs)`/`su` • ⚡ Blazing fast • 🛡️ Memory-safe • 🔐 Security-oriented RootAsRole is a Linux/Unix privilege delegation tool based on **Role-Based Access Control (RBAC)**. It empowers administrators to assign precise privileges — not full root — to users and commands. @@ -44,7 +44,7 @@ RootAsRole solves this: ## 📊 Why It’s Better Than Others -| Feature | setcap?? | doas | sudo | sudo-rs | dosr (RootAsRole) | +| Feature | setcap?? | doas | sudo | sudo-rs | sr (RootAsRole) | |------------------------------------------|-------------------|------------|--------------------------------|--------------------------------|----------------------------------------------| | **Change user/groups** | N/A | ✅ | ✅ | ✅ | ✅✅ mandatory or optional | | **Environment variables** | N/A | partial | ✅ | partial | ✅ | @@ -97,7 +97,7 @@ RootAsRole solves this:
 Execute privileged commands with a role-based access control system
 
-Usage: dosr [OPTIONS] [COMMAND]...
+Usage: sr [OPTIONS] [COMMAND]...
 
 Arguments:
   [COMMAND]...  Command to execute
@@ -116,8 +116,7 @@ Execute privileged commands with a role-based access control system
 
 If you're accustomed to utilizing the sudo tool and find it difficult to break that habit, consider creating an alias : 
 ```sh
-alias sudo="dosr"
-alias sr="dosr"
+alias sudo="sr"
 ```
 
 ## 🏎️ Performance
@@ -133,7 +132,7 @@ RootAsRole **3.1.0** introduced **CBOR** support, significantly boosting perform
 
 ### Why Performance Matters
 
-When using **Ansible** (or any automation tool), every task that uses `become: true` will invoke `dosr` on the target host.
+When using **Ansible** (or any automation tool), every task that uses `become: true` will invoke `sr` on the target host.
 With **RootAsRole (RaR)**, each role and task introduces additional access control logic --- this doesn’t slow you down.
 
 💡 **Here’s the reality**: You can reach the performance of **1 `sudo` rule** with **~4000 RaR rules**.
diff --git a/book/src/README.md b/book/src/README.md
index 1def54fc..ee0c29a2 100644
--- a/book/src/README.md
+++ b/book/src/README.md
@@ -17,13 +17,13 @@
 
 ## Usage
 
-The main command line tool is `dosr`. It allows you to execute a command by simply typing:
+The main command line tool is `sr`. It allows you to execute a command by simply typing:
   
 ```bash
-dosr 
+sr 
 ```
 
-You can find more information about this command in the [dosr](sr/README.md) section.
+You can find more information about this command in the [sr](sr/README.md) section.
 
 The `chsr` command allows you to configure the roles and capabilities of the system. You can find more information about this command in the [Configure RootAsRole](chsr/README.md) section.
 
@@ -51,7 +51,7 @@ By using a role-based access control model, this project allows us to better man
 You are using your personal computer and you want to install a new package. By default, RootAsRole add one role with 2 tasks : one task for using `chsr` command that grant only the `CAP_LINUX_IMMUTABLE` capability as `root` user (unprivileged), and one task for all commands but without `CAP_LINUX_IMMUTABLE` privilege. As installing a package may require almost all capabilities, you can use the default role to install a package. Indeed, if you wish to install apache2, you'll need `CAP_NET_BIND_SERVICE`, if you install docker you'll need many privileges, virtualbox needs `CAP_SYS_MODULE`, etc. So, you can use the default role to install a package:
 
 ```bash
-dosr apt install 
+sr apt install 
 ```
 
 ### Scenario 2: Granting users the right to restart their system
@@ -59,17 +59,17 @@ dosr apt install 
 You are the system administrator of a company and you want to delegate the right to restart the server to a user. You can use `chsr` to create a role and grant the right to restart the server to users.
 
 ```bash
-dosr chsr role r_users add # Create a new role
-dosr chsr role r_users grant -g users # Grant the role to the group users
-dosr chsr role r_users task t_reboot add # Create a new task
-dosr chsr role r_users task t_reboot cmd whitelist add reboot # Add the reboot command to the task
-dosr chsr role r_users task t_reboot cred caps whitelist add CAP_SYS_BOOT # Add the CAP_SYS_BOOT capability to the task
+sr chsr role r_users add # Create a new role
+sr chsr role r_users grant -g users # Grant the role to the group users
+sr chsr role r_users task t_reboot add # Create a new task
+sr chsr role r_users task t_reboot cmd whitelist add reboot # Add the reboot command to the task
+sr chsr role r_users task t_reboot cred caps whitelist add CAP_SYS_BOOT # Add the CAP_SYS_BOOT capability to the task
 ```
 
 Then users can restart the server with the following command:
 
 ```bash
-dosr reboot
+sr reboot
 ```
 
 ### Scenario 3 : Passing environment variables to a command
@@ -77,17 +77,17 @@ dosr reboot
 You are a developer and you want to pass environment variables to a command. For example with sudo you can use the `-E` option to pass environment variables to a command. With RootAsRole, you'll need to setup a role with a task that allows the command to use environment variables. However, as you keep the default configuration, you'll have two roles that matches ANY commands, and if the first one is more restrictive than the second one, you'll need to specify the role to use. Here is an example:
   
 ```bash
-dosr chsr role env add # Create a new role
-dosr chsr role env task env add # Create a new task
-dosr chsr role env task env cmd setpolicy allow-all # Add all command to the task
-dosr chsr role env task env cred caps setpolicy allow-all # Add all capabilities to the task
-dosr chsr role env task env o env setpolicy keep-all # Keep the environment variables
+sr chsr role env add # Create a new role
+sr chsr role env task env add # Create a new task
+sr chsr role env task env cmd setpolicy allow-all # Add all command to the task
+sr chsr role env task env cred caps setpolicy allow-all # Add all capabilities to the task
+sr chsr role env task env o env setpolicy keep-all # Keep the environment variables
 ```
 
 Then you can use the following command to pass environment variables to a command:
 
 ```bash
-dosr -r env [command]
+sr -r env [command]
 ```
 
 This is because the default role do not keep the environment variables, so if you want to keep environment variables you need to specify the role to use.
@@ -97,26 +97,26 @@ This is because the default role do not keep the environment variables, so if yo
 You are an administrator that want to automatically reboot the system at 04:05 every day with cron for example. You can disable authentication by setting skip-auth in the options. Here is an example:
 
 ```bash
-dosr chsr role auto add # Create a new role
-dosr chsr role grant -u cron # Grant the role to the user cron
-dosr chsr role auto task cron_reboot add # Create a new task
-dosr chsr role auto task cron_reboot cmd whitelist add reboot # Add the reboot command to the task
-dosr chsr role auto task cron_reboot cred caps whitelist add CAP_SYS_BOOT # Add the CAP_SYS_BOOT capability to the task
-dosr chsr role auto task cron_reboot o authentication skip # Skip authentication
+sr chsr role auto add # Create a new role
+sr chsr role grant -u cron # Grant the role to the user cron
+sr chsr role auto task cron_reboot add # Create a new task
+sr chsr role auto task cron_reboot cmd whitelist add reboot # Add the reboot command to the task
+sr chsr role auto task cron_reboot cred caps whitelist add CAP_SYS_BOOT # Add the CAP_SYS_BOOT capability to the task
+sr chsr role auto task cron_reboot o authentication skip # Skip authentication
 ```
 
 Then you can configure the cron to reboot the system with the following command:
 
 ```bash
-dosr crontab -u cron -e
+sr crontab -u cron -e
 ```
 
 and add the following line to reboot the system at 04:05 every day
 
 ```cron
-5 4 * * * dosr -r auto -t cron_reboot reboot
+5 4 * * * sr -r auto -t cron_reboot reboot
 ```
 
-Note: You should consider to set the `-r auto -t cron_reboot` options to the `dosr` command when you automate a task to avoid any security issue or future conflict.
+Note: You should consider to set the `-r auto -t cron_reboot` options to the `sr` command when you automate a task to avoid any security issue or future conflict.
 
 For a more complete example, you can checkout the [Is a Linux system without root user possible ?](knowledge/no-root.md) section.
\ No newline at end of file
diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
index 3a7732e9..9916d87b 100644
--- a/book/src/SUMMARY.md
+++ b/book/src/SUMMARY.md
@@ -6,7 +6,7 @@
 # User Guide
 
 - [Installation](guide/installation.md)
-- [`dosr` Command Line Tool](dosr/README.md)
+- [`sr` Command Line Tool](sr/README.md)
 - [`chsr` Command Line Tool](chsr/README.md)
 - [`capable` Command Line Tool](capable/README.md)
 
diff --git a/book/src/chsr/file-config.md b/book/src/chsr/file-config.md
index f9b32c3f..b2f1860c 100644
--- a/book/src/chsr/file-config.md
+++ b/book/src/chsr/file-config.md
@@ -93,9 +93,9 @@ The following example shows a RootAsRole config without plugins when almost ever
           "cred": {
             "setuid": {
               "fallback": "thefallbackuser", // Fallback user if the -u option is not set
-              "default": "none", // The dosr user cannot use -u option in general
-              "add": ["theuser"], // the dosr user can use "-u theuser" option
-              "sub": ["anotheruser"] // the dosr user cannot use "-u anotheruser" option (overrides add, applies only if default is all)
+              "default": "none", // The sr user cannot use -u option in general
+              "add": ["theuser"], // the sr user can use "-u theuser" option
+              "sub": ["anotheruser"] // the sr user cannot use "-u anotheruser" option (overrides add, applies only if default is all)
             }, // User to setuid before executing the command
             "setgid": [ // Groups to setgid before executing the command, The first one is the primary group
               "group1",
diff --git a/book/src/guide/installation.md b/book/src/guide/installation.md
index 8b2ba93b..7f914906 100644
--- a/book/src/guide/installation.md
+++ b/book/src/guide/installation.md
@@ -28,12 +28,12 @@ Install script does the following:
 - Dependency Step :
   - Installing necessary dependencies considering if compiling from source.
 - Build Step :
-  - Building dosr and chsr binaries
+  - Building sr and chsr binaries
 - Install Step : 
-  - Copying dosr and chsr binaries to /usr/bin
-  - Setting all capabilities on /usr/bin/dosr
-  - Setting owners and permissions on /usr/bin/dosr
+  - Copying sr and chsr binaries to /usr/bin
+  - Setting all capabilities on /usr/bin/sr
+  - Setting owners and permissions on /usr/bin/sr
 - Configuration Step :
-  - Deploying /etc/pam.d/dosr for PAM configuration
+  - Deploying /etc/pam.d/sr for PAM configuration
   - Deploying /etc/security/rootasrole.json for configuration
   - Setting immutable on /etc/security/rootasrole.json if filesytem supports it
\ No newline at end of file
diff --git a/book/src/knowledge/no-root.md b/book/src/knowledge/no-root.md
index 6497f766..1ad549fd 100644
--- a/book/src/knowledge/no-root.md
+++ b/book/src/knowledge/no-root.md
@@ -3,35 +3,35 @@
 To make it short, not really. But you can design your system to never have to use the root user. This is what RootAsRole aims, and the exact purpose of Linux Capabilities. Let's consider you want a system without root user and you want to setup a webserver. Firstly, let's create the apache2 user and group:
 
 ```bash
-dosr adduser apache2
+sr adduser apache2
 ```
 
 We consider that we still use the default configuration of RootAsRole. Then, let's add a task to install apache2 with the apache2 user:
 
 ```bash
-dosr chsr r r_root t install_apache2 add
-dosr chsr r r_root t install_apache2 cmd whitelist add apt install apache2
-dosr chsr r r_root t install_apache2 cmd whitelist add "apt upgrade( -y)? apache2"
-dosr chsr r r_root t install_apache2 cred set --caps CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_SETUID --setuid apache2 --setgid apache2
+sr chsr r r_root t install_apache2 add
+sr chsr r r_root t install_apache2 cmd whitelist add apt install apache2
+sr chsr r r_root t install_apache2 cmd whitelist add "apt upgrade( -y)? apache2"
+sr chsr r r_root t install_apache2 cred set --caps CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_SETUID --setuid apache2 --setgid apache2
 ```
 
 Then, let's add a task to start apache2 with the apache2 user:
 
 ```bash
-dosr chsr r r_root t start_apache2 add
-dosr chsr r r_root t start_apache2 cmd whitelist add "systemctl ((re)?start|stop) apache2"
-dosr chsr r r_root t start_apache2 cmd whitelist add "service apache2 ((re)?start|stop)"
-dosr chsr r r_root t install_apache2 cred set --caps CAP_NET_BIND_SERVICE,CAP_SETUID --setuid apache2 --setgid apache2
+sr chsr r r_root t start_apache2 add
+sr chsr r r_root t start_apache2 cmd whitelist add "systemctl ((re)?start|stop) apache2"
+sr chsr r r_root t start_apache2 cmd whitelist add "service apache2 ((re)?start|stop)"
+sr chsr r r_root t install_apache2 cred set --caps CAP_NET_BIND_SERVICE,CAP_SETUID --setuid apache2 --setgid apache2
 ```
 
 So now you can install and start apache2 with the apache2 user:
 
 ```bash
-dosr apt install apache2
+sr apt install apache2
 ```
 
 This should install apache2 configuration files owned by apache2 user and group. Then you can start apache2 with the apache2 user:
 
 ```bash
-dosr systemctl start apache2
+sr systemctl start apache2
 ```
\ No newline at end of file
diff --git a/book/src/dosr/README.md b/book/src/sr/README.md
similarity index 66%
rename from book/src/dosr/README.md
rename to book/src/sr/README.md
index 6b5314c7..33fedd3a 100644
--- a/book/src/dosr/README.md
+++ b/book/src/sr/README.md
@@ -1,11 +1,11 @@
-# What is dosr tool
+# What is sr tool
 
-`dosr` is the abbrevation of "do switch role" is a command line tool like sudo. It allows a permitted user to execute a command as another user and groups. More than sudo it allows to a permitted user to obtain some privileges. The sr command is used to switch to a role.
+`sr` is the abbrevation of "switch role" is a command line tool like sudo. It allows a permitted user to execute a command as another user and groups. More than sudo it allows to a permitted user to obtain some privileges. The sr command is used to switch to a role.
 
 # Usage
 
 
-Usage: dosr [OPTIONS] [COMMAND]...
+Usage: sr [OPTIONS] [COMMAND]...
 
 Arguments:
   [COMMAND]...  Command to execute
diff --git a/build.rs b/build.rs
index 708bf347..87d750c2 100644
--- a/build.rs
+++ b/build.rs
@@ -74,10 +74,6 @@ fn main() {
         eprintln!("cargo:warning={}", err);
     }
 
-    if let Err(err) = set_cargo_version(&package_version, "Cargo.toml") {
-        eprintln!("cargo:warning={}", err);
-    }
-
     if let Err(err) = set_readme_version(&package_version, "README.md") {
         eprintln!("cargo:warning={}", err);
     }
diff --git a/capable b/capable
new file mode 160000
index 00000000..42fff41a
--- /dev/null
+++ b/capable
@@ -0,0 +1 @@
+Subproject commit 42fff41a5d814a5fe1666fd285a9d5a5646be4d7
diff --git a/rar-common/Cargo.toml b/rar-common/Cargo.toml
index aa1469dd..a940ee4e 100644
--- a/rar-common/Cargo.toml
+++ b/rar-common/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rootasrole-core"
-version = "3.1.2"
+version = "3.1.1"
 edition = "2021"
 description = "This core crate contains the RBAC and main features for the RootAsRole project."
 license = "LGPL-3.0-or-later"
@@ -12,23 +12,23 @@ semver = { version = "1.0", features = ["serde"] }
 nix = { version = "0.29", features = ["user","process", "signal", "fs", "hostname"] }
 capctl = "0.2"
 pcre2 = { version = "0.2", optional = true }
-serde = { version = "1.0", features=["rc", "derive"] }
-serde_json = "1.0"
+serde = { version = "1.0.210", features=["rc", "derive"] }
+serde_json = "1.0.132"
 glob = { version = "0.3", optional = true }
-bitflags = { version = "2.9" }
+bitflags = { version = "2.5" }
 shell-words = "1.1"
 linked_hash_set = { version = "0.1" }
 derivative = "2.2"
 sha2 = "0.10"
 chrono = "0.4"
-once_cell = "1.20"
+once_cell = "1.19"
 hex = "0.4"
 log = "0.4"
-syslog = "6.0"
+syslog = "7.0"
 env_logger = "0.11"
-bon = { version = "3", features = ["experimental-overwritable"] }
-cbor4ii = { version = "1.0", features = ["serde", "serde1", "use_std"] }
-konst = "0.3"
+bon = { version = "3.3.2", features = ["experimental-overwritable"] }
+cbor4ii = { version = "1.0.0", features = ["serde", "serde1", "use_std"] }
+konst = "0.3.16"
 
 [dev-dependencies]
 log = "0.4"
@@ -36,8 +36,8 @@ env_logger = "0.11"
 test-log = { version = "0.2" }
 
 [build-dependencies]
-serde = { version = "1.0", features=["rc", "derive"] }
-serde_json = "1.0"
+serde = { version = "1.0.210", features=["rc", "derive"] }
+serde_json = "1.0.132"
 
 [features]
 pcre2 = ["dep:pcre2"]
diff --git a/rar-common/src/database/actor.rs b/rar-common/src/database/actor.rs
index 8b001f90..aeb9e8af 100644
--- a/rar-common/src/database/actor.rs
+++ b/rar-common/src/database/actor.rs
@@ -9,8 +9,6 @@ use serde::{Deserialize, Serialize};
 use serde_json::{Map, Value};
 use strum::EnumIs;
 
-use crate::util::{HARDENED_ENUM_VALUE_0, HARDENED_ENUM_VALUE_1};
-
 #[derive(Serialize, Debug, EnumIs, Clone, PartialEq, Eq, strum::Display)]
 #[serde(untagged, rename_all = "lowercase")]
 pub enum SGenericActorType {
@@ -151,10 +149,9 @@ impl Display for DUserType<'_> {
 
 #[derive(Serialize, PartialEq, Eq, Debug, Clone, EnumIs)]
 #[serde(untagged)]
-#[repr(u32)]
 pub enum SGroups {
-    Single(SGroupType) = HARDENED_ENUM_VALUE_0,
-    Multiple(Vec) = HARDENED_ENUM_VALUE_1,
+    Single(SGroupType),
+    Multiple(Vec),
 }
 
 impl Display for SGroups {
diff --git a/rar-common/src/database/de.rs b/rar-common/src/database/de.rs
index 794a7399..43e3f29f 100644
--- a/rar-common/src/database/de.rs
+++ b/rar-common/src/database/de.rs
@@ -40,7 +40,13 @@ impl<'de> Deserialize<'de> for SetBehavior {
             where
                 E: de::Error,
             {
-                SetBehavior::from_repr(v as u32).ok_or(de::Error::custom(format!(
+                if v > 1 || v < 0 {
+                    return Err(de::Error::custom(format!(
+                        "Invalid value for SetBehavior: {}",
+                        v
+                    )));
+                }
+                SetBehavior::from_repr(v as u8).ok_or(de::Error::custom(format!(
                     "Invalid value for SetBehavior: {}",
                     v
                 )))
@@ -91,7 +97,7 @@ impl<'de> Deserialize<'de> for SetBehavior {
             where
                 E: de::Error,
             {
-                if v > i32::MAX as i64 {
+                if v > i32::MAX as i64 || v < i32::MIN as i64 {
                     return Err(de::Error::custom(format!(
                         "Invalid value for SetBehavior: {}",
                         v
@@ -313,8 +319,6 @@ impl<'de> Deserialize<'de> for SCommands {
 
 #[cfg(test)]
 mod tests {
-    use crate::util::{HARDENED_ENUM_VALUE_0, HARDENED_ENUM_VALUE_1, HARDENED_ENUM_VALUE_2};
-
     use super::*;
     use capctl::Cap;
     use serde_json::json;
@@ -329,21 +333,15 @@ mod tests {
         let behavior: SetBehavior = serde_json::from_value(json_data).unwrap();
         assert_eq!(behavior, SetBehavior::All);
 
-        let json_data = json!(HARDENED_ENUM_VALUE_0);
+        let json_data = json!(0);
         let behavior: SetBehavior = serde_json::from_value(json_data).unwrap();
-        assert_eq!(
-            behavior,
-            SetBehavior::from_repr(HARDENED_ENUM_VALUE_0).unwrap()
-        );
+        assert_eq!(behavior, SetBehavior::from_repr(0).unwrap());
 
-        let json_data = json!(HARDENED_ENUM_VALUE_1);
+        let json_data = json!(1);
         let behavior: SetBehavior = serde_json::from_value(json_data).unwrap();
-        assert_eq!(
-            behavior,
-            SetBehavior::from_repr(HARDENED_ENUM_VALUE_1).unwrap()
-        );
+        assert_eq!(behavior, SetBehavior::from_repr(1).unwrap());
 
-        let invalid_data = json!(HARDENED_ENUM_VALUE_2);
+        let invalid_data = json!(2);
         assert!(serde_json::from_value::(invalid_data).is_err());
     }
 
diff --git a/rar-common/src/database/options.rs b/rar-common/src/database/options.rs
index 40a0f606..0d4a9014 100644
--- a/rar-common/src/database/options.rs
+++ b/rar-common/src/database/options.rs
@@ -17,9 +17,6 @@ use strum::{Display, EnumIs, EnumIter, EnumString, FromRepr};
 use log::debug;
 
 use crate::rc_refcell;
-use crate::util::{
-    HARDENED_ENUM_VALUE_0, HARDENED_ENUM_VALUE_1, HARDENED_ENUM_VALUE_2, HARDENED_ENUM_VALUE_3,
-};
 
 //#[cfg(feature = "finder")]
 //use super::finder::Cred;
@@ -61,13 +58,13 @@ pub enum OptType {
 #[strum(ascii_case_insensitive)]
 #[serde(rename_all = "lowercase")]
 #[derive(Default)]
-#[repr(u32)]
+#[repr(u8)]
 pub enum PathBehavior {
-    Delete = HARDENED_ENUM_VALUE_0,
-    KeepSafe = HARDENED_ENUM_VALUE_1,
-    KeepUnsafe = HARDENED_ENUM_VALUE_2,
+    Delete,
+    KeepSafe,
+    KeepUnsafe,
     #[default]
-    Inherit = HARDENED_ENUM_VALUE_3,
+    Inherit,
 }
 
 #[derive(
@@ -136,12 +133,12 @@ impl SPathOptions {}
 #[strum(ascii_case_insensitive)]
 #[serde(rename_all = "lowercase")]
 #[derive(Default)]
-#[repr(u32)]
+#[repr(u8)]
 pub enum EnvBehavior {
-    Delete = HARDENED_ENUM_VALUE_0,
-    Keep = HARDENED_ENUM_VALUE_1,
+    Delete,
+    Keep,
     #[default]
-    Inherit = HARDENED_ENUM_VALUE_2,
+    Inherit,
 }
 
 #[derive(Serialize, Hash, Deserialize, PartialEq, Eq, Debug, EnumIs, Clone)]
@@ -213,12 +210,12 @@ pub struct SEnvOptions {
 #[strum(ascii_case_insensitive)]
 #[serde(rename_all = "lowercase")]
 #[derive(Default)]
-#[repr(u32)]
+#[repr(u8)]
 pub enum SBounding {
-    Strict = HARDENED_ENUM_VALUE_0,
+    Strict,
     #[default]
-    Inherit = HARDENED_ENUM_VALUE_1,
-    Ignore = HARDENED_ENUM_VALUE_2,
+    Inherit,
+    Ignore,
 }
 
 #[derive(
@@ -227,12 +224,12 @@ pub enum SBounding {
 #[strum(ascii_case_insensitive)]
 #[serde(rename_all = "kebab-case")]
 #[derive(Default)]
-#[repr(u32)]
+#[repr(u8)]
 pub enum SPrivileged {
     #[default]
-    User = HARDENED_ENUM_VALUE_0,
-    Inherit = HARDENED_ENUM_VALUE_1,
-    Privileged = HARDENED_ENUM_VALUE_2,
+    User,
+    Inherit,
+    Privileged,
 }
 
 #[derive(
@@ -241,12 +238,12 @@ pub enum SPrivileged {
 #[strum(ascii_case_insensitive)]
 #[serde(rename_all = "kebab-case")]
 #[derive(Default)]
-#[repr(u32)]
+#[repr(u8)]
 pub enum SAuthentication {
     #[default]
-    Perform = HARDENED_ENUM_VALUE_0,
-    Inherit = HARDENED_ENUM_VALUE_1,
-    Skip = HARDENED_ENUM_VALUE_2,
+    Perform,
+    Inherit,
+    Skip,
 }
 
 #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
diff --git a/rar-common/src/database/score.rs b/rar-common/src/database/score.rs
index 22842c59..aa02b64b 100644
--- a/rar-common/src/database/score.rs
+++ b/rar-common/src/database/score.rs
@@ -1,39 +1,24 @@
 use std::cmp::Ordering;
 
-use bon::{builder, Builder};
+use bon::Builder;
 use strum::EnumIs;
 
-use crate::util::{
-    HARDENED_ENUM_VALUE_0, HARDENED_ENUM_VALUE_1, HARDENED_ENUM_VALUE_2, HARDENED_ENUM_VALUE_3,
-    HARDENED_ENUM_VALUE_4,
-};
-
 use super::actor::{DGroupType, DGroups, DUserType, SGroupType, SGroups, SUserType};
 
 #[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug, EnumIs, Default)]
 #[repr(u32)]
 // Matching user groups for the role
 pub enum ActorMatchMin {
-    UserMatch = HARDENED_ENUM_VALUE_0,
-    GroupMatch(usize) = HARDENED_ENUM_VALUE_1,
-    #[default]
-    NoMatch = HARDENED_ENUM_VALUE_2,
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug, EnumIs, Default)]
-#[repr(u32)]
-pub enum HardenedBool {
+    UserMatch,
+    GroupMatch(usize),
     #[default]
-    False = HARDENED_ENUM_VALUE_0,
-    True = HARDENED_ENUM_VALUE_1,
+    NoMatch,
 }
 
 impl ActorMatchMin {
-    #[inline]
     pub fn better(&self, other: &Self) -> bool {
         self.cmp(other) == Ordering::Less
     }
-    #[inline]
     pub fn matching(&self) -> bool {
         *self != ActorMatchMin::NoMatch
     }
@@ -141,65 +126,38 @@ impl Ord for SetUserMin {
     }
 }
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug, Default, Builder)]
-#[builder(const)]
-pub struct CmdMin {
-    #[builder(default = HardenedBool::False, with = || HardenedBool::True, name = "matching")]
-    pub status: HardenedBool,
-    #[builder(default = CmdOrder::empty())]
-    pub order: CmdOrder,
-}
-
 #[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug, Default)]
-pub struct CmdOrder(u32);
+pub struct CmdMin(u32);
 
 bitflags::bitflags! {
 
-    impl CmdOrder: u32 {
-        const WildcardPath = 0b0001;
-        const RegexArgs = 0b0010;
-        const FullRegexArgs = 0b0100;
-        const FullWildcardPath = 0b1000;
+    impl CmdMin: u32 {
+        const Match = 0b00001;
+        const WildcardPath = 0b00010;
+        const RegexArgs = 0b00100;
+        const FullRegexArgs = 0b01000;
+        const FullWildcardPath = 0b10000;
     }
 }
 
 impl CmdMin {
-    pub const MATCH: CmdMin = CmdMin::builder().matching().build();
-
-    pub const fn empty() -> Self {
-        CmdMin::builder().build()
-    }
-    pub fn is_empty(&self) -> bool {
-        self.status == HardenedBool::False && self.order.is_empty()
-    }
-    #[inline]
     pub fn better(&self, other: &Self) -> bool {
         (self.matching() && !other.matching())
-            || (self.matching() && self.order.cmp(&other.order) == Ordering::Less)
+            || (self.matching() && self.cmp(other) == Ordering::Less)
     }
-    #[inline]
     pub fn matching(&self) -> bool {
-        self.status == HardenedBool::True
-    }
-
-    pub fn set_matching(&mut self) {
-        self.status = HardenedBool::True;
-    }
-
-    pub fn union_order(&mut self, order: CmdOrder) {
-        self.order |= order;
+        !self.is_empty()
     }
 }
 
 #[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug, Default)]
-#[repr(u32)]
 pub enum CapsMin {
     #[default]
-    Undefined = HARDENED_ENUM_VALUE_0,
-    NoCaps = HARDENED_ENUM_VALUE_1,
-    CapsNoAdmin(usize) = HARDENED_ENUM_VALUE_2,
-    CapsAdmin(usize) = HARDENED_ENUM_VALUE_3,
-    CapsAll = HARDENED_ENUM_VALUE_4,
+    Undefined,
+    NoCaps,
+    CapsNoAdmin(usize),
+    CapsAdmin(usize),
+    CapsAll,
 }
 
 #[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Debug, Default)]
@@ -260,45 +218,37 @@ impl Score {
     }
 
     /// Compare the score of tasks results
-    #[inline]
     pub fn cmd_cmp(&self, other: &Score) -> Ordering {
         self.cmd_min
-            .order
-            .cmp(&other.cmd_min.order)
+            .cmp(&other.cmd_min)
             .then(self.caps_min.cmp(&other.caps_min))
             .then(self.setuser_min.cmp(&other.setuser_min))
             .then(self.security_min.cmp(&other.security_min))
     }
 
-    #[inline]
     pub fn user_matching(&self) -> bool {
         self.user_min != ActorMatchMin::NoMatch
     }
 
-    #[inline]
     pub fn command_matching(&self) -> bool {
-        self.cmd_min.matching()
+        !self.cmd_min.is_empty()
     }
 
-    #[inline]
     pub fn fully_matching(&self) -> bool {
         self.user_matching() && self.command_matching()
     }
 
     /// Return true if the score is better than the other
-    #[inline]
     pub fn better_command(&self, other: &Score) -> bool {
         (self.command_matching() && !other.command_matching())
             || (self.command_matching() && self.cmd_cmp(other) == Ordering::Less)
     }
 
-    #[inline]
     pub fn better_user(&self, other: &Score) -> bool {
         (self.user_matching() && !other.user_matching())
             || (self.user_matching() && self.user_cmp(other) == Ordering::Less)
     }
 
-    #[inline]
     pub fn better_fully(&self, other: &Score) -> bool {
         (self.fully_matching() && !other.fully_matching())
             || (self.fully_matching() && self.cmp(other) == Ordering::Less)
@@ -329,27 +279,20 @@ impl Ord for Score {
     }
 }
 
-#[inline]
 fn group_is_root(actortype: &SGroupType) -> bool {
     (*actortype).fetch_id().map_or(false, |id| id == 0)
 }
-
-#[inline]
 fn dgroup_is_root(actortype: &DGroupType<'_>) -> bool {
     (*actortype).fetch_id().map_or(false, |id| id == 0)
 }
 
-#[inline]
 fn user_is_root(actortype: &SUserType) -> bool {
     (*actortype).fetch_id().map_or(false, |id| id == 0)
 }
-
-#[inline]
 fn duser_is_root(actortype: &DUserType<'_>) -> bool {
     (*actortype).fetch_id().map_or(false, |id| id == 0)
 }
 
-#[inline]
 fn groups_contains_root(list: Option<&SGroups>) -> bool {
     if let Some(list) = list {
         match list {
@@ -361,7 +304,6 @@ fn groups_contains_root(list: Option<&SGroups>) -> bool {
     }
 }
 
-#[inline]
 fn dgroups_contains_root(list: Option<&DGroups<'_>>) -> bool {
     if let Some(list) = list {
         match list {
@@ -373,7 +315,6 @@ fn dgroups_contains_root(list: Option<&DGroups<'_>>) -> bool {
     }
 }
 
-#[inline]
 fn groups_len(groups: Option<&SGroups>) -> usize {
     match groups {
         Some(groups) => groups.len(),
@@ -381,7 +322,6 @@ fn groups_len(groups: Option<&SGroups>) -> usize {
     }
 }
 
-#[inline]
 fn dgroups_len(groups: Option<&DGroups<'_>>) -> usize {
     match groups {
         Some(groups) => groups.len(),
@@ -537,11 +477,8 @@ mod tests {
     fn test_score_ordering() {
         let mut score1 = Score::default();
         let mut score2 = Score::default();
-        score1.cmd_min = CmdMin::builder().matching().build();
-        score2.cmd_min = CmdMin::builder()
-            .matching()
-            .order(CmdOrder::WildcardPath)
-            .build();
+        score1.cmd_min = CmdMin::from_bits_truncate(0b00001);
+        score2.cmd_min = CmdMin::from_bits_truncate(0b00010);
         assert!(score1 < score2 || score1 == score2 || score1 > score2);
     }
 
@@ -554,8 +491,8 @@ mod tests {
 
     #[test]
     fn test_cmdmin_better_and_matching() {
-        let a = CmdMin::builder().matching().build();
-        let b = CmdMin::builder().build();
+        let a = CmdMin::from_bits_truncate(0b00001);
+        let b = CmdMin::from_bits_truncate(0b00000);
         assert!(a.matching());
         assert!(!b.matching());
         assert!(!b.better(&a));
@@ -566,8 +503,8 @@ mod tests {
     fn test_score_better_methods() {
         let mut score1 = Score::default();
         let mut score2 = Score::default();
-        score1.cmd_min = CmdMin::builder().matching().build();
-        score2.cmd_min = CmdMin::builder().build();
+        score1.cmd_min = CmdMin::from_bits_truncate(0b00001);
+        score2.cmd_min = CmdMin::from_bits_truncate(0b00000);
         assert!(score1.better_command(&score2));
         assert!(!score2.better_command(&score1));
     }
@@ -653,34 +590,23 @@ mod tests {
     fn test_set_score() {
         let mut score = Score::default();
         let task_score = TaskScore {
-            cmd_min: CmdMin::builder().matching().build(),
+            cmd_min: CmdMin::from_bits_truncate(0b00001),
             caps_min: CapsMin::NoCaps,
             setuser_min: SetUserMin::default(),
         };
         score.set_task_score(&task_score);
-        assert_eq!(score.cmd_min, CmdMin::builder().matching().build());
+        assert_eq!(score.cmd_min, CmdMin::from_bits_truncate(0b00001));
         assert_eq!(score.caps_min, CapsMin::NoCaps);
         assert_eq!(score.setuser_min, SetUserMin::default());
         let role_score = ActorMatchMin::UserMatch;
         score.set_role_score(&role_score);
         assert_eq!(score.user_min, ActorMatchMin::UserMatch);
-        assert_eq!(score.cmd_min, CmdMin::builder().matching().build());
+        assert_eq!(score.cmd_min, CmdMin::from_bits_truncate(0b00001));
         assert_eq!(score.caps_min, CapsMin::NoCaps);
         assert_eq!(score.setuser_min, SetUserMin::default());
         assert_eq!(score.security_min, SecurityMin::empty());
-        score.set_cmd_score(
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::WildcardPath)
-                .build(),
-        );
-        assert_eq!(
-            score.cmd_min,
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::WildcardPath)
-                .build()
-        );
+        score.set_cmd_score(CmdMin::from_bits_truncate(0b00010));
+        assert_eq!(score.cmd_min, CmdMin::from_bits_truncate(0b00010));
         assert_eq!(score.caps_min, CapsMin::NoCaps);
         assert_eq!(score.setuser_min, SetUserMin::default());
         assert_eq!(score.user_min, ActorMatchMin::UserMatch);
@@ -697,7 +623,7 @@ mod tests {
         assert!(score.user_matching());
         assert!(!score.command_matching());
         assert!(!score.fully_matching());
-        score.cmd_min = CmdMin::builder().matching().build();
+        score.cmd_min = CmdMin::from_bits_truncate(0b00001);
         assert!(score.user_matching());
         assert!(score.command_matching());
         assert!(score.fully_matching());
@@ -711,11 +637,8 @@ mod tests {
     fn test_score_better() {
         let mut score1 = Score::default();
         let mut score2 = Score::default();
-        score1.cmd_min = CmdMin::builder().matching().build();
-        score2.cmd_min = CmdMin::builder()
-            .matching()
-            .order(CmdOrder::WildcardPath)
-            .build();
+        score1.cmd_min = CmdMin::from_bits_truncate(0b00001);
+        score2.cmd_min = CmdMin::from_bits_truncate(0b00010);
         assert!(!score2.better_command(&score1));
         assert!(score1.better_command(&score2));
         assert!(!score1.better_user(&score2));
@@ -734,20 +657,14 @@ mod tests {
     fn test_score_max_min_clamp() {
         let mut score1 = Score::default();
         let mut score2 = Score::default();
-        score1.cmd_min = CmdMin::builder().matching().build();
-        score2.cmd_min = CmdMin::builder()
-            .matching()
-            .order(CmdOrder::WildcardPath)
-            .build();
+        score1.cmd_min = CmdMin::from_bits_truncate(0b00001);
+        score2.cmd_min = CmdMin::from_bits_truncate(0b00010);
         assert_eq!(score1.max(score2), score2);
         assert_eq!(score2.max(score1), score2);
         assert_eq!(score1.min(score2), score1);
         assert_eq!(score2.min(score1), score1);
         let mut score3 = Score::default();
-        score3.cmd_min = CmdMin::builder()
-            .matching()
-            .order(CmdOrder::RegexArgs)
-            .build();
+        score3.cmd_min = CmdMin::from_bits_truncate(0b00011);
         assert_eq!(score1.clamp(score2, score3), score2);
         assert_eq!(score2.clamp(score1, score3), score2);
     }
diff --git a/rar-common/src/database/ser.rs b/rar-common/src/database/ser.rs
index 62346488..ddb89e4d 100644
--- a/rar-common/src/database/ser.rs
+++ b/rar-common/src/database/ser.rs
@@ -87,7 +87,7 @@ impl Serialize for SetBehavior {
         if serializer.is_human_readable() {
             return serializer.serialize_str(&self.to_string());
         } else {
-            return serializer.serialize_u32(*self as u32);
+            return serializer.serialize_u8(*self as u8);
         }
     }
 }
@@ -114,7 +114,7 @@ impl Serialize for SSetuidSet {
             map.end()
         } else {
             let mut map = serializer.serialize_map(None)?;
-            map.serialize_entry("d", &(self.default as u32))?;
+            map.serialize_entry("d", &(self.default as u8))?;
             if let Some(fallback) = &self.fallback {
                 map.serialize_entry("f", fallback)?;
             }
@@ -155,7 +155,7 @@ impl Serialize for SSetgidSet {
             map.end()
         } else {
             let mut map = serializer.serialize_map(None)?;
-            map.serialize_entry("d", &(self.default as u32))?;
+            map.serialize_entry("d", &(self.default as u8))?;
             if !self.fallback.is_empty() {
                 map.serialize_entry("f", &self.fallback)?;
             }
@@ -198,7 +198,7 @@ impl Serialize for SCapabilities {
             } else {
                 let mut map = serializer.serialize_map(Some(3))?;
                 if self.default_behavior.is_all() {
-                    map.serialize_entry("d", &(self.default_behavior as u32))?;
+                    map.serialize_entry("d", &(self.default_behavior as u8))?;
                 }
                 if !self.add.is_empty() {
                     let v: Vec = self.add.iter().map(|cap| cap.to_string()).collect();
@@ -343,7 +343,7 @@ impl Serialize for SCommands {
         } else {
             let mut map = serializer.serialize_map(Some(3))?;
             if let Some(behavior) = &self.default_behavior {
-                map.serialize_entry("d", &(*behavior as u32))?;
+                map.serialize_entry("d", &(*behavior as u8))?;
             }
             if !self.add.is_empty() {
                 map.serialize_entry("a", &self.add)?;
@@ -424,25 +424,7 @@ mod tests {
         let mut serializer = cbor4ii::serde::Serializer::new(&mut writer);
         b.serialize(&mut serializer).unwrap();
         assert!(!writer.buffer().is_empty());
-        // split HARDENED_ENUM_VALUE_0 to an array of bytes
-        // cbor4ii add 0x1A prefix to the value
-        let splitted = [0x1A, 0x05, 0x2A, 0x29, 0x25];
-        println!("splitted: {:?}", splitted);
-        println!("buffer: {:?}", writer.buffer());
-        assert!(writer.buffer() == splitted);
-        // test serialization of SetBehavior::All
-        let b = SetBehavior::All;
-        let bin: Vec = Vec::new();
-        let mut writer = cbor4ii::core::utils::BufWriter::new(bin);
-        let mut serializer = cbor4ii::serde::Serializer::new(&mut writer);
-        b.serialize(&mut serializer).unwrap();
-        assert!(!writer.buffer().is_empty());
-        // split HARDENED_ENUM_VALUE_0 to an array of bytes
-        // cbor4ii add 0x1A prefix to the value
-        let splitted = [0x1A, 0x0A, 0xD5, 0xD6, 0xDA];
-        println!("splitted: {:?}", splitted);
-        println!("buffer: {:?}", writer.buffer());
-        assert!(writer.buffer() == splitted);
+        assert!(writer.buffer() == [0x00]);
     }
 
     #[test]
diff --git a/rar-common/src/database/structs.rs b/rar-common/src/database/structs.rs
index 12c0b322..5f14ac4d 100644
--- a/rar-common/src/database/structs.rs
+++ b/rar-common/src/database/structs.rs
@@ -13,10 +13,7 @@ use std::{
     rc::{Rc, Weak},
 };
 
-use crate::{
-    rc_refcell,
-    util::{HARDENED_ENUM_VALUE_0, HARDENED_ENUM_VALUE_1},
-};
+use crate::rc_refcell;
 
 use super::{
     actor::{SActor, SGroupType, SGroups, SUserType},
@@ -222,11 +219,11 @@ pub struct SSetuidSet {
 #[derive(PartialEq, Eq, Display, Debug, EnumIs, Clone, Copy, FromRepr, EnumString)]
 #[strum(serialize_all = "lowercase")]
 #[derive(Default)]
-#[repr(u32)]
+#[repr(u8)]
 pub enum SetBehavior {
     #[default]
-    None = HARDENED_ENUM_VALUE_0,
-    All = HARDENED_ENUM_VALUE_1,
+    None,
+    All,
 }
 #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
 #[serde(untagged)]
diff --git a/rar-common/src/util.rs b/rar-common/src/util.rs
index c1e9add0..f1a784c0 100644
--- a/rar-common/src/util.rs
+++ b/rar-common/src/util.rs
@@ -22,16 +22,6 @@ pub const BOLD: &str = "\x1B[1m";
 pub const UNDERLINE: &str = "\x1B[4m";
 pub const RED: &str = "\x1B[31m";
 
-// Hardened enum values used for critical enums to mitigate attacks like Rowhammer.
-// See for example https://arxiv.org/pdf/2309.02545.pdf
-// The values are copied from https://github.com/sudo-project/sudo/commit/7873f8334c8d31031f8cfa83bd97ac6029309e4f#diff-b8ac7ab4c3c4a75aed0bb5f7c5fd38b9ea6c81b7557f775e46c6f8aa115e02cd
-pub const HARDENED_ENUM_VALUE_0: u32 = 0x052a2925; // 0101001010100010100100100101
-pub const HARDENED_ENUM_VALUE_1: u32 = 0x0ad5d6da; // 1010110101011101011011011010
-pub const HARDENED_ENUM_VALUE_2: u32 = 0x69d61fc8; // 1101001110101100001111111001000
-pub const HARDENED_ENUM_VALUE_3: u32 = 0x1629e037; // 0010110001010011110000000110111
-pub const HARDENED_ENUM_VALUE_4: u32 = 0x1fc8d3ac; // 11111110010001101001110101100
-
-
 #[macro_export]
 macro_rules! upweak {
     ($e:expr) => {
@@ -211,20 +201,18 @@ pub fn match_single_path(cmd_path: &PathBuf, role_path: &str) -> CmdMin {
     use glob::Pattern;
     if !role_path.ends_with(cmd_path.to_str().unwrap()) || !role_path.starts_with("/") {
         // the files could not be the same
-        return CmdMin::default();
+        return CmdMin::empty();
     }
-    let mut match_status = CmdMin::default();
+    let mut match_status = CmdMin::empty();
     debug!("Matching path {:?} with {:?}", cmd_path, role_path);
     if cmd_path == Path::new(role_path) {
-        match_status.set_matching();
+        match_status |= CmdMin::Match;
     } else if let Ok(pattern) = Pattern::new(role_path) {
         if pattern.matches_path(&cmd_path) {
-            use crate::database::score::CmdOrder;
-
-            match_status.union_order(CmdOrder::WildcardPath);
+            match_status |= CmdMin::WildcardPath;
         }
     }
-    if !match_status.matching() {
+    if match_status.is_empty() {
         debug!(
             "No match for path ``{:?}`` for evaluated path : ``{:?}``",
             cmd_path, role_path
diff --git a/resources/arch/PKGBUILD b/resources/arch/PKGBUILD
index 0ff43d30..e488694b 100644
--- a/resources/arch/PKGBUILD
+++ b/resources/arch/PKGBUILD
@@ -35,9 +35,9 @@ check() {
 
 package() {
     cd $pkgname-$pkgver
-    install -Dm755 'target/release/dosr' -t "$pkgdir/usr/bin"
+    install -Dm755 'target/release/sr' -t "$pkgdir/usr/bin"
     install -Dm755 'target/release/chsr' -t "$pkgdir/usr/bin"
-    install -Dm644 'resources/arch/arch_sr_pam.conf' -t "$pkgdir/etc/pam.d/dosr"
+    install -Dm644 'resources/arch/arch_sr_pam.conf' -t "$pkgdir/etc/pam.d/sr"
     install -Dm644 'resources/rootasrole.json' -t "$pkgdir/usr/share/rootasrole/default.json"
-    setcap '=p' "$pkgdir/usr/bin/dosr"
+    setcap '=p' "$pkgdir/usr/bin/sr"
 }
diff --git a/resources/arch/rootasrole.install b/resources/arch/rootasrole.install
index 816785f3..b628359f 100644
--- a/resources/arch/rootasrole.install
+++ b/resources/arch/rootasrole.install
@@ -21,7 +21,7 @@ post_install() {
         ext2|ext3|ext4|xfs|btrfs|ocfs2|jfs|reiserfs)
             if ! grep -q '"immutable": true' "$TARGET_PATH"; then
                 sed -i 's/"immutable": false/"immutable": true/' "$TARGET_PATH"
-                log "The file $TARGET_PATH is now immutable, and dosr will check that immutable is enforced before executing."
+                log "The file $TARGET_PATH is now immutable, and sr will check that immutable is enforced before executing."
             fi
             # Attempt to set the immutable flag
             if ! chattr +i "$TARGET_PATH"; then
@@ -31,7 +31,7 @@ post_install() {
             fi
             ;;
         *)
-            log "The file system $FS_TYPE does not support the immutable flag. Avoid checking the immutable flag during dosr execution."
+            log "The file system $FS_TYPE does not support the immutable flag. Avoid checking the immutable flag during sr execution."
             sed -i "s/\"immutable\": true/\"immutable\": false/g" "$TARGET_PATH"
             sed -i "s;\"CAP_LINUX_IMMUTABLE\";;g" "$TARGET_PATH"
             return 1
diff --git a/resources/man/en_US.md b/resources/man/en_US.md
index 0f9b7324..29725c87 100644
--- a/resources/man/en_US.md
+++ b/resources/man/en_US.md
@@ -6,7 +6,7 @@
 RootAsRole - An alternative to sudo/su commands that adheres to the principle of least privilege and provides more secure memory management.
 
 # SYNOPSIS
-- **dosr** [__OPTIONS__] [__COMMAND__]...
+- **sr** [__OPTIONS__] [__COMMAND__]...
 - **chsr** [__ARGUMENTS__]
 
     **chsr**'s arguments follow a grammar available at 
@@ -16,11 +16,11 @@ RootAsRole - An alternative to sudo/su commands that adheres to the principle of
 
 The Role-Based Access Control (RBAC) model is based on sets of permissions assigned to users or groups. In RootAsRole, a role is a set of administrative tasks assigned to users. Tasks are commands with specific rights. Rights can include changing the user, changing the group, or/and using Linux capabilities.
 
-The **dosr** command allows the execution of commands using a role. It requires a command to be executed as a mandatory parameter. It is also possible to specify a role and a task to select.
+The **sr** command allows the execution of commands using a role. It requires a command to be executed as a mandatory parameter. It is also possible to specify a role and a task to select.
 
 There are cases where several tasks correspond to a user's command input. In such cases, sr will select the most precise and least privileged task. The notion of precision is based on how closely the RootAsRole policy matches the user's command. The more the user's profile matches the policy, the higher the level of precision. The same applies to the precision of the user's command compared to its specification in the policy. Similarly, the task with fewer privileges will be prioritized over a task with higher privileges, but only if the tasks are equally precise. Despite this intelligent selection, confusion can still arise, and an error message will be returned.
 
-Example of a confusion case: Two roles are assigned in the same way to a user, and among these roles, two tasks are entirely equivalent, but the configured environment variable are different for these two tasks. In this case, dosr will display the error message "Permission denied" and log a warning that configuration must be fixed. This case should not happen if administrators are using **chsr**, the configuration tool.
+Example of a confusion case: Two roles are assigned in the same way to a user, and among these roles, two tasks are entirely equivalent, but the configured environment variable are different for these two tasks. In this case, sr will display the error message "Permission denied" and log a warning that configuration must be fixed. This case should not happen if administrators are using **chsr**, the configuration tool.
 
 It is possible to change the user's prompt using the **-p** option. It is also possible to view the executor's rights using the **-i** option. The displayed information is very limited for the user. Otherwise, administrator can use **chsr** to obtain the complete policy.
 
@@ -28,7 +28,7 @@ The **chsr** command is used to configure RootAsRole and its access control poli
 
 The storage mode of the access control policy can be configured. By default, RootAsRole uses a JSON file. It is possible to change the storage mode by manually modifying the **/etc/security/rootasrole.json** file.
 
-Regarding authentication, RootAsRole uses Pluggable Authentication Module (PAM). The **/etc/pam.d/dosr** file can be configured to change authentication behavior.
+Regarding authentication, RootAsRole uses Pluggable Authentication Module (PAM). The **/etc/pam.d/sr** file can be configured to change authentication behavior.
 
 The core of RootAsRole implements RBAC-0, a simplified version of RBAC. By default, it adds features in the form of plugins to implement certain RBAC-1 functionalities. RBAC-0 simply implements roles, tasks, and permissions. Plugins add role hierarchy and separation of duties. Plugins can only be implemented directly in the project. Another plugin allows testing the checksum of executed files.
 
@@ -60,10 +60,10 @@ The core of RootAsRole implements RBAC-0, a simplified version of RBAC. By defau
 
 # EXAMPLES
 
-**dosr reboot**  
+**sr reboot**  
   Execute the reboot command (if the policy allows it).
 
-**dosr -r dac chmod 644 /etc/foo/bar**  
+**sr -r dac chmod 644 /etc/foo/bar**  
   Execute the command chmod 644 /etc/foo/bar with the role dac (if the policy has a dac role and a task that allows the chmod command).
 
 # HISTORY
diff --git a/resources/man/fr_FR.md b/resources/man/fr_FR.md
index da1c8dbf..61a71f6f 100644
--- a/resources/man/fr_FR.md
+++ b/resources/man/fr_FR.md
@@ -6,7 +6,7 @@
 RootAsRole - Une alternative pour les commandes sudo/su respectant le principe du moindre privilège et une gestion de la mémoire plus sécurisée.
 
 # SYNOPSIS
-- **dosr** [__OPTIONS__] [__COMMAND__]...
+- **sr** [__OPTIONS__] [__COMMAND__]...
 - **chsr** [__ARGUMENTS__]
     Les arguments suivent une grammaire disponible dans le code source à l'adresse 
 
@@ -15,11 +15,11 @@ RootAsRole - Une alternative pour les commandes sudo/su respectant le principe d
 
 Le modèle de Roles Based Access Control (RBAC) est basé sur des ensembles de permissions assignées à des utilisateurs ou des groupes. Pour RootAsRole, un rôle est un ensemble de tâches administratives assignées à des utilisateurs. Les tâches sont des commandes avec des droits à utiliser. Les droits peuvent être un changement d'utilisateur, un changement de groupe ou/et des Linux capabilities.
 
-La commande **dosr** permet d'exécuter des commandes en utilisant un rôle. Il prends en paramètre obligatoire une commande à exécuter. Il est également possible de spécifier un rôle et une tâche à sélectionner.
+La commande **sr** permet d'exécuter des commandes en utilisant un rôle. Il prends en paramètre obligatoire une commande à exécuter. Il est également possible de spécifier un rôle et une tâche à sélectionner.
 
-Il existe des cas où deux tâches correspondent à la commande d'un utilisateur. Dans ce cas, dosr va sélectionner la tâche la plus précise et la moins privilégiée. La notion de précision est basée sur la précision de la politique RootAsRole comparée à l'occurence de la commande utilisateur. Plus le profil utilisateur et correspond à la politique, plus le niveau de précision est élevé. Il en est de même pour la précision de la commande de l'utilisateur vis-à-vis de sa spécification dans la politique. Pareillement, moins les droits sont élevés pour une tâche, plus la tâche sera prioritaire par rapport à une autre tâche. Le cas de la tâche moins privilégié n'est qu'uniquement si les tâches sont déjà avec le même niveau de précision. Malgré cette sélection intelligente, il reste des cas de confusion, ceux-ci renvoient un message d'erreur.
+Il existe des cas où deux tâches correspondent à la commande d'un utilisateur. Dans ce cas, sr va sélectionner la tâche la plus précise et la moins privilégiée. La notion de précision est basée sur la précision de la politique RootAsRole comparée à l'occurence de la commande utilisateur. Plus le profil utilisateur et correspond à la politique, plus le niveau de précision est élevé. Il en est de même pour la précision de la commande de l'utilisateur vis-à-vis de sa spécification dans la politique. Pareillement, moins les droits sont élevés pour une tâche, plus la tâche sera prioritaire par rapport à une autre tâche. Le cas de la tâche moins privilégié n'est qu'uniquement si les tâches sont déjà avec le même niveau de précision. Malgré cette sélection intelligente, il reste des cas de confusion, ceux-ci renvoient un message d'erreur.
 
-Exemple d'un cas de confusion : Deux rôles sont assignés de la même manière à un utilisateur, parmi ces rôles, deux tâches sont totalement équivalentes mais les variables d'environment sont différents. Dans ce cas, dosr affiche le message d'erreur "Permission denied" et fais un message warning dans les logs.
+Exemple d'un cas de confusion : Deux rôles sont assignés de la même manière à un utilisateur, parmi ces rôles, deux tâches sont totalement équivalentes mais les variables d'environment sont différents. Dans ce cas, sr affiche le message d'erreur "Permission denied" et fais un message warning dans les logs.
 
 Il est possible de changer le prompt de l'utilisateur en utilisant l'option **-p**. Il est également possible de voir les droits de l'exécuteur en utilisant l'option **-i**. Les informations affichées sont très limitées.
 
@@ -27,7 +27,7 @@ La commande **chsr** sert à configurer RootAsRole et sa politique de contrôle
 
 Il est possible de configurer le mode de stockage de la politique de contrôle d'accès. Par défaut, RootAsRole utilise un fichier JSON. Il est possible de changer le mode de stockage en modifiant manuellement le fichier **/etc/security/rootasrole.json**.
 
-Concernant l'authentification, RootAsRole utilise PAM. Il est possible de configurer le fichier **/etc/pam.d/dosr** pour changer le comportement de l'authentification.
+Concernant l'authentification, RootAsRole utilise PAM. Il est possible de configurer le fichier **/etc/pam.d/sr** pour changer le comportement de l'authentification.
 
 Le coeur de RootAsRole implémente RBAC-0, une version simplifiée de RBAC. Par défaut il ajoute des fonctionnalités sous forme de plugins pour implémenter certaines fonctionnalités de RBAC-1. RBAC-0 implémente simplement les rôles, les tâches et les permissions. Les plugins ajoutent la hiérarchie de rôles et séparation des devoirs. Les plugins sont uniquement implémentable directement dans le projet. Il y a également un autre plugin qui permet de tester la somme de contrôle des fichiers exécutés.
 
@@ -50,10 +50,10 @@ Le coeur de RootAsRole implémente RBAC-0, une version simplifiée de RBAC. Par
 
 # EXAMPLES
 
-- **dosr reboot**  
+- **sr reboot**  
   Execute the command reboot. (If the policy is defined and allowed as well)
 
-- **dosr -r dac chmod 644 /etc/foo/bar**
+- **sr -r dac chmod 644 /etc/foo/bar**
   Execute the command chmod 644 /etc/foo/bar with the role dac (If the policy has a role dac and a task that allows chmod command)
 
 # HISTORIQUE
diff --git a/src/sr/finder/api/hashchecker.rs b/src/sr/finder/api/hashchecker.rs
index cd73a293..bbb03bbe 100644
--- a/src/sr/finder/api/hashchecker.rs
+++ b/src/sr/finder/api/hashchecker.rs
@@ -5,7 +5,7 @@ use libc::FS_IOC_GETFLAGS;
 use log::{debug, warn};
 use nix::unistd::{access, AccessFlags};
 use rar_common::{
-    database::score::{CmdMin, CmdOrder},
+    database::score::CmdMin,
     util::{all_paths_from_env, match_single_path, open_with_privileges},
 };
 use serde_json::to_value;
@@ -114,10 +114,7 @@ fn match_path(
     final_path: &mut Option,
 ) -> CmdMin {
     if role_path == "**" {
-        return CmdMin::builder()
-            .matching()
-            .order(CmdOrder::FullWildcardPath)
-            .build();
+        return CmdMin::FullWildcardPath;
     } else if cmd_path.is_absolute() {
         let min = match_single_path(cmd_path, role_path);
         verify_executable_conditions(checker, final_path, cmd_path, min).unwrap_or_default()
@@ -191,12 +188,12 @@ fn match_command_line(
     final_path: &mut Option,
 ) {
     let mut result = match_path(checker, env_path, cmd_path, &role_command[0], final_path);
-    if !result.matching() || role_command.len() == 1 {
+    if result.is_empty() || role_command.len() == 1 {
         *cmd_min = result;
         return;
     }
     match match_args(cmd_args, &shell_words::join(&role_command[1..])) {
-        Ok(args_result) => result = args_result,
+        Ok(args_result) => result |= args_result,
         Err(err) => {
             debug!("Error: {}", err);
             return;
@@ -324,7 +321,7 @@ mod tests {
         let result = deserializer.deserialize(&mut serde_json::Deserializer::from_str(&json));
         assert!(result.is_ok());
         assert_eq!(final_path, Some(PathBuf::from(&filename)));
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
 
         let mut sha256hasher = Sha256::new();
         sha256hasher.update(&buffer);
@@ -347,7 +344,7 @@ mod tests {
         let result = deserializer.deserialize(&mut serde_json::Deserializer::from_str(&json));
         assert!(result.is_ok());
         assert_eq!(final_path, Some(PathBuf::from(&filename)));
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
 
         let mut sha384hasher = Sha384::new();
         sha384hasher.update(&buffer);
@@ -370,7 +367,7 @@ mod tests {
         let result = deserializer.deserialize(&mut serde_json::Deserializer::from_str(&json));
         assert!(result.is_ok());
         assert_eq!(final_path, Some(PathBuf::from(&filename)));
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
 
         let mut sha512hasher = Sha512::new();
         sha512hasher.update(&buffer);
@@ -392,7 +389,7 @@ mod tests {
         let result = deserializer.deserialize(&mut serde_json::Deserializer::from_str(&json));
         assert!(result.is_ok());
         assert_eq!(final_path, Some(PathBuf::from(&filename)));
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
     }
 
     #[test]
@@ -506,7 +503,7 @@ mod tests {
         }
         assert!(result.is_ok());
         assert_eq!(final_path, PathBuf::from(&filename).canonicalize().ok());
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
 
         set_read_only(filename.as_path()).unwrap();
 
@@ -530,7 +527,7 @@ mod tests {
         }
         assert!(result.is_ok());
         assert_eq!(final_path, PathBuf::from(&filename).canonicalize().ok());
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
 
         let json = format!(
             r#"{{"read-only": true, "immutable": true, "command": "{}"}}"#,
@@ -603,7 +600,7 @@ mod tests {
         }
         assert!(result.is_ok());
         assert_eq!(final_path, PathBuf::from(&filename).canonicalize().ok());
-        assert_eq!(cmd_min, CmdMin::MATCH);
+        assert_eq!(cmd_min, CmdMin::Match);
 
         let json = format!(
             r#"{{"read-only": true, "immutable": true, "command": "{}"}}"#,
@@ -626,7 +623,7 @@ mod tests {
         assert!(result.is_ok());
         if immutable {
             assert_eq!(final_path, PathBuf::from(&filename).canonicalize().ok());
-            assert_eq!(cmd_min, CmdMin::MATCH);
+            assert_eq!(cmd_min, CmdMin::Match);
         } else {
             assert_eq!(final_path, None);
             assert_eq!(cmd_min, CmdMin::empty());
diff --git a/src/sr/finder/cmd.rs b/src/sr/finder/cmd.rs
index 79524356..d5e747c7 100644
--- a/src/sr/finder/cmd.rs
+++ b/src/sr/finder/cmd.rs
@@ -1,6 +1,6 @@
 use log::{debug, warn};
 use rar_common::{
-    database::score::{CmdMin, CmdOrder},
+    database::score::CmdMin,
     util::{all_paths_from_env, match_single_path},
 };
 use std::path::PathBuf;
@@ -13,10 +13,7 @@ fn match_path(
     final_path: &mut Option,
 ) -> CmdMin {
     if role_path == "**" {
-        return CmdMin::builder()
-            .matching()
-            .order(CmdOrder::FullWildcardPath)
-            .build();
+        return CmdMin::FullWildcardPath;
     } else if cmd_path.is_absolute() {
         let min = match_single_path(cmd_path, role_path);
         if min.better(&previous_min) {
@@ -47,10 +44,7 @@ pub(super) fn match_args(
     role_args: &str,
 ) -> Result> {
     if role_args == "'^.*$'" {
-        return Ok(CmdMin::builder()
-            .matching()
-            .order(CmdOrder::FullRegexArgs)
-            .build());
+        return Ok(CmdMin::FullRegexArgs);
     }
     let commandline = shell_words::join(input_args);
     if role_args.starts_with("\'^") && role_args.ends_with("$\'") {
@@ -58,9 +52,9 @@ pub(super) fn match_args(
             debug!("{:?},No match for args {:?}", e, input_args);
         })
     } else if commandline == role_args {
-        Ok(CmdMin::builder().matching().build())
+        Ok(CmdMin::Match)
     } else {
-        Ok(CmdMin::builder().build())
+        Ok(CmdMin::empty())
     }
 }
 
@@ -73,12 +67,9 @@ fn evaluate_regex_cmd(
 
     let regex = RegexBuilder::new().build(&role_args)?;
     if regex.is_match(commandline.as_bytes())? {
-        Ok(CmdMin::builder()
-            .matching()
-            .order(CmdOrder::RegexArgs)
-            .build())
+        Ok(CmdMin::RegexArgs)
     } else {
-        Ok(CmdMin::builder().build())
+        Ok(CmdMin::empty())
     }
 }
 
@@ -118,7 +109,7 @@ fn match_command_line(
             if args_result.is_empty() {
                 return CmdMin::empty();
             }
-            result.union_order(args_result.order);
+            result |= args_result;
         }
         Err(err) => {
             debug!("Error: {}", err);
@@ -173,13 +164,7 @@ mod tests {
             &previous_min,
             &mut final_path,
         );
-        assert_eq!(
-            result,
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::FullWildcardPath)
-                .build()
-        );
+        assert_eq!(result, CmdMin::FullWildcardPath);
         assert_eq!(final_path, None);
     }
 
@@ -261,7 +246,7 @@ mod tests {
         let role_args = "-l /tmp";
         let result = match_args(&input_args, &role_args);
         assert!(result.is_ok());
-        assert_eq!(result.unwrap(), CmdMin::MATCH);
+        assert_eq!(result.unwrap(), CmdMin::Match);
     }
 
     #[cfg(feature = "pcre2")]
@@ -271,13 +256,7 @@ mod tests {
         let role_args = "'^.*$'";
         let result = match_args(&input_args, &role_args);
         assert!(result.is_ok());
-        assert_eq!(
-            result.unwrap(),
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::FullRegexArgs)
-                .build()
-        );
+        assert_eq!(result.unwrap(), CmdMin::FullRegexArgs);
     }
 
     #[cfg(feature = "pcre2")]
@@ -287,13 +266,7 @@ mod tests {
         let role_args = "'^.*$'";
         let result = match_args(&input_args, &role_args);
         assert!(result.is_ok());
-        assert_eq!(
-            result.unwrap(),
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::FullRegexArgs)
-                .build()
-        );
+        assert_eq!(result.unwrap(), CmdMin::FullRegexArgs);
     }
 
     #[cfg(feature = "pcre2")]
@@ -303,13 +276,7 @@ mod tests {
         let role_args = "'^[Aa ]*$'";
         let result = match_args(&input_args, &role_args);
         assert!(result.is_ok());
-        assert_eq!(
-            result.unwrap(),
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::RegexArgs)
-                .build()
-        );
+        assert_eq!(result.unwrap(), CmdMin::RegexArgs);
         let role_args = "'^[Aa]*$'";
         let result = match_args(&input_args, &role_args);
         assert!(result.is_ok());
@@ -481,13 +448,7 @@ mod tests {
             &previous_min,
             &mut final_path,
         );
-        assert_eq!(
-            result,
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::FullWildcardPath)
-                .build()
-        );
+        assert_eq!(result, CmdMin::FullWildcardPath);
         assert_eq!(final_path, None);
     }
 
@@ -497,7 +458,7 @@ mod tests {
         let cmd_path = PathBuf::from("ls");
         let cmd_args: Vec = vec!["-l".to_string()];
         let role_command = vec!["/bin/l*".to_string(), "^.*$".to_string()];
-        let previous_min = CmdMin::MATCH; // better than regex
+        let previous_min = CmdMin::Match; // better than regex
         let mut final_path = Some("/usr/bin/ls".into());
         let result = match_command_line(
             &env_path,
@@ -567,13 +528,7 @@ mod tests {
             &previous_min,
             &mut final_path,
         );
-        assert_eq!(
-            result,
-            CmdMin::builder()
-                .matching()
-                .order(CmdOrder::FullWildcardPath)
-                .build()
-        );
+        assert_eq!(result, CmdMin::FullWildcardPath);
         assert_eq!(final_path, None);
     }
 }
diff --git a/src/sr/finder/de.rs b/src/sr/finder/de.rs
index 2f8453bb..574d7671 100644
--- a/src/sr/finder/de.rs
+++ b/src/sr/finder/de.rs
@@ -2348,7 +2348,7 @@ mod tests {
                 .tasks()
                 .next()
                 .unwrap()
-                .score(CmdMin::MATCH, SecurityMin::empty()),
+                .score(CmdMin::Match, SecurityMin::empty()),
             Score::builder()
                 .user_min(ActorMatchMin::UserMatch)
                 .setuser_min(SetUserMin {
@@ -2357,7 +2357,7 @@ mod tests {
                 })
                 .caps_min(CapsMin::NoCaps)
                 .security_min(SecurityMin::empty())
-                .cmd_min(CmdMin::MATCH)
+                .cmd_min(CmdMin::Match)
                 .build()
         );
     }
@@ -2656,7 +2656,7 @@ mod tests {
         assert!(config.roles[0].options.is_some());
         assert!(config.roles[0].tasks[0].options.is_some());
         assert_eq!(config.roles[0].user_min, ActorMatchMin::GroupMatch(1));
-        assert_eq!(config.roles[0].tasks[0].score.cmd_min, CmdMin::MATCH);
+        assert_eq!(config.roles[0].tasks[0].score.cmd_min, CmdMin::Match);
         assert_eq!(
             config.roles[0].tasks[0].score.setuser_min.uid,
             Some(SetuidMin::from(&0.into()))
@@ -2697,7 +2697,7 @@ mod tests {
         assert!(result.is_ok(), "Failed to deserialize: {:?}", result);
         let config = result.unwrap();
         assert_eq!(config.roles[0].user_min, ActorMatchMin::UserMatch);
-        assert_eq!(config.roles[0].tasks[0].score.cmd_min, CmdMin::MATCH);
+        assert_eq!(config.roles[0].tasks[0].score.cmd_min, CmdMin::Match);
         assert_eq!(
             config.roles[0].tasks[0].score.setuser_min.uid,
             Some(SetuidMin::from(&0.into()))
@@ -2754,7 +2754,7 @@ mod tests {
         assert!(result.is_err(), "Expected error, got: {:?}", result);
         assert!(serde_json::from_str::(int).is_err());
         let mut var_name = None;
-        let mut cmd_min = CmdMin::MATCH;
+        let mut cmd_min = CmdMin::Match;
         let dcommand = DCommandDeserializer {
             env_path: &[],
             cmd_path: &cli.cmd_path,
diff --git a/src/sr/finder/mod.rs b/src/sr/finder/mod.rs
index ff713d25..939e9758 100644
--- a/src/sr/finder/mod.rs
+++ b/src/sr/finder/mod.rs
@@ -16,7 +16,7 @@ use rar_common::{
     database::{
         actor::DGroups,
         options::{SAuthentication, SBounding, SPrivileged, STimeout},
-        score::{CmdMin, CmdOrder, Score},
+        score::{CmdMin, Score},
     },
     util::{all_paths_from_env, open_with_privileges},
     Cred, StorageMethod,
@@ -200,10 +200,7 @@ impl BestExecSettings {
                     })?
                     .to_path_buf();
                 }
-                self.score.cmd_min = CmdMin::builder()
-                    .matching()
-                    .order(CmdOrder::FullWildcardPath | CmdOrder::RegexArgs)
-                    .build();
+                self.score.cmd_min = CmdMin::FullWildcardPath | CmdMin::RegexArgs;
             } else {
                 for command in commands.add() {
                     found = self.command_settings(
@@ -482,16 +479,13 @@ mod tests {
     fn test_update_command_score_better() {
         let mut settings = BestExecSettings {
             score: Score {
-                cmd_min: CmdMin::builder()
-                    .matching()
-                    .order(CmdOrder::RegexArgs)
-                    .build(),
+                cmd_min: CmdMin::RegexArgs,
                 ..Default::default()
             },
             final_path: PathBuf::from("/old/path"),
             ..Default::default()
         };
-        let new_cmd_min = CmdMin::MATCH;
+        let new_cmd_min = CmdMin::Match;
         let new_path = PathBuf::from("/new/path");
         let updated = settings.update_command_score(new_path.clone(), new_cmd_min.clone());
         assert!(updated);
@@ -503,16 +497,13 @@ mod tests {
     fn test_update_command_score_not_better() {
         let mut settings = BestExecSettings {
             score: Score {
-                cmd_min: CmdMin::MATCH,
+                cmd_min: CmdMin::Match,
                 ..Default::default()
             },
             final_path: PathBuf::from("/old/path"),
             ..Default::default()
         };
-        let worse_cmd_min = CmdMin::builder()
-            .matching()
-            .order(CmdOrder::RegexArgs)
-            .build();
+        let worse_cmd_min = CmdMin::RegexArgs;
         let new_path = PathBuf::from("/new/path");
         let updated = settings.update_command_score(new_path, worse_cmd_min);
         assert!(!updated);
diff --git a/src/sr/pam/mod.rs b/src/sr/pam/mod.rs
index 4232345c..1a914d50 100644
--- a/src/sr/pam/mod.rs
+++ b/src/sr/pam/mod.rs
@@ -1,10 +1,11 @@
-use std::{error::Error, ffi::CStr, ops::Deref};
+use std::{
+    error::Error,
+    ffi::{CStr, CString},
+    ops::Deref,
+};
 
 use log::{debug, error, info, warn};
-use nonstick::{
-    AuthnFlags, ConversationAdapter, ErrorCode, Result as PamResult, Transaction,
-    TransactionBuilder,
-};
+use pam_client2::{Context, ConversationHandler, ErrorCode, Flag};
 use pcre2::bytes::RegexBuilder;
 
 use crate::timeout;
@@ -23,9 +24,9 @@ mod rpassword;
 mod securemem;
 
 #[cfg(not(test))]
-const PAM_SERVICE: &str = "dosr";
+const PAM_SERVICE: &str = "sr";
 #[cfg(test)]
-const PAM_SERVICE: &str = "dosr_test";
+const PAM_SERVICE: &str = "sr_test";
 
 pub(crate) const PAM_PROMPT: &str = "Password: ";
 
@@ -52,8 +53,8 @@ impl SrConversationHandler {
             Terminal::open_tty()
         }
     }
-    fn is_pam_password_prompt(&self, prompt: &impl AsRef) -> bool {
-        let pam_prompt = prompt.as_ref();
+    fn is_pam_password_prompt(&self, prompt: &CStr) -> bool {
+        let pam_prompt = prompt.to_string_lossy();
         RegexBuilder::new()
             .build("^Password: ?$")
             .unwrap()
@@ -80,47 +81,41 @@ impl Default for SrConversationHandler {
     }
 }
 
-impl ConversationAdapter for SrConversationHandler {
-    fn prompt(&self, prompt: impl AsRef) -> PamResult {
+impl ConversationHandler for SrConversationHandler {
+    fn prompt_echo_on(&mut self, prompt: &CStr) -> Result {
         if self.no_interact {
-            return Err(ErrorCode::ConversationError);
+            return Err(ErrorCode::CONV_ERR);
         }
-        let mut term = self.open().map_err(|_| ErrorCode::ConversationError)?;
-        term.prompt(&prompt.as_ref().to_string_lossy().to_string())
-            .map_err(|_| ErrorCode::ConversationError)?;
-        let read = term.read_cleartext().map_err(|_| ErrorCode::BufferError)?;
-        Ok(std::ffi::OsString::from(
-            String::from_utf8_lossy(read.deref()).to_string(),
-        ))
+        let mut term = self.open().map_err(|_| ErrorCode::CONV_ERR)?;
+        term.prompt(prompt.to_string_lossy().as_ref())
+            .map_err(|_| ErrorCode::CONV_ERR)?;
+        let read = term.read_cleartext().map_err(|_| ErrorCode::BUF_ERR)?;
+        Ok(unsafe { CString::from_vec_unchecked(read.deref().to_vec()) })
     }
 
-    fn masked_prompt(&self, prompt: impl AsRef) -> PamResult {
+    fn prompt_echo_off(&mut self, prompt: &CStr) -> Result {
         if self.no_interact {
-            return Err(ErrorCode::ConversationError);
+            return Err(ErrorCode::CONV_ERR);
         }
-        //if the prompted message is the password prompt, we replace to self.prompt
-        let pam_prompt = if self.is_pam_password_prompt(&prompt.as_ref().to_string_lossy()) {
-            self.prompt.clone()
-        } else {
-            prompt.as_ref().to_string_lossy().to_string()
-        };
-        let mut term = self.open().map_err(|_| ErrorCode::ConversationError)?;
-        term.prompt(&pam_prompt)
-            .map_err(|_| ErrorCode::ConversationError)?;
-        let read = term.read_password().map_err(|_| ErrorCode::BufferError)?;
-        let os_str = CStr::from_bytes_until_nul(&read.deref()).unwrap();
-        Ok(std::ffi::OsString::from(os_str.to_str().unwrap()
-        ))
+        let pam_prompt = prompt.to_string_lossy();
+        if self.prompt == Self::default().prompt && !self.is_pam_password_prompt(prompt) {
+            self.prompt = pam_prompt.to_string()
+        }
+        let mut term = self.open().map_err(|_| ErrorCode::CONV_ERR)?;
+        term.prompt(pam_prompt.as_ref())
+            .map_err(|_| ErrorCode::CONV_ERR)?;
+        let read = term.read_password().map_err(|_| ErrorCode::BUF_ERR)?;
+        Ok(unsafe { CString::from_vec_unchecked(read.deref().to_vec()) })
     }
 
-    fn error_msg(&self, message: impl AsRef) {
-        error!("{}", message.as_ref().to_string_lossy());
-        eprintln!("{}", message.as_ref().to_string_lossy());
+    fn text_info(&mut self, msg: &CStr) {
+        info!("{}", msg.to_string_lossy());
+        println!("{}", msg.to_string_lossy());
     }
 
-    fn info_msg(&self, message: impl AsRef) {
-        info!("{}", message.as_ref().to_string_lossy());
-        println!("{}", message.as_ref().to_string_lossy());
+    fn error_msg(&mut self, msg: &CStr) {
+        error!("{}", msg.to_string_lossy());
+        eprintln!("{}", msg.to_string_lossy());
     }
 }
 
@@ -138,11 +133,10 @@ pub(super) fn check_auth(
     debug!("need to re-authenticate : {}", !is_valid);
     if !is_valid {
         let conv = SrConversationHandler::new(prompt);
-        let mut txn = TransactionBuilder::new_with_service(PAM_SERVICE)
-            .username(&user.user.name)
-            .build(conv.into_conversation())?;
-        txn.authenticate(AuthnFlags::SILENT)?;
-        txn.account_management(AuthnFlags::SILENT)?;
+        let mut context = Context::new(PAM_SERVICE, Some(&user.user.name), conv)
+            .expect("Failed to initialize PAM");
+        context.authenticate(Flag::SILENT)?;
+        context.acct_mgmt(Flag::SILENT)?;
     }
     timeout::update_cookie(user, user, &timeout)?;
     Ok(())
diff --git a/src/sr/pam/rpassword.rs b/src/sr/pam/rpassword.rs
index eadaff23..deebdccb 100644
--- a/src/sr/pam/rpassword.rs
+++ b/src/sr/pam/rpassword.rs
@@ -136,8 +136,8 @@ impl Terminal<'_> {
     }
 
     /// Display information
-    pub fn prompt(&mut self, text: & impl AsRef) -> io::Result<()> {
-        write_unbuffered(&mut self.sink(), text.as_ref())
+    pub fn prompt(&mut self, text: &str) -> io::Result<()> {
+        write_unbuffered(&mut self.sink(), text)
     }
 
     // boilerplate reduction functions
diff --git a/src/sr/pam/securemem.rs b/src/sr/pam/securemem.rs
index 55dc37c0..992fadca 100644
--- a/src/sr/pam/securemem.rs
+++ b/src/sr/pam/securemem.rs
@@ -11,7 +11,9 @@ use std::{
     slice,
 };
 
-pub(super) const SIZE: usize = libpam_sys::PAM_MAX_RESP_SIZE as usize;
+use pam_client2::pam_sys::PAM_MAX_RESP_SIZE;
+
+pub(super) const SIZE: usize = PAM_MAX_RESP_SIZE as usize;
 const ALIGN: usize = mem::align_of::();
 
 pub struct PamBuffer(NonNull<[u8; SIZE]>);
diff --git a/tests/capable/centos8/Vagrantfile b/tests/capable/centos8/Vagrantfile
index ce42ed96..765b2017 100644
--- a/tests/capable/centos8/Vagrantfile
+++ b/tests/capable/centos8/Vagrantfile
@@ -11,7 +11,7 @@ Vagrant.configure("2") do |config|
       ./dependencies.sh -y;
       sudo ./configure.sh -y;
       make install;
-      dosr capable -j cat /etc/shadow;'
+      sr capable -j cat /etc/shadow;'
     SHELL
   end
   
\ No newline at end of file
diff --git a/tests/capable/debian11/Vagrantfile b/tests/capable/debian11/Vagrantfile
index fb34c0d9..eb0ae509 100644
--- a/tests/capable/debian11/Vagrantfile
+++ b/tests/capable/debian11/Vagrantfile
@@ -22,7 +22,7 @@ Vagrant.configure("2") do |config|
       ./dependencies.sh -y;
       sudo ./configure.sh -y;
       PROFILE=debug make install;
-      dosr capable -j cat /etc/shadow;'
+      sr capable -j cat /etc/shadow;'
     SHELL
 end
   
\ No newline at end of file
diff --git a/tests/capable/fedora37/Vagrantfile b/tests/capable/fedora37/Vagrantfile
index 48b5d7d6..29cd44f8 100644
--- a/tests/capable/fedora37/Vagrantfile
+++ b/tests/capable/fedora37/Vagrantfile
@@ -8,7 +8,7 @@ Vagrant.configure("2") do |config|
       ./dependencies.sh -y;
       sudo ./configure.sh -y;
       PROFILE=debug make install;
-      dosr capable -j cat /etc/shadow;'
+      sr capable -j cat /etc/shadow;'
     SHELL
   end
   
\ No newline at end of file
diff --git a/tests/capable/rh9/Vagrantfile b/tests/capable/rh9/Vagrantfile
index d4d0f08f..f63fdfa2 100644
--- a/tests/capable/rh9/Vagrantfile
+++ b/tests/capable/rh9/Vagrantfile
@@ -38,7 +38,7 @@ Vagrant.configure("2") do |config|
       ./dependencies.sh -y;
       sudo ./configure.sh -y;
       PROFILE=debug make install;
-      dosr capable -j cat /etc/shadow;'
+      sr capable -j cat /etc/shadow;'
     SHELL
 
   config.trigger.before :destroy do |trigger|
diff --git a/tests/capable/ubuntu2204/Vagrantfile b/tests/capable/ubuntu2204/Vagrantfile
index 78e25ace..21dfb5a3 100644
--- a/tests/capable/ubuntu2204/Vagrantfile
+++ b/tests/capable/ubuntu2204/Vagrantfile
@@ -9,8 +9,8 @@ Vagrant.configure("2") do |config|
       ./dependencies.sh -y;
       sudo ./configure.sh -y;
       PROFILE=debug make install;
-      dosr chsr role r_root task t_capable o env set RUST_LOG=debug
-      dosr capable -j cat /etc/shadow;'
+      sr chsr role r_root task t_capable o env set RUST_LOG=debug
+      sr capable -j cat /etc/shadow;'
     SHELL
   end
   
\ No newline at end of file
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index f8214d3b..793637e2 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "xtask"
 # The project version is managed on json file in resources/rootasrole.json
-version = "3.1.2"
+version = "3.1.1"
 edition = "2021"
 publish = false
 
diff --git a/xtask/src/configure.rs b/xtask/src/configure.rs
index 02dd8258..652e75c8 100644
--- a/xtask/src/configure.rs
+++ b/xtask/src/configure.rs
@@ -17,7 +17,7 @@ use crate::util::{
 };
 
 const TEMPLATE: &str = include_str!("../../resources/rootasrole.json");
-pub const PAM_CONFIG_PATH: &str = "/etc/pam.d/dosr";
+pub const PAM_CONFIG_PATH: &str = "/etc/pam.d/sr";
 
 fn is_running_in_container() -> bool {
     // Check for environment files that might indicate a container
diff --git a/xtask/src/installer/build.rs b/xtask/src/installer/build.rs
index 800ea721..ada5e619 100644
--- a/xtask/src/installer/build.rs
+++ b/xtask/src/installer/build.rs
@@ -35,7 +35,7 @@ pub fn build(options: &BuildOptions) -> Result<(), anyhow::Error> {
             .status()
             .expect("failed to clean");
     }
-    build_binary("dosr", options, vec![])?;
+    build_binary("sr", options, vec![])?;
     build_binary("chsr", options, vec!["--no-default-features"])?;
 
     build_manpages()?;
@@ -54,7 +54,7 @@ fn build_manpages() -> Result<(), anyhow::Error> {
             "man",
             "resources/man/en_US.md",
             "-o",
-            "target/man/dosr.8",
+            "target/man/sr.8",
         ])
         .status()?;
     fs::create_dir_all("target/man/fr")?;
@@ -65,12 +65,12 @@ fn build_manpages() -> Result<(), anyhow::Error> {
             "man",
             "resources/man/fr_FR.md",
             "-o",
-            "target/man/fr/dosr.8",
+            "target/man/fr/sr.8",
         ])
         .status()?;
     debug!("Compressing manpages");
     Command::new("gzip")
-        .args(["target/man/dosr.8", "target/man/fr/dosr.8"])
+        .args(["target/man/sr.8", "target/man/fr/sr.8"])
         .status()?;
     debug!("Making symlinks");
     unix::fs::symlink("sr.8.gz", "target/man/chsr.8.gz").context("Failed to create symlink")?;
diff --git a/xtask/src/installer/install.rs b/xtask/src/installer/install.rs
index ca6a8297..64e28a7b 100644
--- a/xtask/src/installer/install.rs
+++ b/xtask/src/installer/install.rs
@@ -28,13 +28,13 @@ fn copy_executables(profile: &Profile) -> Result<(), anyhow::Error> {
         .context("unable to get current dir as string")?;
     info!("Current working directory: {}", cwd);
     info!(
-        "Copying files {}/target/{}/dosr to {} and {}",
+        "Copying files {}/target/{}/sr to {} and {}",
         cwd,
         profile,
         sr_dest.to_str().unwrap(),
         chsr_dest.to_str().unwrap()
     );
-    let s_sr = format!("{}/target/{}/dosr", cwd, profile);
+    let s_sr = format!("{}/target/{}/sr", cwd, profile);
     let sr = Path::new(&s_sr);
     let s_chsr = format!("{}/target/{}/chsr", cwd, profile);
     let chsr = Path::new(&s_chsr);
@@ -48,7 +48,7 @@ fn copy_executables(profile: &Profile) -> Result<(), anyhow::Error> {
     fs::copy(sr, format!("{}.tmp", s_sr))?;
     debug!("Copying chsr to chsr.tmp");
     fs::copy(chsr, format!("{}.tmp", s_chsr))?;
-    debug!("Renaming sr to /usr/bin/dosr");
+    debug!("Renaming sr to /usr/bin/sr");
     fs::rename(sr, sr_dest)?;
     debug!("Renaming chsr to /usr/bin/chsr");
     fs::rename(chsr, chsr_dest)?;
@@ -238,7 +238,7 @@ pub fn install(
         //raise dac_override to copy files
         cap_effective(&mut state, Cap::DAC_OVERRIDE).context("Failed to raise DAC_OVERRIDE")?;
 
-        // cp target/{release}/dosr,chsr,capable /usr/bin
+        // cp target/{release}/sr,chsr,capable /usr/bin
         copy_executables(&profile).context("Failed to copy sr and chsr files")?;
 
         copy_docs().context("Failed to copy documentation files")?;
@@ -262,7 +262,7 @@ pub fn install(
     cap_effective(&mut state, Cap::SETFCAP).context("Failed to raise SETFCAP")?;
 
     // set file capabilities for sr only
-    setfcap().context("Failed to set file capabilities on /usr/bin/dosr")?;
+    setfcap().context("Failed to set file capabilities on /usr/bin/sr")?;
 
     // drop all capabilities
     cap_clear(&mut state).context("Failed to drop effective capabilities")?;
diff --git a/xtask/src/installer/mod.rs b/xtask/src/installer/mod.rs
index fbecb5dd..df24954b 100644
--- a/xtask/src/installer/mod.rs
+++ b/xtask/src/installer/mod.rs
@@ -19,7 +19,7 @@ use crate::{
     util::{detect_priv_bin, get_os, OsTarget},
 };
 pub const RAR_BIN_PATH: &str = env!("RAR_BIN_PATH");
-pub const SR_DEST: &str = "dosr";
+pub const SR_DEST: &str = "sr";
 pub const CHSR_DEST: &str = "chsr";
 
 #[derive(Debug, Parser, Clone)]
diff --git a/xtask/src/util.rs b/xtask/src/util.rs
index 4f281a6d..0c2086a8 100644
--- a/xtask/src/util.rs
+++ b/xtask/src/util.rs
@@ -424,9 +424,9 @@ pub fn get_os(os: Option) -> Result {
 }
 
 pub fn detect_priv_bin() -> Option {
-    // is /usr/bin/dosr exist ?
-    if std::fs::metadata("/usr/bin/dosr").is_ok() {
-        Some("/usr/bin/dosr".to_string())
+    // is /usr/bin/sr exist ?
+    if std::fs::metadata("/usr/bin/sr").is_ok() {
+        Some("/usr/bin/sr".to_string())
     } else if std::fs::metadata("/usr/bin/sudo").is_ok() {
         Some("/usr/bin/sudo".to_string())
     } else if std::fs::metadata("/usr/bin/doas").is_ok() {