int main(void) { struct rule rule = { NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, 0, NULL, NULL, NULL }; const char *acls[5]; plan(78); if (chdir(getenv("C_TAP_SOURCE")) < 0) sysbail("can't chdir to C_TAP_SOURCE"); rule.file = (char *) "TEST"; rule.acls = (char **) acls; acls[0] = "data/acl-simple"; acls[1] = NULL; acls[2] = NULL; acls[3] = NULL; acls[4] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "simple 1"); ok(acl_permit(&rule, "*****@*****.**"), "simple 2"); ok(acl_permit(&rule, "*****@*****.**"), "simple 3"); ok(acl_permit(&rule, "*****@*****.**"), "simple 4"); ok(acl_permit(&rule, "*****@*****.**"), "simple 5"); ok(!acl_permit(&rule, "*****@*****.**"), "no 1"); ok(!acl_permit(&rule, "*****@*****.**"), "no 2"); ok(!acl_permit(&rule, "*****@*****.**"), "no 3"); ok(!acl_permit(&rule, "*****@*****.**"), "no 4"); /* Okay, now capture and check the errors. */ acls[0] = "data/acl-bad-include"; acls[1] = "data/acls/valid"; errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "included file not found"); is_string("data/acl-bad-include:1: included file data/acl-nosuchfile" " not found\n", errors, "...and correct error message"); acls[0] = "data/acl-recursive"; errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "recursive ACL inclusion"); is_string("data/acl-recursive:3: data/acl-recursive recursively" " included\n", errors, "...and correct error message"); acls[0] = "data/acls/valid-2"; acls[1] = "data/acl-too-long"; errors_capture(); ok(acl_permit(&rule, "*****@*****.**"), "granted access based on first ACL file"); ok(errors == NULL, "...with no errors"); ok(!acl_permit(&rule, "*****@*****.**"), "...but failed when we hit second file with long line"); is_string("data/acl-too-long:1: ACL file line too long\n", errors, "...with correct error message"); acls[0] = "data/acl-no-such-file"; acls[1] = "data/acls/valid"; errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "no such ACL file"); is_string("TEST:0: included file data/acl-no-such-file not found\n", errors, "...with correct error message"); errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "...even with a principal in an ACL file"); is_string("TEST:0: included file data/acl-no-such-file not found\n", errors, "...still with right error message"); acls[0] = "data/acl-bad-syntax"; errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "incorrect syntax"); is_string("data/acl-bad-syntax:2: parse error\n", errors, "...with correct error message"); errors_uncapture(); /* Check that file: works at the top level. */ acls[0] = "file:data/acl-simple"; acls[1] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "file: success"); ok(!acl_permit(&rule, "*****@*****.**"), "file: failure"); /* Check that include syntax works. */ ok(acl_permit(&rule, "*****@*****.**"), "include 1"); ok(acl_permit(&rule, "*****@*****.**"), "include 2"); ok(acl_permit(&rule, "*****@*****.**"), "include 3"); ok(acl_permit(&rule, "*****@*****.**"), "include 4"); ok(acl_permit(&rule, "*****@*****.**"), "include 5"); ok(!acl_permit(&rule, "*****@*****.**"), "include failure"); /* Check that princ: works at the top level. */ acls[0] = "princ:[email protected]"; ok(acl_permit(&rule, "*****@*****.**"), "princ: success"); ok(!acl_permit(&rule, "*****@*****.**"), "princ: failure"); /* Check that deny: works at the top level. */ acls[0] = "deny:princ:[email protected]"; acls[1] = "princ:[email protected]"; acls[2] = "princ:[email protected]"; acls[3] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "deny: success"); ok(!acl_permit(&rule, "*****@*****.**"), "deny: failure"); /* And make sure deny interacts correctly with files. */ acls[0] = "data/acl-simple"; acls[1] = "princ:[email protected]"; acls[2] = NULL; ok(!acl_permit(&rule, "*****@*****.**"), "deny in file beats later princ"); acls[0] = "deny:princ:[email protected]"; acls[1] = "data/acl-simple"; ok(!acl_permit(&rule, "*****@*****.**"), "deny overrides later file"); /* * Ensure deny never affirmatively grants access, so deny:deny: matches * nothing. */ acls[0] = "deny:deny:princ:[email protected]"; acls[1] = "data/acl-simple"; ok(acl_permit(&rule, "*****@*****.**"), "deny:deny does nothing"); ok(acl_permit(&rule, "*****@*****.**"), "deny:deny doesn't break anything"); /* * Denying a file denies anything that would match the file, and nothing * that wouldn't, including due to an embedded deny. */ acls[0] = "deny:file:data/acl-simple"; acls[1] = "princ:[email protected]"; acls[2] = "princ:[email protected]"; acls[3] = "princ:[email protected]"; acls[4] = NULL; ok(!acl_permit(&rule, "*****@*****.**"), "deny of a file works"); ok(acl_permit(&rule, "*****@*****.**"), "...and doesn't break anything"); ok(acl_permit(&rule, "*****@*****.**"), "...and deny inside a denied file is ignored"); /* Check for an invalid ACL scheme. */ acls[0] = "ihateyou:verymuch"; acls[1] = "data/acls/valid"; errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "invalid ACL scheme"); is_string("TEST:0: invalid ACL scheme 'ihateyou'\n", errors, "...with correct error"); errors_uncapture(); /* * Check GPUT ACLs, or make sure they behave sanely when GPUT support is * not compiled. */ server_config_set_gput_file((char *) "data/gput"); acls[0] = "gput:test"; acls[1] = NULL; #ifdef HAVE_GPUT ok(acl_permit(&rule, "*****@*****.**"), "GPUT 1"); ok(!acl_permit(&rule, "*****@*****.**"), "GPUT 2"); ok(!acl_permit(&rule, "*****@*****.**"), "GPUT 3"); acls[0] = "gput:test[%@EXAMPLE.NET]"; ok(acl_permit(&rule, "*****@*****.**"), "GPUT with transform 1"); ok(!acl_permit(&rule, "*****@*****.**"), "GPUT with transform 2"); ok(!acl_permit(&rule, "*****@*****.**"), "GPUT with transform 3"); #else errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "GPUT"); is_string("TEST:0: ACL scheme 'gput' is not supported\n", errors, "...with not supported error"); errors_uncapture(); skip_block(4, "GPUT support not configured"); #endif /* * Check PCRE ACLs, or make sure they behave as they should when not * supported. */ acls[0] = "deny:pcre:host/foo.+\\.org@EXAMPLE\\.ORG"; acls[1] = "pcre:host/.+\\.org@EXAMPLE\\.ORG"; acls[2] = NULL; #ifdef HAVE_PCRE ok(acl_permit(&rule, "host/[email protected]"), "PCRE 1"); ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 2"); ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 3"); ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 4 (plus operator)"); ok(!acl_permit(&rule, "host/[email protected]"), "PCRE 5 (escaped period)"); acls[1] = "pcre:+host/.*"; errors_capture(); ok(!acl_permit(&rule, "host/[email protected]"), "PCRE invalid regex"); is_string("TEST:0: compilation of regex '+host/.*' failed around 0\n", errors, "...with invalid regex error"); errors_uncapture(); #else errors_capture(); ok(!acl_permit(&rule, "host/[email protected]"), "PCRE"); is_string("TEST:0: ACL scheme 'pcre' is not supported\n", errors, "...with not supported error"); errors_uncapture(); skip_block(5, "PCRE support not configured"); #endif /* * Check POSIX regex ACLs, or make sure they behave as they should when * not supported. */ acls[0] = "deny:regex:host/foo.*\\.org@EXAMPLE\\.ORG"; acls[1] = "regex:host/.*\\.org@EXAMPLE\\.ORG"; acls[2] = NULL; #ifdef HAVE_REGCOMP ok(acl_permit(&rule, "host/[email protected]"), "regex 1"); ok(!acl_permit(&rule, "host/[email protected]"), "regex 2"); ok(!acl_permit(&rule, "host/[email protected]"), "regex 3"); ok(acl_permit(&rule, "host/[email protected]"), "regex 4"); ok(!acl_permit(&rule, "host/[email protected]"), "regex 5 (escaped period)"); acls[1] = "regex:*host/.*"; errors_capture(); ok(!acl_permit(&rule, "host/[email protected]"), "regex invalid regex"); ok(strncmp(errors, "TEST:0: compilation of regex '*host/.*' failed:", strlen("TEST:0: compilation of regex '*host/.*' failed:")) == 0, "...with invalid regex error"); errors_uncapture(); free(errors); errors = NULL; #else errors_capture(); ok(!acl_permit(&rule, "host/[email protected]"), "regex"); is_string("TEST:0: ACL scheme 'regex' is not supported\n", errors, "...with not supported error"); errors_uncapture(); skip_block(5, "regex support not available"); free(errors); errors = NULL; #endif /* Test for valid characters in ACL files. */ acls[0] = "file:data/acls"; acls[1] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "valid chars 1"); ok(acl_permit(&rule, "*****@*****.**"), "valid chars 2"); ok(acl_permit(&rule, "*****@*****.**"), "valid chars 3"); ok(!acl_permit(&rule, "*****@*****.**"), "invalid chars 1"); ok(!acl_permit(&rule, "*****@*****.**"), "invalid chars 2"); ok(!acl_permit(&rule, "*****@*****.**"), "invalid chars 3"); /* Check anyuser:*. */ acls[0] = "anyuser:auth"; acls[1] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "anyuser:auth"); acls[0] = "anyuser:anonymous"; ok(acl_permit(&rule, "*****@*****.**"), "anyuser:anonymous"); acls[0] = "ANYUSER"; ok(acl_permit(&rule, "*****@*****.**"), "ANYUSER"); /* * Ensure that anyuser:auth and ANYUSER don't allow the anonymous * identity, but anyuser:anonymous does. */ acls[0] = "anyuser:auth"; acls[1] = NULL; ok(!acl_permit_anonymous(&rule), "anyuser:auth disallows anonymous"); acls[0] = "ANYUSER"; ok(!acl_permit_anonymous(&rule), "ANYUSER disallows anonymous"); acls[0] = "anyuser:anonymous"; ok(acl_permit_anonymous(&rule), "anyuser:anonymous allows anonymous"); /* Check error handling of unknown anyuser ACLs. */ acls[0] = "anyuser:foo"; acls[1] = NULL; errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "invalid anyuser ACL"); is_string("TEST:0: invalid ACL value 'anyuser:foo'\n", errors, "...with correct error."); errors_uncapture(); free(errors); errors = NULL; return 0; }
int main(void) { krb5_context ctx; const char *message; char *expected; char long_principal[VERY_LONG_PRINCIPAL]; const char *acls[5]; const struct rule rule = { (char *) "TEST", 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, 0, NULL, NULL, (char **) acls }; plan(16); /* Use a krb5.conf with a default realm of EXAMPLE.ORG. */ kerberos_generate_conf("EXAMPLE.ORG"); /* Check behavior with empty groups. */ fake_queue_group(&empty, 0); set_passwd("someone", 0); acls[0] = "localgroup:empty"; acls[1] = NULL; ok(!acl_permit(&rule, "*****@*****.**"), "Empty"); /* Check behavior when user is expected to be in supplied group. */ fake_queue_group(&goodguys, 0); set_passwd("remi", 0); acls[0] = "localgroup:goodguys"; acls[1] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "User in group"); /* And when the user is not in the supplied group. */ fake_queue_group(&goodguys, 0); set_passwd("someoneelse", 0); ok(!acl_permit(&rule, "*****@*****.**"), "User not in group"); /* Check that the user's primary group also counts. */ fake_queue_group(&goodguys, 0); set_passwd("otheruser", 42); ok(acl_permit(&rule, "*****@*****.**"), "User has group as primary group"); /* And when the user does not convert to a local user or is complex. */ fake_queue_group(&goodguys, 0); set_passwd("remi", 0); errors_capture(); ok(!acl_permit(&rule, "remi/[email protected]"), "User with instance with base user in group"); is_string(NULL, errors, "...with no error"); /* Principal name is too long. */ fake_queue_group(&goodguys, 0); memset(long_principal, 'A', sizeof(long_principal)); long_principal[sizeof(long_principal) - 1] = '\0'; errors_capture(); ok(!acl_permit(&rule, long_principal), "Long principal"); /* Determine the expected error message and check it. */ if (krb5_init_context(&ctx) != 0) bail("cannot create Kerberos context"); message = krb5_get_error_message(ctx, KRB5_CONFIG_NOTENUFSPACE); basprintf(&expected, "conversion of %s to local name failed: %s\n", long_principal, message); krb5_free_context(ctx); is_string(expected, errors, "...with correct error message"); krb5_free_error_message(ctx, message); free(expected); /* Unsupported realm. */ fake_queue_group(&goodguys, 0); set_passwd("eagle", 0); ok(!acl_permit(&rule, "*****@*****.**"), "Non-local realm"); /* Check behavior when syscall fails */ fake_queue_group(&goodguys, EPERM); set_passwd("remi", 0); errors_capture(); ok(!acl_permit(&rule, "*****@*****.**"), "Failing getgrnam_r"); is_string("TEST:0: retrieving membership of localgroup goodguys failed\n", errors, "...with correct error message"); /* Check that deny group works as expected */ fake_queue_group(&badguys, 0); set_passwd("boba-fett", 0); acls[0] = "deny:localgroup:badguys"; acls[1] = NULL; ok(!acl_permit(&rule, "*****@*****.**"), "Denied user"); fake_queue_group(&badguys, 0); set_passwd("remi", 0); ok(!acl_permit(&rule, "*****@*****.**"), "User not in denied group but also not allowed"); /* Check that both deny and "allow" pragma work together */ fake_queue_group(&goodguys, 0); fake_queue_group(&badguys, 0); set_passwd("eagle", 0); acls[0] = "localgroup:goodguys"; acls[1] = "deny:localgroup:badguys"; acls[2] = NULL; ok(acl_permit(&rule, "*****@*****.**"), "User in allowed group plus a denied group"); fake_queue_group(&goodguys, 0); fake_queue_group(&badguys, 0); set_passwd("darth-maul", 0); ok(!acl_permit(&rule, "*****@*****.**"), "User in a denied group plus an allowed group"); fake_queue_group(&goodguys, 0); fake_queue_group(&badguys, 0); set_passwd("anyoneelse", 0); ok(!acl_permit(&rule, "*****@*****.**"), "User in neither denied nor allowed group"); /* Clean up. */ free(errors); return 0; }