glusterfs

Форк
0
323 строки · 8.2 Кб
1
/*
2
   Copyright (c) 2017 Red Hat, Inc. <http://www.redhat.com>
3
   This file is part of GlusterFS.
4

5
   This file is licensed to you under your choice of the GNU Lesser
6
   General Public License, version 3 or any later version (LGPLv3 or
7
   later), or the GNU General Public License, version 2 (GPLv2), in all
8
   cases as published by the Free Software Foundation.
9
*/
10

11
#include <glusterfs/xlator.h>
12

13
#include "selinux.h"
14
#include "selinux-messages.h"
15
#include "selinux-mem-types.h"
16
#include <glusterfs/compat-errno.h>
17

18
static int
19
selinux_fgetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
20
                      int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
21
{
22
    int ret = 0;
23
    char *name = cookie;
24

25
    if (op_errno == 0 && dict && name &&
26
        (!strcmp(name, SELINUX_GLUSTER_XATTR))) {
27
        ret = dict_rename_key(dict, SELINUX_GLUSTER_XATTR, SELINUX_XATTR);
28
        if (ret < 0)
29
            gf_msg(this->name, GF_LOG_ERROR, op_errno,
30
                   SL_MSG_SELINUX_GLUSTER_XATTR_MISSING,
31
                   "getxattr failed for %s", SELINUX_XATTR);
32
    }
33

34
    STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata);
35
    return ret;
36
}
37

38
static int
39
selinux_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
40
                  const char *name, dict_t *xdata)
41
{
42
    selinux_priv_t *priv = NULL;
43
    int32_t op_ret = -1;
44
    int32_t op_errno = EINVAL;
45
    char *xattr_name = (char *)name;
46

47
    priv = this->private;
48

49
    GF_VALIDATE_OR_GOTO("selinux", priv, err);
50

51
    /* name can be NULL for listxattr calls */
52
    if (!priv->selinux_enabled || !name)
53
        goto off;
54

55
    if (strcmp(name, SELINUX_XATTR) == 0)
56
        xattr_name = SELINUX_GLUSTER_XATTR;
57

58
off:
59
    STACK_WIND_COOKIE(frame, selinux_fgetxattr_cbk, xattr_name,
60
                      FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd,
61
                      xattr_name, xdata);
62
    return 0;
63
err:
64
    STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, NULL, xdata);
65

66
    return 0;
67
}
68

69
static int
70
selinux_getxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
71
                     int op_ret, int op_errno, dict_t *dict, dict_t *xdata)
72
{
73
    int ret = 0;
74
    char *name = cookie;
75

76
    if (op_errno == 0 && dict && name &&
77
        (!strcmp(name, SELINUX_GLUSTER_XATTR))) {
78
        ret = dict_rename_key(dict, SELINUX_GLUSTER_XATTR, SELINUX_XATTR);
79
        if (ret < 0)
80
            gf_msg(this->name, GF_LOG_ERROR, op_errno,
81
                   SL_MSG_SELINUX_GLUSTER_XATTR_MISSING,
82
                   "getxattr failed for %s", SELINUX_XATTR);
83
    }
84

85
    STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata);
86

87
    return 0;
88
}
89

90
static int
91
selinux_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
92
                 const char *name, dict_t *xdata)
93
{
94
    selinux_priv_t *priv = NULL;
95
    int32_t op_ret = -1;
96
    int32_t op_errno = EINVAL;
97
    char *xattr_name = (char *)name;
98

99
    priv = this->private;
100

101
    GF_VALIDATE_OR_GOTO("selinux", priv, err);
102

103
    /* name can be NULL for listxattr calls */
104
    if (!priv->selinux_enabled || !name)
105
        goto off;
106

107
    if (strcmp(name, SELINUX_XATTR) == 0)
108
        xattr_name = SELINUX_GLUSTER_XATTR;
109

110
off:
111
    STACK_WIND_COOKIE(frame, selinux_getxattr_cbk, xattr_name,
112
                      FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc,
113
                      xattr_name, xdata);
114
    return 0;
115
err:
116
    STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, NULL, xdata);
117
    return 0;
118
}
119

120
static int
121
selinux_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
122
                      int op_ret, int op_errno, dict_t *xdata)
123
{
124
    STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata);
125
    return 0;
126
}
127

128
static int
129
selinux_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
130
                  int flags, dict_t *xdata)
131
{
132
    selinux_priv_t *priv = NULL;
133
    int32_t op_ret = -1;
134
    int32_t op_errno = EINVAL;
135
    int32_t ret = -1;
136

137
    priv = this->private;
138

139
    GF_VALIDATE_OR_GOTO("selinux", priv, err);
140

141
    if (!priv->selinux_enabled && !dict)
142
        goto off;
143

144
    ret = dict_rename_key(dict, SELINUX_XATTR, SELINUX_GLUSTER_XATTR);
145
    if (ret < 0 && ret != -ENODATA)
146
        goto err;
147

148
off:
149
    STACK_WIND(frame, selinux_fsetxattr_cbk, FIRST_CHILD(this),
150
               FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
151

152
    return 0;
153
err:
154
    STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata);
155
    return 0;
156
}
157

158
static int
159
selinux_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
160
                     int op_ret, int op_errno, dict_t *xdata)
161
{
162
    STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata);
163
    return 0;
164
}
165

166
static int
167
selinux_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
168
                 int flags, dict_t *xdata)
169
{
170
    selinux_priv_t *priv = NULL;
171
    int32_t op_ret = -1;
172
    int32_t op_errno = EINVAL;
173
    int32_t ret = -1;
174

175
    priv = this->private;
176

177
    GF_VALIDATE_OR_GOTO("selinux", priv, err);
178

179
    if (!priv->selinux_enabled && !dict)
180
        goto off;
181

182
    ret = dict_rename_key(dict, SELINUX_XATTR, SELINUX_GLUSTER_XATTR);
183
    if (ret < 0 && ret != -ENODATA)
184
        goto err;
185

186
off:
187
    STACK_WIND(frame, selinux_setxattr_cbk, FIRST_CHILD(this),
188
               FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
189
    return 0;
190
err:
191
    STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata);
192
    return 0;
193
}
194

195
int32_t
196
mem_acct_init(xlator_t *this)
197
{
198
    int ret = -1;
199

200
    GF_VALIDATE_OR_GOTO("selinux", this, out);
201

202
    ret = xlator_mem_acct_init(this, gf_selinux_mt_end);
203

204
    if (ret != 0) {
205
        gf_msg(this->name, GF_LOG_ERROR, 0, SL_MSG_MEM_ACCT_INIT_FAILED,
206
               "Memory accounting init failed");
207
        return ret;
208
    }
209
out:
210
    return ret;
211
}
212

213
int32_t
214
init(xlator_t *this)
215
{
216
    int32_t ret = -1;
217
    selinux_priv_t *priv = NULL;
218

219
    GF_VALIDATE_OR_GOTO("selinux", this, out);
220

221
    if (!this->children || this->children->next) {
222
        gf_msg(this->name, GF_LOG_WARNING, 0, SL_MSG_INVALID_VOLFILE,
223
               "Error: SELinux (%s) not configured with exactly one "
224
               "child",
225
               this->name);
226
        return -1;
227
    }
228

229
    if (this->parents == NULL) {
230
        gf_msg(this->name, GF_LOG_WARNING, 0, SL_MSG_INVALID_VOLFILE,
231
               "Dangling volume. Please check the volfile");
232
    }
233

234
    priv = GF_CALLOC(1, sizeof(*priv), gf_selinux_mt_selinux_priv_t);
235
    if (!priv) {
236
        gf_log(this->name, GF_LOG_ERROR, "out of memory");
237
        goto out;
238
    }
239

240
    GF_OPTION_INIT("selinux", priv->selinux_enabled, bool, out);
241

242
    this->local_pool = mem_pool_new(selinux_priv_t, 64);
243
    if (!this->local_pool) {
244
        gf_msg(this->name, GF_LOG_ERROR, ENOMEM, SL_MSG_ENOMEM,
245
               "Failed to create local_t's memory pool");
246
        goto out;
247
    }
248

249
    this->private = (void *)priv;
250
    ret = 0;
251
out:
252
    if (ret) {
253
        GF_FREE(priv);
254
        mem_pool_destroy(this->local_pool);
255
        this->local_pool = NULL;
256
    }
257
    return ret;
258
}
259

260
int
261
reconfigure(xlator_t *this, dict_t *options)
262
{
263
    int32_t ret = -1;
264
    selinux_priv_t *priv = NULL;
265

266
    priv = this->private;
267

268
    GF_OPTION_RECONF("selinux", priv->selinux_enabled, options, bool, out);
269

270
    ret = 0;
271
out:
272
    return ret;
273
}
274

275
void
276
fini(xlator_t *this)
277
{
278
    selinux_priv_t *priv = NULL;
279

280
    priv = this->private;
281
    GF_FREE(priv);
282

283
    mem_pool_destroy(this->local_pool);
284
    this->local_pool = NULL;
285

286
    return;
287
}
288

289
struct xlator_fops fops = {
290
    .getxattr = selinux_getxattr,
291
    .fgetxattr = selinux_fgetxattr,
292
    .setxattr = selinux_setxattr,
293
    .fsetxattr = selinux_fsetxattr,
294
};
295

296
struct xlator_cbks cbks = {};
297

298
struct volume_options options[] = {
299
    {
300
        .key = {"selinux"},
301
        .type = GF_OPTION_TYPE_BOOL,
302
        .default_value = "on",
303
        .description = "Enable/disable selinux translator",
304
        .op_version = {GD_OP_VERSION_3_11_0},
305
        .flags = OPT_FLAG_SETTABLE,
306
        .tags = {"security", "linux"},
307
    },
308
    {
309
        .key = {NULL},
310
    }};
311

312
xlator_api_t xlator_api = {
313
    .init = init,
314
    .fini = fini,
315
    .reconfigure = reconfigure,
316
    .mem_acct_init = mem_acct_init,
317
    .op_version = {1}, /* Present from the initial version */
318
    .fops = &fops,
319
    .cbks = &cbks,
320
    .options = options,
321
    .identifier = "selinux",
322
    .category = GF_MAINTAINED,
323
};
324

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.