From 91d67e6b008382885e36bfbb6c6a7c6c52ad7c6c Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 28 Mar 2023 16:27:51 +0200 Subject: [PATCH] src/confd: import sysrepo ietf-system plugin by Denis Kalashnikov Signed-off-by: Joachim Wiberg --- src/confd/.gitignore | 33 ++ src/confd/LICENSE | 28 ++ src/confd/Makefile.am | 3 + src/confd/README.md | 15 + src/confd/autogen.sh | 3 + src/confd/configure.ac | 51 ++ src/confd/src/Makefile.am | 7 + src/confd/src/ietf-system.c | 307 ++++++++++++ src/confd/yang/Makefile.am | 2 + src/confd/yang/iana-crypt-hash.yang | 132 +++++ src/confd/yang/ietf-inet-types.yang | 457 +++++++++++++++++ src/confd/yang/ietf-netconf-acm.yang | 439 +++++++++++++++++ src/confd/yang/ietf-system.yang | 711 +++++++++++++++++++++++++++ 13 files changed, 2188 insertions(+) create mode 100644 src/confd/.gitignore create mode 100644 src/confd/LICENSE create mode 100644 src/confd/Makefile.am create mode 100644 src/confd/README.md create mode 100755 src/confd/autogen.sh create mode 100644 src/confd/configure.ac create mode 100644 src/confd/src/Makefile.am create mode 100644 src/confd/src/ietf-system.c create mode 100644 src/confd/yang/Makefile.am create mode 100644 src/confd/yang/iana-crypt-hash.yang create mode 100644 src/confd/yang/ietf-inet-types.yang create mode 100644 src/confd/yang/ietf-netconf-acm.yang create mode 100644 src/confd/yang/ietf-system.yang diff --git a/src/confd/.gitignore b/src/confd/.gitignore new file mode 100644 index 00000000..e9e8e747 --- /dev/null +++ b/src/confd/.gitignore @@ -0,0 +1,33 @@ +*~ +*.o +*.la +*.lo +*.so +.deps +.libs + +/aclocal.m4 +/autom4te.cache/ +/aux +/clixon.xml +/compile +/config.h +/config.h.in +/config.guess +/config.log +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/ltmain.sh +/m4 +/missing + +GPATH +GRTAGS +GTAGS +Makefile +Makefile.in + diff --git a/src/confd/LICENSE b/src/confd/LICENSE new file mode 100644 index 00000000..7e5b6c82 --- /dev/null +++ b/src/confd/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2023 Denis Kalashnikov +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of copyright holders nor the names of + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/src/confd/Makefile.am b/src/confd/Makefile.am new file mode 100644 index 00000000..a949b1fc --- /dev/null +++ b/src/confd/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src yang +DISTCLEANFILES = *~ *.d +ACLOCAL_AMFLAGS = -I m4 diff --git a/src/confd/README.md b/src/confd/README.md new file mode 100644 index 00000000..02951ac8 --- /dev/null +++ b/src/confd/README.md @@ -0,0 +1,15 @@ +Configuration Daemon +==================== + +`confd` is the Infix configuration daemon that serves as the glue +between sysrepo and netopeer2 (NETCONF) and the UNIX system under +it all. + + +Origin & References +------------------- + +Based on the Open Source [dklibc/sysrepo_plugin_ietf_system][0] +project by Denis Kalashnikov. + +[0]: https://github.com/dklibc/sysrepo_plugin_ietf_system diff --git a/src/confd/autogen.sh b/src/confd/autogen.sh new file mode 100755 index 00000000..69ad0e18 --- /dev/null +++ b/src/confd/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +autoreconf -W portability -vifm diff --git a/src/confd/configure.ac b/src/confd/configure.ac new file mode 100644 index 00000000..f67a2723 --- /dev/null +++ b/src/confd/configure.ac @@ -0,0 +1,51 @@ +AC_PREREQ(2.61) +AC_INIT([confd], [1.0.0], + [https://github.com/kernelkit/infix/issues]) +AM_INIT_AUTOMAKE(1.11 foreign subdir-objects) +AM_SILENT_RULES(yes) + +LT_INIT + +AC_CONFIG_FILES([ + Makefile + src/Makefile + yang/Makefile +]) + +AC_PROG_CC +AC_PROG_INSTALL + +# Check for pkg-config first, warn if it's not installed +PKG_PROG_PKG_CONFIG + +PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36]) +PKG_CHECK_MODULES([augeas], [augeas >= 1.12.0]) +PKG_CHECK_MODULES([jansson], [jansson >= 2.0.0]) + +# Plugin installation path for sysrepo-plugind +PKG_CHECK_VAR([SRPD_PLUGINS_PATH], [sysrepo], [plugindir]) + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DATAROOTDIR=`eval echo $datarootdir` +DATAROOTDIR=`eval echo $DATAROOTDIR` +AC_SUBST(DATAROOTDIR) + +LIBDIR=`eval echo $libdir` +LIBDIR=`eval echo $LIBDIR` +AC_SUBST(LIBDIR) + +LOCALSTATEDIR=`eval echo $localstatedir` +LOCALSTATEDIR=`eval echo $LOCALSTATEDIR` +AC_SUBST(LOCALSTATEDIR) + +RUNSTATEDIR=`eval echo $runstatedir` +RUNSTATEDIR=`eval echo $RUNSTATEDIR` +AC_SUBST(RUNSTATEDIR) + +SYSCONFDIR=`eval echo $sysconfdir` +SYSCONFDIR=`eval echo $SYSCONFDIR` +AC_SUBST(SYSCONFDIR) + +AC_OUTPUT diff --git a/src/confd/src/Makefile.am b/src/confd/src/Makefile.am new file mode 100644 index 00000000..7e22675d --- /dev/null +++ b/src/confd/src/Makefile.am @@ -0,0 +1,7 @@ +plugindir = $(sysrepo_plugind_PLUGINDIR) +plugin_LTLIBRARIES = confd-plugin.la + +confd_plugin_la_CFLAGS = $(sysrepo_CFLAGS) $(CFLAGS) +confd_plugin_la_LIBADD = $(sysrepo_LIBS) $(CFLAGS) +confd_plugin_la_LDFLAGS = -module -avoid-version -shared +confd_plugin_la_SOURCES = ietf-system.c diff --git a/src/confd/src/ietf-system.c b/src/confd/src/ietf-system.c new file mode 100644 index 00000000..1a61f8f3 --- /dev/null +++ b/src/confd/src/ietf-system.c @@ -0,0 +1,307 @@ +/* Sysrepo plugin of ietf-system@2014-08-06.yang module */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Linux specific */ +#include + +#include +#include + +#define CLOCK_PATH "/ietf-system:system-state/clock" +#define PLATFORM_PATH "/ietf-system:system-state/platform" + +#define DEBUG(frmt, ...) +//#define DEBUG(frmt, ...) syslog(LOG_DEBUG, "%s: "frmt, __func__, ##__VA_ARGS__) +#define ERROR(frmt, ...) syslog(LOG_ERR, "%s: "frmt, __func__, ##__VA_ARGS__) +#define ERRNO(frmt, ...) syslog(LOG_ERR, "%s: "frmt": ", __func__, ##__VA_ARGS__, strerror(errno)) + +/* Return seconds since boot */ +static long get_uptime(void) +{ + struct sysinfo info; + + /* + * !!!Linux specific!!! Use '/var/run/utmp' BOOT record + * to be portable. But utmp file can be missing in some + * Unixes. + */ + sysinfo(&info); + return info.uptime; +} + +static int get_time_as_str(time_t *time, char *buf, int bufsz) +{ + int n; + + n = strftime(buf, bufsz, "%Y-%m-%dT%H:%M:%S%z", + localtime(time)); + if (!n) + return -1; + + /* Buf ends with +hhmm but should be +hh:mm, fix this */ + memmove(buf + n - 1, buf + n - 2, 3); + buf[n - 2] = ':'; + + return 0; +} + +static int clock_cb(sr_session_ctx_t *session, const char *module, + const char *path, const char *request_path, + unsigned request_id, struct lyd_node **parent, + void *priv) +{ + static char boottime[64]; + char curtime[64]; + time_t t; + char *buf; + const struct ly_ctx *ctx; + + DEBUG("path=%s, request_path=%s", path, request_path); + + ctx = sr_get_context(sr_session_get_connection(session)); + + *parent = lyd_new_path(NULL, ctx, CLOCK_PATH, NULL, 0, 0); + + lyd_print_mem(&buf, *parent, LYD_XML, 0); + DEBUG("%s", buf); + + if (!*boottime) { + t = time(NULL) - get_uptime(); + get_time_as_str(&t, boottime, sizeof(boottime)); + } + + if (!lyd_new_path(*parent, NULL, CLOCK_PATH"/boot-datetime", + boottime, 0, 0)) { + ERROR("lyd_new_path() boot-datetime failed"); + } + + t = time(NULL); + get_time_as_str(&t, curtime, sizeof(curtime)); + if (!lyd_new_path(*parent, NULL, CLOCK_PATH"/current-datetime", + curtime, 0, 0)) { + ERROR("lyd_new_path() current-datetime failed"); + } + + lyd_print_mem(&buf, *parent, LYD_XML, 0); + DEBUG("%s", buf); + + return SR_ERR_OK; +} + +static int platform_cb(sr_session_ctx_t *session, const char *module, + const char *path, const char *request_path, + unsigned request_id, struct lyd_node **parent, + void *priv) +{ + struct utsname data; + char *buf; + const struct ly_ctx *ctx; + + DEBUG("path=%s request_path=%s", path, request_path); + + /* POSIX func */ + uname(&data); + + ctx = sr_get_context(sr_session_get_connection(session)); + + *parent = lyd_new_path(NULL, ctx, PLATFORM_PATH, NULL, 0, 0); + + lyd_print_mem(&buf, *parent, LYD_XML, 0); + DEBUG("%s", buf); + + lyd_new_path(*parent, NULL, PLATFORM_PATH"/os-name", + data.sysname, 0, 0); + lyd_new_path(*parent, NULL, PLATFORM_PATH"/os-release", + data.release, 0, 0); + lyd_new_path(*parent, NULL, PLATFORM_PATH"/os-version", + data.version, 0, 0); + lyd_new_path(*parent, NULL, PLATFORM_PATH"/machine", + data.machine, 0, 0); + + lyd_print_mem(&buf, *parent, LYD_XML, 0); + DEBUG("%s", buf); + + return SR_ERR_OK; +} + +static int exec_rpc_cb(sr_session_ctx_t *session, const char *path, + const sr_val_t *input, const size_t input_cnt, + sr_event_t event, unsigned request_id, + sr_val_t **output, size_t *output_cnt, + void *priv) +{ + DEBUG("path: %s", path); + system(priv); + + return SR_ERR_OK; +} + +/* '/ietf-system:set-current-date-time' */ +static int set_datetime_rpc_cb(sr_session_ctx_t *session, + const char *path, const sr_val_t *input, + const size_t input_cnt, sr_event_t event, + unsigned request_id, sr_val_t **output, + size_t *output_cnt, void *priv) +{ + struct tm tm; + time_t t; + struct timeval tv; + + memset(&tm, 0, sizeof(tm)); + + /* Parse 'current-datetime'. */ + sscanf(input->data.string_val, "%d-%d-%dT%d:%d:%d", &tm.tm_year, + &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, + &tm.tm_sec); + + DEBUG("Setting datetime to '%d-%02d-%02d %02d:%02d:%02d'", + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, + tm.tm_sec); + + tm.tm_year -= 1900; + tm.tm_mon--; + + /* + * We suppose that this is a local time and ignore timezone. + */ + + t = mktime(&tm); + + tv.tv_sec = t; + tv.tv_usec = 0; + if (settimeofday(&tv, NULL)) { + ERRNO("settimeofday() failed"); + return SR_ERR_SYS; + } + + return SR_ERR_OK; +} + +int hostname_change_cb(sr_session_ctx_t *session, const char *module, + const char *xpath, sr_event_t event, + unsigned request_id, void *priv) +{ + int r; + sr_val_t *old_val, *new_val, *val; + sr_change_iter_t *iter; + sr_change_oper_t op; + + if (event != SR_EV_ENABLED && event != SR_EV_DONE) + return SR_ERR_OK; + + r = sr_get_changes_iter(session, "//.", &iter); + if (r != SR_ERR_OK) { + ERROR("failed to get changes iter: %s", sr_strerror(r)); + return r; + } + + while (sr_get_change_next(session, iter, &op, &old_val, + &new_val) == SR_ERR_OK) { + val = new_val ? new_val : old_val; + if (strcmp(val->xpath, "/ietf-system:system/hostname")) + goto free_vals; + + switch (op) { + case SR_OP_CREATED: + case SR_OP_MODIFIED: + if (sethostname(new_val->data.string_val, + strlen(new_val->data.string_val))) { + ERRNO("Failed to set hostname"); + return SR_ERR_SYS; + } + + DEBUG("Set hostname to '%s'", + new_val->data.string_val); + break; + } + +free_vals: + sr_free_val(old_val); + sr_free_val(new_val); + } + + return SR_ERR_OK; +} + +int sr_plugin_init_cb(sr_session_ctx_t *sess, void **priv) +{ + int r; + sr_subscription_ctx_t *sub = NULL; + + openlog("sysrepo ietf-system plugin", LOG_USER, 0); + + r = sr_oper_get_items_subscribe(sess, "ietf-system", + CLOCK_PATH, + clock_cb, NULL, + SR_SUBSCR_CTX_REUSE, &sub); + if (r != SR_ERR_OK) + goto err; + + r = sr_oper_get_items_subscribe(sess, "ietf-system", + PLATFORM_PATH, + platform_cb, NULL, + SR_SUBSCR_CTX_REUSE, &sub); + if (r != SR_ERR_OK) + goto err; + + r = sr_rpc_subscribe(sess, "/ietf-system:system-restart", + exec_rpc_cb, "shutdown -r now", + 0, SR_SUBSCR_CTX_REUSE, &sub); + if (r != SR_ERR_OK) + goto err; + + r = sr_rpc_subscribe(sess, "/ietf-system:system-shutdown", + exec_rpc_cb, "shutdown -h now", + 0, SR_SUBSCR_CTX_REUSE, &sub); + if (r != SR_ERR_OK) + goto err; + + r = sr_rpc_subscribe(sess, "/ietf-system:set-current-datetime", + set_datetime_rpc_cb, NULL, + 0, SR_SUBSCR_CTX_REUSE, &sub); + if (r != SR_ERR_OK) + goto err; + + + r = sr_module_change_subscribe(sess, "ietf-system", + "/ietf-system:system/hostname", + hostname_change_cb, NULL, 0, + SR_SUBSCR_CTX_REUSE | + SR_SUBSCR_ENABLED, &sub); + + if (r != SR_ERR_OK) { + ERROR("failed to subscribe to changes of hostname: %s", + sr_strerror(r)); + goto err; + } + + + *(sr_subscription_ctx_t **)priv = sub; + + DEBUG("init ok"); + + return SR_ERR_OK; + +err: + ERROR("init failed: %s", sr_strerror(r)); + + sr_unsubscribe(sub); + + return r; +} + +void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *priv) +{ + sr_unsubscribe((sr_subscription_ctx_t *)priv); + + DEBUG("cleanup ok"); +} diff --git a/src/confd/yang/Makefile.am b/src/confd/yang/Makefile.am new file mode 100644 index 00000000..a741c5fa --- /dev/null +++ b/src/confd/yang/Makefile.am @@ -0,0 +1,2 @@ +yangdir = $(datarootdir)/yang/modules/confd +yang_DATA = $(wildcard *.yang) diff --git a/src/confd/yang/iana-crypt-hash.yang b/src/confd/yang/iana-crypt-hash.yang new file mode 100644 index 00000000..f7134ccf --- /dev/null +++ b/src/confd/yang/iana-crypt-hash.yang @@ -0,0 +1,132 @@ + + module iana-crypt-hash { + + yang-version 1; + + namespace + "urn:ietf:params:xml:ns:yang:iana-crypt-hash"; + + prefix ianach; + + organization "IANA"; + + contact + " Internet Assigned Numbers Authority + + Postal: ICANN + 4676 Admiralty Way, Suite 330 + Marina del Rey, CA 90292 + + Tel: +1 310 823 9358 + E-Mail: iana&iana.org"; + + description + "This YANG module defines a typedef for storing passwords + using a hash function, and features to indicate which hash + functions are supported by an implementation. + + The latest revision of this YANG module can be obtained from + the IANA web site. + + Requests for new values should be made to IANA via + email (iana&iana.org). + + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + The initial version of this YANG module is part of RFC XXXX; + see the RFC itself for full legal notices."; + + revision "2014-04-04" { + description "Initial revision."; + reference + "RFC XXXX: A YANG Data Model for System Management"; + + } + + + typedef crypt-hash { + type string { + pattern + '$0$.*|$1$[a-zA-Z0-9./]{1,8}$[a-zA-Z0-9./]{22}|$5$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{43}|$6$(rounds=\d+$)?[a-zA-Z0-9./]{1,16}$[a-zA-Z0-9./]{86}'; + } + description + "The crypt-hash type is used to store passwords using + a hash function. The algorithms for applying the hash + function and encoding the result are implemented in + various UNIX systems as the function crypt(3). + + A value of this type matches one of the forms: + + $0$ + $$$ + $$$$ + + The '$0$' prefix signals that the value is clear text. When + such a value is received by the server, a hash value is + calculated, and the string '$$$' or + $$$$ is prepended to the result. This + value is stored in the configuration data store. + + If a value starting with '$$', where is not '0', is + received, the server knows that the value already represents a + hashed value, and stores it as is in the data store. + + When a server needs to verify a password given by a user, it + finds the stored password hash string for that user, extracts + the salt, and calculates the hash with the salt and given + password as input. If the calculated hash value is the same + as the stored value, the password given by the client is + accepted. + + This type defines the following hash functions: + + id | hash function | feature + ---+---------------+------------------- + 1 | MD5 | crypt-hash-md5 + 5 | SHA-256 | crypt-hash-sha-256 + 6 | SHA-512 | crypt-hash-sha-512 + + The server indicates support for the different hash functions + by advertising the corresponding feature."; + reference + "IEEE Std 1003.1-2008 - crypt() function + RFC 1321: The MD5 Message-Digest Algorithm + FIPS.180-3.2008: Secure Hash Standard"; + + } + + feature crypt-hash-md5 { + description + "Indicates that the device supports the MD5 + hash function in 'crypt-hash' values"; + reference + "RFC 1321: The MD5 Message-Digest Algorithm"; + + } + + feature crypt-hash-sha-256 { + description + "Indicates that the device supports the SHA-256 + hash function in 'crypt-hash' values"; + reference + "FIPS.180-3.2008: Secure Hash Standard"; + + } + + feature crypt-hash-sha-512 { + description + "Indicates that the device supports the SHA-512 + hash function in 'crypt-hash' values"; + reference + "FIPS.180-3.2008: Secure Hash Standard"; + + } + } // module iana-crypt-hash diff --git a/src/confd/yang/ietf-inet-types.yang b/src/confd/yang/ietf-inet-types.yang new file mode 100644 index 00000000..2f14270d --- /dev/null +++ b/src/confd/yang/ietf-inet-types.yang @@ -0,0 +1,457 @@ +module ietf-inet-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Kessens + + + WG Chair: Juergen Schoenwaelder + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + + Copyright (c) 2013 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6991; see + the RFC itself for full legal notices."; + + revision 2013-07-15 { + description + "This revision adds the following new data types: + - ip-address-no-zone + - ipv4-address-no-zone + - ipv6-address-no-zone"; + reference + "RFC 6991: Common YANG Data Types"; + } + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of types related to protocol fields ***/ + + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code Point + that may be used for marking packets in a traffic stream. + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The ipv6-flow-label type represents the flow identifier or Flow + Label in an IPv6 packet header that may be used to + discriminate traffic flows. + + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport-layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of types related to autonomous systems ***/ + + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASes. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4001: Textual Conventions for Internet Network Addresses + RFC 6793: BGP Support for Four-Octet Autonomous System (AS) + Number Space"; + } + + /*** collection of types related to IP addresses and hostnames ***/ + + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representation + implies the IP version. This type supports scoped addresses + by allowing zone identifiers in the address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format for the zone index is the numerical + format"; + } + + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format of IPv6 addresses uses the textual + representation defined in Section 4 of RFC 5952. The + canonical format for the zone index is the numerical + format as described in Section 11.2 of RFC 4007."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-address-no-zone { + type union { + type inet:ipv4-address-no-zone; + type inet:ipv6-address-no-zone; + } + description + "The ip-address-no-zone type represents an IP address and is + IP version neutral. The format of the textual representation + implies the IP version. This type does not support scoped + addresses since it does not allow zone identifiers in the + address format."; + reference + "RFC 4007: IPv6 Scoped Address Architecture"; + } + + typedef ipv4-address-no-zone { + type inet:ipv4-address { + pattern '[0-9\.]*'; + } + description + "An IPv4 address without a zone index. This type, derived from + ipv4-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + } + + typedef ipv6-address-no-zone { + type inet:ipv6-address { + pattern '[0-9a-fA-F:\.]*'; + } + description + "An IPv6 address without a zone index. This type, derived from + ipv6-address, may be used in situations where the zone is + known from the context and hence no zone index is needed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 128. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, the IPv6 address is represented + as defined in Section 4 of RFC 5952."; + reference + "RFC 5952: A Recommendation for IPv6 Address Text + Representation"; + } + + /*** collection of domain name and URI types ***/ + + typedef domain-name { + type string { + length "1..253"; + pattern + '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitly or may depend on the configuration of the + resolver. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be A-labels as per RFC 5890."; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 5890: Internationalized Domain Names in Applications + (IDNA): Definitions and Document Framework"; + } + + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } + +} diff --git a/src/confd/yang/ietf-netconf-acm.yang b/src/confd/yang/ietf-netconf-acm.yang new file mode 100644 index 00000000..8347cc05 --- /dev/null +++ b/src/confd/yang/ietf-netconf-acm.yang @@ -0,0 +1,439 @@ + module ietf-netconf-acm { + + yang-version 1; + + namespace + "urn:ietf:params:xml:ns:yang:ietf-netconf-acm"; + + prefix nacm; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETCONF (Network Configuration) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: Mehmet Ersue + + + WG Chair: Bert Wijnen + + + Editor: Andy Bierman + + + Editor: Martin Bjorklund + "; + + description + "NETCONF Access Control Model. + + Copyright (c) 2012 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD + License set forth in Section 4.c of the IETF Trust's + Legal Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6536; see + the RFC itself for full legal notices."; + + revision "2012-02-22" { + description + "Initial version; + Errata ID: 3862 and 3863"; + reference + "RFC 6536: Network Configuration Protocol (NETCONF) + Access Control Model"; + + } + + + extension default-deny-write { + description + "Used to indicate that the data model node + represents a sensitive security system parameter. + + If present, and the NACM module is enabled (i.e., + /nacm/enable-nacm object equals 'true'), the NETCONF server + will only allow the designated 'recovery session' to have + write access to the node. An explicit access control rule is + required for all other users. + + The 'default-deny-write' extension MAY appear within a data + definition statement. It is ignored otherwise."; + } + + extension default-deny-all { + description + "Used to indicate that the data model node + controls a very sensitive security system parameter. + + If present, and the NACM module is enabled (i.e., + /nacm/enable-nacm object equals 'true'), the NETCONF server + will only allow the designated 'recovery session' to have + read, write, or execute access to the node. An explicit + access control rule is required for all other users. + + The 'default-deny-all' extension MAY appear within a data + definition statement, 'rpc' statement, or 'notification' + statement. It is ignored otherwise."; + } + + typedef user-name-type { + type string { + length "1..max"; + } + description + "General Purpose Username string."; + } + + typedef matchall-string-type { + type string { + pattern '\*'; + } + description + "The string containing a single asterisk '*' is used + to conceptually represent all possible values + for the particular leaf using this data type."; + } + + typedef access-operations-type { + type bits { + bit create { + position 0; + description + "Any protocol operation that creates a + new data node."; + } + bit read { + position 1; + description + "Any protocol operation or notification that + returns the value of a data node."; + } + bit update { + position 2; + description + "Any protocol operation that alters an existing + data node."; + } + bit delete { + position 3; + description + "Any protocol operation that removes a data node."; + } + bit exec { + position 4; + description + "Execution access to the specified protocol operation."; + } + } + description + "NETCONF Access Operation."; + } + + typedef group-name-type { + type string { + length "1..max"; + pattern '[^\*].*'; + } + description + "Name of administrative group to which + users can be assigned."; + } + + typedef action-type { + type enumeration { + enum "permit" { + value 0; + description + "Requested action is permitted."; + } + enum "deny" { + value 1; + description + "Requested action is denied."; + } + } + description + "Action taken by the server when a particular + rule matches."; + } + + typedef node-instance-identifier { + type yang:xpath1.0; + description + "Path expression used to represent a special + data node instance identifier string. + + A node-instance-identifier value is an + unrestricted YANG instance-identifier expression. + All the same rules as an instance-identifier apply + except predicates for keys are optional. If a key + predicate is missing, then the node-instance-identifier + represents all possible server instances for that key. + + This XPath expression is evaluated in the following context: + + o The set of namespace declarations are those in scope on + the leaf element where this type is used. + + o The set of variable bindings contains one variable, + 'USER', which contains the name of the user of the current + session. + + o The function library is the core function library, but + note that due to the syntax restrictions of an + instance-identifier, no functions are allowed. + + o The context node is the root node in the data tree."; + } + + container nacm { + nacm:default-deny-all; + description + "Parameters for NETCONF Access Control Model."; + leaf enable-nacm { + type boolean; + default 'true'; + description + "Enables or disables all NETCONF access control + enforcement. If 'true', then enforcement + is enabled. If 'false', then enforcement + is disabled."; + } + + leaf read-default { + type action-type; + default "permit"; + description + "Controls whether read access is granted if + no appropriate rule is found for a + particular read request."; + } + + leaf write-default { + type action-type; + default "deny"; + description + "Controls whether create, update, or delete access + is granted if no appropriate rule is found for a + particular write request."; + } + + leaf exec-default { + type action-type; + default "permit"; + description + "Controls whether exec access is granted if no appropriate + rule is found for a particular protocol operation request."; + } + + leaf enable-external-groups { + type boolean; + default 'true'; + description + "Controls whether the server uses the groups reported by the + NETCONF transport layer when it assigns the user to a set of + NACM groups. If this leaf has the value 'false', any group + names reported by the transport layer are ignored by the + server."; + } + + leaf denied-operations { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request was denied."; + } + + leaf denied-data-writes { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that a + protocol operation request to alter + a configuration datastore was denied."; + } + + leaf denied-notifications { + type yang:zero-based-counter32; + config false; + mandatory true; + description + "Number of times since the server last restarted that + a notification was dropped for a subscription because + access to the event type was denied."; + } + + container groups { + description + "NETCONF Access Control Groups."; + list group { + key "name"; + description + "One NACM Group Entry. This list will only contain + configured entries, not any entries learned from + any transport protocols."; + leaf name { + type group-name-type; + description + "Group name associated with this entry."; + } + + leaf-list user-name { + type user-name-type; + description + "Each entry identifies the username of + a member of the group associated with + this entry."; + } + } // list group + } // container groups + + list rule-list { + key "name"; + ordered-by user; + description + "An ordered collection of access control rules."; + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule-list."; + } + + leaf-list group { + type union { + type matchall-string-type; + type group-name-type; + } + description + "List of administrative groups that will be + assigned the associated access rights + defined by the 'rule' list. + + The string '*' indicates that all groups apply to the + entry."; + } + + list rule { + key "name"; + ordered-by user; + description + "One access control rule. + + Rules are processed in user-defined order until a match is + found. A rule matches if 'module-name', 'rule-type', and + 'access-operations' match the request. If a rule + matches, the 'action' leaf determines if access is granted + or not."; + leaf name { + type string { + length "1..max"; + } + description + "Arbitrary name assigned to the rule."; + } + + leaf module-name { + type union { + type matchall-string-type; + type string; + } + default "*"; + description + "Name of the module associated with this rule. + + This leaf matches if it has the value '*' or if the + object being accessed is defined in the module with the + specified module name."; + } + + choice rule-type { + description + "This choice matches if all leafs present in the rule + match the request. If no leafs are present, the + choice matches all requests."; + leaf rpc-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if + its value equals the requested protocol operation + name."; + } + leaf notification-name { + type union { + type matchall-string-type; + type string; + } + description + "This leaf matches if it has the value '*' or if its + value equals the requested notification name."; + } + leaf path { + type node-instance-identifier; + mandatory true; + description + "Data Node Instance Identifier associated with the + data node controlled by this rule. + + Configuration data or state data instance + identifiers start with a top-level data node. A + complete instance identifier is required for this + type of path value. + + The special value '/' refers to all possible + datastore contents."; + } + } // choice rule-type + + leaf access-operations { + type union { + type matchall-string-type; + type access-operations-type; + } + default "*"; + description + "Access operations associated with this rule. + + This leaf matches if it has the value '*' or if the + bit corresponding to the requested operation is set."; + } + + leaf action { + type action-type; + mandatory true; + description + "The access control action associated with the + rule. If a rule is determined to match a + particular request, then this object is used + to determine whether to permit or deny the + request."; + } + + leaf comment { + type string; + description + "A textual description of the access rule."; + } + } // list rule + } // list rule-list + } // container nacm + } // module ietf-netconf-acm diff --git a/src/confd/yang/ietf-system.yang b/src/confd/yang/ietf-system.yang new file mode 100644 index 00000000..a8d9e089 --- /dev/null +++ b/src/confd/yang/ietf-system.yang @@ -0,0 +1,711 @@ +module ietf-system { + namespace "urn:ietf:params:xml:ns:yang:ietf-system"; + prefix "sys"; + import ietf-yang-types { + prefix yang; + } + import ietf-inet-types { + prefix inet; + } + import ietf-netconf-acm { + prefix nacm; + } + import iana-crypt-hash { + prefix ianach; + } + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + contact + "WG Web: + WG List: + WG Chair: Thomas Nadeau + + WG Chair: Juergen Schoenwaelder + + Editor: Andy Bierman + + Editor: Martin Bjorklund + "; + description + "This module contains a collection of YANG definitions for the + configuration and identification of some common system + properties within a device containing a NETCONF server. This + includes data node definitions for system identification, + time-of-day management, user management, DNS resolver + configuration, and some protocol operations for system + management. + Copyright (c) 2014 IETF Trust and the persons identified as + authors of the code. All rights reserved. + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + This version of this YANG module is part of RFC 7317; see + the RFC itself for full legal notices."; + revision 2014-08-06 { + description + "Initial revision."; + reference + "RFC 7317: A YANG Data Model for System Management"; + } + /* + * Typedefs + */ + typedef timezone-name { + type string; + description + "A time zone name as used by the Time Zone Database, + sometimes referred to as the 'Olson Database'. + The exact set of valid values is an implementation-specific + matter. Client discovery of the exact set of time zone names + for a particular server is out of scope."; + reference + "RFC 6557: Procedures for Maintaining the Time Zone Database"; + } + /* + * Features + */ + feature radius { + description + "Indicates that the device can be configured as a RADIUS + client."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + feature authentication { + description + "Indicates that the device supports configuration of + user authentication."; + } + feature local-users { + if-feature authentication; + description + "Indicates that the device supports configuration of + local user authentication."; + } + feature radius-authentication { + if-feature radius; + if-feature authentication; + description + "Indicates that the device supports configuration of user + authentication over RADIUS."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS) + RFC 5607: Remote Authentication Dial-In User Service (RADIUS) + Authorization for Network Access Server (NAS) + Management"; + } + feature ntp { + description + "Indicates that the device can be configured to use one or + more NTP servers to set the system date and time."; + } + feature ntp-udp-port { + if-feature ntp; + description + "Indicates that the device supports the configuration of + the UDP port for NTP servers. + This is a 'feature', since many implementations do not support + any port other than the default port."; + } + feature timezone-name { + description + "Indicates that the local time zone on the device + can be configured to use the TZ database + to set the time zone and manage daylight saving time."; + reference + "RFC 6557: Procedures for Maintaining the Time Zone Database"; + } + feature dns-udp-tcp-port { + description + "Indicates that the device supports the configuration of + the UDP and TCP port for DNS servers. + This is a 'feature', since many implementations do not support + any port other than the default port."; + } + /* + * Identities + */ + identity authentication-method { + description + "Base identity for user authentication methods."; + } + identity radius { + base authentication-method; + description + "Indicates user authentication using RADIUS."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS) + RFC 5607: Remote Authentication Dial-In User Service (RADIUS) + Authorization for Network Access Server (NAS) + Management"; + } + identity local-users { + base authentication-method; + description + "Indicates password-based authentication of locally + configured users."; + } + identity radius-authentication-type { + description + "Base identity for RADIUS authentication types."; + } + identity radius-pap { + base radius-authentication-type; + description + "The device requests Password Authentication Protocol (PAP) + authentication from the RADIUS server."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + identity radius-chap { + base radius-authentication-type; + description + "The device requests Challenge Handshake Authentication + Protocol (CHAP) authentication from the RADIUS server."; + reference + "RFC 2865: Remote Authentication Dial In User Service (RADIUS)"; + } + /* + * Configuration data nodes + */ + container system { + description + "System group configuration."; + leaf contact { + type string; + description + "The administrator contact information for the system. + A server implementation MAY map this leaf to the sysContact + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and sysContact. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 3418: Management Information Base (MIB) for the + Simple Network Management Protocol (SNMP) + SNMPv2-MIB.sysContact"; + } + leaf hostname { + type inet:domain-name; + description + "The name of the host. This name can be a single domain + label or the fully qualified domain name of the host."; + } + leaf location { + type string; + description + "The system location. + A server implementation MAY map this leaf to the sysLocation + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and sysLocation. The definition + of such a mechanism is outside the scope of this document."; + reference + "RFC 3418: Management Information Base (MIB) for the + Simple Network Management Protocol (SNMP) + SNMPv2-MIB.sysLocation"; + } + container clock { + description + "Configuration of the system date and time properties."; + choice timezone { + description + "The system time zone information."; + case timezone-name { + if-feature timezone-name; + leaf timezone-name { + type timezone-name; + description + "The TZ database name to use for the system, such + as 'Europe/Stockholm'."; + } + } + case timezone-utc-offset { + leaf timezone-utc-offset { + type int16 { + range "-1500 .. 1500"; + } + units "minutes"; + description + "The number of minutes to add to UTC time to + identify the time zone for this system. For example, + 'UTC - 8:00 hours' would be represented as '-480'. + Note that automatic daylight saving time adjustment + is not provided if this object is used."; + } + } + } + } + container ntp { + if-feature ntp; + presence + "Enables the NTP client unless the 'enabled' leaf + (which defaults to 'true') is set to 'false'"; + description + "Configuration of the NTP client."; + leaf enabled { + type boolean; + default true; + description + "Indicates that the system should attempt to + synchronize the system clock with an NTP server + from the 'ntp/server' list."; + } + list server { + key name; + description + "List of NTP servers to use for system clock + synchronization. If '/system/ntp/enabled' + is 'true', then the system will attempt to + contact and utilize the specified NTP servers."; + leaf name { + type string; + description + "An arbitrary name for the NTP server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + case udp { + container udp { + description + "Contains UDP-specific configuration parameters + for NTP."; + leaf address { + type inet:host; + mandatory true; + description + "The address of the NTP server."; + } + leaf port { + if-feature ntp-udp-port; + type inet:port-number; + default 123; + description + "The port number of the NTP server."; + } + } + } + } + leaf association-type { + type enumeration { + enum server { + description + "Use client association mode. This device + will not provide synchronization to the + configured NTP server."; + } + enum peer { + description + "Use symmetric active association mode. + This device may provide synchronization + to the configured NTP server."; + } + enum pool { + description + "Use client association mode with one or + more of the NTP servers found by DNS + resolution of the domain name given by + the 'address' leaf. This device will not + provide synchronization to the servers."; + } + } + default server; + description + "The desired association type for this NTP server."; + } + leaf iburst { + type boolean; + default false; + description + "Indicates whether this server should enable burst + synchronization or not."; + } + leaf prefer { + type boolean; + default false; + description + "Indicates whether this server should be preferred + or not."; + } + } + } + container dns-resolver { + description + "Configuration of the DNS resolver."; + leaf-list search { + type inet:domain-name; + ordered-by user; + description + "An ordered list of domains to search when resolving + a host name."; + } + list server { + key name; + ordered-by user; + description + "List of the DNS servers that the resolver should query. + When the resolver is invoked by a calling application, it + sends the query to the first name server in this list. If + no response has been received within 'timeout' seconds, + the resolver continues with the next server in the list. + If no response is received from any server, the resolver + continues with the first server again. When the resolver + has traversed the list 'attempts' times without receiving + any response, it gives up and returns an error to the + calling application. + Implementations MAY limit the number of entries in this + list."; + leaf name { + type string; + description + "An arbitrary name for the DNS server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + case udp-and-tcp { + container udp-and-tcp { + description + "Contains UDP- and TCP-specific configuration + parameters for DNS."; + reference + "RFC 1035: Domain Names - Implementation and + Specification + RFC 5966: DNS Transport over TCP - Implementation + Requirements"; + leaf address { + type inet:ip-address; + mandatory true; + description + "The address of the DNS server."; + } + leaf port { + if-feature dns-udp-tcp-port; + type inet:port-number; + default 53; + description + "The UDP and TCP port number of the DNS server."; + } + } + } + } + } + container options { + description + "Resolver options. The set of available options has been + limited to those that are generally available across + different resolver implementations and generally useful."; + leaf timeout { + type uint8 { + range "1..max"; + } + units "seconds"; + default "5"; + description + "The amount of time the resolver will wait for a + response from each remote name server before + retrying the query via a different name server."; + } + leaf attempts { + type uint8 { + range "1..max"; + } + default "2"; + description + "The number of times the resolver will send a query to + all of its name servers before giving up and returning + an error to the calling application."; + } + } + } + container radius { + if-feature radius; + description + "Configuration of the RADIUS client."; + list server { + key name; + ordered-by user; + description + "List of RADIUS servers used by the device. + When the RADIUS client is invoked by a calling + application, it sends the query to the first server in + this list. If no response has been received within + 'timeout' seconds, the client continues with the next + server in the list. If no response is received from any + server, the client continues with the first server again. + When the client has traversed the list 'attempts' times + without receiving any response, it gives up and returns an + error to the calling application."; + leaf name { + type string; + description + "An arbitrary name for the RADIUS server."; + } + choice transport { + mandatory true; + description + "The transport-protocol-specific parameters for this + server."; + case udp { + container udp { + description + "Contains UDP-specific configuration parameters + for RADIUS."; + leaf address { + type inet:host; + mandatory true; + description + "The address of the RADIUS server."; + } + leaf authentication-port { + type inet:port-number; + default "1812"; + description + "The port number of the RADIUS server."; + } + leaf shared-secret { + type string; + mandatory true; + nacm:default-deny-all; + description + "The shared secret, which is known to both the + RADIUS client and server."; + reference + "RFC 2865: Remote Authentication Dial In User + Service (RADIUS)"; + } + } + } + } + leaf authentication-type { + type identityref { + base radius-authentication-type; + } + default radius-pap; + description + "The authentication type requested from the RADIUS + server."; + } + } + container options { + description + "RADIUS client options."; + leaf timeout { + type uint8 { + range "1..max"; + } + units "seconds"; + default "5"; + description + "The number of seconds the device will wait for a + response from each RADIUS server before trying with a + different server."; + } + leaf attempts { + type uint8 { + range "1..max"; + } + default "2"; + description + "The number of times the device will send a query to + all of its RADIUS servers before giving up."; + } + } + } + container authentication { + nacm:default-deny-write; + if-feature authentication; + description + "The authentication configuration subtree."; + leaf-list user-authentication-order { + type identityref { + base authentication-method; + } + must '(. != "sys:radius" or ../../radius/server)' { + error-message + "When 'radius' is used, a RADIUS server" + + " must be configured."; + description + "When 'radius' is used as an authentication method, + a RADIUS server must be configured."; + } + ordered-by user; + description + "When the device authenticates a user with a password, + it tries the authentication methods in this leaf-list in + order. If authentication with one method fails, the next + method is used. If no method succeeds, the user is + denied access. + An empty user-authentication-order leaf-list still allows + authentication of users using mechanisms that do not + involve a password. + If the 'radius-authentication' feature is advertised by + the NETCONF server, the 'radius' identity can be added to + this list. + If the 'local-users' feature is advertised by the + NETCONF server, the 'local-users' identity can be + added to this list."; + } + list user { + if-feature local-users; + key name; + description + "The list of local users configured on this device."; + leaf name { + type string; + description + "The user name string identifying this entry."; + } + leaf password { + type ianach:crypt-hash; + description + "The password for this entry."; + } + list authorized-key { + key name; + description + "A list of public SSH keys for this user. These keys + are allowed for SSH authentication, as described in + RFC 4253."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + leaf name { + type string; + description + "An arbitrary name for the SSH key."; + } + leaf algorithm { + type string; + mandatory true; + description + "The public key algorithm name for this SSH key. + Valid values are the values in the IANA 'Secure Shell + (SSH) Protocol Parameters' registry, Public Key + Algorithm Names."; + reference + "IANA 'Secure Shell (SSH) Protocol Parameters' + registry, Public Key Algorithm Names"; + } + leaf key-data { + type binary; + mandatory true; + description + "The binary public key data for this SSH key, as + specified by RFC 4253, Section 6.6, i.e.: + string certificate or public key format + identifier + byte[n] key/certificate data."; + reference + "RFC 4253: The Secure Shell (SSH) Transport Layer + Protocol"; + } + } + } + } + } + /* + * Operational state data nodes + */ + container system-state { + config false; + description + "System group operational state."; + container platform { + description + "Contains vendor-specific information for + identifying the system platform and operating system."; + reference + "IEEE Std 1003.1-2008 - sys/utsname.h"; + leaf os-name { + type string; + description + "The name of the operating system in use - + for example, 'Linux'."; + reference + "IEEE Std 1003.1-2008 - utsname.sysname"; + } + leaf os-release { + type string; + description + "The current release level of the operating + system in use. This string MAY indicate + the OS source code revision."; + reference + "IEEE Std 1003.1-2008 - utsname.release"; + } + leaf os-version { + type string; + description + "The current version level of the operating + system in use. This string MAY indicate + the specific OS build date and target variant + information."; + reference + "IEEE Std 1003.1-2008 - utsname.version"; + } + leaf machine { + type string; + description + "A vendor-specific identifier string representing + the hardware in use."; + reference + "IEEE Std 1003.1-2008 - utsname.machine"; + } + } + container clock { + description + "Monitoring of the system date and time properties."; + leaf current-datetime { + type yang:date-and-time; + description + "The current system date and time."; + } + leaf boot-datetime { + type yang:date-and-time; + description + "The system date and time when the system last restarted."; + } + } + } + rpc set-current-datetime { + nacm:default-deny-all; + description + "Set the /system-state/clock/current-datetime leaf + to the specified value. + If the system is using NTP (i.e., /system/ntp/enabled + is set to 'true'), then this operation will fail with + error-tag 'operation-failed' and error-app-tag value of + 'ntp-active'."; + input { + leaf current-datetime { + type yang:date-and-time; + mandatory true; + description + "The current system date and time."; + } + } + } + rpc system-restart { + nacm:default-deny-all; + description + "Request that the entire system be restarted immediately. + A server SHOULD send an rpc reply to the client before + restarting the system."; + } + rpc system-shutdown { + nacm:default-deny-all; + description + "Request that the entire system be shut down immediately. + A server SHOULD send an rpc reply to the client before + shutting down the system."; + } +}