diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index eb915210..da6c2f14 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -109,6 +109,8 @@ backend_terminate(clicon_handle h) xml_free(x); if ((yspec = clicon_dbspec_yang(h)) != NULL) yspec_free(yspec); + if ((yspec = clicon_config_yang(h)) != NULL) + yspec_free(yspec); if ((nsctx = clicon_nsctx_global_get(h)) != NULL) cvec_free(nsctx); if ((x = clicon_nacm_ext(h)) != NULL) @@ -507,7 +509,7 @@ main(int argc, clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); clicon_debug_init(debug, NULL); - /* Create configure yang-spec */ + /* Create configure yang-spec (note different from dbspec holding application specs) */ if ((yspecfg = yspec_new()) == NULL) goto done; @@ -517,6 +519,9 @@ main(int argc, usage(h, argv[0]); return -1; } + if (clicon_config_yang_set(h, yspecfg) < 0) + goto done; + /* External NACM file? */ nacm_mode = clicon_option_str(h, "CLICON_NACM_MODE"); if (nacm_mode && strcmp(nacm_mode, "external") == 0) diff --git a/apps/backend/backend_socket.c b/apps/backend/backend_socket.c index 018f6b6c..5d6bc82f 100644 --- a/apps/backend/backend_socket.c +++ b/apps/backend/backend_socket.c @@ -270,10 +270,12 @@ backend_accept_client(int fd, #error "Need getsockopt O_PEERCRED or getpeereid for unix socket peer cred" #endif if (name != NULL){ - if ((ce->ce_username = strdup(name)) == NULL){ + if ((ce->ce_username = name) == NULL){ clicon_err(OE_UNIX, errno, "strdup"); + name = NULL; goto done; } + name = NULL; } break; case AF_INET: @@ -291,5 +293,7 @@ backend_accept_client(int fd, goto done; retval = 0; done: + if (name) + free(name); return retval; } diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c index 83c38625..172fc8d0 100644 --- a/apps/cli/cli_main.c +++ b/apps/cli/cli_main.c @@ -169,6 +169,8 @@ cli_terminate(clicon_handle h) clicon_rpc_close_session(h); if ((yspec = clicon_dbspec_yang(h)) != NULL) yspec_free(yspec); + if ((yspec = clicon_config_yang(h)) != NULL) + yspec_free(yspec); if ((nsctx = clicon_nsctx_global_get(h)) != NULL) cvec_free(nsctx); if ((x = clicon_conf_xml(h)) != NULL) @@ -350,7 +352,7 @@ main(int argc, char **argv) clicon_debug_init(debug, NULL); - /* Create top-level yang spec and store as option */ + /* Create configure yang-spec (note different from dbspec holding application specs) */ if ((yspecfg = yspec_new()) == NULL) goto done; /* Find and read configfile */ @@ -359,6 +361,9 @@ main(int argc, char **argv) usage(h, argv[0]); return -1; } + if (clicon_config_yang_set(h, yspecfg) < 0) + goto done; + /* Now rest of options */ opterr = 0; optind = 1; diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index 153ec13f..b3d8b215 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -331,6 +331,8 @@ netconf_terminate(clicon_handle h) clicon_rpc_close_session(h); if ((yspec = clicon_dbspec_yang(h)) != NULL) yspec_free(yspec); + if ((yspec = clicon_config_yang(h)) != NULL) + yspec_free(yspec); if ((nsctx = clicon_nsctx_global_get(h)) != NULL) cvec_free(nsctx); if ((x = clicon_conf_xml(h)) != NULL) @@ -441,12 +443,15 @@ main(int argc, clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); clicon_debug_init(debug, NULL); - /* Create configure yang-spec */ + /* Create configure yang-spec (note different from dbspec holding application specs) */ if ((yspecfg = yspec_new()) == NULL) goto done; /* Find and read configfile */ if (clicon_options_main(h, yspecfg) < 0) return -1; + if (clicon_config_yang_set(h, yspecfg) < 0) + goto done; + /* Now rest of options */ optind = 1; opterr = 0; diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c index b79de44f..22d474cb 100644 --- a/apps/restconf/restconf_lib.c +++ b/apps/restconf/restconf_lib.c @@ -605,6 +605,8 @@ restconf_terminate(clicon_handle h) clicon_rpc_close_session(h); if ((yspec = clicon_dbspec_yang(h)) != NULL) yspec_free(yspec); + if ((yspec = clicon_config_yang(h)) != NULL) + yspec_free(yspec); if ((nsctx = clicon_nsctx_global_get(h)) != NULL) cvec_free(nsctx); if ((x = clicon_conf_xml(h)) != NULL) diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c index f188f7da..aaa639be 100644 --- a/apps/restconf/restconf_main.c +++ b/apps/restconf/restconf_main.c @@ -642,12 +642,15 @@ main(int argc, goto done; } - /* Create configure yang-spec */ + /* Create configure yang-spec note different from dbspec holding application specs) */ if ((yspecfg = yspec_new()) == NULL) goto done; /* Find and read configfile */ if (clicon_options_main(h, yspecfg) < 0) goto done; + if (clicon_config_yang_set(h, yspecfg) < 0) + goto done; + stream_path = clicon_option_str(h, "CLICON_STREAM_PATH"); /* Now rest of options, some overwrite option file */ optind = 1; diff --git a/lib/clixon/clixon_data.h b/lib/clixon/clixon_data.h index 42981a3b..961ac7aa 100644 --- a/lib/clixon/clixon_data.h +++ b/lib/clixon/clixon_data.h @@ -55,6 +55,9 @@ typedef struct { yang_stmt * clicon_dbspec_yang(clicon_handle h); int clicon_dbspec_yang_set(clicon_handle h, yang_stmt *ys); +yang_stmt * clicon_config_yang(clicon_handle h); +int clicon_config_yang_set(clicon_handle h, yang_stmt *ys); + cvec *clicon_nsctx_global_get(clicon_handle h); int clicon_nsctx_global_set(clicon_handle h, cvec *nsctx); diff --git a/lib/src/clixon_data.c b/lib/src/clixon_data.c index 595e5db3..45e5bc46 100644 --- a/lib/src/clixon_data.c +++ b/lib/src/clixon_data.c @@ -73,10 +73,11 @@ #include "clixon_xpath.h" #include "clixon_data.h" -/*! Get YANG specification for application +/*! Get YANG specification for application specs * Must use hash functions directly since they are not strings. * @param[in] h Clicon handle * @retval yspec Yang spec + * @see clicon_config_yang for the configuration yang */ yang_stmt * clicon_dbspec_yang(clicon_handle h) @@ -90,10 +91,10 @@ clicon_dbspec_yang(clicon_handle h) return NULL; } -/*! Set yang specification for application - * ys must be a malloced pointer +/*! Set yang specification for application specifications * @param[in] h Clicon handle - * @param[in] yspec Yang spec + * @param[in] yspec Yang spec (malloced pointer) + * @see clicon_config_yang_set for the configuration yang */ int clicon_dbspec_yang_set(clicon_handle h, @@ -109,6 +110,42 @@ clicon_dbspec_yang_set(clicon_handle h, return 0; } +/*! Get YANG specification for clixon config (separate from application yangs) + * @param[in] h Clicon handle + * @retval yspec Yang spec + * @see clicon_dbspec_yang for the application specs + */ +yang_stmt * +clicon_config_yang(clicon_handle h) +{ + clicon_hash_t *cdat = clicon_data(h); + size_t len; + void *p; + + if ((p = clicon_hash_value(cdat, "control_yang", &len)) != NULL) + return *(yang_stmt **)p; + return NULL; +} + +/*! Set yang specification for configuration + * @param[in] h Clicon handle + * @param[in] yspec Yang spec (malloced pointer) + * @see clicon_dbspec_yang_set for the application specs + */ +int +clicon_config_yang_set(clicon_handle h, + yang_stmt *ys) +{ + clicon_hash_t *cdat = clicon_data(h); + + /* It is the pointer to ys that should be copied by hash, + so we send a ptr to the ptr to indicate what to copy. + */ + if (clicon_hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL) + return -1; + return 0; +} + /*! Get Global "canonical" namespace context * Canonical: use prefix and namespace specified in the yang modules. * @param[in] h Clicon handle diff --git a/lib/src/clixon_uid.c b/lib/src/clixon_uid.c index b08cef5b..21160e4c 100644 --- a/lib/src/clixon_uid.c +++ b/lib/src/clixon_uid.c @@ -121,7 +121,7 @@ name2uid(const char *name, /*! Translate uid to user name * @param[in] uid User id - * @param[out] name User name + * @param[out] name User name (Malloced, need to be freed) * @retval 0 OK * @retval -1 Error. or not found */ @@ -131,7 +131,7 @@ uid2name(const uid_t uid, { int retval = -1; char buf[1024]; - struct passwd pwbuf; + struct passwd pwbuf = {0,}; struct passwd *pwbufp = NULL; if (getpwuid_r(uid, &pwbuf, buf, sizeof(buf), &pwbufp) != 0){ @@ -139,17 +139,21 @@ uid2name(const uid_t uid, goto done; } if (pwbufp == NULL){ - clicon_err(OE_UNIX, 0, "No such user: %u", uid); + clicon_err(OE_UNIX, ENOENT, "No such user: %u", uid); goto done; } - if (name) - *name = pwbufp->pw_name; + + if (name){ + if ((*name = strdup(pwbufp->pw_name)) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + } retval = 0; done: return retval; } - /* Privileges drop perm, temp and restore * @see https://www.usenix.org/legacy/events/sec02/full_papers/chen/chen.pdf */