NACM external file support. CLICON_NACM_FILE config option, if CLICON_NACM_MODE is external
This commit is contained in:
parent
d032dbe1cb
commit
602f5034b4
17 changed files with 867 additions and 39 deletions
|
|
@ -904,7 +904,9 @@ nacm_match_rule(clicon_handle h,
|
|||
|
||||
/*! Make nacm access control
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] mode NACMmode, internal or external
|
||||
* @param[in] name rpc name
|
||||
* @param[in] username
|
||||
* @param[out] cbret Cligen buffer result. Set to an error msg if retval=0.
|
||||
* @retval -1 Error
|
||||
* @retval 0 Not access and cbret set
|
||||
|
|
@ -913,6 +915,7 @@ nacm_match_rule(clicon_handle h,
|
|||
*/
|
||||
static int
|
||||
nacm_access(clicon_handle h,
|
||||
char *mode,
|
||||
char *name,
|
||||
char *username,
|
||||
cbuf *cbret)
|
||||
|
|
@ -935,10 +938,26 @@ nacm_access(clicon_handle h,
|
|||
int ret;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* 0. If nacm-mode is external, get NACM defintion from separet tree,
|
||||
otherwise get it from internal configuration */
|
||||
if (strcmp(mode, "external")==0){
|
||||
if ((xtop = backend_nacm_list_get(h)) == NULL){
|
||||
clicon_err(OE_XML, 0, "No nacm external tree");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (strcmp(mode, "internal")==0){
|
||||
if (xmldb_get(h, "running", "nacm", 0, &xtop) < 0)
|
||||
goto done;
|
||||
}
|
||||
else{
|
||||
clicon_err(OE_UNIX, 0, "Invalid NACM mode: %s", mode);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 1. If the "enable-nacm" leaf is set to "false", then the protocol
|
||||
operation is permitted. (or config does not exist) */
|
||||
if (xmldb_get(h, "running", "nacm", 0, &xtop) < 0)
|
||||
goto done;
|
||||
|
||||
if ((xacm = xpath_first(xtop, "nacm")) == NULL)
|
||||
goto permit;
|
||||
exec_default = xml_find_body(xacm, "exec-default");
|
||||
|
|
@ -1033,7 +1052,7 @@ nacm_access(clicon_handle h,
|
|||
retval = 1;
|
||||
done:
|
||||
clicon_debug(1, "%s retval:%d (0:deny 1:permit)", __FUNCTION__, retval);
|
||||
if (xtop)
|
||||
if (strcmp(mode, "internal")==0 && xtop)
|
||||
xml_free(xtop);
|
||||
if (gvec)
|
||||
free(gvec);
|
||||
|
|
@ -1097,15 +1116,14 @@ from_client_msg(clicon_handle h,
|
|||
while ((xe = xml_child_each(x, xe, CX_ELMNT)) != NULL) {
|
||||
name = xml_name(xe);
|
||||
clicon_debug(1, "%s name:%s", __FUNCTION__, name);
|
||||
#if 1 /* NACM */
|
||||
/* Make NACM access control if enabled as "internal"*/
|
||||
nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE");
|
||||
if (nacm_mode && strcmp(nacm_mode,"internal") == 0)
|
||||
if ((ret = nacm_access(h, name, username, cbret)) < 0)
|
||||
if (nacm_mode && strcmp(nacm_mode, "disabled") != 0){
|
||||
if ((ret = nacm_access(h, nacm_mode, name, username, cbret)) < 0)
|
||||
goto done;
|
||||
if (!ret)
|
||||
goto reply;
|
||||
#endif
|
||||
if (!ret)
|
||||
goto reply;
|
||||
}
|
||||
if (strcmp(name, "get-config") == 0){
|
||||
if (from_client_get_config(h, xe, cbret) <0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -52,4 +52,8 @@ struct client_entry *backend_client_list(clicon_handle h);
|
|||
|
||||
int backend_client_delete(clicon_handle h, struct client_entry *ce);
|
||||
|
||||
int backend_nacm_list_set(clicon_handle h, cxobj *xnacm);
|
||||
|
||||
cxobj * backend_nacm_list_get(clicon_handle h);
|
||||
|
||||
#endif /* _BACKEND_HANDLE_H_ */
|
||||
|
|
|
|||
|
|
@ -260,6 +260,59 @@ plugin_start_useroptions(clicon_handle h,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Load external NACM file
|
||||
*/
|
||||
static int
|
||||
nacm_load_external(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
char *filename; /* NACM config file */
|
||||
yang_spec *yspec = NULL;
|
||||
cxobj *xt = NULL;
|
||||
struct stat st;
|
||||
FILE *f = NULL;
|
||||
int fd;
|
||||
|
||||
filename = clicon_option_str(h, "CLICON_NACM_FILE");
|
||||
if (filename == NULL || strlen(filename)==0){
|
||||
clicon_err(OE_UNIX, errno, "CLICON_NACM_FILE not set in NACM external mode");
|
||||
goto done;
|
||||
}
|
||||
if (stat(filename, &st) < 0){
|
||||
clicon_err(OE_UNIX, errno, "%s", filename);
|
||||
goto done;
|
||||
}
|
||||
if (!S_ISREG(st.st_mode)){
|
||||
clicon_err(OE_UNIX, 0, "%s is not a regular file", filename);
|
||||
goto done;
|
||||
}
|
||||
if ((f = fopen(filename, "r")) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "configure file: %s", filename);
|
||||
return -1;
|
||||
}
|
||||
if ((yspec = yspec_new()) == NULL)
|
||||
goto done;
|
||||
if (yang_parse(h, CLIXON_DATADIR, "ietf-netconf-acm", NULL, yspec) < 0)
|
||||
goto done;
|
||||
fd = fileno(f);
|
||||
/* Read configfile */
|
||||
if (xml_parse_file(fd, "</clicon>", yspec, &xt) < 0)
|
||||
goto done;
|
||||
if (xt == NULL){
|
||||
clicon_err(OE_XML, 0, "No xml tree in %s", filename);
|
||||
goto done;
|
||||
}
|
||||
if (backend_nacm_list_set(h, xt) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
if (yspec) /* The clixon yang-spec is not used after this */
|
||||
yspec_free(yspec);
|
||||
if (f)
|
||||
fclose(f);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Merge xml in filename into database
|
||||
*/
|
||||
static int
|
||||
|
|
@ -498,6 +551,7 @@ main(int argc,
|
|||
int xml_cache;
|
||||
int xml_pretty;
|
||||
char *xml_format;
|
||||
char *nacm_mode;
|
||||
|
||||
/* In the startup, logs to stderr & syslog and debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_STDERR|CLICON_LOG_SYSLOG);
|
||||
|
|
@ -551,7 +605,12 @@ main(int argc,
|
|||
usage(argv[0], h);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* External NACM file? */
|
||||
nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE");
|
||||
if (nacm_mode && strcmp(nacm_mode, "external") == 0)
|
||||
if (nacm_load_external(h) < 0)
|
||||
goto done;
|
||||
|
||||
/* Now run through the operational args */
|
||||
opterr = 1;
|
||||
optind = 1;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ struct backend_handle {
|
|||
struct client_entry *bh_ce_list; /* The client list */
|
||||
int bh_ce_nr; /* Number of clients, just increment */
|
||||
struct handle_subscription *bh_subscription; /* Event subscription list */
|
||||
cxobj *bh_nacm; /* NACM external struct */
|
||||
};
|
||||
|
||||
/*! Creates and returns a clicon config handle for other CLICON API calls
|
||||
|
|
@ -106,11 +107,14 @@ backend_handle_init(void)
|
|||
int
|
||||
backend_handle_exit(clicon_handle h)
|
||||
{
|
||||
struct backend_handle *bh = handle(h);
|
||||
struct client_entry *ce;
|
||||
|
||||
/* only delete client structs, not close sockets, etc, see backend_client_rm */
|
||||
while ((ce = backend_client_list(h)) != NULL)
|
||||
backend_client_delete(h, ce);
|
||||
if (bh->bh_nacm)
|
||||
xml_free(bh->bh_nacm);
|
||||
clicon_handle_exit(h); /* frees h and options */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -431,3 +435,22 @@ subscription_each(clicon_handle h,
|
|||
return hs;
|
||||
}
|
||||
|
||||
int
|
||||
backend_nacm_list_set(clicon_handle h,
|
||||
cxobj *xnacm)
|
||||
{
|
||||
struct backend_handle *bh = handle(h);
|
||||
|
||||
if (bh->bh_nacm)
|
||||
xml_free(bh->bh_nacm);
|
||||
bh->bh_nacm = xnacm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cxobj *
|
||||
backend_nacm_list_get(clicon_handle h)
|
||||
{
|
||||
struct backend_handle *bh = handle(h);
|
||||
|
||||
return bh->bh_nacm;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ distclean: clean
|
|||
# Put config file in etc/
|
||||
install: install-lib $(APPL)
|
||||
install -d -m 0755 $(DESTDIR)$(bindir)
|
||||
install -m 0644 -s $(APPL) $(DESTDIR)$(bindir)
|
||||
install -m 0755 -s $(APPL) $(DESTDIR)$(bindir)
|
||||
|
||||
install-lib: $(MYLIB)
|
||||
install -d -m 0755 $(DESTDIR)$(libdir)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue