File: heimdal.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 (141 lines) | stat: -rw-r--r-- 3,659 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
/*
 * Heimdal shared module API.
 *
 * This is the glue required to connect a Heimdal kadmin hook module to the
 * API for the krb5-sync module.  It is based on a preliminary proposal for
 * the Heimdal hook API, so the interface exposed here may change in the
 * future.
 *
 * Written by Russ Allbery <eagle@eyrie.org>
 * Copyright 2010, 2013
 *     The Board of Trustees of the Leland Stanford Junior University
 *
 * See LICENSE for licensing terms.
 */

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

#include <errno.h>

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

#define KADM5_HOOK_VERSION_V0 0

enum kadm5_hook_stage {
    KADM5_HOOK_STAGE_PRECOMMIT,
    KADM5_HOOK_STAGE_POSTCOMMIT
};

typedef struct kadm5_hook {
    const char *name;
    int version;
    const char *vendor;

    krb5_error_code (*init)(krb5_context, void **);
    void (*fini)(krb5_context, void *);

    krb5_error_code (*chpass)(krb5_context, void *, enum kadm5_hook_stage,
                              krb5_principal, const char *);
    krb5_error_code (*create)(krb5_context, void *, enum kadm5_hook_stage,
                              kadm5_principal_ent_t, uint32_t mask,
                              const char *password);
    krb5_error_code (*modify)(krb5_context, void *, enum kadm5_hook_stage,
                              kadm5_principal_ent_t, uint32_t mask);
} kadm5_hook;


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


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


/*
 * Handle a password change.
 */
static krb5_error_code
chpass(krb5_context ctx, void *data, enum kadm5_hook_stage stage,
       krb5_principal princ, const char *password)
{
    /*
     * If password is NULL, we have a new key set but no password (meaning
     * this is an operation such as add -r).  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 krb5_error_code
create(krb5_context ctx, void *data, enum kadm5_hook_stage stage,
       kadm5_principal_ent_t entry, uint32_t mask UNUSED,
       const char *password)
{
    return chpass(ctx, data, stage, entry->principal, 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 krb5_error_code
modify(krb5_context ctx, void *data, enum kadm5_hook_stage stage,
       kadm5_principal_ent_t entry, uint32_t 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 symbol that Heimdal looks for. */
struct kadm5_hook kadm5_hook_v0 = {
    "krb5-sync",
    KADM5_HOOK_VERSION_V0,
    "Russ Allbery",
    init,
    fini,
    chpass,
    create,
    modify
};