Blame SOURCES/0063-TOOLS-add-sss_colondb-API.patch

6cf099
From d28ed42ad2030090bc511f5b3381b5137885175d Mon Sep 17 00:00:00 2001
6cf099
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
6cf099
Date: Wed, 19 Aug 2015 12:34:08 +0200
6cf099
Subject: [PATCH 63/66] TOOLS: add sss_colondb API
6cf099
6cf099
To simplify import/export users and groups.
6cf099
6cf099
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
6cf099
---
6cf099
 src/tools/common/sss_colondb.c | 305 +++++++++++++++++++++++++++++++++++++++++
6cf099
 src/tools/common/sss_colondb.h |  73 ++++++++++
6cf099
 2 files changed, 378 insertions(+)
6cf099
 create mode 100644 src/tools/common/sss_colondb.c
6cf099
 create mode 100644 src/tools/common/sss_colondb.h
6cf099
6cf099
diff --git a/src/tools/common/sss_colondb.c b/src/tools/common/sss_colondb.c
6cf099
new file mode 100644
6cf099
index 0000000000000000000000000000000000000000..6b340c80e703342defb8582537db2e4ef3926155
6cf099
--- /dev/null
6cf099
+++ b/src/tools/common/sss_colondb.c
6cf099
@@ -0,0 +1,305 @@
6cf099
+/*
6cf099
+    Authors:
6cf099
+        Pavel Březina <pbrezina@redhat.com>
6cf099
+
6cf099
+    Copyright (C) 2015 Red Hat
6cf099
+
6cf099
+    This program is free software; you can redistribute it and/or modify
6cf099
+    it under the terms of the GNU General Public License as published by
6cf099
+    the Free Software Foundation; either version 3 of the License, or
6cf099
+    (at your option) any later version.
6cf099
+
6cf099
+    This program is distributed in the hope that it will be useful,
6cf099
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
6cf099
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6cf099
+    GNU General Public License for more details.
6cf099
+
6cf099
+    You should have received a copy of the GNU General Public License
6cf099
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
6cf099
+*/
6cf099
+
6cf099
+#include <stdlib.h>
6cf099
+
6cf099
+#include "util/util.h"
6cf099
+#include "util/strtonum.h"
6cf099
+#include "tools/common/sss_colondb.h"
6cf099
+
6cf099
+#define IS_STD_FILE(db) ((db)->file == stdin || (db)->file == stdout)
6cf099
+
6cf099
+static char *read_field_as_string(char *line,
6cf099
+                                  const char **_value)
6cf099
+{
6cf099
+    char *rest;
6cf099
+    char *value;
6cf099
+
6cf099
+    if (line == NULL || *line == '\n' || *line == '\0') {
6cf099
+        /* There is nothing else to read. */
6cf099
+        rest = NULL;
6cf099
+        value = NULL;
6cf099
+        goto done;
6cf099
+    }
6cf099
+
6cf099
+    if (*line == ':') {
6cf099
+        /* Special case for empty value. */
6cf099
+        *line = '\0';
6cf099
+        rest = line + 1;
6cf099
+        value = NULL;
6cf099
+        goto done;
6cf099
+    }
6cf099
+
6cf099
+    /* Value starts at current position. */
6cf099
+    value = line;
6cf099
+
6cf099
+    /* Find next field delimiter. */
6cf099
+    rest = strchr(line, ':');
6cf099
+    if (rest == NULL) {
6cf099
+        /* There is no more field. Remove \n from the end. */
6cf099
+        rest = strchr(line, '\n');
6cf099
+        if (rest != NULL) {
6cf099
+            *rest = '\0';
6cf099
+            rest = NULL;
6cf099
+        }
6cf099
+        goto done;
6cf099
+    }
6cf099
+
6cf099
+    /* Remove it and step one character further. */
6cf099
+    *rest = '\0';
6cf099
+    rest++;
6cf099
+
6cf099
+done:
6cf099
+    *_value = value;
6cf099
+
6cf099
+    return rest;
6cf099
+}
6cf099
+
6cf099
+static char *read_field_as_uint32(char *line,
6cf099
+                                  uint32_t *_value)
6cf099
+{
6cf099
+    const char *str;
6cf099
+    char *rest;
6cf099
+    errno_t ret;
6cf099
+
6cf099
+    rest = read_field_as_string(line, &str);
6cf099
+    if (str == NULL) {
6cf099
+        *_value = 0;
6cf099
+        return rest;
6cf099
+    }
6cf099
+
6cf099
+    *_value = strtouint32(str, NULL, 10);
6cf099
+    if (errno != 0) {
6cf099
+        ret = errno;
6cf099
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse number [%d]: %s\n",
6cf099
+              ret, sss_strerror(ret));
6cf099
+
6cf099
+        *_value = 0;
6cf099
+    }
6cf099
+
6cf099
+    return rest;
6cf099
+}
6cf099
+
6cf099
+struct sss_colondb {
6cf099
+    FILE *file;
6cf099
+    enum sss_colondb_mode mode;
6cf099
+};
6cf099
+
6cf099
+errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
6cf099
+                             struct sss_colondb *db,
6cf099
+                             struct sss_colondb_read_field *table)
6cf099
+{
6cf099
+    int readchars;
6cf099
+    size_t linelen = 0;
6cf099
+    char *line = NULL;
6cf099
+    char *tcline;
6cf099
+    char *rest;
6cf099
+    errno_t ret;
6cf099
+    int i;
6cf099
+
6cf099
+    if (db->mode != SSS_COLONDB_READ) {
6cf099
+        return ERR_INTERNAL;
6cf099
+    }
6cf099
+
6cf099
+    readchars = getline(&line, &linelen, db->file);
6cf099
+    if (readchars == -1) {
6cf099
+        /* Nothing was read. */
6cf099
+        if (errno != 0) {
6cf099
+            ret = errno;
6cf099
+            DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read line [%d]: %s",
6cf099
+                  ret, sss_strerror(ret));
6cf099
+            return ret;
6cf099
+        }
6cf099
+
6cf099
+        return EOF;
6cf099
+    }
6cf099
+
6cf099
+    /* Copy line to mem_ctx. */
6cf099
+    tcline = talloc_strdup(mem_ctx, line);
6cf099
+
6cf099
+    free(line);
6cf099
+    line = NULL;
6cf099
+
6cf099
+    if (tcline == NULL) {
6cf099
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
6cf099
+        return ENOMEM;
6cf099
+    }
6cf099
+
6cf099
+    rest = tcline;
6cf099
+    for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) {
6cf099
+        switch (table[i].type) {
6cf099
+        case SSS_COLONDB_UINT32:
6cf099
+            rest = read_field_as_uint32(rest, table[i].data.uint32);
6cf099
+            break;
6cf099
+        case SSS_COLONDB_STRING:
6cf099
+            rest = read_field_as_string(rest, table[i].data.str);
6cf099
+            break;
6cf099
+        case SSS_COLONDB_SENTINEL:
6cf099
+            DEBUG(SSSDBG_CRIT_FAILURE, "Trying to process sentinel?!\n");
6cf099
+            ret = ERR_INTERNAL;
6cf099
+            goto done;
6cf099
+        }
6cf099
+
6cf099
+        if (rest == NULL && table[i + 1].type != SSS_COLONDB_SENTINEL) {
6cf099
+            DEBUG(SSSDBG_CRIT_FAILURE,
6cf099
+                  "Line contains less values than expected!\n");
6cf099
+            ret = EINVAL;
6cf099
+            goto done;
6cf099
+        } else if (rest != NULL && table[i + 1].type == SSS_COLONDB_SENTINEL) {
6cf099
+            DEBUG(SSSDBG_CRIT_FAILURE,
6cf099
+                  "Line contains more values than expected!\n");
6cf099
+            ret = EINVAL;
6cf099
+            goto done;
6cf099
+        }
6cf099
+    }
6cf099
+
6cf099
+    ret = EOK;
6cf099
+
6cf099
+done:
6cf099
+    if (ret != EOK) {
6cf099
+        talloc_free(tcline);
6cf099
+    }
6cf099
+
6cf099
+    return ret;
6cf099
+}
6cf099
+
6cf099
+errno_t sss_colondb_writeline(struct sss_colondb *db,
6cf099
+                              struct sss_colondb_write_field *table)
6cf099
+{
6cf099
+    TALLOC_CTX *tmp_ctx;
6cf099
+    char *line = NULL;
6cf099
+    errno_t ret;
6cf099
+    int i;
6cf099
+
6cf099
+    if (db->mode != SSS_COLONDB_WRITE) {
6cf099
+        return ERR_INTERNAL;
6cf099
+    }
6cf099
+
6cf099
+    tmp_ctx = talloc_new(NULL);
6cf099
+    if (tmp_ctx == NULL) {
6cf099
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n");
6cf099
+        return ENOMEM;
6cf099
+    }
6cf099
+
6cf099
+    for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) {
6cf099
+        switch (table[i].type) {
6cf099
+        case SSS_COLONDB_UINT32:
6cf099
+            if (table[i].data.uint32 == 0) {
6cf099
+                line = talloc_asprintf_append(line, ":");
6cf099
+            } else {
6cf099
+                line = talloc_asprintf_append(line, ":%u", table[i].data.uint32);
6cf099
+            }
6cf099
+            break;
6cf099
+        case SSS_COLONDB_STRING:
6cf099
+            if (table[i].data.str == NULL) {
6cf099
+                line = talloc_asprintf_append(line, ":");
6cf099
+            } else {
6cf099
+                line = talloc_asprintf_append(line, ":%s", table[i].data.str);
6cf099
+            }
6cf099
+            break;
6cf099
+        case SSS_COLONDB_SENTINEL:
6cf099
+            DEBUG(SSSDBG_CRIT_FAILURE, "Trying to process sentinel?!\n");
6cf099
+            ret = ERR_INTERNAL;
6cf099
+            goto done;
6cf099
+        }
6cf099
+
6cf099
+        if (line == NULL) {
6cf099
+            ret = ENOMEM;
6cf099
+            goto done;
6cf099
+        }
6cf099
+    }
6cf099
+
6cf099
+    /* Remove starting : */
6cf099
+    line++;
6cf099
+
6cf099
+    fprintf(db->file, "%s\n", line);
6cf099
+    fflush(db->file);
6cf099
+
6cf099
+    ret = EOK;
6cf099
+
6cf099
+done:
6cf099
+    talloc_free(tmp_ctx);
6cf099
+
6cf099
+    return ret;
6cf099
+}
6cf099
+
6cf099
+static int sss_colondb_close(void *pvt)
6cf099
+{
6cf099
+    struct sss_colondb *db = talloc_get_type(pvt, struct sss_colondb);
6cf099
+
6cf099
+    if (db->file == NULL || IS_STD_FILE(db)) {
6cf099
+        return 0;
6cf099
+    }
6cf099
+
6cf099
+    fclose(db->file);
6cf099
+    db->file = NULL;
6cf099
+
6cf099
+    return 0;
6cf099
+}
6cf099
+
6cf099
+static FILE *open_db(const char *filename, enum sss_colondb_mode mode)
6cf099
+{
6cf099
+    FILE *fp = NULL;
6cf099
+    errno_t ret;
6cf099
+
6cf099
+    errno = 0;
6cf099
+
6cf099
+    switch (mode) {
6cf099
+    case SSS_COLONDB_READ:
6cf099
+        fp = filename == NULL ? stdin : fopen(filename, "r");
6cf099
+        break;
6cf099
+    case SSS_COLONDB_WRITE:
6cf099
+        fp = filename == NULL ? stdout : fopen(filename, "w");
6cf099
+        break;
6cf099
+    }
6cf099
+
6cf099
+    if (fp == NULL && filename != NULL) {
6cf099
+        ret = errno;
6cf099
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open file %s [%d]: %s\n",
6cf099
+              filename, ret, sss_strerror(ret));
6cf099
+    }
6cf099
+
6cf099
+    return fp;
6cf099
+}
6cf099
+
6cf099
+struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx,
6cf099
+                                     enum sss_colondb_mode mode,
6cf099
+                                     const char *filename)
6cf099
+{
6cf099
+    struct sss_colondb *db;
6cf099
+
6cf099
+    db = talloc_zero(mem_ctx, struct sss_colondb);
6cf099
+    if (db == NULL) {
6cf099
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n");
6cf099
+        return NULL;
6cf099
+    }
6cf099
+
6cf099
+    db->file = open_db(filename, mode);
6cf099
+    db->mode = mode;
6cf099
+
6cf099
+    if (db->file == NULL) {
6cf099
+        talloc_free(db);
6cf099
+        return NULL;
6cf099
+    }
6cf099
+
6cf099
+    talloc_set_destructor((TALLOC_CTX *)db, sss_colondb_close);
6cf099
+
6cf099
+    return db;
6cf099
+}
6cf099
diff --git a/src/tools/common/sss_colondb.h b/src/tools/common/sss_colondb.h
6cf099
new file mode 100644
6cf099
index 0000000000000000000000000000000000000000..6edd99cbe3b9ef5c86a48632ac3fc71e8a3e55fe
6cf099
--- /dev/null
6cf099
+++ b/src/tools/common/sss_colondb.h
6cf099
@@ -0,0 +1,73 @@
6cf099
+/*
6cf099
+    Authors:
6cf099
+        Pavel Březina <pbrezina@redhat.com>
6cf099
+
6cf099
+    Copyright (C) 2015 Red Hat
6cf099
+
6cf099
+    This program is free software; you can redistribute it and/or modify
6cf099
+    it under the terms of the GNU General Public License as published by
6cf099
+    the Free Software Foundation; either version 3 of the License, or
6cf099
+    (at your option) any later version.
6cf099
+
6cf099
+    This program is distributed in the hope that it will be useful,
6cf099
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
6cf099
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6cf099
+    GNU General Public License for more details.
6cf099
+
6cf099
+    You should have received a copy of the GNU General Public License
6cf099
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
6cf099
+*/
6cf099
+
6cf099
+#ifndef _SSS_COLONDB_H_
6cf099
+#define _SSS_COLONDB_H_
6cf099
+
6cf099
+#include <stdlib.h>
6cf099
+#include <stdint.h>
6cf099
+#include <errno.h>
6cf099
+#include <talloc.h>
6cf099
+
6cf099
+struct sss_colondb;
6cf099
+
6cf099
+enum sss_colondb_mode {
6cf099
+    SSS_COLONDB_READ,
6cf099
+    SSS_COLONDB_WRITE
6cf099
+};
6cf099
+
6cf099
+enum sss_colondb_type {
6cf099
+    SSS_COLONDB_UINT32,
6cf099
+    SSS_COLONDB_STRING,
6cf099
+    SSS_COLONDB_SENTINEL
6cf099
+};
6cf099
+
6cf099
+union sss_colondb_write_data {
6cf099
+    uint32_t uint32;
6cf099
+    const char *str;
6cf099
+};
6cf099
+
6cf099
+union sss_colondb_read_data {
6cf099
+    uint32_t *uint32;
6cf099
+    const char **str;
6cf099
+};
6cf099
+
6cf099
+struct sss_colondb_write_field {
6cf099
+    enum sss_colondb_type type;
6cf099
+    union sss_colondb_write_data data;
6cf099
+};
6cf099
+
6cf099
+struct sss_colondb_read_field {
6cf099
+    enum sss_colondb_type type;
6cf099
+    union sss_colondb_read_data data;
6cf099
+};
6cf099
+
6cf099
+struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx,
6cf099
+                                     enum sss_colondb_mode mode,
6cf099
+                                     const char *filename);
6cf099
+
6cf099
+errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
6cf099
+                             struct sss_colondb *db,
6cf099
+                             struct sss_colondb_read_field *table);
6cf099
+
6cf099
+errno_t sss_colondb_writeline(struct sss_colondb *db,
6cf099
+                              struct sss_colondb_write_field *table);
6cf099
+
6cf099
+#endif /* _SSS_COLONDB_H_ */
6cf099
-- 
6cf099
2.4.3
6cf099