xref: /freebsd/contrib/pam-krb5/tests/tap/kadmin.c (revision bf6873c5786e333d679a7838d28812febf479a8a)
1*bf6873c5SCy Schubert /*
2*bf6873c5SCy Schubert  * Kerberos test setup requiring the kadmin API.
3*bf6873c5SCy Schubert  *
4*bf6873c5SCy Schubert  * This file collects Kerberos test setup functions that use the kadmin API to
5*bf6873c5SCy Schubert  * put principals into particular configurations for testing.  Currently, the
6*bf6873c5SCy Schubert  * only implemented functionality is to mark a password as expired.
7*bf6873c5SCy Schubert  *
8*bf6873c5SCy Schubert  * The canonical version of this file is maintained in the rra-c-util package,
9*bf6873c5SCy Schubert  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
10*bf6873c5SCy Schubert  *
11*bf6873c5SCy Schubert  * Written by Russ Allbery <eagle@eyrie.org>
12*bf6873c5SCy Schubert  * Copyright 2017 Russ Allbery <eagle@eyrie.org>
13*bf6873c5SCy Schubert  * Copyright 2011
14*bf6873c5SCy Schubert  *     The Board of Trustees of the Leland Stanford Junior University
15*bf6873c5SCy Schubert  *
16*bf6873c5SCy Schubert  * Permission is hereby granted, free of charge, to any person obtaining a
17*bf6873c5SCy Schubert  * copy of this software and associated documentation files (the "Software"),
18*bf6873c5SCy Schubert  * to deal in the Software without restriction, including without limitation
19*bf6873c5SCy Schubert  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20*bf6873c5SCy Schubert  * and/or sell copies of the Software, and to permit persons to whom the
21*bf6873c5SCy Schubert  * Software is furnished to do so, subject to the following conditions:
22*bf6873c5SCy Schubert  *
23*bf6873c5SCy Schubert  * The above copyright notice and this permission notice shall be included in
24*bf6873c5SCy Schubert  * all copies or substantial portions of the Software.
25*bf6873c5SCy Schubert  *
26*bf6873c5SCy Schubert  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27*bf6873c5SCy Schubert  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28*bf6873c5SCy Schubert  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
29*bf6873c5SCy Schubert  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30*bf6873c5SCy Schubert  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31*bf6873c5SCy Schubert  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32*bf6873c5SCy Schubert  * DEALINGS IN THE SOFTWARE.
33*bf6873c5SCy Schubert  *
34*bf6873c5SCy Schubert  * SPDX-License-Identifier: MIT
35*bf6873c5SCy Schubert  */
36*bf6873c5SCy Schubert 
37*bf6873c5SCy Schubert #include <config.h>
38*bf6873c5SCy Schubert #ifdef HAVE_KADM5CLNT
39*bf6873c5SCy Schubert #    include <portable/kadmin.h>
40*bf6873c5SCy Schubert #    include <portable/krb5.h>
41*bf6873c5SCy Schubert #endif
42*bf6873c5SCy Schubert #include <portable/system.h>
43*bf6873c5SCy Schubert 
44*bf6873c5SCy Schubert #include <time.h>
45*bf6873c5SCy Schubert 
46*bf6873c5SCy Schubert #include <tests/tap/basic.h>
47*bf6873c5SCy Schubert #include <tests/tap/kadmin.h>
48*bf6873c5SCy Schubert #include <tests/tap/kerberos.h>
49*bf6873c5SCy Schubert 
50*bf6873c5SCy Schubert /* Used for unused parameters to silence gcc warnings. */
51*bf6873c5SCy Schubert #define UNUSED __attribute__((__unused__))
52*bf6873c5SCy Schubert 
53*bf6873c5SCy Schubert 
54*bf6873c5SCy Schubert /*
55*bf6873c5SCy Schubert  * Given the principal to set an expiration on, set that principal to have an
56*bf6873c5SCy Schubert  * expired password.  This requires that the realm admin server be configured
57*bf6873c5SCy Schubert  * either in DNS (with SRV records) or in krb5.conf (possibly the one
58*bf6873c5SCy Schubert  * KRB5_CONFIG is pointing to).  Authentication is done using the keytab
59*bf6873c5SCy Schubert  * stored in config/admin-keytab.
60*bf6873c5SCy Schubert  *
61*bf6873c5SCy Schubert  * Returns true on success.  Returns false if necessary configuration is
62*bf6873c5SCy Schubert  * missing so that the caller can choose whether to call bail or skip_all.  If
63*bf6873c5SCy Schubert  * the configuration is present but the operation fails, bails.
64*bf6873c5SCy Schubert  */
65*bf6873c5SCy Schubert #ifdef HAVE_KADM5CLNT
66*bf6873c5SCy Schubert bool
kerberos_expire_password(const char * principal,time_t expires)67*bf6873c5SCy Schubert kerberos_expire_password(const char *principal, time_t expires)
68*bf6873c5SCy Schubert {
69*bf6873c5SCy Schubert     char *path, *user;
70*bf6873c5SCy Schubert     const char *realm;
71*bf6873c5SCy Schubert     krb5_context ctx;
72*bf6873c5SCy Schubert     krb5_principal admin = NULL;
73*bf6873c5SCy Schubert     krb5_principal princ = NULL;
74*bf6873c5SCy Schubert     kadm5_ret_t code;
75*bf6873c5SCy Schubert     kadm5_config_params params;
76*bf6873c5SCy Schubert     kadm5_principal_ent_rec ent;
77*bf6873c5SCy Schubert     void *handle;
78*bf6873c5SCy Schubert     bool okay = false;
79*bf6873c5SCy Schubert 
80*bf6873c5SCy Schubert     /* Set up for making our call. */
81*bf6873c5SCy Schubert     path = test_file_path("config/admin-keytab");
82*bf6873c5SCy Schubert     if (path == NULL)
83*bf6873c5SCy Schubert         return false;
84*bf6873c5SCy Schubert     code = krb5_init_context(&ctx);
85*bf6873c5SCy Schubert     if (code != 0)
86*bf6873c5SCy Schubert         bail_krb5(ctx, code, "error initializing Kerberos");
87*bf6873c5SCy Schubert     admin = kerberos_keytab_principal(ctx, path);
88*bf6873c5SCy Schubert     realm = krb5_principal_get_realm(ctx, admin);
89*bf6873c5SCy Schubert     code = krb5_set_default_realm(ctx, realm);
90*bf6873c5SCy Schubert     if (code != 0)
91*bf6873c5SCy Schubert         bail_krb5(ctx, code, "cannot set default realm");
92*bf6873c5SCy Schubert     code = krb5_unparse_name(ctx, admin, &user);
93*bf6873c5SCy Schubert     if (code != 0)
94*bf6873c5SCy Schubert         bail_krb5(ctx, code, "cannot unparse admin principal");
95*bf6873c5SCy Schubert     code = krb5_parse_name(ctx, principal, &princ);
96*bf6873c5SCy Schubert     if (code != 0)
97*bf6873c5SCy Schubert         bail_krb5(ctx, code, "cannot parse principal %s", principal);
98*bf6873c5SCy Schubert 
99*bf6873c5SCy Schubert     /*
100*bf6873c5SCy Schubert      * If the actual kadmin calls fail, we may be built with MIT Kerberos
101*bf6873c5SCy Schubert      * against a Heimdal server or vice versa.  Return false to skip the
102*bf6873c5SCy Schubert      * tests.
103*bf6873c5SCy Schubert      */
104*bf6873c5SCy Schubert     memset(&params, 0, sizeof(params));
105*bf6873c5SCy Schubert     params.realm = (char *) realm;
106*bf6873c5SCy Schubert     params.mask = KADM5_CONFIG_REALM;
107*bf6873c5SCy Schubert     code = kadm5_init_with_skey_ctx(ctx, user, path, KADM5_ADMIN_SERVICE,
108*bf6873c5SCy Schubert                                     &params, KADM5_STRUCT_VERSION,
109*bf6873c5SCy Schubert                                     KADM5_API_VERSION, &handle);
110*bf6873c5SCy Schubert     if (code != 0) {
111*bf6873c5SCy Schubert         diag_krb5(ctx, code, "error initializing kadmin");
112*bf6873c5SCy Schubert         goto done;
113*bf6873c5SCy Schubert     }
114*bf6873c5SCy Schubert     memset(&ent, 0, sizeof(ent));
115*bf6873c5SCy Schubert     ent.principal = princ;
116*bf6873c5SCy Schubert     ent.pw_expiration = (krb5_timestamp) expires;
117*bf6873c5SCy Schubert     code = kadm5_modify_principal(handle, &ent, KADM5_PW_EXPIRATION);
118*bf6873c5SCy Schubert     if (code == 0)
119*bf6873c5SCy Schubert         okay = true;
120*bf6873c5SCy Schubert     else
121*bf6873c5SCy Schubert         diag_krb5(ctx, code, "error setting password expiration");
122*bf6873c5SCy Schubert 
123*bf6873c5SCy Schubert done:
124*bf6873c5SCy Schubert     kadm5_destroy(handle);
125*bf6873c5SCy Schubert     krb5_free_unparsed_name(ctx, user);
126*bf6873c5SCy Schubert     krb5_free_principal(ctx, admin);
127*bf6873c5SCy Schubert     krb5_free_principal(ctx, princ);
128*bf6873c5SCy Schubert     krb5_free_context(ctx);
129*bf6873c5SCy Schubert     test_file_path_free(path);
130*bf6873c5SCy Schubert     return okay;
131*bf6873c5SCy Schubert }
132*bf6873c5SCy Schubert #else  /* !HAVE_KADM5CLNT */
133*bf6873c5SCy Schubert bool
kerberos_expire_password(const char * principal UNUSED,time_t expires UNUSED)134*bf6873c5SCy Schubert kerberos_expire_password(const char *principal UNUSED, time_t expires UNUSED)
135*bf6873c5SCy Schubert {
136*bf6873c5SCy Schubert     return false;
137*bf6873c5SCy Schubert }
138*bf6873c5SCy Schubert #endif /* !HAVE_KADM5CLNT */
139