[SSSD] [PATCH] TOOLS: Allow adding and modifying custom attributes with sss_usermod

Jakub Hrozek jhrozek at redhat.com
Mon May 26 08:38:23 UTC 2014


Hi,

the attached patch implements https://fedorahosted.org/sssd/ticket/2182
by adding three more options to the sss_usermod tool.
-------------- next part --------------
>From 797a7101f58f9dd3c10c3ee08785e8de099aee0a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Sun, 25 May 2014 17:17:57 +0200
Subject: [PATCH] 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.
---
 src/man/sss_usermod.8.xml |  33 ++++++++++++++
 src/tools/sss_sync_ops.c  | 112 ++++++++++++++++++++++++++++++++++++++++++++++
 src/tools/sss_sync_ops.h  |   6 +++
 src/tools/sss_usermod.c   |  35 +++++++++++++++
 4 files changed, 186 insertions(+)

diff --git a/src/man/sss_usermod.8.xml b/src/man/sss_usermod.8.xml
index 55f8cd00d7626d3d26df39ac1ce19eed5f1d049e..a6c7a3a36d401d7b9e59b320385aef29e69ab662 100644
--- a/src/man/sss_usermod.8.xml
+++ b/src/man/sss_usermod.8.xml
@@ -130,6 +130,39 @@
                     </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 4c8f7102e6da4a7de819979096482853246e974f..232a711dd42e091842dc75386892c420191ebf95 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 6b50c5af54f0d824e597d627aa4de02d14e5600c..c92efdfc8149fbe000f24858add51010c12ca3ac 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 */
@@ -95,5 +99,7 @@ int sysdb_getgrnam_sync(TALLOC_CTX *mem_ctx,
                         const char *name,
                         struct ops_ctx *out);
 
+/* addattr/setattr/delattr utility */
+
 #endif /* __SSS_OPS_H__ */
 
diff --git a/src/tools/sss_usermod.c b/src/tools/sss_usermod.c
index 11369b7e63ee22f5288d2458934283f76768ded2..079c078e7b4cca7177f2d00ed3ec440a3013bba2 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) {
-- 
1.9.0



More information about the sssd-devel mailing list