Move gpo_ini stuff to the main libgpo. Make gpo_ini use a common parser.
[gd/samba-autobuild/.git] / libgpo / gpo_ini.c
similarity index 62%
rename from source3/libgpo/gpo_ini.c
rename to libgpo/gpo_ini.c
index edca85530bf57baf88db253aed657cc164eff8e9..79bf5fd8d83fc90aa44cd175b8463f7707ec24f7 100644 (file)
@@ -2,6 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  Group Policy Support
  *  Copyright (C) Guenther Deschner 2007
+ *  Copyright (C) Wilco Baan Hofman 2009
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  */
 
 #include "includes.h"
+#include "gpo.h"
 #include "gpo_ini.h"
+#include "system/filesys.h"
 
-/****************************************************************
-****************************************************************/
 
-static int gp_inifile_free_context(struct gp_inifile_context *ctx)
+static bool change_section(const char *section, void *ctx_ptr)
 {
-       if (!ctx) {
-               return 0;
-       }
-
-       if (ctx->generated_filename) {
-               unlink(ctx->generated_filename);
-               ctx->generated_filename = NULL;
-       }
+       struct gp_inifile_context *ctx = (struct gp_inifile_context *) ctx_ptr;
 
-       if (ctx->dict) {
-               iniparser_freedict(ctx->dict);
-               ctx->dict = NULL;
+       if (ctx->current_section) {
+               talloc_free(ctx->current_section);
        }
+       ctx->current_section = talloc_strdup(ctx, section);
+       return true;
+}
 
-       ctx = NULL;
+/****************************************************************
+****************************************************************/
 
-       return 0;
+static bool store_keyval_pair(const char *key, const char *value, void *ctx_ptr)
+{
+       struct gp_inifile_context *ctx = (struct gp_inifile_context *) ctx_ptr;
+       ctx->data = talloc_realloc(ctx, ctx->data, struct keyval_pair *, ctx->keyval_count+1);
+       ctx->data[ctx->keyval_count]->key = talloc_asprintf(ctx, "%s:%s", ctx->current_section, key);
+       ctx->data[ctx->keyval_count]->val = talloc_strdup(ctx, value);
+       ctx->keyval_count++;
+       return true;
 }
 
 /****************************************************************
@@ -52,8 +56,8 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                                       char **filename_out)
 {
        int tmp_fd = -1;
-       uint8 *data_in = NULL;
-       uint8 *data_out = NULL;
+       uint8_t *data_in = NULL;
+       uint8_t *data_out = NULL;
        char *tmp_name = NULL;
        NTSTATUS status;
        size_t n = 0;
@@ -63,7 +67,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       data_in = (uint8 *)file_load(filename_in, &n, 0, NULL);
+       data_in = (uint8_t *)file_load(filename_in, &n, 0, NULL);
        if (!data_in) {
                status = NT_STATUS_NO_SUCH_FILE;
                goto out;
@@ -76,14 +80,14 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                goto out;
        }
 
-       tmp_fd = smb_mkstemp(tmp_name);
+       tmp_fd = mkstemp(tmp_name);
        if (tmp_fd == -1) {
                status = NT_STATUS_ACCESS_DENIED;
                goto out;
        }
 
        if (!convert_string_talloc(mem_ctx, CH_UTF16LE, CH_UNIX, data_in, n,
-                                  (void **)&data_out, &converted_size, False))
+                                  (void **)&data_out, &converted_size, false))
        {
                status = NT_STATUS_INVALID_BUFFER_SIZE;
                goto out;
@@ -102,7 +106,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                converted_size -= 3;
        }
 
-       if (sys_write(tmp_fd, data_out, converted_size) != converted_size) {
+       if (write(tmp_fd, data_out, converted_size) != converted_size) {
                status = map_nt_error_from_unix(errno);
                goto out;
        }
@@ -116,7 +120,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                close(tmp_fd);
        }
 
-       TALLOC_FREE(data_in);
+       talloc_free(data_in);
 
        return status;
 }
@@ -124,7 +128,40 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
 /****************************************************************
 ****************************************************************/
 
- NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx,
+NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, char **ret)
+{
+       int i;
+
+       for (i = 0; i < ctx->keyval_count; i++) {
+               if (strcmp(ctx->data[i]->key, key) == 0) {
+                       *ret = ctx->data[i]->val;
+                       return NT_STATUS_OK;
+               }
+       }
+       return NT_STATUS_NOT_FOUND;
+}
+
+/****************************************************************
+****************************************************************/
+
+NTSTATUS gp_inifile_getint(struct gp_inifile_context *ctx, const char *key, int *ret)
+{
+       char *value;
+       NTSTATUS result;
+
+       result = gp_inifile_getstring(ctx,key, &value);
+       if (!NT_STATUS_IS_OK(result)) {
+               return result;
+       }
+
+       *ret = (int)strtol(value, NULL, 10);
+       return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx,
                                 uint32_t flags,
                                 const char *unix_path,
                                 const char *suffix,
@@ -132,7 +169,6 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
 {
        struct gp_inifile_context *ctx = NULL;
        NTSTATUS status;
-       dictionary *dict = NULL;
        char *tmp_filename = NULL;
        const char *ini_filename = NULL;
 
@@ -140,11 +176,9 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       ctx = TALLOC_ZERO_P(mem_ctx, struct gp_inifile_context);
+       ctx = talloc_zero(mem_ctx, struct gp_inifile_context);
        NT_STATUS_HAVE_NO_MEMORY(ctx);
 
-       talloc_set_destructor(ctx, gp_inifile_free_context);
-
        status = gp_find_file(mem_ctx, flags, unix_path, suffix,
                              &ini_filename);
 
@@ -158,14 +192,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       dict = iniparser_load(tmp_filename);
-       if (!dict) {
-               status = NT_STATUS_NO_SUCH_FILE;
-               goto failed;
-       }
-
        ctx->generated_filename = tmp_filename;
-       ctx->dict = dict;
        ctx->mem_ctx = mem_ctx;
 
        *ctx_ret = ctx;
@@ -177,7 +204,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
        DEBUG(1,("gp_inifile_init_context failed: %s\n",
                nt_errstr(status)));
 
-       TALLOC_FREE(ctx);
+       talloc_free(ctx);
 
        return status;
 }
@@ -190,45 +217,46 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
 #define GPT_INI_PARAMETER_VERSION "Version"
 #define GPT_INI_PARAMETER_DISPLAYNAME "displayName"
 
-NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx,
+NTSTATUS parse_gpt_ini(struct gp_inifile_context *ctx,
                       const char *filename,
                       uint32_t *version,
                       char **display_name)
 {
        NTSTATUS result;
-       uint32_t v = 0;
+       int rv;
+       int v = 0;
        char *name = NULL;
-       dictionary *dict = NULL;
 
        if (!filename) {
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       dict = iniparser_load(filename);
-       if (!dict) {
+       rv = pm_process(filename, change_section, store_keyval_pair, NULL);
+       if (!rv) {
                return NT_STATUS_NO_SUCH_FILE;
        }
 
-       if ((name = iniparser_getstring(dict, GPT_INI_SECTION_GENERAL
-                       ":"GPT_INI_PARAMETER_DISPLAYNAME, NULL)) == NULL) {
+
+       result = gp_inifile_getstring(ctx, GPT_INI_SECTION_GENERAL
+                       ":"GPT_INI_PARAMETER_DISPLAYNAME, &name);
+       if (!NT_STATUS_IS_OK(result)) {
                /* the default domain policy and the default domain controller
                 * policy never have a displayname in their gpt.ini file */
                DEBUG(10,("parse_gpt_ini: no name in %s\n", filename));
        }
 
        if (name && display_name) {
-               *display_name = talloc_strdup(mem_ctx, name);
+               *display_name = talloc_strdup(ctx, name);
                if (*display_name == NULL) {
-                       result = NT_STATUS_NO_MEMORY;
-                       goto out;
+                       return NT_STATUS_NO_MEMORY;
                }
        }
 
-       if ((v = iniparser_getint(dict, GPT_INI_SECTION_GENERAL
-                       ":"GPT_INI_PARAMETER_VERSION, Undefined)) == Undefined) {
+       result = gp_inifile_getint(ctx, GPT_INI_SECTION_GENERAL
+                       ":"GPT_INI_PARAMETER_VERSION, &v);
+       if (!NT_STATUS_IS_OK(result)) {
                DEBUG(10,("parse_gpt_ini: no version\n"));
-               result = NT_STATUS_INTERNAL_DB_CORRUPTION;
-               goto out;
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
        if (version) {
@@ -236,10 +264,6 @@ NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx,
        }
 
        result = NT_STATUS_OK;
- out:
-       if (dict) {
-               iniparser_freedict(dict);
-       }
 
        return result;
 }