At connect time, compute SELinux policy info on client side, and
send it over the wire.
On server side, get SELinux policy info from nodemap and compare
it with the one received from client.
Lustre-change: https://review.whamcloud.com/24422
Lustre-commit:
dd200e5530fd841999399f6dcafb5ded46ba3cf1
Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I9b4a206455f2c0b451f6b3ed7e3a85285592758e
Reviewed-by: Patrick Farrell <pfarrell@whamcloud.com>
Reviewed-by: Li Dongyang <dongyangli@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/34641
Tested-by: Jenkins
Tested-by: Maloo <maloo@whamcloud.com>
return !!(exp_connect_flags2(exp) & OBD_CONNECT2_ARCHIVE_ID_ARRAY);
}
+static inline int exp_connect_sepol(struct obd_export *exp)
+{
+ return !!(exp_connect_flags2(exp) & OBD_CONNECT2_SELINUX_POLICY);
+}
+
enum {
/* archive_ids in array format */
KKUC_CT_DATA_ARRAY_MAGIC = 0x092013cea,
__u32 newlen);
int req_layout_init(void);
void req_layout_fini(void);
+int req_check_sepol(struct req_capsule *pill);
extern struct req_format RQF_OBD_PING;
extern struct req_format RQF_OBD_SET_INFO;
extern struct req_msg_field RMF_HSM_STATE_SET;
extern struct req_msg_field RMF_MDS_HSM_CURRENT_ACTION;
extern struct req_msg_field RMF_MDS_HSM_REQUEST;
+extern struct req_msg_field RMF_SELINUX_POL;
/* seq-mgr fields */
extern struct req_msg_field RMF_SEQ_OPC;
OBD_CONNECT2_SUM_STATFS | \
OBD_CONNECT2_LOCK_CONVERT | \
OBD_CONNECT2_DIR_MIGRATE | \
- OBD_CONNECT2_ARCHIVE_ID_ARRAY)
+ OBD_CONNECT2_ARCHIVE_ID_ARRAY | \
+ OBD_CONNECT2_SELINUX_POLICY)
#define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \
OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \
obd_connect_set_secctx(data);
+#if defined(CONFIG_SECURITY)
+ data->ocd_connect_flags2 |= OBD_CONNECT2_SELINUX_POLICY;
+#endif
+
data->ocd_brw_size = MD_MAX_BRW_SIZE;
err = obd_connect(NULL, &sbi->ll_md_exp, sbi->ll_md_obd,
obd2cli_tgt(imp->imp_obd),
obd->obd_uuid.uuid,
(char *)&imp->imp_dlm_handle,
- (char *)&imp->imp_connect_data };
+ (char *)&imp->imp_connect_data,
+ NULL };
struct ptlrpc_connect_async_args *aa;
int rc;
ENTRY;
if (request == NULL)
GOTO(out, rc = -ENOMEM);
+ /* get SELinux policy info if any */
+ rc = sptlrpc_get_sepol(request);
+ if (rc < 0) {
+ ptlrpc_request_free(request);
+ GOTO(out, rc);
+ }
+
+ bufs[5] = request->rq_sepol;
+
+ req_capsule_set_size(&request->rq_pill, &RMF_SELINUX_POL, RCL_CLIENT,
+ strlen(request->rq_sepol) ?
+ strlen(request->rq_sepol) + 1 : 0);
+
rc = ptlrpc_request_bufs_pack(request, LUSTRE_OBD_VERSION,
imp->imp_connect_op, bufs, NULL);
if (rc) {
/* struct ptlrpc_request, lustre_msg* */
#include <lustre_req_layout.h>
#include <lustre_acl.h>
+#include <lustre_nodemap.h>
/*
* RQFs (see below) refer to two struct req_msg_field arrays describing the
};
static const struct req_msg_field *obd_connect_client[] = {
- &RMF_PTLRPC_BODY,
- &RMF_TGTUUID,
- &RMF_CLUUID,
- &RMF_CONN,
- &RMF_CONNECT_DATA
+ &RMF_PTLRPC_BODY,
+ &RMF_TGTUUID,
+ &RMF_CLUUID,
+ &RMF_CONN,
+ &RMF_CONNECT_DATA,
+ &RMF_SELINUX_POL
};
static const struct req_msg_field *obd_connect_server[] = {
NULL);
EXPORT_SYMBOL(RMF_LAYOUT_INTENT);
+struct req_msg_field RMF_SELINUX_POL =
+ DEFINE_MSGF("selinux_pol", RMF_F_STRING, -1, NULL, NULL);
+EXPORT_SYMBOL(RMF_SELINUX_POL);
+
/*
* OST request field.
*/
return 0;
}
EXPORT_SYMBOL(req_capsule_server_grow);
+
+int req_check_sepol(struct req_capsule *pill)
+{
+ int rc = 0;
+#ifdef HAVE_SERVER_SUPPORT
+ struct obd_export *export;
+ struct lu_nodemap *nm = NULL;
+ const char *sepol = NULL;
+ const char *nm_sepol = NULL;
+
+ if (!pill->rc_req)
+ return -EPROTO;
+
+ export = pill->rc_req->rq_export;
+ if (!export || !exp_connect_sepol(export) ||
+ !req_capsule_has_field(pill, &RMF_SELINUX_POL, RCL_CLIENT))
+ goto nm;
+
+ if (req_capsule_get_size(pill, &RMF_SELINUX_POL, RCL_CLIENT) == 0)
+ goto nm;
+
+ sepol = req_capsule_client_get(pill, &RMF_SELINUX_POL);
+ CDEBUG(D_SEC, "retrieved sepol %s\n", sepol);
+
+nm:
+ if (export) {
+ nm = nodemap_get_from_exp(export);
+ if (!IS_ERR_OR_NULL(nm)) {
+ nm_sepol = nodemap_get_sepol(nm);
+ if (nm_sepol && nm_sepol[0])
+ if (sepol == NULL ||
+ strcmp(sepol, nm_sepol) != 0)
+ rc = -EACCES;
+ }
+ }
+
+ if (!IS_ERR_OR_NULL(nm))
+ nodemap_putref(nm);
+#endif
+
+ return rc;
+}
+EXPORT_SYMBOL(req_check_sepol);
tsi->tsi_exp->exp_connect_data.ocd_brw_size = reply->ocd_brw_size;
spin_unlock(&tsi->tsi_exp->exp_lock);
+ if (strcmp(tsi->tsi_exp->exp_obd->obd_type->typ_name,
+ LUSTRE_MDT_NAME) == 0) {
+ rc = req_check_sepol(tsi->tsi_pill);
+ if (rc)
+ GOTO(out, rc);
+ }
+
RETURN(0);
out:
obd_disconnect(class_export_get(tsi->tsi_exp));