aboutsummaryrefslogtreecommitdiff
path: root/pam_cap/test_pam_cap.c
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2021-06-28 22:03:08 -0700
committerAndrew G. Morgan <morgan@kernel.org>2021-06-28 22:13:56 -0700
commit6926f78d99fc0e5ed5b10a06ffde79539b70df6a (patch)
treea76b0dc82fe81eac54cb652f43c4090b54c16265 /pam_cap/test_pam_cap.c
parent8c6c3628061dadc58bc6a3ec66b627f8412797ce (diff)
downloadlibcap-6926f78d99fc0e5ed5b10a06ffde79539b70df6a.tar.gz
Add pam_cap.so "default=<IAB>" module argument support
Add a new optional argument to pam_cap.so. This argument substitutes for a line like this in the capability.conf file: <IAB> * That is, it supplies the default <IAB> 3-tuple of capability vectors. Any * value in the prevailing capability.conf file overrides this default. However, the admin can supply arguments like this: auth pam_cap.so autoauth config=/dev/null default=^cap_wake_alarm to grant everyone who executes it the ambient capability cap_wake_alarm. This addresses: https://bugzilla.kernel.org/show_bug.cgi?id=213611 However, see: https://bugzilla.kernel.org/show_bug.cgi?id=212945 for issues limiting PAM application support for ambient capabilities in general at present. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
Diffstat (limited to 'pam_cap/test_pam_cap.c')
-rw-r--r--pam_cap/test_pam_cap.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/pam_cap/test_pam_cap.c b/pam_cap/test_pam_cap.c
index 452a27f..4c09a5d 100644
--- a/pam_cap/test_pam_cap.c
+++ b/pam_cap/test_pam_cap.c
@@ -5,6 +5,11 @@
* it.
*/
+#define _DEFAULT_SOURCE
+
+#include <unistd.h>
+#include <sys/types.h>
+
#include "./pam_cap.c"
const char *test_groups[] = {
@@ -121,12 +126,106 @@ static void load_vectors(unsigned long int bits[3]) {
cap_free(prev);
}
+struct vargs {
+ struct pam_cap_s cs;
+ const char *args[5];
+};
+
+static int test_arg_parsing(void) {
+ static struct vargs vs[] = {
+ {
+ { 1, 0, 0, NULL, NULL, NULL },
+ { "debug", NULL }
+ },
+ {
+ { 0, 1, 0, NULL, NULL, NULL },
+ { "keepcaps", NULL }
+ },
+ {
+ { 0, 0, 1, NULL, NULL, NULL },
+ { "autoauth", NULL }
+ },
+ {
+ { 1, 0, 1, NULL, NULL, NULL },
+ { "autoauth", "debug", NULL }
+ },
+ {
+ { 0, 0, 0, NULL, "/over/there", NULL },
+ { "config=/over/there", NULL }
+ },
+ {
+ { 0, 0, 0, NULL, NULL, "^cap_setfcap" },
+ { "default=^cap_setfcap", NULL }
+ },
+ {
+ { 0, 0, 0, NULL, NULL, NULL },
+ { NULL }
+ }
+ };
+ int i;
+
+ for (i=0; ; i++) {
+ int argc;
+ const char **argv;
+ struct vargs *v;
+
+ v = &vs[i];
+ argv = v->args;
+
+ for (argc = 0; argv[argc] != NULL; argc++);
+
+ struct pam_cap_s cs;
+ parse_args(argc, argv, &cs);
+
+ if (cs.debug != v->cs.debug) {
+ printf("test_arg_parsing[%d]: debug=%d, wanted debug=%d\n",
+ i, cs.debug, v->cs.debug);
+ return 1;
+ }
+ if (cs.keepcaps != v->cs.keepcaps) {
+ printf("test_arg_parsing[%d]: keepcaps=%d, wanted keepcaps=%d\n",
+ i, cs.keepcaps, v->cs.keepcaps);
+ return 1;
+ }
+ if (cs.autoauth != v->cs.autoauth) {
+ printf("test_arg_parsing[%d]: autoauth=%d, wanted autoauth=%d\n",
+ i, cs.autoauth, v->cs.autoauth);
+ return 1;
+ }
+ if (cs.conf_filename != v->cs.conf_filename &&
+ strcmp(cs.conf_filename, v->cs.conf_filename)) {
+ printf("test_arg_parsing[%d]: conf_filename=[%s], wanted=[%s]\n",
+ i, cs.conf_filename, v->cs.conf_filename);
+ return 1;
+ }
+ if (cs.fallback != v->cs.fallback &&
+ strcmp(cs.fallback, v->cs.fallback)) {
+ printf("test_arg_parsing[%d]: fallback=[%s], wanted=[%s]\n",
+ i, cs.fallback, v->cs.fallback);
+ return 1;
+ }
+
+ if (argc == 0) {
+ break;
+ }
+ }
+ return 0;
+}
+
/*
* args: user a b i config-args...
*/
int main(int argc, char *argv[]) {
unsigned long int before[3], change[3], after[3];
+ if (test_arg_parsing()) {
+ printf("failed to parse arguments\n");
+ exit(1);
+ }
+ if (read_capabilities_for_user("morgan", "/dev/null") != NULL) {
+ printf("/dev/null is not a valid config file\n");
+ }
+
/*
* Start out with a cleared inheritable set.
*/
@@ -134,6 +233,12 @@ int main(int argc, char *argv[]) {
cap_clear_flag(orig, CAP_INHERITABLE);
cap_set_proc(orig);
+ if (getuid() != 0) {
+ cap_free(orig);
+ printf("test_pam_cap: OK! (Skipping privileged tests (uid!=0))\n");
+ exit(0);
+ }
+
change[A] = strtoul(argv[2], NULL, 0);
change[B] = strtoul(argv[3], NULL, 0);
change[I] = strtoul(argv[4], NULL, 0);