diff --git a/CMakeLists.txt b/CMakeLists.txt index a7e02ce7..7c10434f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ set(LIBYANG_DEP_SOVERSION 2.37.1) set(LIBYANG_DEP_SOVERSION_MAJOR 2) # libnetconf2 required version -set(LIBNETCONF2_DEP_VERSION 3.0.0) +set(LIBNETCONF2_DEP_VERSION 3.0.2) set(LIBNETCONF2_DEP_SOVERSION 4.0.0) set(LIBNETCONF2_DEP_SOVERSION_MAJOR 4) diff --git a/src/common.c b/src/common.c index 6e1ba156..ddf01e73 100644 --- a/src/common.c +++ b/src/common.c @@ -49,7 +49,7 @@ #include "log.h" #include "netconf_monitoring.h" -struct np2srv np2srv = {0}; +struct np2srv np2srv = {.unix_mode = -1, .unix_uid = -1, .unix_gid = -1}; int np_ignore_rpc(sr_session_ctx_t *ev_sess, sr_event_t event, int *rc) diff --git a/src/common.h b/src/common.h index 62287826..8df46d5f 100644 --- a/src/common.h +++ b/src/common.h @@ -69,6 +69,11 @@ struct np2srv { sr_subscription_ctx_t *sr_nacm_stats_sub; /**< sysrepo NACM global stats subscription context */ sr_subscription_ctx_t *sr_notif_sub; /**< sysrepo notification subscription context */ + const char *unix_path; /**< path to the UNIX socket to listen on */ + mode_t unix_mode; /**< UNIX socket mode */ + uid_t unix_uid; /**< UNIX socket UID */ + gid_t unix_gid; /**< UNIX socket GID */ + uint32_t sr_timeout; /**< timeout in ms for all sysrepo functions */ const char *ext_data_path; /**< path to the data file with data for LY ext data callback */ diff --git a/src/main.c b/src/main.c index e8dcf732..a615b88d 100644 --- a/src/main.c +++ b/src/main.c @@ -615,6 +615,14 @@ server_init(void) /* set libnetconf2 global PRC callback */ nc_set_global_rpc_clb(np2srv_rpc_cb); + /* UNIX socket */ + if (np2srv.unix_path) { + if (nc_server_add_endpt_unix_socket_listen("unix", np2srv.unix_path, np2srv.unix_mode, + np2srv.unix_uid, np2srv.unix_gid)) { + goto error; + } + } + /* restore a previous confirmed commit if restore file exists */ ncc_try_restore(); @@ -1061,6 +1069,8 @@ main(int argc, char *argv[]) int daemonize = 1, verb = 0; const char *pidfile = NP2SRV_PID_FILE_PATH; char *ptr; + struct passwd *pwd; + struct group *grp; struct sigaction action; sigset_t block_mask; @@ -1087,7 +1097,7 @@ main(int argc, char *argv[]) np2srv.server_dir = SERVER_DIR; /* process command line options */ - while ((c = getopt(argc, argv, "dFhVp:f:t:x:v:c:")) != -1) { + while ((c = getopt(argc, argv, "dFhVp:f:U::m:u:g:t:x:v:c:")) != -1) { switch (c) { case 'd': daemonize = 0; @@ -1138,6 +1148,43 @@ main(int argc, char *argv[]) case 'f': np2srv.server_dir = optarg; break; + case 'U': + /* optional argument */ + if (!optarg && (optind < argc) && (argv[optind][0] != '-')) { + /* assume the parameter is the optional argument */ + optarg = argv[optind++]; + } + np2srv.unix_path = optarg ? optarg : NP2SRV_UNIX_SOCK_PATH; + break; + case 'm': + np2srv.unix_mode = strtoul(optarg, &ptr, 8); + if (*ptr || (np2srv.unix_mode > 0777)) { + ERR("Invalid UNIX socket mode \"%s\".", optarg); + return EXIT_FAILURE; + } + break; + case 'u': + np2srv.unix_uid = strtoul(optarg, &ptr, 10); + if (*ptr) { + pwd = getpwnam(optarg); + if (!pwd) { + ERR("Invalid UNIX socket UID/user \"%s\".", optarg); + return EXIT_FAILURE; + } + np2srv.unix_uid = pwd->pw_uid; + } + break; + case 'g': + np2srv.unix_gid = strtoul(optarg, &ptr, 10); + if (*ptr) { + grp = getgrnam(optarg); + if (!grp) { + ERR("Invalid UNIX socket GID/group \"%s\".", optarg); + return EXIT_FAILURE; + } + np2srv.unix_gid = grp->gr_gid; + } + break; case 't': np2srv.sr_timeout = strtoul(optarg, &ptr, 10); if (*ptr) { diff --git a/tests/np_test.c b/tests/np_test.c index c320b012..dc46326e 100644 --- a/tests/np_test.c +++ b/tests/np_test.c @@ -232,7 +232,8 @@ np_glob_setup_np2(void **state, const char *test_name, const char **modules) close(fd); /* exec the server */ - execl(NP_BINARY_DIR "/netopeer2-server", NP_BINARY_DIR "/netopeer2-server", "-d", "-v3", "-t10", "-p", pidfile_path, "-f", server_dir, "-x", extdata_path, NULL); + execl(NP_BINARY_DIR "/netopeer2-server", NP_BINARY_DIR "/netopeer2-server", "-d", "-v3", "-t10", "-p", pidfile_path, + "-U", sock_path, "-m 600", "-f", server_dir, "-x", extdata_path, NULL); child_error: printf("Child execution failed\n"); @@ -283,22 +284,6 @@ np_glob_setup_np2(void **state, const char *test_name, const char **modules) return 1; } - /* prepare UNIX socket data for server configuration in the data store */ - if (sr_set_item_str(st->sr_sess, "/ietf-netconf-server:netconf-server/listen/endpoint[name='unix']/libnetconf2-netconf-server:unix-socket/path", sock_path, NULL, 0) != SR_ERR_OK) { - SETUP_FAIL_LOG; - return 1; - } - if (sr_set_item_str(st->sr_sess, "/ietf-netconf-server:netconf-server/listen/endpoint[name='unix']/libnetconf2-netconf-server:unix-socket/mode", "600", NULL, 0) != SR_ERR_OK) { - SETUP_FAIL_LOG; - return 1; - } - - /* apply the configuration */ - if (sr_apply_changes(st->sr_sess, 0)) { - SETUP_FAIL_LOG; - return 1; - } - /* acquire context */ if (!(st->ctx = sr_acquire_context(st->conn))) { SETUP_FAIL_LOG;