Previously any session with access permissions for the corresponding method
was able to confirm or rollback commits initiated by another session.
Change those methods to only grant access to the initiating session.
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
static struct uci_context *cursor;
static struct uloop_timeout apply_timer;
static struct ubus_context *apply_ctx;
static struct uci_context *cursor;
static struct uloop_timeout apply_timer;
static struct ubus_context *apply_ctx;
-static bool apply_running;
+static char apply_sid[RPC_SID_LEN + 1];
struct uci_package *p = NULL;
struct uci_ptr ptr = { 0 };
struct uci_package *p = NULL;
struct uci_ptr ptr = { 0 };
return UBUS_STATUS_PERMISSION_DENIED;
blobmsg_parse(rpc_uci_config_policy, __RPC_C_MAX, tb,
return UBUS_STATUS_PERMISSION_DENIED;
blobmsg_parse(rpc_uci_config_policy, __RPC_C_MAX, tb,
rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
uloop_timeout_cancel(&apply_timer);
rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
uloop_timeout_cancel(&apply_timer);
+ memset(apply_sid, 0, sizeof(apply_sid));
if (tb[RPC_T_ROLLBACK])
rollback = blobmsg_get_bool(tb[RPC_T_ROLLBACK]);
if (tb[RPC_T_ROLLBACK])
rollback = blobmsg_get_bool(tb[RPC_T_ROLLBACK]);
- if (apply_running && rollback)
+ if (apply_sid[0] && rollback)
return UBUS_STATUS_PERMISSION_DENIED;
if (!tb[RPC_T_SESSION])
return UBUS_STATUS_PERMISSION_DENIED;
if (!tb[RPC_T_SESSION])
rpc_uci_purge_dir(RPC_SNAPSHOT_FILES);
rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
rpc_uci_purge_dir(RPC_SNAPSHOT_FILES);
rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
mkdir(RPC_SNAPSHOT_FILES, 0700);
mkdir(RPC_SNAPSHOT_DELTA, 0700);
mkdir(RPC_SNAPSHOT_FILES, 0700);
mkdir(RPC_SNAPSHOT_DELTA, 0700);
globfree(&gl);
if (rollback) {
globfree(&gl);
if (rollback) {
+ strncpy(apply_sid, sid, RPC_SID_LEN);
apply_timer.cb = rpc_uci_apply_timeout;
uloop_timeout_set(&apply_timer, timeout * 1000);
apply_ctx = ctx;
apply_timer.cb = rpc_uci_apply_timeout;
uloop_timeout_set(&apply_timer, timeout * 1000);
apply_ctx = ctx;
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
+ struct blob_attr *tb[__RPC_B_MAX];
+ char *sid;
+
+ blobmsg_parse(rpc_uci_rollback_policy, __RPC_B_MAX, tb,
+ blob_data(msg), blob_len(msg));
+
+ if (!tb[RPC_B_SESSION])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ sid = blobmsg_data(tb[RPC_B_SESSION]);
+
+ if (!apply_sid[0])
return UBUS_STATUS_NO_DATA;
return UBUS_STATUS_NO_DATA;
+ if (strcmp(apply_sid, sid))
+ return UBUS_STATUS_PERMISSION_DENIED;
+
rpc_uci_purge_dir(RPC_SNAPSHOT_FILES);
rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
uloop_timeout_cancel(&apply_timer);
rpc_uci_purge_dir(RPC_SNAPSHOT_FILES);
rpc_uci_purge_dir(RPC_SNAPSHOT_DELTA);
uloop_timeout_cancel(&apply_timer);
+ memset(apply_sid, 0, sizeof(apply_sid));
apply_ctx = NULL;
return 0;
apply_ctx = NULL;
return 0;
char tmp[PATH_MAX];
glob_t gl;
char *sid;
char tmp[PATH_MAX];
glob_t gl;
char *sid;
blobmsg_parse(rpc_uci_rollback_policy, __RPC_B_MAX, tb,
blob_data(msg), blob_len(msg));
blobmsg_parse(rpc_uci_rollback_policy, __RPC_B_MAX, tb,
blob_data(msg), blob_len(msg));
return UBUS_STATUS_NO_DATA;
if (!tb[RPC_B_SESSION])
return UBUS_STATUS_NO_DATA;
if (!tb[RPC_B_SESSION])
sid = blobmsg_data(tb[RPC_B_SESSION]);
sid = blobmsg_data(tb[RPC_B_SESSION]);
+ if (strcmp(apply_sid, sid))
+ return UBUS_STATUS_PERMISSION_DENIED;
+
snprintf(tmp, sizeof(tmp), "%s/*", RPC_SNAPSHOT_FILES);
if (glob(tmp, GLOB_PERIOD, NULL, &gl) < 0)
return UBUS_STATUS_NOT_FOUND;
snprintf(tmp, sizeof(tmp), "%s/*", RPC_SNAPSHOT_FILES);
if (glob(tmp, GLOB_PERIOD, NULL, &gl) < 0)
return UBUS_STATUS_NOT_FOUND;
- ret = rpc_uci_apply_access(sid, &gl);
- if (ret) {
- globfree(&gl);
- return ret;
- }
-
rpc_uci_do_rollback(ctx, sid, &gl);
globfree(&gl);
rpc_uci_do_rollback(ctx, sid, &gl);
globfree(&gl);