Skip to content

Commit

Permalink
server UPDATE use sysrepo NACM
Browse files Browse the repository at this point in the history
NACM moved from the server to sysrepo.
  • Loading branch information
michalvasko committed Mar 4, 2022
1 parent 05d9ac4 commit 1269b40
Show file tree
Hide file tree
Showing 27 changed files with 138 additions and 2,222 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ option(ENABLE_COVERAGE "Build code coverage report from tests" OFF)
option(BUILD_CLI "Build and install neotpeer2-cli" ON)
option(ENABLE_URL "Enable URL capability" ON)
set(THREAD_COUNT 5 CACHE STRING "Number of threads accepting new sessions and handling requests")
set(NACM_RECOVERY_UID 0 CACHE STRING "NACM recovery session UID that has unrestricted access")
set(POLL_IO_TIMEOUT 10 CACHE STRING "Timeout in milliseconds of polling sessions for new data. It is also used for synchronization of low level IO such as sending a reply while a notification is being sent")
set(YANG_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/yang/modules/netopeer2" CACHE STRING "Directory where to copy the YANG modules to")

Expand Down Expand Up @@ -129,7 +128,6 @@ set(SERVER_SRC
src/common.c
src/netconf.c
src/netconf_monitoring.c
src/netconf_acm.c
src/netconf_nmda.c
src/netconf_subscribed_notifications.c
src/netconf_confirmed_commit.c
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,10 @@ $ make coverage

## NACM

This NETCONF server implements full *ietf-netconf-acm* access control that **bypasses** *sysrepo*
file system access control. NACM is enabled by default, so users other than `root` will not be
allowed to *write* any data but should be granted *read* and *execute* permissions unless
the access was modified by a NACM extension. When deploying this server, it is strongly advised
to configure NACM properly.
This NETCONF server uses *ietf-netconf-acm* access control of *sysrepo*. NACM is enabled by default,
so except for the recovery user, no others will be allowed to *write* any data but should be granted
*read* and *execute* permissions unless the access was modified by a NACM extension. When deploying
this server, it is strongly advised to configure NACM properly.

## Server configuration

Expand Down
1 change: 0 additions & 1 deletion scripts/remove.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ fi

# array of modules to remove, exact same as setup.sh
MODULES=(
"[email protected]"
"[email protected] -e writable-running -e candidate -e rollback-on-error -e validate -e startup -e url -e xpath -e confirmed-commit"
"[email protected]"
"[email protected] -e origin -e with-defaults"
Expand Down
1 change: 0 additions & 1 deletion scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ GROUP=${NP2_MODULE_GROUP}

# array of modules to install
MODULES=(
"[email protected]"
"[email protected] -e writable-running -e candidate -e rollback-on-error -e validate -e startup -e url -e xpath -e confirmed-commit"
"[email protected]"
"[email protected] -e origin -e with-defaults"
Expand Down
7 changes: 6 additions & 1 deletion src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@
#include <libyang/libyang.h>
#include <libyang/plugins_types.h>
#include <nc_server.h>
#include <sysrepo/netconf_acm.h>

#include "common.h"
#include "compat.h"
#include "log.h"
#include "netconf_acm.h"
#include "netconf_monitoring.h"

struct np2srv np2srv = {.unix_mode = -1, .unix_uid = -1, .unix_gid = -1};
Expand Down Expand Up @@ -297,6 +297,11 @@ np2srv_new_session_cb(const char *UNUSED(client_name), struct nc_session *new_se
username = nc_session_get_username(new_session);
sr_session_push_orig_data(sr_sess, strlen(username) + 1, username);

/* set NACM username for it to be applied */
if (sr_nacm_set_user(sr_sess, username)) {
goto error;
}

c = 0;
while ((c < 3) && nc_ps_add_session(np2srv.nc_ps, new_session)) {
/* presumably timeout, give it a shot 2 times */
Expand Down
1 change: 0 additions & 1 deletion src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ struct np2srv {
};

extern struct np2srv np2srv;
extern ATOMIC_T skip_nacm_nc_sid;

/**
* @brief Sleep in milliseconds.
Expand Down
17 changes: 0 additions & 17 deletions src/err_netconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,6 @@
#include "common.h"
#include "compat.h"

void
np_err_nacm_access_denied(sr_session_ctx_t *ev_sess, const char *module_name, const char *user, const char *path)
{
char *msg;

/* generate message */
if (asprintf(&msg, "Access to the data model \"%s\" is denied because \"%s\" NACM authorization failed.",
module_name, user) == -1) {
return;
}

/* set error */
sr_session_set_netconf_error(ev_sess, "protocol", "access-denied", NULL, path, msg, 0);

free(msg);
}

void
np_err_sr2nc_lock_denied(sr_session_ctx_t *ev_sess, const sr_error_info_t *err_info)
{
Expand Down
2 changes: 0 additions & 2 deletions src/err_netconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

#include <sysrepo.h>

void np_err_nacm_access_denied(sr_session_ctx_t *ev_sess, const char *module_name, const char *user, const char *path);

void np_err_sr2nc_lock_denied(sr_session_ctx_t *ev_sess, const sr_error_info_t *err_info);

void np_err_sr2nc_in_use(sr_session_ctx_t *ev_sess, const sr_error_info_t *err_info);
Expand Down
101 changes: 5 additions & 96 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <nc_server.h>
#include <sysrepo.h>
#include <sysrepo/error_format.h>
#include <sysrepo/netconf_acm.h>

#include "common.h"
#include "compat.h"
Expand All @@ -48,7 +49,6 @@
#ifdef NC_ENABLED_TLS
# include "netconf_server_tls.h"
#endif
#include "netconf_acm.h"
#include "netconf_confirmed_commit.h"
#include "netconf_monitoring.h"
#include "netconf_nmda.h"
Expand All @@ -62,9 +62,6 @@
/** @brief flag for main loop */
ATOMIC_T loop_continue = 1;

/* NETCONF SID of session to skip diff check for */
ATOMIC_T skip_nacm_nc_sid;

static void *worker_thread(void *arg);

/**
Expand Down Expand Up @@ -331,36 +328,14 @@ static struct nc_server_reply *
np2srv_rpc_cb(struct lyd_node *rpc, struct nc_session *ncs)
{
struct np2_user_sess *user_sess;
const struct lyd_node *denied;
struct lyd_node *node;
const sr_error_info_t *err_info;
struct nc_server_reply *reply = NULL;
struct lyd_node *child = NULL;
sr_data_t *output;
NC_WD_MODE nc_wd;
struct lyd_node *e;
char *str;
int rc;

/* check NACM */
if ((denied = ncac_check_operation(rpc, nc_session_get_username(ncs)))) {
e = nc_err(LYD_CTX(rpc), NC_ERR_ACCESS_DENIED, NC_ERR_TYPE_APP);

/* set path */
str = lysc_path(denied->schema, LYSC_PATH_LOG, NULL, 0);
nc_err_set_path(e, str);
free(str);

/* set message */
if (asprintf(&str, "Executing the operation is denied because \"%s\" NACM authorization failed.",
nc_session_get_username(ncs)) > -1) {
nc_err_set_msg(e, str, "en");
free(str);
}

return nc_server_reply_err(e);
}

/* use default lnc2 callbacks when available */
if (!strcmp(LYD_NAME(rpc), "get-schema") && !strcmp(lyd_owner_module(rpc)->name, "ietf-netconf-monitoring")) {
return nc_clb_default_get_schema(rpc, ncs);
Expand Down Expand Up @@ -425,44 +400,6 @@ np2srv_rpc_cb(struct lyd_node *rpc, struct nc_session *ncs)
return reply;
}

/**
* @brief Sysrepo callback for checking NACM of data diff.
*
* @param[in] session SR session.
* @param[in] diff Diff to check.
* @return SR error value.
*/
static int
np2srv_diff_check_cb(sr_session_ctx_t *session, const struct lyd_node *diff)
{
const struct lyd_node *node;
char *path;
const char *user, *name;
uint32_t *nc_sid;

name = sr_session_get_orig_name(session);
if (!name || strcmp(name, "netopeer2")) {
EINT;
return SR_ERR_INTERNAL;
}
sr_session_get_orig_data(session, 0, NULL, (const void **)&nc_sid);
if (ATOMIC_LOAD_RELAXED(skip_nacm_nc_sid) == *nc_sid) {
/* skip the NACM check */
return SR_ERR_OK;
}

sr_session_get_orig_data(session, 1, NULL, (const void **)&user);
if ((node = ncac_check_diff(diff, user))) {
/* access denied */
path = lysc_path(node->schema, LYSC_PATH_LOG, NULL, 0);
np_err_nacm_access_denied(session, node->schema->module->name, user, path);
free(path);
return SR_ERR_UNAUTHORIZED;
}

return SR_ERR_OK;
}

/**
* @brief Check SR schema context for all the required schemas and features.
*
Expand Down Expand Up @@ -568,12 +505,6 @@ server_init(void)
goto error;
}

/* set edit-config NACM diff check callback */
rc = sr_set_diff_check_callback(np2srv.sr_conn, np2srv_diff_check_cb);
if (rc != SR_ERR_OK) {
WRN("Unable to set diff check callback (%s), NACM will not be applied when editing data.", sr_strerror(rc));
}

/* set the content-id callback */
nc_server_set_content_id_clb(np2srv_content_id_cb, NULL, NULL);

Expand All @@ -592,9 +523,6 @@ server_init(void)
/* init monitoring */
ncm_init();

/* init NACM */
ncac_init();

/* init libnetconf2 */
if (nc_server_init()) {
goto error;
Expand Down Expand Up @@ -696,7 +624,7 @@ server_destroy(void)
ncm_destroy();

/* NACM cleanup */
ncac_destroy();
sr_nacm_destroy();

/* confirmed commit cleanup */
ncc_commit_ctx_destroy();
Expand Down Expand Up @@ -946,28 +874,9 @@ server_data_subscribe(void)
/*
* ietf-netconf-acm
*/
mod_name = "ietf-netconf-acm";
xpath = "/ietf-netconf-acm:nacm";
SR_CONFIG_SUBSCR(mod_name, xpath, ncac_nacm_params_cb);

xpath = "/ietf-netconf-acm:nacm/groups/group";
SR_CONFIG_SUBSCR(mod_name, xpath, ncac_group_cb);

xpath = "/ietf-netconf-acm:nacm/rule-list";
SR_CONFIG_SUBSCR(mod_name, xpath, ncac_rule_list_cb);

xpath = "/ietf-netconf-acm:nacm/rule-list/rule";
SR_CONFIG_SUBSCR(mod_name, xpath, ncac_rule_cb);

/* state data */
xpath = "/ietf-netconf-acm:nacm/denied-operations";
SR_OPER_SUBSCR(mod_name, xpath, ncac_oper_cb);

xpath = "/ietf-netconf-acm:nacm/denied-data-writes";
SR_OPER_SUBSCR(mod_name, xpath, ncac_oper_cb);

xpath = "/ietf-netconf-acm:nacm/denied-notifications";
SR_OPER_SUBSCR(mod_name, xpath, ncac_oper_cb);
if (sr_nacm_init(np2srv.sr_sess, 0, &np2srv.sr_data_sub)) {
goto error;
}

return 0;

Expand Down
Loading

0 comments on commit 1269b40

Please sign in to comment.