* Restructure and more generic plugin API (cli,backend,restconf,netconf)
* For preparation for authorization RFC8341
* Plugins add clixon_plugin_init() and api struct for function pointers, eg:
```
static const struct clixon_plugin_api api = {
"example",
clixon_plugin_init,
...
}
clixon_plugin_api *clixon_plugin_init(clicon_handle h)
{
return (void*)&api;
}
```
* Moved specific plugin functions from apps/ to generic functions in lib/
* New generic plugin load function: clixon_plugins_load()
* Removed client-local netconf plugins netconf_plugin_callbacks()
* This was code used before generic YANG rpc calls
* Added username to clixon handle:
* clicon_username_get() / clicon_username_set()
* Added authentication plugin callback
* Removed some obscure plugin code that seem not to be used (please report if needed!)
* CLI parse hook
* CLICON_FIND_PLUGIN
* clicon_valcb()
* Removed username to rpc calls (added below)
This commit is contained in:
parent
b8e35742b9
commit
79e3fbdaa9
41 changed files with 470 additions and 772 deletions
|
|
@ -71,7 +71,7 @@
|
|||
* @note the following should match the prototypes in clixon_backend.h
|
||||
*/
|
||||
#define PLUGIN_RESET "plugin_reset"
|
||||
typedef int (plgreset_t)(clicon_handle h, const char *db); /* Reset system status */
|
||||
|
||||
|
||||
/*! Plugin callback, if defined called to get state data from plugin
|
||||
* @param[in] h Clicon handle
|
||||
|
|
@ -82,7 +82,7 @@ typedef int (plgreset_t)(clicon_handle h, const char *db); /* Reset system statu
|
|||
* @see xmldb_get
|
||||
*/
|
||||
#define PLUGIN_STATEDATA "plugin_statedata"
|
||||
typedef int (plgstatedata_t)(clicon_handle h, char *xpath, cxobj *xtop);
|
||||
|
||||
|
||||
#define PLUGIN_TRANS_BEGIN "transaction_begin"
|
||||
#define PLUGIN_TRANS_VALIDATE "transaction_validate"
|
||||
|
|
@ -92,8 +92,6 @@ typedef int (plgstatedata_t)(clicon_handle h, char *xpath, cxobj *xtop);
|
|||
#define PLUGIN_TRANS_ABORT "transaction_abort"
|
||||
|
||||
|
||||
typedef int (trans_cb_t)(clicon_handle h, transaction_data td); /* Transaction cbs */
|
||||
|
||||
/* Backend (config) plugins */
|
||||
struct plugin {
|
||||
char p_name[PATH_MAX]; /* Plugin name */
|
||||
|
|
@ -118,28 +116,6 @@ struct plugin {
|
|||
static int _nplugins = 0;
|
||||
static struct plugin *_plugins = NULL;
|
||||
|
||||
/*! Find a plugin by name and return the dlsym handl
|
||||
* Used by libclicon code to find callback funcctions in plugins.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] h Name of plugin
|
||||
* @retval handle Plugin handle if found
|
||||
* @retval NULL Not found
|
||||
*/
|
||||
static void *
|
||||
config_find_plugin(clicon_handle h,
|
||||
char *name)
|
||||
{
|
||||
int i;
|
||||
struct plugin *p;
|
||||
|
||||
for (i = 0; i < _nplugins; i++){
|
||||
p = &_plugins[i];
|
||||
if (strcmp(p->p_name, name) == 0)
|
||||
return p->p_handle;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Initialize plugin code (not the plugins themselves)
|
||||
* @param[in] h Clicon handle
|
||||
* @retval 0 OK
|
||||
|
|
@ -148,14 +124,6 @@ config_find_plugin(clicon_handle h,
|
|||
int
|
||||
backend_plugin_init(clicon_handle h)
|
||||
{
|
||||
find_plugin_t *fp = config_find_plugin;
|
||||
clicon_hash_t *data = clicon_data(h);
|
||||
|
||||
/* Register CLICON_FIND_PLUGIN in data hash */
|
||||
if (hash_add(data, "CLICON_FIND_PLUGIN", &fp, sizeof(fp)) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "failed to register CLICON_FIND_PLUGIN");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,8 +92,6 @@ int subscription_delete(clicon_handle h, char *stream,
|
|||
struct handle_subscription *subscription_each(clicon_handle h,
|
||||
struct handle_subscription *hprev);
|
||||
|
||||
/* XXX backward compat */
|
||||
#define backend_netconf_register_callback(a,b,c,d) backend_rpc_cb_register(a,b,c,d)
|
||||
int backend_rpc_cb_register(clicon_handle h, backend_rpc_cb cb, void *arg,
|
||||
char *tag);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ typedef int (*downcall_cb)(clicon_handle h, uint16_t op, uint16_t len,
|
|||
* (defined in config_dbdep.c)
|
||||
* @see transaction_data_t internal structure
|
||||
*/
|
||||
typedef void *transaction_data;
|
||||
uint64_t transaction_id(transaction_data td);
|
||||
void *transaction_arg(transaction_data td);
|
||||
cxobj *transaction_src(transaction_data td);
|
||||
|
|
|
|||
|
|
@ -654,13 +654,13 @@ compare_dbs(clicon_handle h,
|
|||
astext = cv_int32_get(cvec_i(argv, 0));
|
||||
else
|
||||
astext = 0;
|
||||
if (clicon_rpc_get_config(h, "running", "/", NULL, &xc1) < 0)
|
||||
if (clicon_rpc_get_config(h, "running", "/", &xc1) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Get configuration", xerr);
|
||||
goto done;
|
||||
}
|
||||
if (clicon_rpc_get_config(h, "candidate", "/", NULL, &xc2) < 0)
|
||||
if (clicon_rpc_get_config(h, "candidate", "/", &xc2) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Get configuration", xerr);
|
||||
|
|
@ -827,7 +827,7 @@ save_config_file(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
filename = cv_string_get(cv);
|
||||
if (clicon_rpc_get_config(h, dbstr,"/", NULL, &xt) < 0)
|
||||
if (clicon_rpc_get_config(h, dbstr,"/", &xt) < 0)
|
||||
goto done;
|
||||
if (xt == NULL){
|
||||
clicon_err(OE_CFG, 0, "get config: empty tree"); /* Shouldnt happen */
|
||||
|
|
@ -1180,7 +1180,7 @@ cli_copy_config(clicon_handle h,
|
|||
cprintf(cb, xpath, keyname, fromname);
|
||||
|
||||
/* Get from object configuration and store in x1 */
|
||||
if (clicon_rpc_get_config(h, db, cbuf_get(cb), NULL, &x1) < 0)
|
||||
if (clicon_rpc_get_config(h, db, cbuf_get(cb), &x1) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Get configuration", xerr);
|
||||
|
|
|
|||
|
|
@ -66,13 +66,11 @@
|
|||
#include "cli_plugin.h"
|
||||
#include "cli_handle.h"
|
||||
|
||||
|
||||
/*! Name of master plugin functions
|
||||
* More in clicon_plugin.h
|
||||
* @note not really used consider documenting or remove
|
||||
*/
|
||||
#define PLUGIN_PROMPT_HOOK "plugin_prompt_hook"
|
||||
#define PLUGIN_PARSE_HOOK "plugin_parse_hook"
|
||||
#define PLUGIN_SUSP_HOOK "plugin_susp_hook"
|
||||
|
||||
/*
|
||||
|
|
@ -380,7 +378,6 @@ cli_plugin_load_dir(clicon_handle h,
|
|||
struct stat st;
|
||||
int retval = -1;
|
||||
|
||||
|
||||
/* Format master plugin path */
|
||||
if ((master_plugin = clicon_master_plugin(h)) == NULL){
|
||||
clicon_err(OE_PLUGIN, 0, "clicon_master_plugin option not set");
|
||||
|
|
@ -403,8 +400,6 @@ cli_plugin_load_dir(clicon_handle h,
|
|||
/* Look up certain call-backs in master plugin */
|
||||
stx->stx_prompt_hook =
|
||||
dlsym(cp->cp_handle, PLUGIN_PROMPT_HOOK);
|
||||
stx->stx_parse_hook =
|
||||
dlsym(cp->cp_handle, PLUGIN_PARSE_HOOK);
|
||||
stx->stx_susp_hook =
|
||||
dlsym(cp->cp_handle, PLUGIN_SUSP_HOOK);
|
||||
INSQ(cp, stx->stx_plugins);
|
||||
|
|
@ -679,15 +674,6 @@ clicon_parse(clicon_handle h,
|
|||
goto done;
|
||||
case CG_NOMATCH: /* no match */
|
||||
smode = NULL;
|
||||
if (stx->stx_parse_hook) {
|
||||
/* Try to find a match in upper modes, a'la IOS. */
|
||||
if ((modename = stx->stx_parse_hook(h, cmd, modename)) != NULL) {
|
||||
if ((smode = syntax_mode_find(stx, modename, 0)) != NULL)
|
||||
continue;
|
||||
else
|
||||
cli_output(f, "Can't find syntax mode '%s'\n", modename);
|
||||
}
|
||||
}
|
||||
/* clicon_err(OE_CFG, 0, "CLI syntax error: \"%s\": %s",
|
||||
cmd, cli_nomatch(h));*/
|
||||
cli_output(f, "CLI syntax error: \"%s\": %s\n",
|
||||
|
|
@ -745,42 +731,14 @@ clicon_cliread(clicon_handle h)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* cli_find_plugin
|
||||
* Find a plugin by name and return the dlsym handl
|
||||
* Used by libclicon code to find callback funcctions in plugins.
|
||||
*/
|
||||
static void *
|
||||
cli_find_plugin(clicon_handle h, char *plugin)
|
||||
{
|
||||
struct cli_plugin *p;
|
||||
|
||||
p = plugin_find_cli(cli_syntax(h), plugin);
|
||||
if (p)
|
||||
return p->cp_handle;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*! Initialize plugin code (not the plugins themselves)
|
||||
*/
|
||||
int
|
||||
cli_plugin_init(clicon_handle h)
|
||||
{
|
||||
find_plugin_t *fp = cli_find_plugin;
|
||||
clicon_hash_t *data = clicon_data(h);
|
||||
|
||||
/* Register CLICON_FIND_PLUGIN in data hash */
|
||||
if (hash_add(data, "CLICON_FIND_PLUGIN", &fp, sizeof(fp)) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "failed to register CLICON_FIND_PLUGIN");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* CLI PLUGIN INTERFACE, PUBLIC SECTION
|
||||
|
|
@ -816,7 +774,6 @@ cli_syntax_mode(clicon_handle h)
|
|||
return csm->csm_name;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback from cli_set_prompt(). Set prompt format for syntax mode
|
||||
* Arguments:
|
||||
|
|
@ -880,7 +837,6 @@ prompt_fmt (char *prompt, size_t plen, char *fmt, ...)
|
|||
cprintf(cb, "%c", *s);
|
||||
s++;
|
||||
}
|
||||
|
||||
done:
|
||||
if (cb)
|
||||
fmt = cbuf_get(cb);
|
||||
|
|
@ -905,55 +861,3 @@ cli_prompt(char *fmt)
|
|||
return prompt;
|
||||
}
|
||||
|
||||
/*! Find a cli plugin based on name and resolve a function pointer in it.
|
||||
* Callback from clicon_dbvars_parse()
|
||||
* Find a cli plugin based on name if given and use dlsym to resolve a
|
||||
* function pointer in it.
|
||||
* Call the resolved function to get the cgv populated
|
||||
*/
|
||||
int
|
||||
clicon_valcb(void *arg, cvec *vars, cg_var *cgv, char *fname, cg_var *funcarg)
|
||||
{
|
||||
char *func;
|
||||
char *plgnam = NULL;
|
||||
void *handle;
|
||||
struct cli_plugin *p;
|
||||
cli_valcb_t *cb;
|
||||
clicon_handle h = (clicon_handle)arg;
|
||||
|
||||
/* Make copy */
|
||||
if ((fname = strdup(fname)) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "strdup");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Extract plugin name if any */
|
||||
if ((func = strstr(fname, "::")) != NULL) {
|
||||
*func = '\0';
|
||||
func += 2;
|
||||
plgnam = fname;
|
||||
}
|
||||
else
|
||||
func = fname;
|
||||
|
||||
/* If we have specified a plugin name, find the handle to be used
|
||||
* with dlsym()
|
||||
*/
|
||||
handle = NULL;
|
||||
if (plgnam && (p = plugin_find_cli(cli_syntax(h), plgnam)))
|
||||
handle = p->cp_handle;
|
||||
|
||||
/* Look up function pointer */
|
||||
if ((cb = dlsym(handle, func)) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "unable to find %s()", func);
|
||||
free(fname);
|
||||
return -1;
|
||||
}
|
||||
free(fname);
|
||||
|
||||
if (cb(vars, cgv, funcarg) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,10 +77,9 @@ typedef struct {
|
|||
int stx_nplugins; /* Number of plugins */
|
||||
struct cli_plugin *stx_plugins; /* List of plugins */
|
||||
int stx_nmodes; /* Number of syntax modes */
|
||||
cli_syntaxmode_t *stx_active_mode; /* Current active syntax mode */
|
||||
cli_syntaxmode_t *stx_modes; /* List of syntax modes */
|
||||
cli_syntaxmode_t *stx_active_mode; /* Current active syntax mode */
|
||||
cli_syntaxmode_t *stx_modes; /* List of syntax modes */
|
||||
cli_prompthook_t *stx_prompt_hook; /* Prompt hook */
|
||||
cli_parsehook_t *stx_parse_hook; /* Parse mode hook */
|
||||
cli_susphook_t *stx_susp_hook; /* Ctrl-Z hook from getline() */
|
||||
} cli_syntax_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ expand_dbvar(void *h,
|
|||
goto done;
|
||||
|
||||
/* XXX read whole configuration, why not send xpath? */
|
||||
if (clicon_rpc_get_config(h, dbstr, "/", NULL, &xt) < 0)
|
||||
if (clicon_rpc_get_config(h, dbstr, "/", &xt) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Get configuration", xerr);
|
||||
|
|
@ -487,7 +487,7 @@ cli_show_config(clicon_handle h,
|
|||
else
|
||||
cprintf(cbxpath, "%s", xpath);
|
||||
/* Get configuration from database */
|
||||
if (clicon_rpc_get_config(h, db, cbuf_get(cbxpath), NULL, &xt) < 0)
|
||||
if (clicon_rpc_get_config(h, db, cbuf_get(cbxpath), &xt) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Get configuration", xerr);
|
||||
|
|
@ -571,7 +571,7 @@ show_conf_xpath(clicon_handle h,
|
|||
}
|
||||
cv = cvec_find_var(cvv, "xpath");
|
||||
xpath = cv_string_get(cv);
|
||||
if (clicon_rpc_get_config(h, str, xpath, NULL, &xt) < 0)
|
||||
if (clicon_rpc_get_config(h, str, xpath, &xt) < 0)
|
||||
goto done;
|
||||
if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
|
||||
clicon_rpc_generate_error("Get configuration", xerr);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ MYLIBLINK = lib$(MYNAME)$(SH_SUFFIX)
|
|||
MYLIB = $(MYLIBLINK).$(CLIXON_MAJOR).$(CLIXON_MINOR)
|
||||
MYLIBSO = $(MYLIBLINK).$(CLIXON_MAJOR)
|
||||
|
||||
LIBSRC = netconf_hello.c netconf_rpc.c netconf_filter.c netconf_lib.c netconf_plugin.c
|
||||
LIBSRC = netconf_hello.c netconf_rpc.c netconf_filter.c netconf_lib.c
|
||||
LIBOBJS = $(LIBSRC:.c=.o)
|
||||
|
||||
all: $(MYLIB) $(APPL)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@
|
|||
#include "clixon_netconf.h"
|
||||
#include "netconf_lib.h"
|
||||
#include "netconf_hello.h"
|
||||
#include "netconf_plugin.h"
|
||||
#include "netconf_rpc.h"
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
|
|
@ -307,6 +306,7 @@ main(int argc,
|
|||
int quiet = 0;
|
||||
clicon_handle h;
|
||||
int use_syslog;
|
||||
char *dir;
|
||||
|
||||
/* Defaults */
|
||||
use_syslog = 0;
|
||||
|
|
@ -383,13 +383,14 @@ main(int argc,
|
|||
goto done;
|
||||
|
||||
/* Initialize plugins group */
|
||||
if (netconf_plugin_load(h) < 0)
|
||||
goto done;
|
||||
if ((dir = clicon_netconf_dir(h)) != NULL)
|
||||
if (clixon_plugins_load(h, dir) < 0)
|
||||
goto done;
|
||||
|
||||
/* Call start function is all plugins before we go interactive */
|
||||
tmp = *(argv-1);
|
||||
*(argv-1) = argv0;
|
||||
netconf_plugin_start(h, argc+1, argv-1);
|
||||
clixon_plugin_start(h, argc+1, argv-1);
|
||||
*(argv-1) = tmp;
|
||||
|
||||
if (!quiet)
|
||||
|
|
@ -401,7 +402,7 @@ main(int argc,
|
|||
if (event_loop() < 0)
|
||||
goto done;
|
||||
done:
|
||||
netconf_plugin_unload(h);
|
||||
clixon_plugin_unload(h);
|
||||
netconf_terminate(h);
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
|
||||
clicon_log(LOG_NOTICE, "%s: %u Terminated\n", __PROGRAM__, getpid());
|
||||
|
|
|
|||
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
the GNU General Public License Version 3 or later (the "GPL"),
|
||||
in which case the provisions of the GPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of the GPL, and not to allow others to
|
||||
use your version of this file under the terms of Apache License version 2,
|
||||
indicate your decision by deleting the provisions above and replace them with
|
||||
the notice and other provisions required by the GPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the Apache License version 2 or the GPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
*
|
||||
* handling netconf plugins
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <dirent.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* cligen */
|
||||
#include <cligen/cligen.h>
|
||||
|
||||
/* clicon */
|
||||
#include <clixon/clixon.h>
|
||||
|
||||
/* clicon netconf*/
|
||||
#include "clixon_netconf.h"
|
||||
#include "netconf_lib.h"
|
||||
#include "netconf_plugin.h"
|
||||
|
||||
/* Database dependency description */
|
||||
struct netconf_reg {
|
||||
qelem_t nr_qelem; /* List header */
|
||||
netconf_cb_t nr_callback; /* Validation/Commit Callback */
|
||||
void *nr_arg; /* Application specific argument to cb */
|
||||
char *nr_tag; /* Xml tag when matched, callback called */
|
||||
};
|
||||
typedef struct netconf_reg netconf_reg_t;
|
||||
|
||||
static int nplugins = 0;
|
||||
static plghndl_t *plugins = NULL;
|
||||
static netconf_reg_t *deps = NULL;
|
||||
|
||||
/*! Load all plugins you can find in CLICON_NETCONF_DIR
|
||||
*/
|
||||
int
|
||||
netconf_plugin_load(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
char *dir;
|
||||
int ndp;
|
||||
struct dirent *dp = NULL;
|
||||
int i;
|
||||
char filename[MAXPATHLEN];
|
||||
plghndl_t *handle;
|
||||
|
||||
/* If no DIR defined, then dont load plugins */
|
||||
if ((dir = clicon_netconf_dir(h)) == NULL){
|
||||
retval = 0;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
/* Get plugin objects names from plugin directory */
|
||||
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG))<0)
|
||||
goto quit;
|
||||
|
||||
/* Load all plugins */
|
||||
for (i = 0; i < ndp; i++) {
|
||||
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
|
||||
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
|
||||
(int)strlen(filename), filename);
|
||||
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
|
||||
goto quit;
|
||||
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "realloc");
|
||||
goto quit;
|
||||
}
|
||||
plugins[nplugins++] = handle;
|
||||
}
|
||||
retval = 0;
|
||||
quit:
|
||||
if (dp)
|
||||
free(dp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Unload all netconf plugins */
|
||||
int
|
||||
netconf_plugin_unload(clicon_handle h)
|
||||
{
|
||||
int i;
|
||||
netconf_reg_t *nr;
|
||||
|
||||
while((nr = deps) != NULL) {
|
||||
DELQ(nr, deps, netconf_reg_t *);
|
||||
if (nr->nr_tag)
|
||||
free(nr->nr_tag);
|
||||
free(nr);
|
||||
}
|
||||
for (i = 0; i < nplugins; i++)
|
||||
plugin_unload(h, plugins[i]);
|
||||
if (plugins){
|
||||
free(plugins);
|
||||
plugins = NULL;
|
||||
}
|
||||
nplugins = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Call plugin_start in all plugins
|
||||
*/
|
||||
int
|
||||
netconf_plugin_start(clicon_handle h, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
plgstart_t *startfn;
|
||||
|
||||
for (i = 0; i < nplugins; i++) {
|
||||
/* Call exit function is it exists */
|
||||
if ((startfn = dlsym(plugins[i], PLUGIN_START)) == NULL)
|
||||
break;
|
||||
optind = 0;
|
||||
if (startfn(h, argc, argv) < 0) {
|
||||
clicon_debug(1, "plugin_start() failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*! Register netconf callback
|
||||
* Called from plugin to register a callback for a specific netconf XML tag.
|
||||
*/
|
||||
int
|
||||
netconf_register_callback(clicon_handle h,
|
||||
netconf_cb_t cb, /* Callback called */
|
||||
void *arg, /* Arg to send to callback */
|
||||
char *tag) /* Xml tag when callback is made */
|
||||
{
|
||||
netconf_reg_t *nr;
|
||||
|
||||
if ((nr = malloc(sizeof(netconf_reg_t))) == NULL) {
|
||||
clicon_err(OE_DB, errno, "malloc: %s", strerror(errno));
|
||||
goto catch;
|
||||
}
|
||||
memset (nr, 0, sizeof (*nr));
|
||||
nr->nr_callback = cb;
|
||||
nr->nr_arg = arg;
|
||||
nr->nr_tag = strdup(tag); /* strdup */
|
||||
INSQ(nr, deps);
|
||||
return 0;
|
||||
catch:
|
||||
if (nr){
|
||||
if (nr->nr_tag)
|
||||
free(nr->nr_tag);
|
||||
free(nr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*! See if there is any callback registered for this tag
|
||||
*
|
||||
* Look for local (client-side) netconf plugins. This feature may no
|
||||
* longer be necessary as generic RPC:s should be handled by backend.
|
||||
*
|
||||
* @param[in] h clicon handle
|
||||
* @param[in] xn Sub-tree (under xorig) at child of rpc: <rpc><xn></rpc>.
|
||||
* @param[out] xret Return XML, error or OK
|
||||
*
|
||||
* @retval -1 Error
|
||||
* @retval 0 OK, not found handler.
|
||||
* @retval 1 OK, handler called
|
||||
*/
|
||||
int
|
||||
netconf_plugin_callbacks(clicon_handle h,
|
||||
cxobj *xn,
|
||||
cxobj **xret)
|
||||
{
|
||||
int retval = -1;
|
||||
netconf_reg_t *nreg;
|
||||
|
||||
if (deps != NULL){
|
||||
nreg = deps;
|
||||
do {
|
||||
if (strcmp(nreg->nr_tag, xml_name(xn)) == 0){
|
||||
if ((retval = nreg->nr_callback(h, xn, xret, nreg->nr_arg)) < 0)
|
||||
goto done;
|
||||
retval = 1; /* handled */
|
||||
goto done;
|
||||
}
|
||||
nreg = NEXTQ(netconf_reg_t *, nreg);
|
||||
} while (nreg != deps);
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||
|
||||
This file is part of CLIXON.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
the GNU General Public License Version 3 or later (the "GPL"),
|
||||
in which case the provisions of the GPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of the GPL, and not to allow others to
|
||||
use your version of this file under the terms of Apache License version 2,
|
||||
indicate your decision by deleting the provisions above and replace them with
|
||||
the notice and other provisions required by the GPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the Apache License version 2 or the GPL.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
*
|
||||
* handling netconf plugins
|
||||
*****************************************************************************/
|
||||
#ifndef _NETCONF_PLUGIN_H_
|
||||
#define _NETCONF_PLUGIN_H_
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int netconf_plugin_load(clicon_handle h);
|
||||
|
||||
int netconf_plugin_start(clicon_handle h, int argc, char **argv);
|
||||
|
||||
int netconf_plugin_unload(clicon_handle h);
|
||||
|
||||
int netconf_plugin_callbacks(clicon_handle h, cxobj *xn, cxobj **xret);
|
||||
|
||||
#endif /* _NETCONF_PLUGIN_H_ */
|
||||
|
|
@ -65,7 +65,6 @@
|
|||
#include "clixon_netconf.h"
|
||||
#include "netconf_lib.h"
|
||||
#include "netconf_filter.h"
|
||||
#include "netconf_plugin.h"
|
||||
#include "netconf_rpc.h"
|
||||
|
||||
/*
|
||||
|
|
@ -1018,14 +1017,8 @@ netconf_rpc_dispatch(clicon_handle h,
|
|||
}
|
||||
/* Others */
|
||||
else {
|
||||
/* Look for local (client-side) netconf plugins. This feature may no
|
||||
* longer be necessary as generic RPC:s should be handled by backend.
|
||||
*/
|
||||
if ((retval = netconf_plugin_callbacks(h, xe, xret)) < 0)
|
||||
if ((retval = netconf_application_rpc(h, xe, xret)) < 0)
|
||||
goto done;
|
||||
if (retval == 0)
|
||||
if ((retval = netconf_application_rpc(h, xe, xret)) < 0)
|
||||
goto done;
|
||||
if (retval == 0){ /* not handled by callback */
|
||||
xml_parse_va(xret, NULL, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ LIBDEPS = $(top_srcdir)/lib/src/$(CLIXON_LIB)
|
|||
|
||||
LIBS = -L$(top_srcdir)/lib/src @LIBS@ -l:$(CLIXON_LIB)
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@ -fPIC
|
||||
|
||||
INCLUDES = -I. -I$(top_srcdir)/lib/src -I$(top_srcdir)/lib -I$(top_srcdir)/include -I$(top_srcdir) @INCLUDES@
|
||||
|
||||
|
|
|
|||
|
|
@ -60,11 +60,6 @@ int notimplemented(FCGX_Request *r);
|
|||
int clicon_debug_xml(int dbglevel, char *str, cxobj *cx);
|
||||
int test(FCGX_Request *r, int dbg);
|
||||
cbuf *readdata(FCGX_Request *r);
|
||||
|
||||
int restconf_plugin_load(clicon_handle h);
|
||||
int restconf_plugin_start(clicon_handle h, int argc, char **argv);
|
||||
int restconf_plugin_unload(clicon_handle h);
|
||||
int restconf_credentials(clicon_handle h, FCGX_Request *r, char **user);
|
||||
int get_user_cookie(char *cookiestr, char *attribute, char **val);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -358,129 +358,6 @@ readdata(FCGX_Request *r)
|
|||
return cb;
|
||||
}
|
||||
|
||||
|
||||
static int nplugins = 0;
|
||||
static plghndl_t *plugins = NULL;
|
||||
static plgcredentials_t *_credentials_fn = NULL; /* Credentials callback */
|
||||
|
||||
/*! Load all plugins you can find in CLICON_RESTCONF_DIR
|
||||
*/
|
||||
int
|
||||
restconf_plugin_load(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
char *dir;
|
||||
int ndp;
|
||||
struct dirent *dp = NULL;
|
||||
int i;
|
||||
plghndl_t *handle;
|
||||
char filename[MAXPATHLEN];
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
if ((dir = clicon_restconf_dir(h)) == NULL){
|
||||
retval = 0;
|
||||
goto quit;
|
||||
}
|
||||
/* Get plugin objects names from plugin directory */
|
||||
if((ndp = clicon_file_dirent(dir, &dp, "(.so)$", S_IFREG))<0)
|
||||
goto quit;
|
||||
/* Load all plugins */
|
||||
for (i = 0; i < ndp; i++) {
|
||||
snprintf(filename, MAXPATHLEN-1, "%s/%s", dir, dp[i].d_name);
|
||||
clicon_debug(1, "DEBUG: Loading plugin '%.*s' ...",
|
||||
(int)strlen(filename), filename);
|
||||
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
|
||||
goto quit;
|
||||
if ((_credentials_fn = dlsym(handle, PLUGIN_CREDENTIALS)) == NULL)
|
||||
clicon_debug(1, "Failed to load %s", PLUGIN_CREDENTIALS);
|
||||
else
|
||||
clicon_debug(1, "%s callback loaded", PLUGIN_CREDENTIALS);
|
||||
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
|
||||
clicon_err(OE_UNIX, errno, "realloc");
|
||||
goto quit;
|
||||
}
|
||||
plugins[nplugins++] = handle;
|
||||
}
|
||||
retval = 0;
|
||||
quit:
|
||||
if (dp)
|
||||
free(dp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Unload all restconf plugins */
|
||||
int
|
||||
restconf_plugin_unload(clicon_handle h)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nplugins; i++)
|
||||
plugin_unload(h, plugins[i]);
|
||||
if (plugins){
|
||||
free(plugins);
|
||||
plugins = NULL;
|
||||
}
|
||||
nplugins = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Call plugin_start in all plugins
|
||||
*/
|
||||
int
|
||||
restconf_plugin_start(clicon_handle h,
|
||||
int argc,
|
||||
char **argv)
|
||||
{
|
||||
int i;
|
||||
plgstart_t *startfn;
|
||||
|
||||
for (i = 0; i < nplugins; i++) {
|
||||
/* Call exit function is it exists */
|
||||
if ((startfn = dlsym(plugins[i], PLUGIN_START)) == NULL)
|
||||
break;
|
||||
optind = 0;
|
||||
if (startfn(h, argc, argv) < 0) {
|
||||
clicon_debug(1, "plugin_start() failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Run the restconf user-defined credentials callback if present
|
||||
* The callback is expected to return the authenticated user, or NULL if not
|
||||
* authenticasted.
|
||||
* If no callback exists, return user "none"
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] r Fastcgi request handle
|
||||
* @param[out] user The authenticated user (or NULL). Malloced, must be freed.
|
||||
*/
|
||||
int
|
||||
restconf_credentials(clicon_handle h,
|
||||
FCGX_Request *r,
|
||||
char **user)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
/* If no authentication callback then allow anything. Is this OK? */
|
||||
if (_credentials_fn == NULL){
|
||||
if ((*user = strdup("none")) == NULL){
|
||||
clicon_err(OE_XML, errno, "strdup");
|
||||
goto done;
|
||||
}
|
||||
goto ok;
|
||||
}
|
||||
if (_credentials_fn(h, r, user) < 0)
|
||||
*user = NULL;
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
clicon_debug(1, "%s retval:%d user:%s", __FUNCTION__, retval, *user);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Parse a cookie string and return value of cookie attribute
|
||||
* @param[in] cookiestr cookie string according to rfc6265 (modified)
|
||||
* @param[in] attribute cookie attribute
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ int notimplemented(FCGX_Request *r);
|
|||
int clicon_debug_xml(int dbglevel, char *str, cxobj *cx);
|
||||
int test(FCGX_Request *r, int dbg);
|
||||
cbuf *readdata(FCGX_Request *r);
|
||||
|
||||
int restconf_plugin_load(clicon_handle h);
|
||||
int restconf_plugin_start(clicon_handle h, int argc, char **argv);
|
||||
int restconf_plugin_unload(clicon_handle h);
|
||||
int restconf_credentials(clicon_handle h, FCGX_Request *r, char **user);
|
||||
int get_user_cookie(char *cookiestr, char *attribute, char **val);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@
|
|||
* @param[in] pi Offset, where to start pcvec
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] dvec Stream input daat
|
||||
* @param[in] username Authenticated user
|
||||
*/
|
||||
static int
|
||||
api_data(clicon_handle h,
|
||||
|
|
@ -101,8 +100,7 @@ api_data(clicon_handle h,
|
|||
cvec *pcvec,
|
||||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username)
|
||||
char *data)
|
||||
{
|
||||
int retval = -1;
|
||||
char *request_method;
|
||||
|
|
@ -127,17 +125,17 @@ api_data(clicon_handle h,
|
|||
if (strcmp(request_method, "OPTIONS")==0)
|
||||
retval = api_data_options(h, r);
|
||||
else if (strcmp(request_method, "HEAD")==0)
|
||||
retval = api_data_head(h, r, pcvec, pi, qvec, username, pretty, use_xml);
|
||||
retval = api_data_head(h, r, pcvec, pi, qvec, pretty, use_xml);
|
||||
else if (strcmp(request_method, "GET")==0)
|
||||
retval = api_data_get(h, r, pcvec, pi, qvec, username, pretty, use_xml);
|
||||
retval = api_data_get(h, r, pcvec, pi, qvec, pretty, use_xml);
|
||||
else if (strcmp(request_method, "POST")==0)
|
||||
retval = api_data_post(h, r, api_path, pcvec, pi, qvec, data, username, pretty, use_xml, parse_xml);
|
||||
retval = api_data_post(h, r, api_path, pcvec, pi, qvec, data, pretty, use_xml, parse_xml);
|
||||
else if (strcmp(request_method, "PUT")==0)
|
||||
retval = api_data_put(h, r, api_path, pcvec, pi, qvec, data, username, pretty, use_xml, parse_xml);
|
||||
retval = api_data_put(h, r, api_path, pcvec, pi, qvec, data, pretty, use_xml, parse_xml);
|
||||
else if (strcmp(request_method, "PATCH")==0)
|
||||
retval = api_data_patch(h, r, api_path, pcvec, pi, qvec, data, username);
|
||||
retval = api_data_patch(h, r, api_path, pcvec, pi, qvec, data);
|
||||
else if (strcmp(request_method, "DELETE")==0)
|
||||
retval = api_data_delete(h, r, api_path, pi, username, pretty, use_xml);
|
||||
retval = api_data_delete(h, r, api_path, pi, pretty, use_xml);
|
||||
else
|
||||
retval = notfound(r);
|
||||
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
|
||||
|
|
@ -152,7 +150,6 @@ api_data(clicon_handle h,
|
|||
* @param[in] pi Offset, where to start pcvec
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] data Stream input data
|
||||
* @param[in] username Authenticated user
|
||||
*/
|
||||
static int
|
||||
api_operations(clicon_handle h,
|
||||
|
|
@ -161,8 +158,7 @@ api_operations(clicon_handle h,
|
|||
cvec *pcvec,
|
||||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username)
|
||||
char *data)
|
||||
{
|
||||
int retval = -1;
|
||||
char *request_method;
|
||||
|
|
@ -185,9 +181,9 @@ api_operations(clicon_handle h,
|
|||
parse_xml++;
|
||||
|
||||
if (strcmp(request_method, "GET")==0)
|
||||
retval = api_operations_get(h, r, path, pcvec, pi, qvec, data, username, pretty, use_xml);
|
||||
retval = api_operations_get(h, r, path, pcvec, pi, qvec, data, pretty, use_xml);
|
||||
else if (strcmp(request_method, "POST")==0)
|
||||
retval = api_operations_post(h, r, path, pcvec, pi, qvec, data, username,
|
||||
retval = api_operations_post(h, r, path, pcvec, pi, qvec, data,
|
||||
pretty, use_xml, parse_xml);
|
||||
else
|
||||
retval = notfound(r);
|
||||
|
|
@ -338,7 +334,7 @@ api_restconf(clicon_handle h,
|
|||
cvec *pcvec = NULL; /* for rest api */
|
||||
cbuf *cb = NULL;
|
||||
char *data;
|
||||
char *username = NULL;
|
||||
int authenticated = 0;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
path = FCGX_GetParam("REQUEST_URI", r->envp);
|
||||
|
|
@ -384,12 +380,14 @@ api_restconf(clicon_handle h,
|
|||
/* If present, check credentials. See "plugin_credentials" in plugin
|
||||
* See RFC 8040 section 2.5
|
||||
*/
|
||||
if (restconf_credentials(h, r, &username) < 0)
|
||||
if ((authenticated = clixon_plugin_auth(h, r)) < 0)
|
||||
goto done;
|
||||
clicon_debug(1, "%s username:%s", __FUNCTION__, username);
|
||||
clicon_debug(1, "%s credentials ok username:%s (should be non-NULL)",
|
||||
__FUNCTION__, username);
|
||||
if (username == NULL){
|
||||
/* If set but no user, we set a dummy user */
|
||||
if (authenticated){
|
||||
if (clicon_username_get(h) == NULL)
|
||||
clicon_username_set(h, "none");
|
||||
}
|
||||
else{
|
||||
unauthorized(r);
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -398,11 +396,11 @@ api_restconf(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
else if (strcmp(method, "data") == 0){ /* restconf, skip /api/data */
|
||||
if (api_data(h, r, path, pcvec, 2, qvec, data, username) < 0)
|
||||
if (api_data(h, r, path, pcvec, 2, qvec, data) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (strcmp(method, "operations") == 0){ /* rpc */
|
||||
if (api_operations(h, r, path, pcvec, 2, qvec, data, username) < 0)
|
||||
if (api_operations(h, r, path, pcvec, 2, qvec, data) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (strcmp(method, "test") == 0)
|
||||
|
|
@ -423,8 +421,6 @@ api_restconf(clicon_handle h,
|
|||
cvec_free(pcvec);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
if (username)
|
||||
free(username);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -500,6 +496,7 @@ main(int argc,
|
|||
char *path;
|
||||
clicon_handle h;
|
||||
char *yangspec=NULL;
|
||||
char *dir;
|
||||
|
||||
/* In the startup, logs to stderr & debug flag set later */
|
||||
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_SYSLOG);
|
||||
|
|
@ -556,8 +553,9 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_YANG_MODULE_MAIN", yangspec);
|
||||
|
||||
/* Initialize plugins group */
|
||||
if (restconf_plugin_load(h) < 0)
|
||||
return -1;
|
||||
if ((dir = clicon_restconf_dir(h)) != NULL)
|
||||
if (clixon_plugins_load(h, clicon_restconf_dir(h)) < 0)
|
||||
return -1;
|
||||
|
||||
/* Parse yang database spec file */
|
||||
if (yang_spec_main(h) == NULL)
|
||||
|
|
@ -605,7 +603,7 @@ main(int argc,
|
|||
}
|
||||
retval = 0;
|
||||
done:
|
||||
restconf_plugin_unload(h);
|
||||
clixon_plugin_unload(h);
|
||||
restconf_terminate(h);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,7 +227,6 @@ api_return_err(clicon_handle h,
|
|||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
||||
* @param[in] pi Offset, where path starts
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML
|
||||
* @param[in] head If 1 is HEAD, otherwise GET
|
||||
|
|
@ -254,7 +253,6 @@ api_data_get2(clicon_handle h,
|
|||
cvec *pcvec,
|
||||
int pi,
|
||||
cvec *qvec,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml,
|
||||
int head)
|
||||
|
|
@ -284,7 +282,7 @@ api_data_get2(clicon_handle h,
|
|||
}
|
||||
path = cbuf_get(cbpath);
|
||||
clicon_debug(1, "%s path:%s", __FUNCTION__, path);
|
||||
if (clicon_rpc_get(h, path, username, &xret) < 0){
|
||||
if (clicon_rpc_get(h, path, &xret) < 0){
|
||||
notfound(r);
|
||||
goto ok;
|
||||
}
|
||||
|
|
@ -362,7 +360,6 @@ api_data_get2(clicon_handle h,
|
|||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
||||
* @param[in] pi Offset, where path starts
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML
|
||||
*
|
||||
|
|
@ -377,11 +374,10 @@ api_data_head(clicon_handle h,
|
|||
cvec *pcvec,
|
||||
int pi,
|
||||
cvec *qvec,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml)
|
||||
{
|
||||
return api_data_get2(h, r, pcvec, pi, qvec, username, pretty, use_xml, 1);
|
||||
return api_data_get2(h, r, pcvec, pi, qvec, pretty, use_xml, 1);
|
||||
}
|
||||
|
||||
/*! REST GET method
|
||||
|
|
@ -391,7 +387,6 @@ api_data_head(clicon_handle h,
|
|||
* @param[in] pcvec Vector of path ie DOCUMENT_URI element
|
||||
* @param[in] pi Offset, where path starts
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML
|
||||
* @code
|
||||
|
|
@ -416,11 +411,10 @@ api_data_get(clicon_handle h,
|
|||
cvec *pcvec,
|
||||
int pi,
|
||||
cvec *qvec,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml)
|
||||
{
|
||||
return api_data_get2(h, r, pcvec, pi, qvec, username, pretty, use_xml, 0);
|
||||
return api_data_get2(h, r, pcvec, pi, qvec, pretty, use_xml, 0);
|
||||
}
|
||||
|
||||
/*! Generic REST POST method
|
||||
|
|
@ -431,7 +425,6 @@ api_data_get(clicon_handle h,
|
|||
* @param[in] pi Offset, where to start pcvec
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] data Stream input data
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML for output data
|
||||
* @param[in] parse_xml Set to 0 for JSON and 1 for XML for input data
|
||||
|
|
@ -464,7 +457,6 @@ api_data_post(clicon_handle h,
|
|||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml,
|
||||
int parse_xml)
|
||||
|
|
@ -484,6 +476,7 @@ api_data_post(clicon_handle h,
|
|||
cxobj *xret = NULL;
|
||||
cxobj *xretcom = NULL;
|
||||
cxobj *xerr;
|
||||
char *username;
|
||||
|
||||
clicon_debug(1, "%s api_path:\"%s\" json:\"%s\"",
|
||||
__FUNCTION__,
|
||||
|
|
@ -501,7 +494,7 @@ api_data_post(clicon_handle h,
|
|||
xbot = xtop;
|
||||
/* For internal XML protocol: add username attribute for backend access control
|
||||
*/
|
||||
if (username){
|
||||
if ((username = clicon_username_get(h)) != NULL){
|
||||
if ((xu = xml_new("username", xtop, NULL)) == NULL)
|
||||
goto done;
|
||||
xml_type_set(xu, CX_ATTR);
|
||||
|
|
@ -645,7 +638,6 @@ match_list_keys(yang_stmt *y,
|
|||
* @param[in] pi Offset, where to start pcvec
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] data Stream input data
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML for output data
|
||||
* @param[in] parse_xml Set to 0 for JSON and 1 for XML for input data
|
||||
|
|
@ -670,7 +662,6 @@ api_data_put(clicon_handle h,
|
|||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml,
|
||||
int parse_xml)
|
||||
|
|
@ -692,6 +683,7 @@ api_data_put(clicon_handle h,
|
|||
cxobj *xret = NULL;
|
||||
cxobj *xretcom = NULL;
|
||||
cxobj *xerr;
|
||||
char *username;
|
||||
|
||||
clicon_debug(1, "%s api_path:\"%s\" json:\"%s\"",
|
||||
__FUNCTION__, api_path0, data);
|
||||
|
|
@ -709,7 +701,7 @@ api_data_put(clicon_handle h,
|
|||
xbot = xtop;
|
||||
/* For internal XML protocol: add username attribute for backend access control
|
||||
*/
|
||||
if (username){
|
||||
if ((username = clicon_username_get(h)) != NULL){
|
||||
if ((xu = xml_new("username", xtop, NULL)) == NULL)
|
||||
goto done;
|
||||
xml_type_set(xu, CX_ATTR);
|
||||
|
|
@ -824,7 +816,6 @@ api_data_put(clicon_handle h,
|
|||
* @param[in] pi Offset, where to start pcvec
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] data Stream input data
|
||||
* @param[in] username Authenticated user
|
||||
* Netconf: <edit-config> (nc:operation="merge")
|
||||
* See RFC8040 Sec 4.6
|
||||
*/
|
||||
|
|
@ -835,8 +826,7 @@ api_data_patch(clicon_handle h,
|
|||
cvec *pcvec,
|
||||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username)
|
||||
char *data)
|
||||
{
|
||||
notimplemented(r);
|
||||
return 0;
|
||||
|
|
@ -847,7 +837,6 @@ api_data_patch(clicon_handle h,
|
|||
* @param[in] r Fastcgi request handle
|
||||
* @param[in] api_path According to restconf (Sec 3.5.3.1 in rfc8040)
|
||||
* @param[in] pi Offset, where path starts
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML
|
||||
* See RFC 8040 Sec 4.7
|
||||
|
|
@ -860,7 +849,6 @@ api_data_delete(clicon_handle h,
|
|||
FCGX_Request *r,
|
||||
char *api_path,
|
||||
int pi,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml)
|
||||
{
|
||||
|
|
@ -877,6 +865,7 @@ api_data_delete(clicon_handle h,
|
|||
cxobj *xret = NULL;
|
||||
cxobj *xretcom = NULL;
|
||||
cxobj *xerr;
|
||||
char *username;
|
||||
|
||||
clicon_debug(1, "%s api_path:%s", __FUNCTION__, api_path);
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
|
|
@ -891,7 +880,7 @@ api_data_delete(clicon_handle h,
|
|||
xbot = xtop;
|
||||
/* For internal XML protocol: add username attribute for backend access control
|
||||
*/
|
||||
if (username){
|
||||
if ((username = clicon_username_get(h)) != NULL){
|
||||
if ((xu = xml_new("username", xtop, NULL)) == NULL)
|
||||
goto done;
|
||||
xml_type_set(xu, CX_ATTR);
|
||||
|
|
@ -955,7 +944,6 @@ api_data_delete(clicon_handle h,
|
|||
* @param[in] pi Offset, where path starts
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] data Stream input data
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML
|
||||
*
|
||||
|
|
@ -976,7 +964,6 @@ api_operations_get(clicon_handle h,
|
|||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml)
|
||||
{
|
||||
|
|
@ -1047,7 +1034,6 @@ api_operations_get(clicon_handle h,
|
|||
* @param[in] pi Offset, where to start pcvec
|
||||
* @param[in] qvec Vector of query string (QUERY_STRING)
|
||||
* @param[in] data Stream input data
|
||||
* @param[in] username Authenticated user
|
||||
* @param[in] pretty Set to 1 for pretty-printed xml/json output
|
||||
* @param[in] use_xml Set to 0 for JSON and 1 for XML for output data
|
||||
* @param[in] parse_xml Set to 0 for JSON and 1 for XML for input data
|
||||
|
|
@ -1063,7 +1049,6 @@ api_operations_post(clicon_handle h,
|
|||
int pi,
|
||||
cvec *qvec,
|
||||
char *data,
|
||||
char *username,
|
||||
int pretty,
|
||||
int use_xml,
|
||||
int parse_xml)
|
||||
|
|
@ -1085,7 +1070,8 @@ api_operations_post(clicon_handle h,
|
|||
cxobj *xoutput;
|
||||
cxobj *x;
|
||||
cxobj *xa;
|
||||
|
||||
char *username;
|
||||
|
||||
clicon_debug(1, "%s json:\"%s\" path:\"%s\"", __FUNCTION__, data, path);
|
||||
if ((yspec = clicon_dbspec_yang(h)) == NULL){
|
||||
clicon_err(OE_FATAL, 0, "No DB_SPEC");
|
||||
|
|
@ -1112,7 +1098,7 @@ api_operations_post(clicon_handle h,
|
|||
xbot = xtop;
|
||||
/* For internal XML protocol: add username attribute for backend access control
|
||||
*/
|
||||
if (username){
|
||||
if ((username = clicon_username_get(h)) != NULL){
|
||||
if ((xa = xml_new("username", xtop, NULL)) == NULL)
|
||||
goto done;
|
||||
xml_type_set(xa, CX_ATTR);
|
||||
|
|
|
|||
|
|
@ -46,31 +46,31 @@
|
|||
*/
|
||||
int api_data_options(clicon_handle h, FCGX_Request *r);
|
||||
int api_data_head(clicon_handle h, FCGX_Request *r, cvec *pcvec, int pi,
|
||||
cvec *qvec, char *username, int pretty, int use_xml);
|
||||
cvec *qvec, int pretty, int use_xml);
|
||||
int api_data_get(clicon_handle h, FCGX_Request *r, cvec *pcvec, int pi,
|
||||
cvec *qvec, char *username, int pretty, int use_xml);
|
||||
cvec *qvec, int pretty, int use_xml);
|
||||
int api_data_post(clicon_handle h, FCGX_Request *r, char *api_path,
|
||||
cvec *pcvec, int pi,
|
||||
cvec *qvec, char *data, char *username,
|
||||
cvec *qvec, char *data,
|
||||
int pretty, int use_xml, int parse_xml);
|
||||
int api_data_put(clicon_handle h, FCGX_Request *r, char *api_path,
|
||||
cvec *pcvec, int pi,
|
||||
cvec *qvec, char *data, char *username,
|
||||
cvec *qvec, char *data,
|
||||
int pretty, int use_xml, int parse_xml);
|
||||
int api_data_patch(clicon_handle h, FCGX_Request *r, char *api_path,
|
||||
cvec *pcvec, int pi,
|
||||
cvec *qvec, char *data, char *username);
|
||||
cvec *qvec, char *data);
|
||||
int api_data_delete(clicon_handle h, FCGX_Request *r, char *api_path, int pi,
|
||||
char *username, int pretty, int use_xml);
|
||||
int pretty, int use_xml);
|
||||
|
||||
int api_operations_get(clicon_handle h, FCGX_Request *r,
|
||||
char *path,
|
||||
cvec *pcvec, int pi, cvec *qvec, char *data, char *username,
|
||||
cvec *pcvec, int pi, cvec *qvec, char *data,
|
||||
int pretty, int use_xml);
|
||||
|
||||
int api_operations_post(clicon_handle h, FCGX_Request *r,
|
||||
char *path,
|
||||
cvec *pcvec, int pi, cvec *qvec, char *data,
|
||||
char *username, int pretty, int use_xml, int parse_xml);
|
||||
int pretty, int use_xml, int parse_xml);
|
||||
|
||||
#endif /* _RESTCONF_METHODS_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue