File: mit.c

package info (click to toggle)
krb5-sync 3.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 2,556 kB
  • sloc: sh: 11,750; ansic: 7,181; perl: 663; makefile: 135
file content (148 lines) | stat: -rw-r--r-- 4,114 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
 * MIT kadm5_hook shared module API.
 *
 * This is the glue required to connect an MIT Kerberos kadmin hook module to
 * the API for the krb5-sync module.  It is based on the kadm5_hook interface
 * released with MIT Kerberos 1.9, which was based on a preliminary proposal
 * for the Heimdal hook API.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Contributions by Sam Hartman <hartmans@painless-security.com>
 * Copyright 2010, 2011, 2013
 *     The Board of Trustees of the Leland Stanford Junior University
 * Copyright 2010 The Massachusetts Institute of Technology
 *
 * See LICENSE for licensing terms.
 */

#include <config.h>
#include <portable/kadmin.h>
#include <portable/krb5.h>
#include <portable/system.h>

#include <errno.h>
#ifdef HAVE_KRB5_KADM5_HOOK_PLUGIN_H
# include <krb5/kadm5_hook_plugin.h>
#endif

#include <plugin/internal.h>
#include <util/macros.h>

/*
 * Skip this entire file if the relevant MIT Kerberos header isn't available,
 * since without that header we don't have the data types that we need.
 */
#ifdef HAVE_KRB5_KADM5_HOOK_PLUGIN_H

/*
 * The public function that the MIT kadm5 library looks for.  It contains the
 * module name, so it can't be prototyped by the MIT headers.
 */
krb5_error_code kadm5_hook_sync_initvt(krb5_context, int, int,
                                       krb5_plugin_vtable);


/*
 * Initialize the plugin.  Calls the pwupdate_init() function and returns the
 * resulting data object.
 */
static kadm5_ret_t
init(krb5_context ctx, kadm5_hook_modinfo **data)
{
    return sync_init(ctx, data);
}


/*
 * Shut down the plugin, freeing any internal resources.
 */
static void
fini(krb5_context ctx, kadm5_hook_modinfo *data)
{
    sync_close(ctx, data);
}


/*
 * Handle a password change.
 */
static kadm5_ret_t
chpass(krb5_context ctx, kadm5_hook_modinfo *data, int stage,
       krb5_principal princ, krb5_boolean keepold UNUSED,
       int n_ks_tuple UNUSED, krb5_key_salt_tuple *ks_tuple UNUSED,
       const char *password)
{
    /*
     * If password is NULL, we have a new key set but no password (meaning
     * this is an operation such as addprinc -randkey).  We can't do anything
     * without a password, so ignore these cases.
     */
    if (password == NULL)
        return 0;

    /* Dispatch to the appropriate function. */
    if (stage == KADM5_HOOK_STAGE_PRECOMMIT)
        return sync_chpass(data, ctx, princ, password);
    else
        return 0;
}


/*
 * Handle a principal creation.
 *
 * We only care about synchronizing the password, so we just call the same
 * hooks as we did for a password change.
 */
static kadm5_ret_t
create(krb5_context ctx, kadm5_hook_modinfo *data, int stage,
       kadm5_principal_ent_t entry, long mask UNUSED, int n_ks_tuple UNUSED,
       krb5_key_salt_tuple *ks_tuple UNUSED, const char *password)
{
    return chpass(ctx, data, stage, entry->principal, false, n_ks_tuple,
                  ks_tuple, password);
}


/*
 * Handle a principal modification.
 *
 * We only care about changes to the DISALLOW_ALL_TIX flag, and we only
 * support status postcommit.  Check whether that's what's being changed and
 * call the appropriate hook.
 */
static kadm5_ret_t
modify(krb5_context ctx, kadm5_hook_modinfo *data, int stage,
       kadm5_principal_ent_t entry, long mask)
{
    bool enabled;

    if (mask & KADM5_ATTRIBUTES && stage == KADM5_HOOK_STAGE_POSTCOMMIT) {
        enabled = !(entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX);
        return sync_status(data, ctx, entry->principal, enabled);
    }
    return 0;
}


/*
 * The public interface called by the kadmin hook code in MIT Kerberos.
 */
krb5_error_code
kadm5_hook_sync_initvt(krb5_context ctx UNUSED, int maj_ver,
                       int min_ver UNUSED, krb5_plugin_vtable vtable)
{
    kadm5_hook_vftable_1 *vt = (kadm5_hook_vftable_1 *) vtable;

    if (maj_ver != 1)
        return KRB5_PLUGIN_VER_NOTSUPP;
    vt->name = "krb5-sync";
    vt->init = init;
    vt->fini = fini;
    vt->chpass = chpass;
    vt->create = create;
    vt->modify = modify;
    return 0;
}

#endif /* HAVE_KRB5_KADM5_HOOK_PLUGIN_H */