From 8bf5cb0de549833a3c219c1232fcfa72de46645b Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 1 Feb 2019 14:56:45 +0100 Subject: [PATCH] NACM module access control point for edit-config --- CHANGELOG.md | 4 +- datastore/text/clixon_xmldb_text.c | 130 +++++++--- test/test_list.sh | 2 +- test/test_nacm.sh | 3 - test/test_nacm_datanode.sh | 239 ------------------ test/test_nacm_ext.sh | 3 - ...acm_module.sh => test_nacm_module_read.sh} | 0 test/test_nacm_module_write.sh | 222 +++++++++------- test/test_order.sh | 8 +- 9 files changed, 237 insertions(+), 374 deletions(-) delete mode 100755 test/test_nacm_datanode.sh rename test/{test_nacm_module.sh => test_nacm_module_read.sh} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec014366..cb4278be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,9 +78,9 @@ * CLICON_YANG_MAIN_DIR Provides a directory where all yang modules should be loaded. * NACM extension (RFC8341) * 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] - * Remaining work: data-node PATH + * Remaining work: data-node PATH * Recovery user "_nacm_recovery" added. * Example use is restconf PUT when NACM edit-config is permitted, then automatic commit and discard are permitted using recovery user. diff --git a/datastore/text/clixon_xmldb_text.c b/datastore/text/clixon_xmldb_text.c index 2e5ad5ea..277e0373 100644 --- a/datastore/text/clixon_xmldb_text.c +++ b/datastore/text/clixon_xmldb_text.c @@ -601,6 +601,9 @@ text_get(xmldb_handle xh, * @param[in] x0p Parent of x0 * @param[in] x1 xml tree which modifies base * @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. * @retval -1 Error * @retval 0 Failed (cbret set) @@ -617,6 +620,7 @@ text_modify(struct text_handle *th, enum operation_type op, char *username, cxobj *xnacm, + int permit, cbuf *cbret) { int retval = -1; @@ -655,6 +659,13 @@ text_modify(struct text_handle *th, case OP_MERGE: case OP_REPLACE: 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; if ((x0 = xml_new(x1name, x0p, (yang_stmt*)y0)) == NULL) goto done; @@ -681,25 +692,13 @@ text_modify(struct text_handle *th, } } if (x1bstr){ - 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{ + if ((x0b = xml_body_get(x0)) != NULL){ x0bstr = xml_value(x0b); if (x0bstr==NULL || strcmp(x0bstr, x1bstr)){ - if (xnacm){ - if ((ret = nacm_datanode_write(NULL, x0, NACM_UPDATE, username, xnacm, cbret)) < 0) + if ((op != OP_NONE) && !permit && xnacm){ + if ((ret = nacm_datanode_write(NULL, x1, + x0bstr==NULL?NACM_CREATE:NACM_UPDATE, + username, xnacm, cbret)) < 0) goto done; if (ret == 0) goto fail; @@ -708,7 +707,6 @@ text_modify(struct text_handle *th, goto done; } } - } break; case OP_DELETE: @@ -719,7 +717,14 @@ text_modify(struct text_handle *th, } case OP_REMOVE: /* fall thru */ 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; default: @@ -735,6 +740,13 @@ text_modify(struct text_handle *th, goto fail; } 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){ xml_purge(x0); x0 = NULL; @@ -742,10 +754,21 @@ text_modify(struct text_handle *th, case OP_MERGE: /* fall thru */ case OP_NONE: /* 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 (op == OP_NONE) 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){ xml_purge(x0); } @@ -756,6 +779,13 @@ text_modify(struct text_handle *th, break; } 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) goto done; /* Copy xmlns attributes */ @@ -809,7 +839,7 @@ text_modify(struct text_handle *th, x0c = x0vec[i++]; yc = yang_find_datanode(y0, x1cname); if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, - username, xnacm, cbret)) < 0) + username, xnacm, permit, cbret)) < 0) goto done; /* If xml return - ie netconf error xml tree, then stop and return OK */ if (ret == 0) @@ -823,8 +853,16 @@ text_modify(struct text_handle *th, goto fail; } case OP_REMOVE: /* fall thru */ - if (x0) - xml_purge(x0); + if (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; default: break; @@ -847,6 +885,8 @@ text_modify(struct text_handle *th, * @param[in] x1 xml tree which modifies base * @param[in] yspec Top-level yang spec (if y is NULL) * @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. * @retval -1 Error * @retval 0 Failed (cbret set) @@ -871,6 +911,7 @@ text_modify_top(struct text_handle *th, yang_stmt *ymod;/* yang module */ char *opstr; int ret; + int permit = 0; /* Assure top-levels are 'config' */ 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) goto done; /* Special case if x1 is empty, top-level only */ - if (xml_child_nr(x1) == 0){ - if (xml_child_nr(x0)) /* base tree not empty */ + if (xml_child_nr_type(x1, CX_ELMNT) == 0){ + if (xml_child_nr_type(x0, CX_ELMNT)){ /* base tree not empty */ switch(op){ case OP_DELETE: case OP_REMOVE: case OP_REPLACE: - if ((ret = nacm_datanode_write(NULL, x0, NACM_DELETE, username, xnacm, cbret)) < 0) /* XXX */ - goto done; - if (ret == 0) - goto fail; - x0c = NULL; - while ((x0c = xml_child_each(x0, x0c, CX_ELMNT)) != NULL) - xml_purge(x0c); + if (xnacm){ + if ((ret = nacm_datanode_write(NULL, x0, NACM_DELETE, username, xnacm, cbret)) < 0) + goto done; + if (ret == 0) + goto fail; + permit = 1; + } + while ((x0c = xml_child_i(x0, 0)) != 0) + if (xml_purge(x0c) < 0) + goto done; break; default: break; } + } else /* base tree empty */ 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: if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0) goto done; goto fail; break; +#endif default: break; } } /* Special case top-level replace */ - if (op == OP_REPLACE || op == OP_DELETE){ - x0c = NULL; + else if (op == OP_REPLACE || op == OP_DELETE){ + 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) - xml_purge(x0c); + if (xml_purge(x0c) < 0) + goto done; } /* Loop through children of the modification tree */ x1c = NULL; @@ -946,7 +1004,7 @@ text_modify_top(struct text_handle *th, } #endif if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, - username,xnacm, cbret)) < 0) + username, xnacm, permit, cbret)) < 0) goto done; /* If xml return - ie netconf error xml tree, then stop and return OK */ if (ret == 0) diff --git a/test/test_list.sh b/test/test_list.sh index b0e37eb6..2b3ef573 100755 --- a/test/test_list.sh +++ b/test/test_list.sh @@ -96,7 +96,7 @@ new "minmax: empty" expecteof "$clixon_netconf -qf $cfg" 0 'replace]]>]]>' '^]]>]]>$' # NYI -if false; then +if false; then # nyi new "minmax: validate should fail" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" diff --git a/test/test_nacm.sh b/test/test_nacm.sh index 528eabcc..ba3fae4d 100755 --- a/test/test_nacm.sh +++ b/test/test_nacm.sh @@ -131,9 +131,6 @@ sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data & sleep $RCWAIT -new "restconf DELETE whole datastore" -expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" "" - new2 "auth get" expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 'null ' diff --git a/test/test_nacm_datanode.sh b/test/test_nacm_datanode.sh deleted file mode 100755 index f6aa50b4..00000000 --- a/test/test_nacm_datanode.sh +++ /dev/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 . -# permit-dummy-interface: This rule gives the "limited" and "guest" -# groups read-update access to the acme 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 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 < $cfg - - $cfg - /usr/local/share/clixon - $IETFRFC - $fyang - /usr/local/lib/$APPNAME/clispec - /usr/local/lib/$APPNAME/restconf - /usr/local/lib/$APPNAME/cli - $APPNAME - /usr/local/var/$APPNAME/$APPNAME.sock - /usr/local/lib/$APPNAME/backend - /usr/local/var/$APPNAME/$APPNAME.pidfile - 1 - /usr/local/var/$APPNAME - /usr/local/lib/xmldb/text.so - false - internal - -EOF - -cat < $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 < - false - deny - deny - deny - - $NGROUPS - - - guest-acl - guest - - - deny-nacm - - /n:nacm - - * - deny - - Deny the 'guest' group any access to the /nacm data. - - - - - - limited-acl - limited - - - permit-acme-config - - /acme:acme-netconf/acme:config-parameters - - - read create update delete - - permit - - Allow the 'limited' group complete access to the acme - NETCONF configuration parameters. Showing long form - of 'access-operations' instead of shorthand. - - - - - guest-limited-acl - guest - limited - - - permit-dummy-interface - - /acme:interfaces/acme:interface[acme:name='dummy'] - - read update - permit - - Allow the 'limited' and 'guest' groups read - and update access to the dummy interface. - - - - - admin-acl - admin - - permit-interface - - /acme:interfaces/acme:interface - - * - permit - - Allow the 'admin' group full access to all acme interfaces. - - - - - $NADMIN - - - 0 -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 "$RULES]]>]]>" "^]]>]]>$" - -new "commit it" -expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" - -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 diff --git a/test/test_nacm_ext.sh b/test/test_nacm_ext.sh index bb9302bc..f4587c71 100755 --- a/test/test_nacm_ext.sh +++ b/test/test_nacm_ext.sh @@ -151,9 +151,6 @@ sudo su -c "$clixon_restconf -f $cfg -D $DBG -- -a" -s /bin/sh www-data & sleep $RCWAIT -new "restconf DELETE whole datastore" -expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" "" - new2 "auth get" expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" '{"clixon-example:state": {"op": "42"}} ' diff --git a/test/test_nacm_module.sh b/test/test_nacm_module_read.sh similarity index 100% rename from test/test_nacm_module.sh rename to test/test_nacm_module_read.sh diff --git a/test/test_nacm_module_write.sh b/test/test_nacm_module_write.sh index 5351ab33..49f708e7 100755 --- a/test/test_nacm_module_write.sh +++ b/test/test_nacm_module_write.sh @@ -6,17 +6,19 @@ # @see test_nacm.sh is slightly modified - this follows the RFC more closely # See RFC 8341 A.1 and A.2 # Note: use clixon-example instead of ietf-netconf-monitoring since the latter is -# Tests for -# deny-ncm: This rule prevents the "guest" group from reading any -# monitoring information in the "clixon-example" YANG -# module. -# permit-ncm: This rule allows the "limited" group to read the -# "clixon-example" YANG module. -# permit-exec: This rule allows the "limited" group to invoke any -# protocol operation supported by the server. -# permit-all: This rule allows the "admin" group complete access to -# all content in the server. No subsequent rule will match for the -# "admin" group because of this module rule +# A) Three tracks in the code for leaf/leaf-list, container/lists, and root +# B) Three operations: create, update, delete (write) +# C) Two access operations: permit, deny (also default deny/permit) +# This gives 18 testcases +# Set group access: +# - Admin: permit: create, update, delete +# - Limit: permit: create, delete; deny: update +# - Guest: permit: update; deny: create delete +# ops\track:| root | leaf | list +#-----------+--------+--------+---------- +# create | na | p/d | p/d +# update | p/d | p/d | p/d +# delete | p/d | p/d | p/d APPNAME=example # include err() and new() functions and creates $dir @@ -62,6 +64,17 @@ module nacm-example{ type int32; description "something to edit"; } + list a{ + key k; + leaf k{ + type string; + } + container b{ + leaf c{ + type string; + } + } + } } EOF @@ -69,77 +82,51 @@ EOF # The rule-list is from A.2 RULES=$(cat < - false + true deny deny - deny + permit $NGROUPS + + limited-acl + limited + + permit-create-delete + nacm-example + read create delete + permit + + + deny-update + nacm-example + read update + deny + + + guest-acl guest - permit-get - ietf-netconf - * - exec + permit-update + nacm-example + read update permit - - Allow invocation of get rpc - - permit-read - clixon-example - read - permit - - Do not allow guests any access to the NETCONF - monitoring information. - - - - deny-write - clixon-example - * + deny-create-delete + nacm-example + read create delete deny - - Do not allow guests any access to the NETCONF - monitoring information. - - - limited-acl - limited - - permit-ncm - clixon-example - read create update delete - permit - - Allow write access to the NETCONF monitoring information. - - - - permit-exec - * - exec - permit - - Allow invocation of the supported server operations. - - - $NADMIN - 42 - key42val42 - key43val43 EOF ) @@ -167,40 +154,103 @@ 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 "$RULES]]>]]>" "^]]>]]>$" +# Set nacm from scratch +nacm(){ + new "auth set authentication config" + expecteof "$clixon_netconf -qf $cfg" 0 "$RULES]]>]]>" "^]]>]]>$" -new "commit it" -expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" + new "commit it" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" -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)" "" + 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 -#----WRITE access -#user:admin -new2 "admin read element ok" -expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/clixon-example:translate=key42/value)" '{"clixon-example:value": "val42"} +#--------------- enable nacm +nacm + +# ops\track:| root | leaf | list +#-----------+--------+--------+---------- +# 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 '42$RULES')" '{"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="$RULES" +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 '42')" '{"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 '42')" '' + +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 '99')" '{"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 '99')" '' + +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" -expecteq "$(curl -u andy:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42/value -d '{"clixon-example:value": "val99"}')" +new2 "delete leaf deny" +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 -new2 "limit read element ok" -expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-example:translate=key42/value)" '{"clixon-example:value": "val99"} +new "delete leaf permit" +expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data/nacm-example:x)" '' + +#----- 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 'key42str')" '{"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 'key42str')" '' + +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 'key42update')" '{"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 'key42update')" '' + +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" -expecteq "$(curl -u wilma:bar -sS -X PUT http://localhost/restconf/data/clixon-example:translate=key42/value -d '{"clixon-example:value": "val55"}')" +new2 "delete list deny" +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 -new2 "guest read element ok" -expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/clixon-example:translate=key42/value)" '{"clixon-example:value": "val55"} - ' +new "delete list permit" +expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data/nacm-example:a=key42)" '' -new2 "guest write element ok" -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"}}} ' +#----- default deny (clixon-example limit and guest have default access) +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" sudo pkill -u www-data -f "/www-data/clixon_restconf" diff --git a/test/test_order.sh b/test/test_order.sh index 8f96c726..a1f646db 100755 --- a/test/test_order.sh +++ b/test/test_order.sh @@ -143,22 +143,22 @@ expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 'cb]]>]]>' "^]]>]]>$" -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 'a]]>]]>' "^]]>]]>$" new "netconf commit" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" -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 '0]]>]]>' "^]]>]]>$" new "netconf commit" expecteof "$clixon_netconf -qf $cfg -y $fyang" 0 "]]>]]>" "^]]>]]>$" -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 ']]>]]>' '^cba0]]>]]>$' # LISTS