diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2014-05-25 17:17:57 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-06-01 22:15:01 +0200 |
commit | d10fb882aa4a30f78493b7162f482bb0f17d3ff5 (patch) | |
tree | dc33d5403cd4c11e7d7248657e9564795cdca2fd | |
parent | 6973f38e624e757587b14f1dbabc3466492d1dac (diff) | |
download | sssd-d10fb882aa4a30f78493b7162f482bb0f17d3ff5.tar.gz sssd-d10fb882aa4a30f78493b7162f482bb0f17d3ff5.tar.xz sssd-d10fb882aa4a30f78493b7162f482bb0f17d3ff5.zip |
TOOLS: Allow adding and modifying custom attributes with sss_usermod
https://fedorahosted.org/sssd/ticket/2182
Adds three new options to the sss_usermod tool:
--addattr
--setattr
--delattr
The syntax is attrname=val1,val2, For example:
sss_usermod --addattr=phone-123-456 tuser
The operations are performed in the order of add, mod, del.
Reviewed-by: Michal Židek <mzidek@redhat.com>
-rw-r--r-- | src/man/sss_usermod.8.xml | 36 | ||||
-rw-r--r-- | src/tools/sss_sync_ops.c | 112 | ||||
-rw-r--r-- | src/tools/sss_sync_ops.h | 4 | ||||
-rw-r--r-- | src/tools/sss_usermod.c | 35 |
4 files changed, 187 insertions, 0 deletions
diff --git a/src/man/sss_usermod.8.xml b/src/man/sss_usermod.8.xml index 55f8cd00d..b9fef8237 100644 --- a/src/man/sss_usermod.8.xml +++ b/src/man/sss_usermod.8.xml @@ -130,6 +130,42 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <option>--addattr</option> + <replaceable>ATTR_NAME_VAL</replaceable> + </term> + <listitem> + <para> + Add an attribute/value pair. The format is + attrname=value. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <option>--setattr</option> + <replaceable>ATTR_NAME_VAL</replaceable> + </term> + <listitem> + <para> + Set an attribute to a name/value pair. The format + is attrname=value. For multi-valued attributes, + the command replaces the values already present + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <option>--delattr</option> + <replaceable>ATTR_NAME_VAL</replaceable> + </term> + <listitem> + <para> + Delete an attribute/value pair. The format is attrname=value. + </para> + </listitem> + </varlistentry> <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/param_help.xml" /> </variablelist> </refsect1> diff --git a/src/tools/sss_sync_ops.c b/src/tools/sss_sync_ops.c index 4c8f7102e..232a711dd 100644 --- a/src/tools/sss_sync_ops.c +++ b/src/tools/sss_sync_ops.c @@ -35,6 +35,8 @@ #define DFL_SKEL_DIR "/etc/skel" #define DFL_MAIL_DIR "/var/spool/mail" +#define ATTR_NAME_SEP '=' +#define ATTR_VAL_SEP ',' #define VAR_CHECK(var, val, attr, msg) do { \ if (var != (val)) { \ @@ -43,6 +45,94 @@ } \ } while(0) +static int attr_name_val_split(TALLOC_CTX *mem_ctx, const char *nameval, + char **_name, char ***_values, int *_nvals) +{ + char *name; + char **values; + const char *vals; + int nvals; + TALLOC_CTX *tmp_ctx; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) return ENOMEM; + + vals = strchr(nameval, ATTR_NAME_SEP); + if (vals == NULL) { + ret = EINVAL; + goto done; + } + + name = talloc_strndup(tmp_ctx, nameval, vals-nameval); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + vals++; + + ret = split_on_separator(tmp_ctx, vals, ATTR_VAL_SEP, true, true, + &values, &nvals); + if (ret != EOK) { + goto done; + } + + *_name = talloc_steal(mem_ctx, name); + *_values = talloc_steal(mem_ctx, values); + *_nvals = nvals; + ret = EOK; +done: + talloc_free(tmp_ctx); + return EOK; +} + +static int attr_op(struct ops_ctx *octx, const char *nameval, int op) +{ + TALLOC_CTX *tmp_ctx; + errno_t ret; + struct sysdb_attrs *attrs; + char *name; + char **vals; + int nvals; + int i; + + switch(op) { + case SYSDB_MOD_ADD: + case SYSDB_MOD_DEL: + case SYSDB_MOD_REP: + break; + default: + return EINVAL; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) return ENOMEM; + + attrs = sysdb_new_attrs(tmp_ctx); + if (attrs == NULL) { + ret = ENOMEM; + goto done; + } + + ret = attr_name_val_split(tmp_ctx, nameval, &name, &vals, &nvals); + if (ret != EOK) { + goto done; + } + + for (i=0; i < nvals; i++) { + ret = sysdb_attrs_add_string(attrs, name, vals[i]); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not add %s to %s\n", vals[i], name); + continue; + } + } + + ret = sysdb_set_user_attr(octx->domain, octx->name, attrs, op); +done: + talloc_free(tmp_ctx); + return EOK; +} /* * Generic modify groups member */ @@ -231,6 +321,28 @@ int usermod(TALLOC_CTX *mem_ctx, } } + if (data->addattr) { + ret = attr_op(data, data->addattr, SYSDB_MOD_ADD); + if (ret) { + return ret; + } + } + + if (data->setattr) { + ret = attr_op(data, data->setattr, SYSDB_MOD_REP); + if (ret) { + return ret; + } + + } + + if (data->delattr) { + ret = attr_op(data, data->delattr, SYSDB_MOD_DEL); + if (ret) { + return ret; + } + } + flush_nscd_cache(NSCD_DB_PASSWD); flush_nscd_cache(NSCD_DB_GROUP); diff --git a/src/tools/sss_sync_ops.h b/src/tools/sss_sync_ops.h index 6b50c5af5..3aaf7a9f3 100644 --- a/src/tools/sss_sync_ops.h +++ b/src/tools/sss_sync_ops.h @@ -53,6 +53,10 @@ struct ops_ctx { char **addgroups; char **rmgroups; + + char *addattr; + char *setattr; + char *delattr; }; /* default values for add operations */ diff --git a/src/tools/sss_usermod.c b/src/tools/sss_usermod.c index 11369b7e6..079c078e7 100644 --- a/src/tools/sss_usermod.c +++ b/src/tools/sss_usermod.c @@ -54,11 +54,15 @@ int main(int argc, const char **argv) { "remove-group", 'r', POPT_ARG_STRING, NULL, 'r', _("Groups to remove this user from"), NULL }, { "lock", 'L', POPT_ARG_NONE, NULL, 'L', _("Lock the account"), NULL }, { "unlock", 'U', POPT_ARG_NONE, NULL, 'U', _("Unlock the account"), NULL }, + { "addattr", '\0', POPT_ARG_STRING, NULL, 't' , _("Add an attribute/value pair. The format is attrname=value."), NULL }, + { "delattr", '\0', POPT_ARG_STRING, NULL, 'd' , _("Delete an attribute/value pair. The format is attrname=value."), NULL }, + { "setattr", '\0', POPT_ARG_STRING, NULL, 's' , _("Set an attribute to a name/value pair. The format is attrname=value. For multi-valued attributes, the command replaces the values already present"), NULL }, { "selinux-user", 'Z', POPT_ARG_STRING, &pc_selinux_user, 0, _("The SELinux user for user's login"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; char *addgroups = NULL, *rmgroups = NULL; + char *addattr = NULL, *delattr = NULL, *setattr = NULL; int ret; errno_t sret; const char *pc_username = NULL; @@ -105,6 +109,34 @@ int main(int argc, const char **argv) case 'U': pc_lock = DO_UNLOCK; break; + + case 't': + addattr = poptGetOptArg(pc); + if (addattr == NULL) { + BAD_POPT_PARAMS(pc, + _("Specify the attribute name/value pair(s)\n"), + ret, fini); + } + break; + + case 'd': + delattr = poptGetOptArg(pc); + if (delattr == NULL) { + BAD_POPT_PARAMS(pc, + _("Specify the attribute name/value pair(s)\n"), + ret, fini); + } + break; + + case 's': + setattr = poptGetOptArg(pc); + if (setattr == NULL) { + BAD_POPT_PARAMS(pc, + _("Specify the attribute name/value pair(s)\n"), + ret, fini); + } + break; + } } @@ -221,6 +253,9 @@ int main(int argc, const char **argv) tctx->octx->uid = pc_uid; tctx->octx->gid = pc_gid; tctx->octx->lock = pc_lock; + tctx->octx->addattr = addattr; + tctx->octx->delattr = delattr; + tctx->octx->setattr = setattr; tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { |