NACM module access control point for edit-config
This commit is contained in:
parent
ef86cda2fe
commit
8bf5cb0de5
9 changed files with 237 additions and 374 deletions
|
|
@ -78,7 +78,7 @@
|
||||||
* CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded.
|
* CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded.
|
||||||
* NACM extension (RFC8341)
|
* NACM extension (RFC8341)
|
||||||
* NACM Data node READ and WRITE access module support (RFC8341 3.4.5)
|
* NACM Data node READ and WRITE access module support (RFC8341 3.4.5)
|
||||||
* Access control points added for `get` and `get-config` in addition to incoming rpc.
|
* Access control points added for `get`, `get-config`, `edit-config` in addition to incoming rpc.
|
||||||
* RFC 8341 Example A.2 implemented, see: [test/test_nacm_module.sh]
|
* RFC 8341 Example A.2 implemented, see: [test/test_nacm_module.sh]
|
||||||
* Remaining work: data-node PATH
|
* Remaining work: data-node PATH
|
||||||
* Recovery user "_nacm_recovery" added.
|
* Recovery user "_nacm_recovery" added.
|
||||||
|
|
|
||||||
|
|
@ -601,6 +601,9 @@ text_get(xmldb_handle xh,
|
||||||
* @param[in] x0p Parent of x0
|
* @param[in] x0p Parent of x0
|
||||||
* @param[in] x1 xml tree which modifies base
|
* @param[in] x1 xml tree which modifies base
|
||||||
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
||||||
|
* @param[in] username User name of requestor for nacm
|
||||||
|
* @param[in] xnacm NACM XML tree
|
||||||
|
* @param[in] permit If set, NACM has permitted this tree on an upper level
|
||||||
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
|
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 Failed (cbret set)
|
* @retval 0 Failed (cbret set)
|
||||||
|
|
@ -617,6 +620,7 @@ text_modify(struct text_handle *th,
|
||||||
enum operation_type op,
|
enum operation_type op,
|
||||||
char *username,
|
char *username,
|
||||||
cxobj *xnacm,
|
cxobj *xnacm,
|
||||||
|
int permit,
|
||||||
cbuf *cbret)
|
cbuf *cbret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
@ -655,6 +659,13 @@ text_modify(struct text_handle *th,
|
||||||
case OP_MERGE:
|
case OP_MERGE:
|
||||||
case OP_REPLACE:
|
case OP_REPLACE:
|
||||||
if (x0==NULL){
|
if (x0==NULL){
|
||||||
|
if ((op != OP_NONE) && !permit && xnacm){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x1, NACM_CREATE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
permit = 1;
|
||||||
|
}
|
||||||
// int iamkey=0;
|
// int iamkey=0;
|
||||||
if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL)
|
if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -681,25 +692,13 @@ text_modify(struct text_handle *th,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x1bstr){
|
if (x1bstr){
|
||||||
if ((x0b = xml_body_get(x0)) == NULL){
|
if ((x0b = xml_body_get(x0)) != NULL){
|
||||||
if (xnacm){
|
|
||||||
if ((ret = nacm_datanode_write(NULL, x0, NACM_CREATE, username, xnacm, cbret)) < 0)
|
|
||||||
goto done;
|
|
||||||
if (ret == 0)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
if ((x0b = xml_new("body", x0, NULL)) == NULL)
|
|
||||||
goto done;
|
|
||||||
xml_type_set(x0b, CX_BODY);
|
|
||||||
|
|
||||||
if (xml_value_set(x0b, x1bstr) < 0)
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
x0bstr = xml_value(x0b);
|
x0bstr = xml_value(x0b);
|
||||||
if (x0bstr==NULL || strcmp(x0bstr, x1bstr)){
|
if (x0bstr==NULL || strcmp(x0bstr, x1bstr)){
|
||||||
if (xnacm){
|
if ((op != OP_NONE) && !permit && xnacm){
|
||||||
if ((ret = nacm_datanode_write(NULL, x0, NACM_UPDATE, username, xnacm, cbret)) < 0)
|
if ((ret = nacm_datanode_write(NULL, x1,
|
||||||
|
x0bstr==NULL?NACM_CREATE:NACM_UPDATE,
|
||||||
|
username, xnacm, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -708,7 +707,6 @@ text_modify(struct text_handle *th,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
|
|
@ -719,7 +717,14 @@ text_modify(struct text_handle *th,
|
||||||
}
|
}
|
||||||
case OP_REMOVE: /* fall thru */
|
case OP_REMOVE: /* fall thru */
|
||||||
if (x0){
|
if (x0){
|
||||||
xml_purge(x0);
|
if ((op != OP_NONE) && !permit && xnacm){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x0, NACM_DELETE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (xml_purge(x0) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -735,6 +740,13 @@ text_modify(struct text_handle *th,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
case OP_REPLACE: /* fall thru */
|
case OP_REPLACE: /* fall thru */
|
||||||
|
if (xnacm && !permit){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x1, x0?NACM_UPDATE:NACM_CREATE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
permit = 1;
|
||||||
|
}
|
||||||
if (x0){
|
if (x0){
|
||||||
xml_purge(x0);
|
xml_purge(x0);
|
||||||
x0 = NULL;
|
x0 = NULL;
|
||||||
|
|
@ -742,10 +754,21 @@ text_modify(struct text_handle *th,
|
||||||
case OP_MERGE: /* fall thru */
|
case OP_MERGE: /* fall thru */
|
||||||
case OP_NONE:
|
case OP_NONE:
|
||||||
/* Special case: anyxml, just replace tree,
|
/* Special case: anyxml, just replace tree,
|
||||||
See 7.10.3 of RFC6020bis */
|
See rfc6020 7.10.3:n
|
||||||
|
An anyxml node is treated as an opaque chunk of data. This data
|
||||||
|
can be modified in its entirety only.
|
||||||
|
Any "operation" attributes present on subelements of an anyxml
|
||||||
|
node are ignored by the NETCONF server.*/
|
||||||
if (y0->yn_keyword == Y_ANYXML){
|
if (y0->yn_keyword == Y_ANYXML){
|
||||||
if (op == OP_NONE)
|
if (op == OP_NONE)
|
||||||
break;
|
break;
|
||||||
|
if (xnacm && op==OP_MERGE && !permit){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x0, x0?NACM_UPDATE:NACM_CREATE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
permit = 1;
|
||||||
|
}
|
||||||
if (x0){
|
if (x0){
|
||||||
xml_purge(x0);
|
xml_purge(x0);
|
||||||
}
|
}
|
||||||
|
|
@ -756,6 +779,13 @@ text_modify(struct text_handle *th,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (x0==NULL){
|
if (x0==NULL){
|
||||||
|
if (xnacm && op==OP_MERGE && !permit){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x0, x0?NACM_UPDATE:NACM_CREATE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
permit = 1;
|
||||||
|
}
|
||||||
if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL)
|
if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
/* Copy xmlns attributes */
|
/* Copy xmlns attributes */
|
||||||
|
|
@ -809,7 +839,7 @@ text_modify(struct text_handle *th,
|
||||||
x0c = x0vec[i++];
|
x0c = x0vec[i++];
|
||||||
yc = yang_find_datanode(y0, x1cname);
|
yc = yang_find_datanode(y0, x1cname);
|
||||||
if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op,
|
if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op,
|
||||||
username, xnacm, cbret)) < 0)
|
username, xnacm, permit, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
|
@ -823,8 +853,16 @@ text_modify(struct text_handle *th,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
case OP_REMOVE: /* fall thru */
|
case OP_REMOVE: /* fall thru */
|
||||||
if (x0)
|
if (x0){
|
||||||
xml_purge(x0);
|
if (xnacm){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x0, NACM_DELETE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (xml_purge(x0) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -847,6 +885,8 @@ text_modify(struct text_handle *th,
|
||||||
* @param[in] x1 xml tree which modifies base
|
* @param[in] x1 xml tree which modifies base
|
||||||
* @param[in] yspec Top-level yang spec (if y is NULL)
|
* @param[in] yspec Top-level yang spec (if y is NULL)
|
||||||
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
||||||
|
* @param[in] username User name of requestor for nacm
|
||||||
|
* @param[in] xnacm NACM XML tree
|
||||||
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
|
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
* @retval 0 Failed (cbret set)
|
* @retval 0 Failed (cbret set)
|
||||||
|
|
@ -871,6 +911,7 @@ text_modify_top(struct text_handle *th,
|
||||||
yang_stmt *ymod;/* yang module */
|
yang_stmt *ymod;/* yang module */
|
||||||
char *opstr;
|
char *opstr;
|
||||||
int ret;
|
int ret;
|
||||||
|
int permit = 0;
|
||||||
|
|
||||||
/* Assure top-levels are 'config' */
|
/* Assure top-levels are 'config' */
|
||||||
assert(x0 && strcmp(xml_name(x0),"config")==0);
|
assert(x0 && strcmp(xml_name(x0),"config")==0);
|
||||||
|
|
@ -881,39 +922,56 @@ text_modify_top(struct text_handle *th,
|
||||||
if (xml_operation(opstr, &op) < 0)
|
if (xml_operation(opstr, &op) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* Special case if x1 is empty, top-level only <config/> */
|
/* Special case if x1 is empty, top-level only <config/> */
|
||||||
if (xml_child_nr(x1) == 0){
|
if (xml_child_nr_type(x1, CX_ELMNT) == 0){
|
||||||
if (xml_child_nr(x0)) /* base tree not empty */
|
if (xml_child_nr_type(x0, CX_ELMNT)){ /* base tree not empty */
|
||||||
switch(op){
|
switch(op){
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
case OP_REMOVE:
|
case OP_REMOVE:
|
||||||
case OP_REPLACE:
|
case OP_REPLACE:
|
||||||
if ((ret = nacm_datanode_write(NULL, x0, NACM_DELETE, username, xnacm, cbret)) < 0) /* XXX */
|
if (xnacm){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x0, NACM_DELETE, username, xnacm, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
x0c = NULL;
|
permit = 1;
|
||||||
while ((x0c = xml_child_each(x0, x0c, CX_ELMNT)) != NULL)
|
}
|
||||||
xml_purge(x0c);
|
while ((x0c = xml_child_i(x0, 0)) != 0)
|
||||||
|
if (xml_purge(x0c) < 0)
|
||||||
|
goto done;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else /* base tree empty */
|
else /* base tree empty */
|
||||||
switch(op){
|
switch(op){
|
||||||
|
#if 0 /* According to RFC6020 7.5.8 you cant delete a non-existing object.
|
||||||
|
On the other hand, the top-level cannot be removed anyway.
|
||||||
|
Additionally, I think this is irritating so I disable it.
|
||||||
|
I.e., curl -u andy:bar -sS -X DELETE http://localhost/restconf/data
|
||||||
|
*/
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Special case top-level replace */
|
/* Special case top-level replace */
|
||||||
if (op == OP_REPLACE || op == OP_DELETE){
|
else if (op == OP_REPLACE || op == OP_DELETE){
|
||||||
x0c = NULL;
|
if (xnacm && !permit){
|
||||||
|
if ((ret = nacm_datanode_write(NULL, x1, NACM_UPDATE, username, xnacm, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
permit = 1;
|
||||||
|
}
|
||||||
while ((x0c = xml_child_i(x0, 0)) != 0)
|
while ((x0c = xml_child_i(x0, 0)) != 0)
|
||||||
xml_purge(x0c);
|
if (xml_purge(x0c) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
/* Loop through children of the modification tree */
|
/* Loop through children of the modification tree */
|
||||||
x1c = NULL;
|
x1c = NULL;
|
||||||
|
|
@ -946,7 +1004,7 @@ text_modify_top(struct text_handle *th,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op,
|
if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op,
|
||||||
username,xnacm, cbret)) < 0)
|
username, xnacm, permit, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ new "minmax: empty"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><c xmlns="urn:example:clixon"/></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><edit-config><target><candidate/></target><default-operation>replace</default-operation><config><c xmlns="urn:example:clixon"/></config></edit-config></rpc>]]>]]>' '^<rpc-reply><ok/></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
# NYI
|
# NYI
|
||||||
if false; then
|
if false; then # nyi
|
||||||
new "minmax: validate should fail"
|
new "minmax: validate should fail"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,9 +131,6 @@ sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data &
|
||||||
|
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
|
|
||||||
new "restconf DELETE whole datastore"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
|
||||||
|
|
||||||
new2 "auth get"
|
new2 "auth get"
|
||||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 'null
|
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 'null
|
||||||
'
|
'
|
||||||
|
|
|
||||||
|
|
@ -1,239 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Authentication and authorization and IETF NACM
|
|
||||||
# NACM data node rule
|
|
||||||
# @see RFC 8341 A.1 and A.4 (and permit-all from A.2)
|
|
||||||
# Tests for:
|
|
||||||
# deny-nacm: This rule denies the "guest" group any access to the
|
|
||||||
# /nacm subtree.
|
|
||||||
# permit-acme-config: This rule gives the "limited" group read-write
|
|
||||||
# access to the acme <config-parameters>.
|
|
||||||
# permit-dummy-interface: This rule gives the "limited" and "guest"
|
|
||||||
# groups read-update access to the acme <interface> entry named
|
|
||||||
# "dummy". This entry cannot be created or deleted by these groups;
|
|
||||||
# it can only be altered.
|
|
||||||
# permit-interface: This rule gives the "admin" group read-write
|
|
||||||
# access to all acme <interface> entries.
|
|
||||||
|
|
||||||
APPNAME=example
|
|
||||||
# include err() and new() functions and creates $dir
|
|
||||||
. ./lib.sh
|
|
||||||
. ./nacm.sh
|
|
||||||
|
|
||||||
cfg=$dir/conf_yang.xml
|
|
||||||
fyang=$dir/test.yang
|
|
||||||
|
|
||||||
cat <<EOF > $cfg
|
|
||||||
<config>
|
|
||||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
|
||||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
|
||||||
<CLICON_YANG_DIR>$IETFRFC</CLICON_YANG_DIR>
|
|
||||||
<CLICON_YANG_MAIN_FILE>$fyang</CLICON_YANG_MAIN_FILE>
|
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
|
||||||
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
|
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
|
||||||
<CLICON_CLI_MODE>$APPNAME</CLICON_CLI_MODE>
|
|
||||||
<CLICON_SOCK>/usr/local/var/$APPNAME/$APPNAME.sock</CLICON_SOCK>
|
|
||||||
<CLICON_BACKEND_DIR>/usr/local/lib/$APPNAME/backend</CLICON_BACKEND_DIR>
|
|
||||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
|
||||||
<CLICON_CLI_GENMODEL_COMPLETION>1</CLICON_CLI_GENMODEL_COMPLETION>
|
|
||||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
|
||||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
|
||||||
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
|
||||||
<CLICON_NACM_MODE>internal</CLICON_NACM_MODE>
|
|
||||||
</config>
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF > $fyang
|
|
||||||
module nacm-example{
|
|
||||||
yang-version 1.1;
|
|
||||||
namespace "urn:example:nacm";
|
|
||||||
prefix nacm;
|
|
||||||
import clixon-example {
|
|
||||||
prefix ex;
|
|
||||||
}
|
|
||||||
import ietf-netconf-acm {
|
|
||||||
prefix nacm;
|
|
||||||
}
|
|
||||||
leaf x{
|
|
||||||
type int32;
|
|
||||||
description "something to edit";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# The groups are slightly modified from RFC8341 A.1
|
|
||||||
# The rule-list is from A.2
|
|
||||||
RULES=$(cat <<EOF
|
|
||||||
<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
|
|
||||||
<enable-nacm>false</enable-nacm>
|
|
||||||
<read-default>deny</read-default>
|
|
||||||
<write-default>deny</write-default>
|
|
||||||
<exec-default>deny</exec-default>
|
|
||||||
|
|
||||||
$NGROUPS
|
|
||||||
|
|
||||||
<rule-list>
|
|
||||||
<name>guest-acl</name>
|
|
||||||
<group>guest</group>
|
|
||||||
|
|
||||||
<rule>
|
|
||||||
<name>deny-nacm</name>
|
|
||||||
<path xmlns:n="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
|
|
||||||
/n:nacm
|
|
||||||
</path>
|
|
||||||
<access-operations>*</access-operations>
|
|
||||||
<action>deny</action>
|
|
||||||
<comment>
|
|
||||||
Deny the 'guest' group any access to the /nacm data.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
</rule-list>
|
|
||||||
|
|
||||||
<rule-list>
|
|
||||||
<name>limited-acl</name>
|
|
||||||
<group>limited</group>
|
|
||||||
|
|
||||||
<rule>
|
|
||||||
<name>permit-acme-config</name>
|
|
||||||
<path xmlns:acme="http://example.com/ns/netconf">
|
|
||||||
/acme:acme-netconf/acme:config-parameters
|
|
||||||
</path>
|
|
||||||
<access-operations>
|
|
||||||
read create update delete
|
|
||||||
</access-operations>
|
|
||||||
<action>permit</action>
|
|
||||||
<comment>
|
|
||||||
Allow the 'limited' group complete access to the acme
|
|
||||||
NETCONF configuration parameters. Showing long form
|
|
||||||
of 'access-operations' instead of shorthand.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
</rule-list>
|
|
||||||
<rule-list>
|
|
||||||
<name>guest-limited-acl</name>
|
|
||||||
<group>guest</group>
|
|
||||||
<group>limited</group>
|
|
||||||
|
|
||||||
<rule>
|
|
||||||
<name>permit-dummy-interface</name>
|
|
||||||
<path xmlns:acme="http://example.com/ns/itf">
|
|
||||||
/acme:interfaces/acme:interface[acme:name='dummy']
|
|
||||||
</path>
|
|
||||||
<access-operations>read update</access-operations>
|
|
||||||
<action>permit</action>
|
|
||||||
<comment>
|
|
||||||
Allow the 'limited' and 'guest' groups read
|
|
||||||
and update access to the dummy interface.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
</rule-list>
|
|
||||||
<rule-list>
|
|
||||||
<name>admin-acl</name>
|
|
||||||
<group>admin</group>
|
|
||||||
<rule>
|
|
||||||
<name>permit-interface</name>
|
|
||||||
<path xmlns:acme="http://example.com/ns/itf">
|
|
||||||
/acme:interfaces/acme:interface
|
|
||||||
</path>
|
|
||||||
<access-operations>*</access-operations>
|
|
||||||
<action>permit</action>
|
|
||||||
<comment>
|
|
||||||
Allow the 'admin' group full access to all acme interfaces.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
</rule-list>
|
|
||||||
|
|
||||||
$NADMIN
|
|
||||||
|
|
||||||
</nacm>
|
|
||||||
<x xmlns="urn:example:clixon">0</x>
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
exit # XXX
|
|
||||||
new "test params: -f $cfg"
|
|
||||||
|
|
||||||
if [ $BE -ne 0 ]; then
|
|
||||||
new "kill old backend"
|
|
||||||
sudo clixon_backend -zf $cfg
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
err
|
|
||||||
fi
|
|
||||||
new "start backend -s init -f $cfg"
|
|
||||||
sudo $clixon_backend -s init -f $cfg -D $DBG
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
err
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
new "kill old restconf daemon"
|
|
||||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
new "start restconf daemon (-a is enable basic authentication)"
|
|
||||||
sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data &
|
|
||||||
|
|
||||||
sleep $RCWAIT
|
|
||||||
|
|
||||||
new "auth set authentication config"
|
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
|
||||||
|
|
||||||
new "commit it"
|
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
|
||||||
|
|
||||||
new "enable nacm"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"enable-nacm": true}' http://localhost/restconf/data/ietf-netconf-acm:nacm/enable-nacm)" ""
|
|
||||||
|
|
||||||
#--------------- nacm enabled
|
|
||||||
|
|
||||||
new2 "auth get (wrong passwd: access denied)"
|
|
||||||
expecteq "$(curl -u andy:foo -sS -X GET http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "access-denied","error-severity": "error","error-message": "The requested URL was unauthorized"}}}
'
|
|
||||||
|
|
||||||
new2 "auth get (access)"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/example:x)" '{"example:x": 0}
|
|
||||||
'
|
|
||||||
|
|
||||||
#----------------Enable NACM
|
|
||||||
|
|
||||||
new "enable nacm"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"enable-nacm": true}' http://localhost/restconf/data/ietf-netconf-acm:nacm/enable-nacm)" ""
|
|
||||||
|
|
||||||
new2 "admin get nacm"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/example:x)" '{"example:x": 0}
|
|
||||||
'
|
|
||||||
|
|
||||||
new2 "limited get nacm"
|
|
||||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/example:x)" '{"example:x": 0}
|
|
||||||
'
|
|
||||||
|
|
||||||
new2 "guest get nacm"
|
|
||||||
expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/example:x)" '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "access-denied","error-severity": "error","error-message": "The requested URL was unauthorized"}}}
'
|
|
||||||
|
|
||||||
new "admin edit nacm"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/example:x)" ""
|
|
||||||
|
|
||||||
new2 "limited edit nacm"
|
|
||||||
expecteq "$(curl -u wilma:bar -sS -X PUT -d '{"x": 2}' http://localhost/restconf/data/example:x)" '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
|
||||||
|
|
||||||
new2 "guest edit nacm"
|
|
||||||
expecteq "$(curl -u guest:bar -sS -X PUT -d '{"x": 3}' http://localhost/restconf/data/example:x)" '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "access-denied","error-severity": "error","error-message": "The requested URL was unauthorized"}}}
'
|
|
||||||
|
|
||||||
new "Kill restconf daemon"
|
|
||||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
|
||||||
|
|
||||||
if [ $BE -eq 0 ]; then
|
|
||||||
exit # BE
|
|
||||||
fi
|
|
||||||
|
|
||||||
new "Kill backend"
|
|
||||||
# Check if premature kill
|
|
||||||
pid=`pgrep -u root -f clixon_backend`
|
|
||||||
if [ -z "$pid" ]; then
|
|
||||||
err "backend already dead"
|
|
||||||
fi
|
|
||||||
# kill backend
|
|
||||||
sudo clixon_backend -z -f $cfg
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
err "kill backend"
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf $dir
|
|
||||||
|
|
@ -151,9 +151,6 @@ sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data &
|
||||||
|
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
|
|
||||||
new "restconf DELETE whole datastore"
|
|
||||||
expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" ""
|
|
||||||
|
|
||||||
new2 "auth get"
|
new2 "auth get"
|
||||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}}
|
||||||
'
|
'
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,19 @@
|
||||||
# @see test_nacm.sh is slightly modified - this follows the RFC more closely
|
# @see test_nacm.sh is slightly modified - this follows the RFC more closely
|
||||||
# See RFC 8341 A.1 and A.2
|
# See RFC 8341 A.1 and A.2
|
||||||
# Note: use clixon-example instead of ietf-netconf-monitoring since the latter is
|
# Note: use clixon-example instead of ietf-netconf-monitoring since the latter is
|
||||||
# Tests for
|
# A) Three tracks in the code for leaf/leaf-list, container/lists, and root
|
||||||
# deny-ncm: This rule prevents the "guest" group from reading any
|
# B) Three operations: create, update, delete (write)
|
||||||
# monitoring information in the "clixon-example" YANG
|
# C) Two access operations: permit, deny (also default deny/permit)
|
||||||
# module.
|
# This gives 18 testcases
|
||||||
# permit-ncm: This rule allows the "limited" group to read the
|
# Set group access:
|
||||||
# "clixon-example" YANG module.
|
# - Admin: permit: create, update, delete
|
||||||
# permit-exec: This rule allows the "limited" group to invoke any
|
# - Limit: permit: create, delete; deny: update
|
||||||
# protocol operation supported by the server.
|
# - Guest: permit: update; deny: create delete
|
||||||
# permit-all: This rule allows the "admin" group complete access to
|
# ops\track:| root | leaf | list
|
||||||
# all content in the server. No subsequent rule will match for the
|
#-----------+--------+--------+----------
|
||||||
# "admin" group because of this module rule
|
# create | na | p/d | p/d
|
||||||
|
# update | p/d | p/d | p/d
|
||||||
|
# delete | p/d | p/d | p/d
|
||||||
|
|
||||||
APPNAME=example
|
APPNAME=example
|
||||||
# include err() and new() functions and creates $dir
|
# include err() and new() functions and creates $dir
|
||||||
|
|
@ -62,6 +64,17 @@ module nacm-example{
|
||||||
type int32;
|
type int32;
|
||||||
description "something to edit";
|
description "something to edit";
|
||||||
}
|
}
|
||||||
|
list a{
|
||||||
|
key k;
|
||||||
|
leaf k{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
container b{
|
||||||
|
leaf c{
|
||||||
|
type string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
@ -69,77 +82,51 @@ EOF
|
||||||
# The rule-list is from A.2
|
# The rule-list is from A.2
|
||||||
RULES=$(cat <<EOF
|
RULES=$(cat <<EOF
|
||||||
<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
|
<nacm xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-acm">
|
||||||
<enable-nacm>false</enable-nacm>
|
<enable-nacm>true</enable-nacm>
|
||||||
<read-default>deny</read-default>
|
<read-default>deny</read-default>
|
||||||
<write-default>deny</write-default>
|
<write-default>deny</write-default>
|
||||||
<exec-default>deny</exec-default>
|
<exec-default>permit</exec-default>
|
||||||
|
|
||||||
$NGROUPS
|
$NGROUPS
|
||||||
|
|
||||||
|
<rule-list>
|
||||||
|
<name>limited-acl</name>
|
||||||
|
<group>limited</group>
|
||||||
|
<rule>
|
||||||
|
<name>permit-create-delete</name>
|
||||||
|
<module-name>nacm-example</module-name>
|
||||||
|
<access-operations>read create delete</access-operations>
|
||||||
|
<action>permit</action>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<name>deny-update</name>
|
||||||
|
<module-name>nacm-example</module-name>
|
||||||
|
<access-operations>read update</access-operations>
|
||||||
|
<action>deny</action>
|
||||||
|
</rule>
|
||||||
|
</rule-list>
|
||||||
|
|
||||||
<rule-list>
|
<rule-list>
|
||||||
<name>guest-acl</name>
|
<name>guest-acl</name>
|
||||||
<group>guest</group>
|
<group>guest</group>
|
||||||
<rule>
|
<rule>
|
||||||
<name>permit-get</name>
|
<name>permit-update</name>
|
||||||
<module-name>ietf-netconf</module-name>
|
<module-name>nacm-example</module-name>
|
||||||
<rpc-name>*</rpc-name>
|
<access-operations>read update</access-operations>
|
||||||
<access-operations>exec</access-operations>
|
|
||||||
<action>permit</action>
|
<action>permit</action>
|
||||||
<comment>
|
|
||||||
Allow invocation of get rpc
|
|
||||||
</comment>
|
|
||||||
</rule>
|
</rule>
|
||||||
<rule>
|
<rule>
|
||||||
<name>permit-read</name>
|
<name>deny-create-delete</name>
|
||||||
<module-name>clixon-example</module-name>
|
<module-name>nacm-example</module-name>
|
||||||
<access-operations>read</access-operations>
|
<access-operations>read create delete</access-operations>
|
||||||
<action>permit</action>
|
|
||||||
<comment>
|
|
||||||
Do not allow guests any access to the NETCONF
|
|
||||||
monitoring information.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
<rule>
|
|
||||||
<name>deny-write</name>
|
|
||||||
<module-name>clixon-example</module-name>
|
|
||||||
<access-operations>*</access-operations>
|
|
||||||
<action>deny</action>
|
<action>deny</action>
|
||||||
<comment>
|
|
||||||
Do not allow guests any access to the NETCONF
|
|
||||||
monitoring information.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
</rule-list>
|
</rule-list>
|
||||||
<rule-list>
|
|
||||||
<name>limited-acl</name>
|
|
||||||
<group>limited</group>
|
|
||||||
<rule>
|
|
||||||
<name>permit-ncm</name>
|
|
||||||
<module-name>clixon-example</module-name>
|
|
||||||
<access-operations>read create update delete</access-operations>
|
|
||||||
<action>permit</action>
|
|
||||||
<comment>
|
|
||||||
Allow write access to the NETCONF monitoring information.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
<rule>
|
|
||||||
<name>permit-exec</name>
|
|
||||||
<module-name>*</module-name>
|
|
||||||
<access-operations>exec</access-operations>
|
|
||||||
<action>permit</action>
|
|
||||||
<comment>
|
|
||||||
Allow invocation of the supported server operations.
|
|
||||||
</comment>
|
|
||||||
</rule>
|
|
||||||
</rule-list>
|
|
||||||
|
|
||||||
$NADMIN
|
$NADMIN
|
||||||
|
|
||||||
</nacm>
|
</nacm>
|
||||||
<x xmlns="urn:example:nacm">42</x>
|
|
||||||
<translate xmlns="urn:example:clixon"><k>key42</k><value>val42</value></translate>
|
|
||||||
<translate xmlns="urn:example:clixon"><k>key43</k><value>val43</value></translate>
|
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -167,40 +154,103 @@ sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data &
|
||||||
|
|
||||||
sleep $RCWAIT
|
sleep $RCWAIT
|
||||||
|
|
||||||
|
# Set nacm from scratch
|
||||||
|
nacm(){
|
||||||
new "auth set authentication config"
|
new "auth set authentication config"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config operation='replace'>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "commit it"
|
new "commit it"
|
||||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "enable nacm"
|
new "enable nacm"
|
||||||
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"enable-nacm": true}' http://localhost/restconf/data/ietf-netconf-acm:nacm/enable-nacm)" ""
|
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"enable-nacm": true}' http://localhost/restconf/data/ietf-netconf-acm:nacm/enable-nacm)" ""
|
||||||
|
}
|
||||||
|
|
||||||
#--------------- nacm enabled
|
#--------------- enable nacm
|
||||||
#----WRITE access
|
nacm
|
||||||
#user:admin
|
|
||||||
new2 "admin read element ok"
|
# ops\track:| root | leaf | list
|
||||||
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:translate=key42/value)" '{"clixon-example:value": "val42"}
|
#-----------+--------+--------+----------
|
||||||
|
# create | n/a | xp/dx | p/d
|
||||||
|
# update | p/d | xp/dx | p/d
|
||||||
|
# delete | p/d | xp/dx | p/d
|
||||||
|
|
||||||
|
#----------root
|
||||||
|
new2 "update root list default deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data -d '<data><x xmlns="urn:example:nacm">42</x>$RULES</data>')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||||
|
|
||||||
|
# replace all, then must include NACM rules as well
|
||||||
|
MSG="<data>$RULES</data>"
|
||||||
|
new "update root list permit"
|
||||||
|
expecteq "$(curl -u andy:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data -d "$MSG")" ''
|
||||||
|
|
||||||
|
new "delete root list deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||||
|
|
||||||
|
new "delete root permit"
|
||||||
|
expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" ''
|
||||||
|
|
||||||
|
#--------------- re-enable nacm
|
||||||
|
nacm
|
||||||
|
|
||||||
|
#----------leaf
|
||||||
|
new2 "create leaf deny"
|
||||||
|
expecteq "$(curl -u guest:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:x -d '<x xmlns="urn:example:nacm">42</x>')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
||||||
|
|
||||||
|
new "create leaf permit"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:x -d '<x xmlns="urn:example:nacm">42</x>')" ''
|
||||||
|
|
||||||
|
new2 "update leaf deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:x -d '<x xmlns="urn:example:nacm">99</x>')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
||||||
|
|
||||||
|
new "update leaf permit"
|
||||||
|
expecteq "$(curl -u guest:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:x -d '<x xmlns="urn:example:nacm">99</x>')" ''
|
||||||
|
|
||||||
|
new2 "read leaf check"
|
||||||
|
expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" '{"nacm-example:x": 99}
|
||||||
'
|
'
|
||||||
|
|
||||||
new "admin write element ok"
|
new2 "delete leaf deny"
|
||||||
expecteq "$(curl -u andy:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42/value -d '{"clixon-example:value": "val99"}')"
|
expecteq "$(curl -u guest:bar -sS -X DELETE http://localhost/restconf/data/nacm-example:x)" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
||||||
|
|
||||||
#user:limit
|
new "delete leaf permit"
|
||||||
new2 "limit read element ok"
|
expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data/nacm-example:x)" ''
|
||||||
expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-example:translate=key42/value)" '{"clixon-example:value": "val99"}
|
|
||||||
|
#----- list/container
|
||||||
|
new2 "create list deny"
|
||||||
|
expecteq "$(curl -u guest:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:a=key42 -d '<a xmlns="urn:example:nacm"><k>key42</k><b><c>str</c></b></a>')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
||||||
|
|
||||||
|
new "create list permit"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:a=key42 -d '<a xmlns="urn:example:nacm"><k>key42</k><b><c>str</c></b></a>')" ''
|
||||||
|
|
||||||
|
new2 "update list deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:a=key42 -d '<a xmlns="urn:example:nacm"><k>key42</k><b><c>update</c></b></a>')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
||||||
|
|
||||||
|
new "update list permit"
|
||||||
|
expecteq "$(curl -u guest:bar -sS -H 'Content-Type: application/yang-data+xml' -X PUT http://localhost/restconf/data/nacm-example:a=key42 -d '<a xmlns="urn:example:nacm"><k>key42</k><b><c>update</c></b></a>')" ''
|
||||||
|
|
||||||
|
new2 "read list check"
|
||||||
|
expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/nacm-example:a)" '{"nacm-example:a": [{"k": "key42","b": {"c": "update"}}]}
|
||||||
'
|
'
|
||||||
|
|
||||||
new "limit write element ok"
|
new2 "delete list deny"
|
||||||
expecteq "$(curl -u wilma:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42/value -d '{"clixon-example:value": "val55"}')"
|
expecteq "$(curl -u guest:bar -sS -X DELETE http://localhost/restconf/data/nacm-example:a=key42)" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
||||||
|
|
||||||
#user:guest
|
new "delete list permit"
|
||||||
new2 "guest read element ok"
|
expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data/nacm-example:a=key42)" ''
|
||||||
expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/clixon-example:translate=key42/value)" '{"clixon-example:value": "val55"}
|
|
||||||
'
|
|
||||||
|
|
||||||
new2 "guest write element ok"
|
#----- default deny (clixon-example limit and guest have default access)
|
||||||
expecteq "$(curl -u guest:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42/value -d '{"clixon-example:value": "val99"}')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "access denied"}}}
'
|
new2 "default create list deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42 -d '{"clixon-example:translate": [{"k": "key42","value": "val42"}]}')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||||
|
|
||||||
|
new2 "create list permit"
|
||||||
|
expecteq "$(curl -u andy:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42 -d '{"clixon-example:translate": [{"k": "key42","value": "val42"}]}')" ''
|
||||||
|
|
||||||
|
new2 "default update list deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42 -d '{"clixon-example:translate": [{"k": "key42","value": "val99"}]}')" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||||
|
|
||||||
|
new2 "default delete list deny"
|
||||||
|
expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data/clixon-example:translate=key42)" '{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}}
'
|
||||||
|
|
||||||
new "Kill restconf daemon"
|
new "Kill restconf daemon"
|
||||||
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
sudo pkill -u www-data -f "/www-data/clixon_restconf"
|
||||||
|
|
|
||||||
|
|
@ -143,22 +143,22 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><can
|
||||||
|
|
||||||
# LEAF_LISTS
|
# LEAF_LISTS
|
||||||
|
|
||||||
new "add two entries to leaf-list user order"
|
new "add two entries (c,b) to leaf-list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">b</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">b</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry to leaf-list user order"
|
new "add one entry (a) to leaf-list user order"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">a</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">a</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "add one entry to leaf-list user order after commit"
|
new "add one entry (0) to leaf-list user order after commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">0</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><edit-config><target><candidate/></target><config><y0 xmlns="urn:example:clixon">0</y0></config></edit-config></rpc>]]>]]>' "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "netconf commit"
|
new "netconf commit"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "verify leaf-list user order in running (as entered)"
|
new "verify leaf-list user order in running (as entered: c,b,a,0)"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source><filter type="xpath" select="/y0"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">b</y0><y0 xmlns="urn:example:clixon">a</y0><y0 xmlns="urn:example:clixon">0</y0></data></rpc-reply>]]>]]>$'
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 '<rpc><get-config><source><running/></source><filter type="xpath" select="/y0"/></get-config></rpc>]]>]]>' '^<rpc-reply><data><y0 xmlns="urn:example:clixon">c</y0><y0 xmlns="urn:example:clixon">b</y0><y0 xmlns="urn:example:clixon">a</y0><y0 xmlns="urn:example:clixon">0</y0></data></rpc-reply>]]>]]>$'
|
||||||
|
|
||||||
# LISTS
|
# LISTS
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue