1 /*
2  * Tests for the alt_auth_map functionality in libpam-krb5.
3  *
4  * This test case tests the variations of the alt_auth_map functionality for
5  * both authentication and account management.  It requires a Kerberos
6  * configuration, but does not attempt to save a session ticket cache (to
7  * avoid requiring user configuration).
8  *
9  * Written by Russ Allbery <eagle@eyrie.org>
10  * Copyright 2020 Russ Allbery <eagle@eyrie.org>
11  * Copyright 2012
12  *     The Board of Trustees of the Leland Stanford Junior University
13  *
14  * SPDX-License-Identifier: BSD-3-clause or GPL-1+
15  */
16 
17 #include <config.h>
18 #include <portable/system.h>
19 
20 #include <tests/fakepam/script.h>
21 #include <tests/tap/kerberos.h>
22 #include <tests/tap/process.h>
23 #include <tests/tap/string.h>
24 
25 
26 int
main(void)27 main(void)
28 {
29     struct script_config config;
30     struct kerberos_config *krbconf;
31     char *user;
32 
33     /*
34      * Load the Kerberos principal and password from a file, but set the
35      * principal as extra[0] and use something else bogus as the user.  We
36      * want to test that alt_auth_map works when there's no relationship
37      * between the mapped principal and the user.
38      */
39     krbconf = kerberos_setup(TAP_KRB_NEEDS_PASSWORD);
40     memset(&config, 0, sizeof(config));
41     config.user = "bogus-nonexistent-account";
42     config.authtok = krbconf->password;
43     config.extra[0] = krbconf->username;
44     config.extra[1] = krbconf->userprinc;
45 
46     /*
47      * Generate a testing krb5.conf file with a nonexistent default realm so
48      * that we can be sure that our principals will stay fully-qualified in
49      * the logs.
50      */
51     kerberos_generate_conf("bogus.example.com");
52     config.extra[2] = "bogus.example.com";
53 
54     /* Test without password prompting. */
55     plan_lazy();
56     run_script("data/scripts/alt-auth/basic", &config);
57     run_script("data/scripts/alt-auth/basic-debug", &config);
58     run_script("data/scripts/alt-auth/fail", &config);
59     run_script("data/scripts/alt-auth/fail-debug", &config);
60     run_script("data/scripts/alt-auth/force", &config);
61     run_script("data/scripts/alt-auth/only", &config);
62 
63     /*
64      * If the alternate account exists but the password is incorrect, we
65      * should not fall back to the regular account.  Test with debug so that
66      * we don't need two principals configured.
67      */
68     config.authtok = "bogus incorrect password";
69     run_script("data/scripts/alt-auth/force-fail-debug", &config);
70 
71     /*
72      * Switch to our correct user (but wrong realm) realm to test username
73      * mapping to a different realm.
74      */
75     config.authtok = krbconf->password;
76     config.user = krbconf->username;
77     config.extra[2] = krbconf->realm;
78     run_script("data/scripts/alt-auth/username-map", &config);
79 
80     /*
81      * Split the username into two parts, one in the PAM configuration and one
82      * in the real username, so that we can test interpolation of the username
83      * when %s isn't the first token.
84      */
85     config.user = &krbconf->username[1];
86     user = bstrndup(krbconf->username, 1);
87     config.extra[3] = user;
88     run_script("data/scripts/alt-auth/username-map-prefix", &config);
89     free(user);
90     config.extra[3] = NULL;
91 
92     /*
93      * Ensure that we don't add the realm of the authentication username when
94      * the alt_auth_map already includes a realm.
95      */
96     basprintf(&user, "%s@foo.example.com", krbconf->username);
97     config.user = user;
98     diag("re-running username-map with fully-qualified PAM user");
99     run_script("data/scripts/alt-auth/username-map", &config);
100     free(user);
101 
102     /*
103      * Add the password and make the user match our authentication principal,
104      * and then test fallback to normal authentication when alternative
105      * authentication fails.
106      */
107     config.user = krbconf->userprinc;
108     config.password = krbconf->password;
109     config.extra[2] = krbconf->realm;
110     run_script("data/scripts/alt-auth/fallback", &config);
111     run_script("data/scripts/alt-auth/fallback-debug", &config);
112     run_script("data/scripts/alt-auth/fallback-realm", &config);
113     run_script("data/scripts/alt-auth/force-fallback", &config);
114     run_script("data/scripts/alt-auth/only-fail", &config);
115 
116     return 0;
117 }
118