11
#include <glusterfs/xlator.h>
14
#include "selinux-messages.h"
15
#include "selinux-mem-types.h"
16
#include <glusterfs/compat-errno.h>
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)
25
if (op_errno == 0 && dict && name &&
26
(!strcmp(name, SELINUX_GLUSTER_XATTR))) {
27
ret = dict_rename_key(dict, SELINUX_GLUSTER_XATTR, SELINUX_XATTR);
29
gf_msg(this->name, GF_LOG_ERROR, op_errno,
30
SL_MSG_SELINUX_GLUSTER_XATTR_MISSING,
31
"getxattr failed for %s", SELINUX_XATTR);
34
STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, dict, xdata);
39
selinux_fgetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd,
40
const char *name, dict_t *xdata)
42
selinux_priv_t *priv = NULL;
44
int32_t op_errno = EINVAL;
45
char *xattr_name = (char *)name;
49
GF_VALIDATE_OR_GOTO("selinux", priv, err);
52
if (!priv->selinux_enabled || !name)
55
if (strcmp(name, SELINUX_XATTR) == 0)
56
xattr_name = SELINUX_GLUSTER_XATTR;
59
STACK_WIND_COOKIE(frame, selinux_fgetxattr_cbk, xattr_name,
60
FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, fd,
64
STACK_UNWIND_STRICT(fgetxattr, frame, op_ret, op_errno, NULL, xdata);
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)
76
if (op_errno == 0 && dict && name &&
77
(!strcmp(name, SELINUX_GLUSTER_XATTR))) {
78
ret = dict_rename_key(dict, SELINUX_GLUSTER_XATTR, SELINUX_XATTR);
80
gf_msg(this->name, GF_LOG_ERROR, op_errno,
81
SL_MSG_SELINUX_GLUSTER_XATTR_MISSING,
82
"getxattr failed for %s", SELINUX_XATTR);
85
STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, dict, xdata);
91
selinux_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
92
const char *name, dict_t *xdata)
94
selinux_priv_t *priv = NULL;
96
int32_t op_errno = EINVAL;
97
char *xattr_name = (char *)name;
101
GF_VALIDATE_OR_GOTO("selinux", priv, err);
104
if (!priv->selinux_enabled || !name)
107
if (strcmp(name, SELINUX_XATTR) == 0)
108
xattr_name = SELINUX_GLUSTER_XATTR;
111
STACK_WIND_COOKIE(frame, selinux_getxattr_cbk, xattr_name,
112
FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, loc,
116
STACK_UNWIND_STRICT(getxattr, frame, op_ret, op_errno, NULL, xdata);
121
selinux_fsetxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
122
int op_ret, int op_errno, dict_t *xdata)
124
STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata);
129
selinux_fsetxattr(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict,
130
int flags, dict_t *xdata)
132
selinux_priv_t *priv = NULL;
134
int32_t op_errno = EINVAL;
137
priv = this->private;
139
GF_VALIDATE_OR_GOTO("selinux", priv, err);
141
if (!priv->selinux_enabled && !dict)
144
ret = dict_rename_key(dict, SELINUX_XATTR, SELINUX_GLUSTER_XATTR);
145
if (ret < 0 && ret != -ENODATA)
149
STACK_WIND(frame, selinux_fsetxattr_cbk, FIRST_CHILD(this),
150
FIRST_CHILD(this)->fops->fsetxattr, fd, dict, flags, xdata);
154
STACK_UNWIND_STRICT(fsetxattr, frame, op_ret, op_errno, xdata);
159
selinux_setxattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
160
int op_ret, int op_errno, dict_t *xdata)
162
STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata);
167
selinux_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
168
int flags, dict_t *xdata)
170
selinux_priv_t *priv = NULL;
172
int32_t op_errno = EINVAL;
175
priv = this->private;
177
GF_VALIDATE_OR_GOTO("selinux", priv, err);
179
if (!priv->selinux_enabled && !dict)
182
ret = dict_rename_key(dict, SELINUX_XATTR, SELINUX_GLUSTER_XATTR);
183
if (ret < 0 && ret != -ENODATA)
187
STACK_WIND(frame, selinux_setxattr_cbk, FIRST_CHILD(this),
188
FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, xdata);
191
STACK_UNWIND_STRICT(setxattr, frame, op_ret, op_errno, xdata);
196
mem_acct_init(xlator_t *this)
200
GF_VALIDATE_OR_GOTO("selinux", this, out);
202
ret = xlator_mem_acct_init(this, gf_selinux_mt_end);
205
gf_msg(this->name, GF_LOG_ERROR, 0, SL_MSG_MEM_ACCT_INIT_FAILED,
206
"Memory accounting init failed");
217
selinux_priv_t *priv = NULL;
219
GF_VALIDATE_OR_GOTO("selinux", this, out);
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 "
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");
234
priv = GF_CALLOC(1, sizeof(*priv), gf_selinux_mt_selinux_priv_t);
236
gf_log(this->name, GF_LOG_ERROR, "out of memory");
240
GF_OPTION_INIT("selinux", priv->selinux_enabled, bool, out);
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");
249
this->private = (void *)priv;
254
mem_pool_destroy(this->local_pool);
255
this->local_pool = NULL;
261
reconfigure(xlator_t *this, dict_t *options)
264
selinux_priv_t *priv = NULL;
266
priv = this->private;
268
GF_OPTION_RECONF("selinux", priv->selinux_enabled, options, bool, out);
278
selinux_priv_t *priv = NULL;
280
priv = this->private;
283
mem_pool_destroy(this->local_pool);
284
this->local_pool = NULL;
289
struct xlator_fops fops = {
290
.getxattr = selinux_getxattr,
291
.fgetxattr = selinux_fgetxattr,
292
.setxattr = selinux_setxattr,
293
.fsetxattr = selinux_fsetxattr,
296
struct xlator_cbks cbks = {};
298
struct volume_options options[] = {
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"},
312
xlator_api_t xlator_api = {
315
.reconfigure = reconfigure,
316
.mem_acct_init = mem_acct_init,
321
.identifier = "selinux",
322
.category = GF_MAINTAINED,