* NACM extension (RFC8341)
* NACM module support (RFC8341 A1+A2)
* 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.
* Example user changed adm1 to andy to comply with RFC8341 example
* Yang code upgrade (RFC7950)
* RPC method input parameters validated
* see https://github.com/clicon/clixon/issues/4
* Correct XML namespace handling
* XML multiple modules was based on "loose" semantics so that yang modules were found by iterating thorugh namespaces until a match was made. This did not adhere to proper [XML namespace handling](https://www.w3.org/TR/2009/REC-xml-names-20091208), and causes problems with overlapping names and false positives. Below see XML accepted (but wrong), and correct namespace declaration:
```
<rpc><my-own-method></rpc> # Wrong but accepted
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> # Correct
<my-own-method xmlns="http://example.net/me/my-own/1.0">
</rpc>
```
* To keep old loose semantics set config option CLICON_XML_NS_ITERATE (true by default)
* XML to JSON translator support for mapping xmlns attribute to module name prefix.
* Default namespace is still "urn:ietf:params:xml:ns:netconf:base:1.0"
* See https://github.com/clicon/clixon/issues/49
* Changed all make tags --> make TAGS
* Keyvalue datastore removed (it has been disabled since 3.3.3)
* debug rpc added in example application (should be in clixon-config).
This commit is contained in:
parent
e5c0b06cf9
commit
ae1af8da9e
63 changed files with 1852 additions and 3492 deletions
|
|
@ -36,9 +36,19 @@
|
|||
#ifndef _CLIXON_NACM_H
|
||||
#define _CLIXON_NACM_H
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
/* RFC8341 defines a "recovery session" as outside the scope.
|
||||
* Clixon defines this user as having special admin rights to expemt from
|
||||
* all access control enforcements
|
||||
*/
|
||||
#define NACM_RECOVERY_USER "_nacm_recovery"
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int nacm_access(clicon_handle h, char *mode, char *name, char *username, cbuf *cbret);
|
||||
int nacm_access(clicon_handle h, char *rpc, char *module,
|
||||
char *username, cbuf *cbret);
|
||||
|
||||
#endif /* _CLIXON_NACM_H */
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
/*
|
||||
* Constants
|
||||
*/
|
||||
/* If rpc call does not have a namespace (eg w xmlns) then use the default NETCONF
|
||||
* namespace (rfc6241 3.1)
|
||||
*/
|
||||
#define DEFAULT_XML_RPC_NAMESPACE "urn:ietf:params:xml:ns:netconf:base:1.0"
|
||||
|
||||
/*
|
||||
* Types
|
||||
|
|
@ -81,10 +85,13 @@ typedef int (xml_applyfn_t)(cxobj *x, void *arg);
|
|||
#define XML_FLAG_NONE 0x10 /* Node is added as NONE */
|
||||
|
||||
|
||||
/* Sort and binary search of XML children
|
||||
* Experimental
|
||||
/* Iterate through modules to find the matching datanode
|
||||
* or rpc if no xmlns attribute specifies namespace.
|
||||
* This is loose semantics of finding namespaces.
|
||||
* And it is wrong, but is the way Clixon originally was written."
|
||||
* @see CLICON_XML_NS_ITERATE clixon configure option
|
||||
*/
|
||||
extern int xml_child_sort;
|
||||
extern int _CLICON_XML_NS_ITERATE;
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
|
|
@ -94,6 +101,7 @@ char *xml_name(cxobj *xn);
|
|||
int xml_name_set(cxobj *xn, char *name);
|
||||
char *xml_namespace(cxobj *xn);
|
||||
int xml_namespace_set(cxobj *xn, char *name);
|
||||
int xml2ns(cxobj *x, char *localname, char **namespace);
|
||||
cxobj *xml_parent(cxobj *xn);
|
||||
int xml_parent_set(cxobj *xn, cxobj *parent);
|
||||
|
||||
|
|
@ -129,6 +137,8 @@ int xml_rootchild(cxobj *xp, int i, cxobj **xcp);
|
|||
|
||||
char *xml_body(cxobj *xn);
|
||||
cxobj *xml_body_get(cxobj *xn);
|
||||
char *xml_find_type_value(cxobj *xn_parent, char *prefix,
|
||||
char *name, enum cxobj_type type);
|
||||
char *xml_find_value(cxobj *xn_parent, char *name);
|
||||
char *xml_find_body(cxobj *xn, char *name);
|
||||
cxobj *xml_find_body_obj(cxobj *xt, char *name, char *val);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
*/
|
||||
int xml2txt(FILE *f, cxobj *x, int level);
|
||||
int xml2cli(FILE *f, cxobj *x, char *prepend, enum genmodel_type gt);
|
||||
int xml_yang_validate_rpc(cxobj *xrpc);
|
||||
int xml_yang_validate_add(cxobj *xt, void *arg);
|
||||
int xml_yang_validate_all(cxobj *xt, void *arg);
|
||||
int xml2cvec(cxobj *xt, yang_stmt *ys, cvec **cvv0);
|
||||
|
|
@ -60,6 +61,7 @@ int xml_default(cxobj *x, void *arg);
|
|||
int xml_order(cxobj *x, void *arg);
|
||||
int xml_sanity(cxobj *x, void *arg);
|
||||
int xml_non_config_data(cxobj *xt, void *arg);
|
||||
int xml_spec_populate_rpc(clicon_handle h, cxobj *x, yang_spec *yspec);
|
||||
int xml_spec_populate(cxobj *x, void *arg);
|
||||
int api_path2xpath_cvv(yang_spec *yspec, cvec *cvv, int offset, cbuf *xpath);
|
||||
int api_path2xpath(yang_spec *yspec, char *api_path, cbuf *xpath);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
/*
|
||||
* Types
|
||||
*/
|
||||
struct xml;
|
||||
/*! YANG keywords from RFC6020.
|
||||
* See also keywords generated by yacc/bison in clicon_yang_parse.tab.h, but they start with K_
|
||||
* instead of Y_
|
||||
|
|
@ -159,7 +160,6 @@ typedef enum yang_class yang_class;
|
|||
*/
|
||||
#define yang_datadefinition(y) (yang_datanode(y) || (y)->ys_keyword == Y_CHOICE || (y)->ys_keyword == Y_CASE || (y)->ys_keyword == Y_AUGMENT || (y)->ys_keyword == Y_USES)
|
||||
|
||||
|
||||
/* Yang schema node .
|
||||
* See RFC 7950 Sec 3:
|
||||
* o schema node: A node in the schema tree. One of action, container,
|
||||
|
|
@ -253,15 +253,18 @@ char *yang_key2str(int keyword);
|
|||
char *yarg_prefix(yang_stmt *ys);
|
||||
char *yarg_id(yang_stmt *ys);
|
||||
int yang_nodeid_split(char *nodeid, char **prefix, char **id);
|
||||
int ys_module_by_xml(yang_spec *ysp, struct xml *xt, yang_stmt **ymodp);
|
||||
yang_stmt *ys_module(yang_stmt *ys);
|
||||
yang_spec *ys_spec(yang_stmt *ys);
|
||||
yang_stmt *yang_find_module_by_prefix(yang_stmt *ys, char *prefix);
|
||||
yang_stmt *yang_find_module_by_namespace(yang_spec *yspec, char *namespace);
|
||||
yang_stmt *yang_find(yang_node *yn, int keyword, const char *argument);
|
||||
int yang_match(yang_node *yn, int keyword, char *argument);
|
||||
yang_stmt *yang_find_datanode(yang_node *yn, char *argument);
|
||||
yang_stmt *yang_find_schemanode(yang_node *yn, char *argument);
|
||||
yang_stmt *yang_find_topnode(yang_spec *ysp, char *name, yang_class class);
|
||||
char *yang_find_myprefix(yang_stmt *ys);
|
||||
char *yang_find_mynamespace(yang_stmt *ys);
|
||||
int yang_order(yang_stmt *y);
|
||||
int yang_print(FILE *f, yang_node *yn);
|
||||
int yang_print_cbuf(cbuf *cb, yang_node *yn, int marginal);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue