diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74122d31..32a6acad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
## 3.3.3 Upcoming
+* Restconf: http cookie sent as attribute in rpc restconf_post operations to backend.
* Added option CLICON_CLISPEC_FILE as complement to CLICON_CLISPEC_DIR to
specify single CLI specification file, not only directory containing files.
diff --git a/apps/backend/clixon_backend_handle.h b/apps/backend/clixon_backend_handle.h
index 0bca3835..171d5dd0 100644
--- a/apps/backend/clixon_backend_handle.h
+++ b/apps/backend/clixon_backend_handle.h
@@ -45,7 +45,7 @@
*/
struct client_entry;
typedef int (*backend_rpc_cb)(
- clicon_handle h,
+ clicon_handle h, /* CLicon handle */
cxobj *xe, /* Request: */
struct client_entry *ce, /* Client session */
cbuf *cbret,/* Reply eg ... */
diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c
index 80571eac..08383266 100644
--- a/apps/restconf/restconf_lib.c
+++ b/apps/restconf/restconf_lib.c
@@ -330,7 +330,7 @@ restconf_plugin_load(clicon_handle h)
(int)strlen(filename), filename);
if ((handle = plugin_load(h, filename, RTLD_NOW)) == NULL)
goto quit;
- p_credentials = dlsym(handle, "restconf_credentials");
+ p_credentials = dlsym(handle, PLUGIN_CREDENTIALS);
if ((plugins = realloc(plugins, (nplugins+1) * sizeof (*plugins))) == NULL) {
clicon_err(OE_UNIX, errno, "realloc");
goto quit;
@@ -406,3 +406,30 @@ plugin_credentials(clicon_handle h,
done:
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
+ * @param[out] val malloced cookie value, free with free()
+ */
+int
+get_user_cookie(char *cookiestr,
+ char *attribute,
+ char **val)
+{
+ int retval = -1;
+ cvec *cvv = NULL;
+ char *c;
+
+ if (str2cvec(cookiestr, ';', '=', &cvv) < 0)
+ goto done;
+ if ((c = cvec_find_str(cvv, attribute)) != NULL){
+ if ((*val = strdup(c)) == NULL)
+ goto done;
+ }
+ retval = 0;
+ done:
+ if (cvv)
+ cvec_free(cvv);
+ return retval;
+}
diff --git a/apps/restconf/restconf_lib.h b/apps/restconf/restconf_lib.h
index 1ebcb74a..fa5459c8 100644
--- a/apps/restconf/restconf_lib.h
+++ b/apps/restconf/restconf_lib.h
@@ -53,10 +53,11 @@ 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 plugin_credentials(clicon_handle h, FCGX_Request *r, int *auth);
+int get_user_cookie(char *cookiestr, char *attribute, char **val);
+
#endif /* _RESTCONF_LIB_H_ */
diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c
index c958730f..d3e07855 100644
--- a/apps/restconf/restconf_methods.c
+++ b/apps/restconf/restconf_methods.c
@@ -706,6 +706,8 @@ api_operation_post(clicon_handle h,
}
for (i=0; ienvp)) != NULL &&
+ get_user_cookie(cookie, "c-user", &cookieval) ==0){
+ if ((xa = xml_new("cookie", xtop)) == NULL)
+ goto done;
+ xml_type_set(xa, CX_ATTR);
+ if (xml_value_set(xa, cookieval) < 0)
+ goto done;
+ if (cookieval)
+ free(cookieval);
+ }
+ }
+ /* Send to backend */
if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0)
goto done;
if ((cbx = cbuf_new()) == NULL)
diff --git a/lib/clixon/clixon_plugin.h b/lib/clixon/clixon_plugin.h
index 10d3d082..61e14fb2 100644
--- a/lib/clixon/clixon_plugin.h
+++ b/lib/clixon/clixon_plugin.h
@@ -69,11 +69,16 @@ typedef int (plginit_t)(clicon_handle); /* Plugin Init */
typedef int (plgstart_t)(clicon_handle, int, char **); /* Plugin start */
/* Called just before plugin unloaded.
- * @see plgexit_t
*/
#define PLUGIN_EXIT "plugin_exit"
typedef int (plgexit_t)(clicon_handle); /* Plugin exit */
+/*! Called by restconf
+ * Returns 0 if credentials OK, -1 if failed
+ */
+#define PLUGIN_CREDENTIALS "plugin_credentials"
+typedef int (plgcredentials_t)(clicon_handle, void *); /* Plugin credentials */
+
/* Find a function in global namespace or a plugin. XXX clicon internal */
void *clicon_find_func(clicon_handle h, char *plugin, char *func);