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));