LCOV - code coverage report
Current view: top level - libgpo - gpo_ini.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 49 200 24.5 %
Date: 2021-09-23 10:06:22 Functions: 5 10 50.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  Group Policy Support
       4             :  *  Copyright (C) Guenther Deschner 2007
       5             :  *  Copyright (C) Wilco Baan Hofman 2009
       6             :  *
       7             :  *  This program is free software; you can redistribute it and/or modify
       8             :  *  it under the terms of the GNU General Public License as published by
       9             :  *  the Free Software Foundation; either version 3 of the License, or
      10             :  *  (at your option) any later version.
      11             :  *
      12             :  *  This program is distributed in the hope that it will be useful,
      13             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  *  GNU General Public License for more details.
      16             :  *
      17             :  *  You should have received a copy of the GNU General Public License
      18             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include "includes.h"
      22             : #include "gpo.h"
      23             : #include "gpo_ini.h"
      24             : #include "system/filesys.h"
      25             : 
      26             : 
      27          46 : static bool change_section(const char *section, void *ctx_ptr)
      28             : {
      29          46 :         struct gp_inifile_context *ctx = (struct gp_inifile_context *) ctx_ptr;
      30             : 
      31          46 :         if (ctx->current_section) {
      32           0 :                 talloc_free(ctx->current_section);
      33             :         }
      34          46 :         ctx->current_section = talloc_strdup(ctx, section);
      35          46 :         if (!ctx->current_section) {
      36           0 :                 return false;
      37             :         }
      38          46 :         return true;
      39             : }
      40             : 
      41             : /****************************************************************
      42             : ****************************************************************/
      43             : 
      44          46 : static bool store_keyval_pair(const char *key, const char *value, void *ctx_ptr)
      45             : {
      46          46 :         struct gp_inifile_context *ctx = (struct gp_inifile_context *) ctx_ptr;
      47             : 
      48          46 :         ctx->data = talloc_realloc(ctx, ctx->data, struct keyval_pair *, ctx->keyval_count+1);
      49          46 :         if (!ctx->data) {
      50           0 :                 return false;
      51             :         }
      52             : 
      53          46 :         ctx->data[ctx->keyval_count] = talloc_zero(ctx, struct keyval_pair);
      54          46 :         if (!ctx->data[ctx->keyval_count]) {
      55           0 :                 return false;
      56             :         }
      57             : 
      58          46 :         ctx->data[ctx->keyval_count]->key = talloc_asprintf(ctx, "%s:%s", ctx->current_section, key);
      59          46 :         ctx->data[ctx->keyval_count]->val = talloc_strdup(ctx, value ? value : "");
      60             : 
      61          69 :         if (!ctx->data[ctx->keyval_count]->key ||
      62          46 :             !ctx->data[ctx->keyval_count]->val) {
      63           0 :                 return false;
      64             :         }
      65             : 
      66          46 :         ctx->keyval_count++;
      67          46 :         return true;
      68             : }
      69             : 
      70             : /****************************************************************
      71             : ****************************************************************/
      72             : 
      73           0 : static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
      74             :                                        const char *filename_in,
      75             :                                        char **filename_out)
      76             : {
      77           0 :         int tmp_fd = -1;
      78           0 :         uint8_t *data_in = NULL;
      79           0 :         uint8_t *data_out = NULL;
      80           0 :         char *tmp_name = NULL;
      81             :         NTSTATUS status;
      82           0 :         size_t n = 0;
      83             :         size_t converted_size;
      84             :         mode_t mask;
      85             : 
      86           0 :         if (!filename_out) {
      87           0 :                 return NT_STATUS_INVALID_PARAMETER;
      88             :         }
      89             : 
      90           0 :         data_in = (uint8_t *)file_load(filename_in, &n, 0, mem_ctx);
      91           0 :         if (!data_in) {
      92           0 :                 status = NT_STATUS_NO_SUCH_FILE;
      93           0 :                 goto out;
      94             :         }
      95             : 
      96           0 :         DEBUG(11,("convert_file_from_ucs2: "
      97             :                "data_in[0]: 0x%x, data_in[1]: 0x%x, data_in[2]: 0x%x\n",
      98             :                 data_in[0], data_in[1], data_in[2]));
      99             : 
     100           0 :         if ((data_in[0] != 0xff) || (data_in[1] != 0xfe) || (data_in[2] != 0x0d)) {
     101           0 :                 *filename_out = NULL;
     102           0 :                 status = NT_STATUS_OK;
     103           0 :                 goto out;
     104             :         }
     105             : 
     106           0 :         tmp_name = talloc_asprintf(mem_ctx, "%s/convert_file_from_ucs2.XXXXXX",
     107             :                 tmpdir());
     108           0 :         if (!tmp_name) {
     109           0 :                 status = NT_STATUS_NO_MEMORY;
     110           0 :                 goto out;
     111             :         }
     112             : 
     113           0 :         mask = umask(S_IRWXO | S_IRWXG);
     114           0 :         tmp_fd = mkstemp(tmp_name);
     115           0 :         umask(mask);
     116           0 :         if (tmp_fd == -1) {
     117           0 :                 status = NT_STATUS_ACCESS_DENIED;
     118           0 :                 goto out;
     119             :         }
     120             : 
     121           0 :         if (!convert_string_talloc(mem_ctx, CH_UTF16LE, CH_UNIX, data_in, n,
     122             :                                    (void *)&data_out, &converted_size))
     123             :         {
     124           0 :                 status = NT_STATUS_INVALID_BUFFER_SIZE;
     125           0 :                 goto out;
     126             :         }
     127             : 
     128           0 :         DEBUG(11,("convert_file_from_ucs2: "
     129             :                  "%s skipping utf16-le BOM\n", tmp_name));
     130             : 
     131           0 :         converted_size -= 3;
     132             : 
     133           0 :         if (write(tmp_fd, data_out + 3, converted_size) != converted_size) {
     134           0 :                 status = map_nt_error_from_unix_common(errno);
     135           0 :                 goto out;
     136             :         }
     137             : 
     138           0 :         *filename_out = tmp_name;
     139             : 
     140           0 :         status = NT_STATUS_OK;
     141             : 
     142           0 :  out:
     143           0 :         if (tmp_fd != -1) {
     144           0 :                 close(tmp_fd);
     145             :         }
     146             : 
     147           0 :         talloc_free(data_in);
     148           0 :         talloc_free(data_out);
     149             : 
     150           0 :         return status;
     151             : }
     152             : 
     153             : /****************************************************************
     154             : ****************************************************************/
     155             : 
     156          92 : NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, const char **ret)
     157             : {
     158             :         int i;
     159             : 
     160         138 :         for (i = 0; i < ctx->keyval_count; i++) {
     161          92 :                 if (strcmp(ctx->data[i]->key, key) == 0) {
     162          46 :                         if (ret) {
     163          46 :                                 *ret = ctx->data[i]->val;
     164             :                         }
     165          46 :                         return NT_STATUS_OK;
     166             :                 }
     167             :         }
     168          46 :         return NT_STATUS_NOT_FOUND;
     169             : }
     170             : 
     171             : /****************************************************************
     172             : ****************************************************************/
     173             : 
     174          46 : NTSTATUS gp_inifile_getint(struct gp_inifile_context *ctx, const char *key, int *ret)
     175             : {
     176             :         const char *value;
     177             :         NTSTATUS result;
     178             : 
     179          46 :         result = gp_inifile_getstring(ctx,key, &value);
     180          46 :         if (!NT_STATUS_IS_OK(result)) {
     181           0 :                 return result;
     182             :         }
     183             : 
     184          46 :         if (ret) {
     185          46 :                 *ret = (int)strtol(value, NULL, 10);
     186             :         }
     187          46 :         return NT_STATUS_OK;
     188             : }
     189             : 
     190             : /****************************************************************
     191             : ****************************************************************/
     192             : 
     193           0 : NTSTATUS gp_inifile_getbool(struct gp_inifile_context *ctx, const char *key, bool *ret)
     194             : {
     195             :         const char *value;
     196             :         NTSTATUS result;
     197             : 
     198           0 :         result = gp_inifile_getstring(ctx,key, &value);
     199           0 :         if (!NT_STATUS_IS_OK(result)) {
     200           0 :                 return result;
     201             :         }
     202             : 
     203           0 :         if (strequal(value, "Yes") ||
     204           0 :             strequal(value, "True")) {
     205           0 :                 if (ret) {
     206           0 :                         *ret = true;
     207             :                 }
     208           0 :                 return NT_STATUS_OK;
     209           0 :         } else if (strequal(value, "No") ||
     210           0 :                    strequal(value, "False")) {
     211           0 :                 if (ret) {
     212           0 :                         *ret = false;
     213             :                 }
     214           0 :                 return NT_STATUS_OK;
     215             :         }
     216             : 
     217           0 :         return NT_STATUS_NOT_FOUND;
     218             : }
     219             : 
     220             : /****************************************************************
     221             : ****************************************************************/
     222             : 
     223           0 : NTSTATUS gp_inifile_enum_section(struct gp_inifile_context *ctx,
     224             :                                  const char *section,
     225             :                                  size_t *num_ini_keys,
     226             :                                  const char ***ini_keys,
     227             :                                  const char ***ini_values)
     228             : {
     229             :         NTSTATUS status;
     230             :         int i;
     231           0 :         size_t num_keys = 0, num_vals = 0;
     232           0 :         const char **keys = NULL;
     233           0 :         const char **values = NULL;
     234             : 
     235           0 :         if (section == NULL || num_ini_keys == NULL ||
     236           0 :             ini_keys == NULL || ini_values == NULL) {
     237           0 :                 return NT_STATUS_INVALID_PARAMETER;
     238             :         }
     239             : 
     240           0 :         for (i = 0; i < ctx->keyval_count; i++) {
     241             : 
     242             :                 bool ok;
     243             : 
     244             :                 /*
     245             :                  * section: KEYNAME
     246             :                  * KEYNAME:value matches
     247             :                  * KEYNAME_OEM:value not
     248             :                  */
     249             : 
     250           0 :                 if (strlen(section)+1 > strlen(ctx->data[i]->key)) {
     251           0 :                         continue;
     252             :                 }
     253             : 
     254           0 :                 if (!strnequal(section, ctx->data[i]->key, strlen(section))) {
     255           0 :                         continue;
     256             :                 }
     257             : 
     258           0 :                 if (ctx->data[i]->key[strlen(section)] != ':') {
     259           0 :                         continue;
     260             :                 }
     261             : 
     262           0 :                 ok = add_string_to_array(ctx, ctx->data[i]->key, &keys, &num_keys);
     263           0 :                 if (!ok) {
     264           0 :                         status = NT_STATUS_NO_MEMORY;
     265           0 :                         goto failed;
     266             :                 }
     267             : 
     268           0 :                 ok = add_string_to_array(ctx, ctx->data[i]->val, &values, &num_vals);
     269           0 :                 if (!ok) {
     270           0 :                         status = NT_STATUS_NO_MEMORY;
     271           0 :                         goto failed;
     272             :                 }
     273             : 
     274           0 :                 if (num_keys != num_vals) {
     275           0 :                         status = NT_STATUS_INTERNAL_DB_CORRUPTION;
     276           0 :                         goto failed;
     277             :                 }
     278             :         }
     279             : 
     280           0 :         *num_ini_keys = num_keys;
     281           0 :         *ini_keys = keys;
     282           0 :         *ini_values = values;
     283             : 
     284           0 :         return NT_STATUS_OK;
     285             : 
     286           0 :  failed:
     287           0 :         talloc_free(keys);
     288           0 :         talloc_free(values);
     289             : 
     290           0 :         return status;
     291             : }
     292             : 
     293             : 
     294             : /****************************************************************
     295             : ****************************************************************/
     296             : 
     297           0 : NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx,
     298             :                                  uint32_t flags,
     299             :                                  const char *unix_path,
     300             :                                  const char *suffix,
     301             :                                  struct gp_inifile_context **ctx_ret)
     302             : {
     303           0 :         struct gp_inifile_context *ctx = NULL;
     304             :         NTSTATUS status;
     305             :         int rv;
     306           0 :         char *tmp_filename = NULL;
     307           0 :         const char *ini_filename = NULL;
     308             : 
     309           0 :         if (!unix_path || !ctx_ret) {
     310           0 :                 return NT_STATUS_INVALID_PARAMETER;
     311             :         }
     312             : 
     313           0 :         ctx = talloc_zero(mem_ctx, struct gp_inifile_context);
     314           0 :         NT_STATUS_HAVE_NO_MEMORY(ctx);
     315             : 
     316           0 :         status = gp_find_file(mem_ctx, flags, unix_path, suffix,
     317             :                               &ini_filename);
     318             : 
     319           0 :         if (!NT_STATUS_IS_OK(status)) {
     320           0 :                 goto failed;
     321             :         }
     322             : 
     323           0 :         status = convert_file_from_ucs2(mem_ctx, ini_filename,
     324             :                                         &tmp_filename);
     325           0 :         if (!NT_STATUS_IS_OK(status)) {
     326           0 :                 goto failed;
     327             :         }
     328             : 
     329           0 :         rv = pm_process(tmp_filename != NULL ? tmp_filename : ini_filename,
     330             :                         change_section, store_keyval_pair, ctx);
     331           0 :         if (!rv) {
     332           0 :                 return NT_STATUS_NO_SUCH_FILE;
     333             :         }
     334             : 
     335             : 
     336           0 :         ctx->generated_filename = tmp_filename;
     337           0 :         ctx->mem_ctx = mem_ctx;
     338             : 
     339           0 :         *ctx_ret = ctx;
     340             : 
     341           0 :         return NT_STATUS_OK;
     342             : 
     343           0 :  failed:
     344             : 
     345           0 :         DEBUG(1,("gp_inifile_init_context failed: %s\n",
     346             :                 nt_errstr(status)));
     347             : 
     348           0 :         talloc_free(ctx);
     349             : 
     350           0 :         return status;
     351             : }
     352             : 
     353             : /****************************************************************
     354             : ****************************************************************/
     355             : 
     356           0 : NTSTATUS gp_inifile_init_context_direct(TALLOC_CTX *mem_ctx,
     357             :                                         const char *unix_path,
     358             :                                         struct gp_inifile_context **pgp_ctx)
     359             : {
     360           0 :         struct gp_inifile_context *gp_ctx = NULL;
     361             :         NTSTATUS status;
     362             :         bool rv;
     363           0 :         char *tmp_filename = NULL;
     364             : 
     365           0 :         if (unix_path == NULL || pgp_ctx == NULL) {
     366           0 :                 return NT_STATUS_INVALID_PARAMETER;
     367             :         }
     368             : 
     369           0 :         gp_ctx = talloc_zero(mem_ctx, struct gp_inifile_context);
     370           0 :         if (gp_ctx == NULL) {
     371           0 :                 return NT_STATUS_NO_MEMORY;
     372             :         }
     373             : 
     374           0 :         status = convert_file_from_ucs2(mem_ctx, unix_path,
     375             :                                         &tmp_filename);
     376           0 :         if (!NT_STATUS_IS_OK(status)) {
     377           0 :                 goto failed;
     378             :         }
     379             : 
     380           0 :         rv = pm_process_with_flags(tmp_filename != NULL ? tmp_filename : unix_path,
     381             :                                    true,
     382             :                                    change_section,
     383             :                                    store_keyval_pair,
     384             :                                    gp_ctx);
     385           0 :         if (!rv) {
     386           0 :                 return NT_STATUS_NO_SUCH_FILE;
     387             :         }
     388             : 
     389           0 :         gp_ctx->generated_filename = tmp_filename;
     390           0 :         gp_ctx->mem_ctx = mem_ctx;
     391             : 
     392           0 :         *pgp_ctx = gp_ctx;
     393             : 
     394           0 :         return NT_STATUS_OK;
     395             : 
     396           0 :  failed:
     397             : 
     398           0 :         DEBUG(1,("gp_inifile_init_context_direct failed: %s\n",
     399             :                 nt_errstr(status)));
     400             : 
     401           0 :         talloc_free(gp_ctx);
     402             : 
     403           0 :         return status;
     404             : }
     405             : 
     406             : 
     407             : /****************************************************************
     408             :  parse the local gpt.ini file
     409             : ****************************************************************/
     410             : 
     411             : #define GPT_INI_SECTION_GENERAL "General"
     412             : #define GPT_INI_PARAMETER_VERSION "Version"
     413             : #define GPT_INI_PARAMETER_DISPLAYNAME "displayName"
     414             : 
     415          46 : NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx,
     416             :                        const char *filename,
     417             :                        uint32_t *version,
     418             :                        char **display_name)
     419             : {
     420             :         NTSTATUS result;
     421             :         int rv;
     422          46 :         int v = 0;
     423          46 :         const char *name = NULL;
     424             :         struct gp_inifile_context *ctx;
     425             : 
     426          46 :         if (!filename) {
     427           0 :                 return NT_STATUS_INVALID_PARAMETER;
     428             :         }
     429             : 
     430          46 :         ctx = talloc_zero(mem_ctx, struct gp_inifile_context);
     431          46 :         NT_STATUS_HAVE_NO_MEMORY(ctx);
     432             : 
     433          46 :         rv = pm_process(filename, change_section, store_keyval_pair, ctx);
     434          46 :         if (!rv) {
     435           0 :                 return NT_STATUS_NO_SUCH_FILE;
     436             :         }
     437             : 
     438             : 
     439          46 :         result = gp_inifile_getstring(ctx, GPT_INI_SECTION_GENERAL
     440             :                         ":"GPT_INI_PARAMETER_DISPLAYNAME, &name);
     441          46 :         if (!NT_STATUS_IS_OK(result)) {
     442             :                 /* the default domain policy and the default domain controller
     443             :                  * policy never have a displayname in their gpt.ini file */
     444          46 :                 DEBUG(10,("parse_gpt_ini: no name in %s\n", filename));
     445             :         }
     446             : 
     447          46 :         if (name && display_name) {
     448           0 :                 *display_name = talloc_strdup(ctx, name);
     449           0 :                 if (*display_name == NULL) {
     450           0 :                         return NT_STATUS_NO_MEMORY;
     451             :                 }
     452             :         }
     453             : 
     454          46 :         result = gp_inifile_getint(ctx, GPT_INI_SECTION_GENERAL
     455             :                         ":"GPT_INI_PARAMETER_VERSION, &v);
     456          46 :         if (!NT_STATUS_IS_OK(result)) {
     457           0 :                 DEBUG(10,("parse_gpt_ini: no version\n"));
     458           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     459             :         }
     460             : 
     461          46 :         if (version) {
     462          46 :                 *version = v;
     463             :         }
     464             : 
     465          46 :         talloc_free(ctx);
     466             : 
     467          46 :         return NT_STATUS_OK;
     468             : }

Generated by: LCOV version 1.13