summaryrefslogtreecommitdiffstats
path: root/src/providers/data_provider/dp.h
blob: 9cdbe5b3a56ba159f9a10df6e010e616e4aefcac (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
    Authors:
        Pavel Březina <pbrezina@redhat.com>

    Copyright (C) 2016 Red Hat

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _DP_H_
#define _DP_H_

#include <stdint.h>

#include "sbus/sssd_dbus.h"
#include "providers/backend.h"
#include "providers/data_provider/dp_request.h"
#include "providers/data_provider/dp_custom_data.h"
#include "providers/data_provider/dp_flags.h"

struct data_provider;
struct dp_method;

/**
 * Module constructor.
 *
 * It is possible to create a module data that is passed into all
 * target initialization functions.
 */
typedef errno_t (*dp_module_init_fn)(TALLOC_CTX *mem_ctx,
                                     struct be_ctx *be_ctx,
                                     struct data_provider *provider,
                                     const char *module_name,
                                     void **_module_data);

/**
 * Target initialization function.
 *
 * Pointer to dp_method is unique for all targets. Make sure that
 * dp_set_method is called in all targets even if you are reusing
 * some existing context or initialization function.
 */
typedef errno_t (*dp_target_init_fn)(TALLOC_CTX *mem_ctx,
                                     struct be_ctx *be_ctx,
                                     void *module_data,
                                     struct dp_method *dp_methods);

enum dp_targets {
    DPT_ID,
    DPT_AUTH,
    DPT_ACCESS,
    DPT_CHPASS,
    DPT_SUDO,
    DPT_AUTOFS,
    DPT_SELINUX,
    DPT_HOSTID,
    DPT_SUBDOMAINS,
    DPT_SESSION,

    DP_TARGET_SENTINEL
};

enum dp_methods {
    DPM_CHECK_ONLINE,
    DPM_ACCOUNT_HANDLER,
    DPM_AUTH_HANDLER,
    DPM_ACCESS_HANDLER,
    DPM_SELINUX_HANDLER,
    DPM_SUDO_HANDLER,
    DPM_AUTOFS_HANDLER,
    DPM_HOSTID_HANDLER,
    DPM_DOMAINS_HANDLER,
    DPM_SESSION_HANDLER,

    DP_METHOD_SENTINEL
};

/* Method handler. */

struct dp_req_params {
    struct tevent_context *ev;
    struct be_ctx *be_ctx;
    struct sss_domain_info *domain;
    enum dp_targets target;
    enum dp_methods method;
};

typedef struct tevent_req *
(*dp_req_send_fn)(TALLOC_CTX *mem_ctx, void *method_data, void *request_data,
                  struct dp_req_params *params);

typedef errno_t
(*dp_req_recv_fn)(TALLOC_CTX *mem_ctx, struct tevent_req *req, void *data);

/* Data provider initialization. */

errno_t dp_init(struct tevent_context *ev,
                struct be_ctx *be_ctx,
                uid_t uid,
                gid_t gid);

bool _dp_target_enabled(struct data_provider *provider,
                        const char *module_name,
                        ...);

#define dp_target_enabled(provider, module_name, ...) \
    _dp_target_enabled(provider, module_name, ##__VA_ARGS__, DP_TARGET_SENTINEL)

struct dp_module *dp_target_module(struct data_provider *provider,
                                   enum dp_targets target);

void *dp_get_module_data(struct dp_module *dp_module);

void _dp_set_method(struct dp_method *methods,
                    enum dp_methods method,
                    dp_req_send_fn send_fn,
                    dp_req_recv_fn recv_fn,
                    void *method_data,
                    const char *method_dtype,
                    const char *request_dtype,
                    const char *output_dtype,
                    uint32_t output_size);

/* We check function headers on compile time and data types on run time. This
 * check requires that both method and request private data are talloc-created
 * with talloc name set to data type name (which is done by talloc unless
 * you use _size variations of talloc functions.
 *
 * This way we ensure that we always pass correct data and we can access them
 * directly in request handler without the need to cast them explicitly
 * from void pointer. */
#define dp_set_method(methods, method, send_fn, recv_fn, method_data,         \
                      method_dtype, req_dtype, output_dtype)                  \
    do {                                                                      \
        /* Check _send function parameter types. */                           \
        struct tevent_req *(*__send_fn)(TALLOC_CTX *, method_dtype *,         \
            req_dtype *, struct dp_req_params *params) = (send_fn);           \
                                                                              \
        /* Check _recv function parameter types. */                           \
        errno_t (*__recv_fn)(TALLOC_CTX *, struct tevent_req *,               \
            output_dtype *) = (recv_fn);                                      \
        _dp_set_method(methods, method, (dp_req_send_fn)__send_fn,            \
                       (dp_req_recv_fn)__recv_fn, method_data,                \
                       #method_dtype, #req_dtype,                             \
                       #output_dtype, sizeof(output_dtype));                  \
    } while (0)

bool dp_method_enabled(struct data_provider *provider,
                       enum dp_targets target,
                       enum dp_methods method);

void dp_terminate_domain_requests(struct data_provider *provider,
                                  const char *domain);

void dp_sbus_domain_active(struct data_provider *provider,
                           struct sss_domain_info *dom);
void dp_sbus_domain_inconsistent(struct data_provider *provider,
                                 struct sss_domain_info *dom);

void dp_sbus_reset_users_ncache(struct data_provider *provider,
                                struct sss_domain_info *dom);
void dp_sbus_reset_groups_ncache(struct data_provider *provider,
                                 struct sss_domain_info *dom);

void dp_sbus_reset_users_memcache(struct data_provider *provider);
void dp_sbus_reset_groups_memcache(struct data_provider *provider);
void dp_sbus_reset_initgr_memcache(struct data_provider *provider);

#endif /* _DP_H_ */