summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-05-25 17:17:57 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-06-01 22:15:01 +0200
commitd10fb882aa4a30f78493b7162f482bb0f17d3ff5 (patch)
treedc33d5403cd4c11e7d7248657e9564795cdca2fd
parent6973f38e624e757587b14f1dbabc3466492d1dac (diff)
downloadsssd-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.xml36
-rw-r--r--src/tools/sss_sync_ops.c112
-rw-r--r--src/tools/sss_sync_ops.h4
-rw-r--r--src/tools/sss_usermod.c35
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) {