module ietf-nacm {
namespace "urn:ietf:params:xml:ns:yang:ietf-nacm";
prefix "nacm";
import ietf-yang-types {
prefix yang;
}
import ietf-inet-types {
prefix inet;
}
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 Server Access Control Model.
Copyright (c) 2010 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 XXX; see
the RFC itself for full legal notices.";
// RFC Ed.: replace XXXX with actual RFC number and remove this note
//reference "RFC XXXX";
// RFC Ed.: remove this note
// Note: extracted from draft-ietf-netconf-access-control-01.txt
// RFC Ed.: please update the date to the date of publication
revision "2010-10-25" {
description
"Initial version";
reference
"RFC XXXX: Network Configuration Protocol Access Control Model";
}
/*
* Extension statements
*/
extension secure {
description
"Used to indicate that the data model node
represents a sensitive security system parameter.
If present, the NETCONF server will only allow
the designated 'superuser' to have write or execute
default nacm-rights-type for the node. An explicit access
control rule is required for all other users.
The 'secure' extension may appear within a data, rpc,
or notification node definition. It is ignored
otherwise.";
}
extension very-secure {
description
"Used to indicate that the data model node
controls a very sensitive security system parameter.
If present, the NETCONF server will only allow
the designated 'superuser' to have read, write, or execute
default nacm-rights-type for the node. An explicit access
control rule is required for all other users.
The 'very-secure' extension may appear within a data, rpc,
or notification node definition. It is ignored
otherwise.";
}
/*
* Features
*/
feature authentication {
description
"Indicates that the NETCONF server can be configured
to do authentication of users.";
}
feature radius {
if-feature authentication;
description
"Indicates that the NETCONF server can be
configured to act as a NAS and authenticate users
with 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 local-users {
if-feature authentication;
description
"Indicates that the NETCONF server supports
local user authentication.";
}
/*
* Identities
*/
identity authentication-method {
description
"Base identity for NETCONF authentication methods.";
}
identity radius {
base authentication-method;
description
"Indicates NETCONF 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 NETCONF authentication using locally
configured users.";
}
/*
* Derived types
*/
typedef nacm-user-name-type {
type string {
length "1..max";
}
description
"General Purpose User Name string.";
}
typedef nacm-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 nacm-rights-type {
type union {
type nacm-matchall-string-type;
type bits {
bit create {
description
"Create access allowed to all specified data.
Any protocol operation that creates a
new instance of the specified data is a create
operation.";
}
bit read {
description
"Read access allowed to all specified data.
Any protocol operation or notification that
returns data to an application is a read
operation.";
}
bit update {
description
"Update access allowed to all specified data.
Any protocol operation that alters an existing
data node is an update operation.";
}
bit delete {
description
"Delete access allowed to all specified data.
Any protocol operation that removes a database
node instance is a delete operation.";
}
bit exec {
description
"Execution access to the specified RPC operation.
Any RPC operation invocation is an exec operation.";
}
}
}
description
"NETCONF Access Rights.
The string '*' indicates that all possible access
rights apply to the access rule. Otherwise, only
the specific access rights represented by the bit names
that are present apply to the access rule.";
}
typedef nacm-group-name-type {
type string {
length "1..max";
pattern "[^\*].*";
}
description
"Name of administrative group that can be
assigned to the user, and specified in
an access control rule.";
}
typedef nacm-action-type {
type enumeration {
enum permit {
description
"Requested action is permitted.";
}
enum deny {
description
"Requested action is denied.";
}
}
description
"Action taken by the server when a particular
rule matches.";
}
typedef schema-instance-identifier {
type yang:xpath1.0;
description
"Path expression used to represent a special
schema-instance identifier string.
A schema-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 schema-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 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.";
}
typedef md5-crypt {
type string {
pattern "$0$.* | $1$[a-zA-Z0-9./]{2,8}$.*";
}
description
"The md5-crypt type is used to store a password hash based on the
MD5 message digest algorithm. When a clear text value is set to
a leaf of this type, the server calculates a MD5 password hash,
and stores the result in the datastore. Thus, the password is
never stored in clear text.
When a leaf of this type is read, the stored password hash is
returned.
A value of this type matches one of the forms:
$0$
$1$$
The '$0$' prefix signals that the value is clear text. When
such a value is received by the server, an MD5 digest is
calculated, and the string '$1$$' is prepended to the
result, where is a random 2-8 characters long salt used
to generate the digest. This value is stored in the
configuration data store.
If a value starting with '$1$$' is received, the server
knows that the value already represents an MD5 digest, 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 correct.
The digest algorithm is the md5 crypt function used for
encrypting passwords for various UNIX systems.";
reference
"RFC 1321: The MD5 Message-Digest Algorithm
http://en.wikipedia.org/wiki/Crypt_(Unix)";
// FIXME: ref to wikipedia ok??
}
container nacm {
nacm:very-secure;
presence
"An empty nacm container indicates that the
NACM service is running, and using
all default parameters.";
description
"Parameters for NETCONF Access Control Model.";
container authentication {
nacm:very-secure;
if-feature authentication;
description
"The authentication configuration for the
NETCONF server.";
leaf-list user-authentication-order {
type identityref {
base authentication-method;
}
must '(. = "nacm:radius" and ../radius/server) or'
+ '(. != "nacm:radius")' {
error-message
"When 'radius' is used, a radius server
must be configured.";
}
ordered-by user;
description
"When the NETCONF server 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.
If the 'radius' 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.";
}
container radius {
if-feature radius;
description
"The radius configuration for the NETCONF server.";
list server {
key address;
description
"The radius server configuration used by
the NETCONF server.";
leaf address {
type inet:host;
description
"The address of the radius server.";
}
leaf port {
type inet:port-number;
default "1812";
description
"The port number of the radius server.";
}
leaf shared-secret {
type string; // FIXME
/*
We're using a special type aes-cfb-128-encrypted-string which works
like the md5-crypt string, but encrypts the clear text value using a
pre-provisioned password (not part of the config db!).
We use $0$ for cleartext and $4$ for the encrypted value.
(we also have a des-version which uses $3$).
But I was thinking that maybe we could define a type for encrypted
values without specifying the encryption algorithm, just specifying
the format. $0$ | $x$, and how it is
encrypted is implementation specific.
One alternative is to store this shared secret in clear text. It is
transmitted over a secure transport, and marked as very-secure. (The
same argument could be made for user passwords, but these are
personal and not even root should be able to read my passwd in clear
text, so it makes more sense to keep them hidden.)
*/
description
"The shared secret which is known to both the RADIUS
client and server.";
reference
"RFC 2865: Remote Authentication Dial In User Service";
}
/*
How about configuration of number of retransmits
and timeout?
*/
}
}
list user {
if-feature local-users;
key name;
description
"The list of local users configured on this device.";
leaf name {
type nacm-user-name-type;
description
"The user name string identifying this entry.";
}
leaf password {
type md5-crypt;
description
"The password for this entry.";
}
leaf ssh-dsa {
type binary;
description
"The public DSA key for this entry.";
}
leaf ssh-rsa {
type binary;
description
"The public RSA key for this entry.";
}
}
}
leaf enable-nacm {
type boolean;
default true;
description
"Enable or disable all NETCONF access control
enforcement. If 'true', then enforcement
is enabled. If 'false', then enforcement
is disabled.";
}
leaf read-default {
type nacm-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 nacm-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 nacm-action-type;
default "permit";
description
"Controls whether exec access is granted if no appropriate
rule is found for a particular RPC operation request.";
}
leaf denied-rpcs {
type yang:zero-based-counter32;
config false;
mandatory true;
description
"Number of times an RPC operation request was denied
since the server last restarted.";
}
leaf denied-data-writes {
type yang:zero-based-counter32;
config false;
mandatory true;
description
"Number of times a request to alter a data node
was denied, since the server last restarted.";
}
container groups {
list group {
key name;
description
"One NACM Group Entry.";
leaf name {
type nacm-group-name-type;
description
"Group name associated with this entry.";
}
leaf-list user-name {
type nacm-user-name-type;
description
"Each entry identifies the user name of
a member of the group associated with
this entry.";
}
}
}
container rules {
description
"NETCONF Access Control Rules.";
grouping common-rule-parms {
leaf rule-name {
type string {
length "1..256";
}
description
"Arbitrary name assigned to the
access control rule.";
}
leaf allowed-rights {
type nacm-rights-type;
description
"List of access rights granted to
specified administrative groups for the
content specified by the associated path.";
}
leaf-list allowed-group {
type union {
type nacm-matchall-string-type;
type nacm-group-name-type;
}
min-elements 1;
description
"List of administrative groups which will be
assigned the associated access rights
for the content specified by the associated path.
The string '*' indicates that all configured
administrative groups apply to the entry.";
}
leaf nacm-action {
type nacm-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 {
length "1..4095";
}
description
"A textual description of the access rule.";
}
}
list module-rule {
key "module-name rule-name";
ordered-by user;
description
"One Module Access Rule.
Rules are processed in user-defined order. A module rule
is considered a match if the XML namespace for the
specified module name matches the XML namespace used
within a NETCONF PDU, and the administrative group
associated with the requesting session is specified in the
'allowed-group' leaf-list, and the requested operation
is included in the 'allowed-rights' leaf.";
leaf module-name {
type string;
description
"Name of the module associated with this rule.";
}
uses common-rule-parms {
refine allowed-rights {
mandatory true;
}
}
}
list rpc-rule {
key "module-name rpc-name rule-name";
ordered-by user;
description
"One RPC Operation Access Rule.
Rules are processed in user-defined order. An RPC rule is
considered a match if the module name of the requested RPC
operation matches 'module-name', the requested RPC
operation matches 'rpc-name', and an administrative group
associated with the session user is listed in the
'allowed-group' leaf-list. The 'allowed-rights' leaf
is ignored by the server if it is present.
Only the 'exec' bit can possibly cause
a match for an RPC rule.";
leaf module-name {
type string;
description
"Name of the module defining this RPC operation.";
}
leaf rpc-name {
type string;
description
"Name of the RPC operation.";
}
uses common-rule-parms;
}
list data-rule {
key "rule-name";
ordered-by user;
description
"One Data Access Control Rule.
Rules are processed in user-defined order. A data rule is
considered to match when the path expression identifies
the same node that is being accessed in the NETCONF
database, and the administrative group associated with the
session is identified in the 'allowed-group' leaf-list,
and the requested operation is included in the
'allowed-rights' leaf.";
leaf path {
type schema-instance-identifier;
mandatory true;
description
"Schema 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 database
contents.";
}
uses common-rule-parms {
refine allowed-rights {
mandatory true;
}
}
}
list notification-rule {
key "module-name
notification-name
rule-name";
ordered-by user;
description
"One Notification Access Rule.
A notification is considered a match if the module name of
the requested event type matches
'module-name', the requested event type
matches the 'notification-name', and the administrative
group associated with the requesting session is listed in
the 'allowed-group' leaf-list. If the 'allowed-rights'
leaf is present, it is ignored by the server.
Only the 'read' bit can possibly cause
a match for a notification rule.";
leaf module-name {
type string;
description
"Name of the module defining this
notification event type.";
}
leaf notification-name {
type string;
description
"Name of the notification event.";
}
uses common-rule-parms;
}
}
}
}