* The backend socket has now support of credentials of peer clients

* Added: CLICON_NACM_CREDENTIALS and CLICON_NACM_RECOVERY_USER
This commit is contained in:
Olof hagsand 2019-10-18 19:33:23 +02:00
parent 77b491c568
commit 279614d64f
33 changed files with 951 additions and 145 deletions

View file

@ -942,6 +942,7 @@ nacm_access_pre(clicon_handle h,
if (xml_rootchild_node(xnacm0, xnacm) < 0)
goto done;
xnacm0 = NULL;
/* Initial NACM steps and common to all NACM access validation. */
if ((retval = nacm_access(mode, xnacm, username)) < 0)
goto done;
if (retval == 0){ /* if retval == 0 then return an xml nacm tree */

View file

@ -101,7 +101,7 @@ static const map_str2int startup_mode_map[] = {
{NULL, -1}
};
/* Mapping between Clicon privilegese modes string <--> constants,
/* Mapping between Clicon privileges modes string <--> constants,
* see clixon-config.yang type priv_mode */
static const map_str2int priv_mode_map[] = {
{"none", PM_NONE},
@ -110,6 +110,16 @@ static const map_str2int priv_mode_map[] = {
{NULL, -1}
};
/* Mapping between Clicon nacm user credential string <--> constants,
* see clixon-config.yang type nacm_cred_mode */
static const map_str2int nacm_credentials_map[] = {
{"none", NC_NONE},
{"exact", NC_EXACT},
{"except", NC_EXCEPT},
{NULL, -1}
};
/* Mapping between datastore cache string <--> constants,
* see clixon-config.yang type datastore_cache */
static const map_str2int datastore_cache_map[] = {
@ -706,7 +716,7 @@ clicon_startup_mode(clicon_handle h)
* @param[in] h Clicon handle
* @retval mode Privileges mode
*/
int
enum priv_mode_t
clicon_backend_privileges_mode(clicon_handle h)
{
char *mode;
@ -716,6 +726,20 @@ clicon_backend_privileges_mode(clicon_handle h)
return clicon_str2int(priv_mode_map, mode);
}
/*! Which privileges drop method to use
* @param[in] h Clicon handle
* @retval mode Privileges mode
*/
enum nacm_credentials_t
clicon_nacm_credentials(clicon_handle h)
{
char *mode;
if ((mode = clicon_option_str(h, "CLICON_NACM_CREDENTIALS")) == NULL)
return -1;
return clicon_str2int(nacm_credentials_map, mode);
}
/*! Which datastore cache method to use
* @param[in] h Clicon handle
* @retval method Datastore cache method

View file

@ -90,10 +90,10 @@ group_name2gid(const char *name,
}
/*! Translate user name to uid. Return -1 if error or not found.
* @param[in] name Name of user
* @param[out] uid User id
* @retval 0 OK
* @retval -1 Error. or not found
* @param[in] name Name of user
* @param[out] uid User id
* @retval 0 OK
* @retval -1 Error. or not found
*/
int
name2uid(const char *name,
@ -119,6 +119,37 @@ name2uid(const char *name,
return retval;
}
/*! Translate uid to user name
* @param[in] uid User id
* @param[out] name User name
* @retval 0 OK
* @retval -1 Error. or not found
*/
int
uid2name(const uid_t uid,
char **name)
{
int retval = -1;
char buf[1024];
struct passwd pwbuf;
struct passwd *pwbufp = NULL;
if (getpwuid_r(uid, &pwbuf, buf, sizeof(buf), &pwbufp) != 0){
clicon_err(OE_UNIX, errno, "getpwuid_r(%u)", uid);
goto done;
}
if (pwbufp == NULL){
clicon_err(OE_UNIX, 0, "No such user: %u", uid);
goto done;
}
if (name)
*name = pwbufp->pw_name;
retval = 0;
done:
return retval;
}
/* Privileges drop perm, temp and restore
* @see https://www.usenix.org/legacy/events/sec02/full_papers/chen/chen.pdf
*/

View file

@ -93,7 +93,9 @@
* Variables
*/
/* Mapping between xpath_tree node name string <--> int */
/* Mapping between xpath_tree node name string <--> int
* @see xpath_tree_int2str
*/
static const map_str2int xpath_tree_map[] = {
{"expr", XP_EXP},
{"andexpr", XP_AND},
@ -115,11 +117,42 @@ static const map_str2int xpath_tree_map[] = {
{NULL, -1}
};
/* Mapping between axis_type string <--> int
* @see axis_type_int2str
*/
static const map_str2int axis_type_map[] = {
{"NaN", A_NAN},
{"ancestor", A_ANCESTOR},
{"ancestor-or-selgf", A_ANCESTOR_OR_SELF},
{"attribute", A_ATTRIBUTE},
{"child", A_CHILD},
{"descendant", A_DESCENDANT},
{"descendeant-or-self", A_DESCENDANT_OR_SELF},
{"following", A_FOLLOWING},
{"following-sibling", A_FOLLOWING_SIBLING},
{"namespace", A_NAMESPACE},
{"parent", A_PARENT},
{"preceding", A_PRECEDING},
{"preceding-sibling", A_PRECEDING_SIBLING},
{"self", A_SELF},
{"root", A_ROOT},
{NULL, -1}
};
/*
* XPATH parse tree type
*/
/*! Map from axis-type int to string
*/
char*
axis_type_int2str(int axis_type)
{
return (char*)clicon_int2str(axis_type_map, axis_type);
}
/*! Map from xpath_tree node name int to string
*/
char*
@ -135,11 +168,21 @@ xpath_tree_print0(cbuf *cb,
int level)
{
cprintf(cb, "%*s%s:", level*3, "", xpath_tree_int2str(xs->xs_type));
if (xs->xs_s0){
if (xs->xs_s0)
cprintf(cb, "\"%s\" ", xs->xs_s0);
if (xs->xs_s1)
cprintf(cb,"\"%s\" ", xs->xs_s1);
}
if (xs->xs_s1)
cprintf(cb,"\"%s\" ", xs->xs_s1);
if (xs->xs_int)
switch (xs->xs_type){
case XP_STEP:
cprintf(cb, "%s", axis_type_int2str(xs->xs_int));
break;
default:
cprintf(cb, "%d ", xs->xs_int);
break;
}
if (xs->xs_double)
cprintf(cb,"%lf ", xs->xs_double);
cprintf(cb, "\n");
if (xs->xs_c0)
xpath_tree_print0(cb, xs->xs_c0,level+1);

View file

@ -167,7 +167,7 @@ nodetest_eval_node(cxobj *x,
name2, nsxpath);
}
#endif
done: /* retval set in preceeding statement */
done: /* retval set in preceding statement */
return retval;
}
@ -303,9 +303,10 @@ xp_eval_step(xp_ctx *xc0,
x = NULL;
while ((x = xml_child_each(xv, x, CX_ELMNT)) != NULL) {
/* xs->xs_c0 is nodetest */
if (nodetest == NULL || nodetest_eval(x, nodetest, nsc) == 1)
if (nodetest == NULL || nodetest_eval(x, nodetest, nsc) == 1){
if (cxvec_append(x, &vec, &veclen) < 0)
goto done;
}
}
}
}
@ -342,9 +343,9 @@ xp_eval_step(xp_ctx *xc0,
vec = NULL;
}
break;
case A_PRECEEDING:
case A_PRECEDING:
break;
case A_PRECEEDING_SIBLING:
case A_PRECEDING_SIBLING:
break;
case A_SELF:
break;

View file

@ -128,8 +128,8 @@ real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+)
<TOKEN>following-sibling:: { clixon_xpath_parselval.intval = A_FOLLOWING_SIBLING; return AXISNAME; }
<TOKEN>namespace:: { clixon_xpath_parselval.intval = A_NAMESPACE; return AXISNAME; }
<TOKEN>parent:: { clixon_xpath_parselval.intval = A_PARENT; return AXISNAME; }
<TOKEN>preceding:: { clixon_xpath_parselval.intval = A_PRECEEDING; return AXISNAME; }
<TOKEN>preceding-sibling:: { clixon_xpath_parselval.intval = A_PRECEEDING_SIBLING; return AXISNAME; }
<TOKEN>preceding:: { clixon_xpath_parselval.intval = A_PRECEDING; return AXISNAME; }
<TOKEN>preceding-sibling:: { clixon_xpath_parselval.intval = A_PRECEDING_SIBLING; return AXISNAME; }
<TOKEN>self:: { clixon_xpath_parselval.intval = A_SELF; return AXISNAME; }
<TOKEN>current { clixon_xpath_parselval.string = strdup(yytext); return NODETYPE; }