diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d4175ee2..77aea1f57 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ set(CMAKE_C_FLAGS_DEBUG "-g -O0 -DDEBUG") # Generic version of not only the library. Major version is reserved for really big changes of the project, # minor version changes with added functionality (new tool, functionality of the tool or library, ...) and # micro version is changed with a set of small changes or bugfixes anywhere in the project. -set(NP2SRV_VERSION 1.1.34) +set(NP2SRV_VERSION 1.1.39) # build options if(CMAKE_BUILD_TYPE STREQUAL debug) @@ -203,11 +203,11 @@ install(TARGETS netopeer2-server DESTINATION ${CMAKE_INSTALL_BINDIR}) if(INSTALL_MODULES) install(CODE " message(STATUS \"Installing missing sysrepo modules...\") - set(ENV{NP2_MODULE_DIR} ${YANG_MODULE_DIR}) - set(ENV{NP2_MODULE_PERMS} ${MODULES_PERMS}) - set(ENV{NP2_MODULE_OWNER} ${MODULES_OWNER}) - set(ENV{NP2_MODULE_GROUP} ${MODULES_GROUP}) - execute_process(COMMAND ${SCRIPT_DIR}/setup.sh) + set(ENV{NP2_MODULE_DIR} \"${YANG_MODULE_DIR}\") + set(ENV{NP2_MODULE_PERMS} \"${MODULES_PERMS}\") + set(ENV{NP2_MODULE_OWNER} \"${MODULES_OWNER}\") + set(ENV{NP2_MODULE_GROUP} \"${MODULES_GROUP}\") + execute_process(COMMAND \"${SCRIPT_DIR}/setup.sh\") ") else() message(WARNING "Server will refuse to start if the modules are not installed!") diff --git a/cli/commands.c b/cli/commands.c index c237423fc..3a5c586fb 100644 --- a/cli/commands.c +++ b/cli/commands.c @@ -1729,7 +1729,11 @@ parse_cert(const char *name, const char *path) BIO_printf(bio_out, "\n"); BIO_printf(bio_out, "Valid until: "); +#if OPENSSL_VERSION_NUMBER < 0x10100000L // < 1.1.0 ASN1_TIME_print(bio_out, X509_get_notAfter(cert)); +#else + ASN1_TIME_print(bio_out, X509_get0_notAfter(cert)); +#endif BIO_printf(bio_out, "\n"); has_san = 0; diff --git a/scripts/merge_config.sh b/scripts/merge_config.sh index dde0c7531..4ad151ce5 100755 --- a/scripts/merge_config.sh +++ b/scripts/merge_config.sh @@ -2,8 +2,12 @@ set -e -# avoid problems with sudo path -SYSREPOCFG=`su -c "which sysrepocfg" $USER` +# avoid problems with sudo PATH +if [ `id -u` -eq 0 ]; then + SYSREPOCFG=`su -c 'which sysrepocfg' -l $USER` +else + SYSREPOCFG=`which sysrepocfg` +fi KS_KEY_NAME=genkey # check that there is no listen/Call Home configuration yet diff --git a/scripts/merge_hostkey.sh b/scripts/merge_hostkey.sh index 87947fa47..a0677ee79 100755 --- a/scripts/merge_hostkey.sh +++ b/scripts/merge_hostkey.sh @@ -2,9 +2,14 @@ set -e -# avoid problems with sudo path -SYSREPOCFG=`su -c "which sysrepocfg" $USER` -OPENSSL=`su -c "which openssl" $USER` +# avoid problems with sudo PATH +if [ `id -u` -eq 0 ]; then + SYSREPOCFG=`su -c 'which sysrepocfg' -l $USER` + OPENSSL=`su -c 'which openssl' -l $USER` +else + SYSREPOCFG=`which sysrepocfg` + OPENSSL=`which openssl` +fi # check that there is no SSH key with this name yet KEYSTORE_KEY=`$SYSREPOCFG -X -x "/ietf-keystore:keystore/asymmetric-keys/asymmetric-key[name='genkey']/name"` diff --git a/scripts/setup.sh b/scripts/setup.sh index 7175bc47a..9591a4982 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -6,9 +6,13 @@ if [ -z "$NP2_MODULE_DIR" -o -z "$NP2_MODULE_PERMS" -o -z "$NP2_MODULE_OWNER" -o exit 1 fi -# avoid problems with sudo path -SYSREPOCTL=`su -c "which sysrepoctl" $USER` -MODDIR=${NP2_MODULE_DIR} +# avoid problems with sudo PATH +if [ `id -u` -eq 0 ]; then + SYSREPOCTL=`su -c 'which sysrepoctl' -l $USER` +else + SYSREPOCTL=`which sysrepoctl` +fi +MODDIR=${DESTDIR}${NP2_MODULE_DIR} PERMS=${NP2_MODULE_PERMS} OWNER=${NP2_MODULE_OWNER} GROUP=${NP2_MODULE_GROUP} @@ -33,7 +37,7 @@ MODULES=( # functions INSTALL_MODULE() { - $SYSREPOCTL -a -i $MODDIR/$1 -s $MODDIR -p $PERMS -o $OWNER -g $GROUP -v2 + "$SYSREPOCTL" -a -i $MODDIR/$1 -s "$MODDIR" -p "$PERMS" -o "$OWNER" -g "$GROUP" -v2 local rc=$? if [ $rc -ne 0 ]; then exit $rc @@ -41,7 +45,7 @@ INSTALL_MODULE() { } UPDATE_MODULE() { - $SYSREPOCTL -a -U $MODDIR/$1 -s $MODDIR -p $PERMS -o $OWNER -g $GROUP -v2 + "$SYSREPOCTL" -a -U $MODDIR/$1 -s "$MODDIR" -p "$PERMS" -o "$OWNER" -g "$GROUP" -v2 local rc=$? if [ $rc -ne 0 ]; then exit $rc @@ -49,7 +53,7 @@ UPDATE_MODULE() { } ENABLE_FEATURE() { - $SYSREPOCTL -a -c $1 -e $2 -v2 + "$SYSREPOCTL" -a -c $1 -e $2 -v2 local rc=$? if [ $rc -ne 0 ]; then exit $rc @@ -74,7 +78,7 @@ for i in "${MODULES[@]}"; do if [ "$sctl_revision" \< "$revision" ]; then # update module without any features file=`echo "$i" | cut -d' ' -f 1` - UPDATE_MODULE $file + UPDATE_MODULE "$file" fi # parse sysrepoctl features and add extra space at the end for easier matching diff --git a/src/main.c b/src/main.c index 5ae8881ac..e3239218a 100644 --- a/src/main.c +++ b/src/main.c @@ -313,6 +313,7 @@ np2srv_err_sr(int err_code, const char *message, const char *xpath) switch (err_code) { case SR_ERR_LOCKED: +err_lock_denied: ptr = strstr(message, "NC SID "); if (!ptr) { EINT; @@ -344,6 +345,12 @@ np2srv_err_sr(int err_code, const char *message, const char *xpath) default: if (strstr(message, "authorization failed")) { goto err_access_denied; + } else if (strstr(message, "is already locked")) { + goto err_lock_denied; + } else if (strstr(message, "Source and target")) { + e = nc_err(NC_ERR_INVALID_VALUE, NC_ERR_TYPE_PROT); + nc_err_set_msg(e, message, "en"); + break; } e = nc_err(NC_ERR_OP_FAILED, NC_ERR_TYPE_APP); nc_err_set_msg(e, message, "en"); @@ -928,7 +935,7 @@ worker_thread(void *arg) int rc, idx = *((int *)arg), monitored; struct nc_session *ncs; - nc_libssh_thread_verbosity(np2_verbose_level); + nc_libssh_thread_verbosity(np2_libssh_verbose_level); while (ATOMIC_LOAD_RELAXED(loop_continue)) { /* try to accept new NETCONF sessions */ @@ -1140,7 +1147,6 @@ main(int argc, char *argv[]) /* set verbose for all, we change to debug later if requested */ np2_verbose_level = NC_VERB_VERBOSE; - nc_verbosity(np2_verbose_level); np2_libssh_verbose_level = 1; ptr = strtok(optarg, ","); @@ -1157,9 +1163,9 @@ main(int argc, char *argv[]) verb |= LY_LDGDIFF; } else if (!strcmp(ptr, "MSG")) { /* NETCONF messages - only lnc2 debug verbosity */ - nc_verbosity(NC_VERB_DEBUG); + np2_verbose_level = NC_VERB_DEBUG; } else if (!strcmp(ptr, "LN2DBG")) { - nc_verbosity(NC_VERB_DEBUG_LOWLVL); + np2_verbose_level = NC_VERB_DEBUG_LOWLVL; } else if (!strcmp(ptr, "SSH")) { /* 2 should be always enough, 3 is too much useless info */ np2_libssh_verbose_level = 2; @@ -1170,7 +1176,8 @@ main(int argc, char *argv[]) return EXIT_FAILURE; } } while ((ptr = strtok(NULL, ","))); - /* set final verbosity of libssh and libyang */ + /* set final verbosity */ + nc_verbosity(np2_verbose_level); nc_libssh_thread_verbosity(np2_libssh_verbose_level); if (verb) { ly_verb(LY_LLDBG); diff --git a/src/netconf.c b/src/netconf.c index a23a08649..29163e501 100755 --- a/src/netconf.c +++ b/src/netconf.c @@ -251,7 +251,7 @@ int np2srv_rpc_copyconfig_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), const struct lyd_node *input, sr_event_t UNUSED(event), uint32_t UNUSED(request_id), struct lyd_node *UNUSED(output), void *UNUSED(private_data)) { - sr_datastore_t ds = SR_DS_OPERATIONAL, sds; + sr_datastore_t ds = SR_DS_OPERATIONAL, sds = SR_DS_OPERATIONAL; struct ly_set *nodeset; const sr_error_info_t *err_info; struct lyd_node *config = NULL; @@ -303,6 +303,12 @@ np2srv_rpc_copyconfig_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), } else { assert(!strcmp(nodeset->set.d[0]->schema->name, "url")); #ifdef NP2SRV_URL_CAPAB + if (trg_url && !strcmp(trg_url, ((struct lyd_node_leaf_list *)nodeset->set.d[0])->value_str)) { + rc = SR_ERR_INVAL_ARG; + sr_set_error(session, NULL, "Source and target URLs are the same."); + goto cleanup; + } + config = op_parse_url(((struct lyd_node_leaf_list *)nodeset->set.d[0])->value_str, LYD_OPT_CONFIG | LYD_OPT_STRICT | LYD_OPT_TRUSTED, &rc, session); if (rc) { @@ -318,6 +324,12 @@ np2srv_rpc_copyconfig_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), } ly_set_free(nodeset); + if (ds == sds) { + rc = SR_ERR_INVAL_ARG; + sr_set_error(session, NULL, "Source and target datastores are the same."); + goto cleanup; + } + /* NACM checks */ if (!config && !run_to_start) { /* get source datastore data and filter them */ @@ -452,6 +464,7 @@ np2srv_rpc_un_lock_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), co { sr_datastore_t ds = 0; struct ly_set *nodeset; + const sr_error_info_t *err_info; int rc = SR_ERR_OK; /* get know which datastore is being affected */ @@ -476,6 +489,8 @@ np2srv_rpc_un_lock_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), co rc = sr_unlock(session, NULL); } if (rc != SR_ERR_OK) { + sr_get_error(session, &err_info); + sr_set_error(session, err_info->err[0].xpath, err_info->err[0].message); goto cleanup; } @@ -709,6 +724,9 @@ np2srv_rpc_subscribe_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), } ly_set_free(nodeset); + /* set ongoing notifications flag */ + nc_session_set_notif_status(ncs, 1); + /* sysrepo API */ if (!strcmp(stream, "NETCONF")) { /* subscribe to all modules with notifications */ @@ -747,9 +765,6 @@ np2srv_rpc_subscribe_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), goto cleanup; } - /* set ongoing notifications flag */ - nc_session_set_notif_status(ncs, 1); - /* success */ cleanup: @@ -758,5 +773,8 @@ np2srv_rpc_subscribe_cb(sr_session_ctx_t *session, const char *UNUSED(op_path), } free(filters); free(xp); + if (ncs && rc) { + nc_session_set_notif_status(ncs, 0); + } return rc; } diff --git a/src/netconf_acm.c b/src/netconf_acm.c index a8868f003..26e575e04 100755 --- a/src/netconf_acm.c +++ b/src/netconf_acm.c @@ -646,7 +646,7 @@ ncac_rule_cb(sr_session_ctx_t *session, const char *UNUSED(module_name), const c str = ((struct lyd_node_leaf_list *)node)->value_str; lydict_remove(ly_ctx, rule->module_name); if (!strcmp(str, "*")) { - rule->module_name = NULL; + rule->module_name = NULL; } else { rule->module_name = lydict_insert(ly_ctx, str, 0); } @@ -1042,29 +1042,37 @@ ncac_allowed_node(const struct lys_node *node, const char *user, uint8_t oper) if (node->nodetype != LYS_RPC) { continue; } + if (rule->target && (rule->target != node->name)) { + /* exact match needed */ + continue; + } break; case NCAC_TARGET_NOTIF: /* only top-level notification */ if (lys_parent(node) || (node->nodetype != LYS_NOTIF)) { continue; } + if (rule->target && (rule->target != node->name)) { + /* exact match needed */ + continue; + } break; case NCAC_TARGET_DATA: if (node->nodetype & (LYS_RPC | LYS_NOTIF)) { continue; } - break; + /* fallthrough */ case NCAC_TARGET_ANY: - break; - } - if (rule->target) { - path = lys_data_path(node); - /* exact match or is a descendant (specified in RFC 8341 page 27) */ - cmp = strncmp(path, rule->target, strlen(rule->target)); - free(path); - if (cmp) { - continue; + if (rule->target) { + path = lys_data_path(node); + /* exact match or is a descendant (specified in RFC 8341 page 27) */ + cmp = strncmp(path, rule->target, strlen(rule->target)); + free(path); + if (cmp) { + continue; + } } + break; } /* access operation matching */