r24416: Some more minor edits for libgpo, mostly reformatting and moving of functions.
authorGünther Deschner <gd@samba.org>
Tue, 14 Aug 2007 15:17:50 +0000 (15:17 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:29:43 +0000 (12:29 -0500)
Guenther
(This used to be commit 3e240672b431b7132dfb2bdd46198ab758eadd0b)

source3/Makefile.in
source3/libgpo/gpo_fetch.c
source3/libgpo/gpo_filesync.c
source3/libgpo/gpo_ini.c [new file with mode: 0644]
source3/libgpo/gpo_ini.h [new file with mode: 0644]
source3/libgpo/gpo_parse.c [deleted file]
source3/libgpo/gpo_util.c

index 36b5df1beddc39aa4b3053b6c2661adfad71d305..149b7445a8cc53ec04c8f35f0a3ae62f18ca3a2b 100644 (file)
@@ -313,7 +313,7 @@ LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsutils.o  libaddns/dnssock.o \
               libaddns/dnsgss.o libaddns/dnsmarshall.o
 LIBADDNS_OBJ = $(LIBADDNS_OBJ0) $(TALLOC_OBJ)
 
-LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_parse.o libgpo/gpo_util.o \
+LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_ini.o libgpo/gpo_util.o \
              libgpo/gpo_fetch.o libgpo/gpo_filesync.o libgpo/gpo_sec.o
 LIBGPO_OBJ = $(LIBGPO_OBJ0)
 
index 7e66974cf4d3bcb7ae447929b5fc247de86563c0..31c6132b9874502bc415501f9ed57d0397a31734 100644 (file)
@@ -1,18 +1,18 @@
-/* 
+/*
  *  Unix SMB/CIFS implementation.
  *  Group Policy Object Support
  *  Copyright (C) Guenther Deschner 2005-2006
- *  
+ *
  *  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
  *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
  explode the GPO CIFS URI into their components
 ****************************************************************/
 
-NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx, 
-                                const char *file_sys_path, 
-                                char **server, 
-                                char **service, 
+NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx,
+                                const char *file_sys_path,
+                                char **server,
+                                char **service,
                                 char **nt_path,
                                 char **unix_path)
 {
@@ -58,7 +58,8 @@ NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if ((*nt_path = talloc_asprintf(mem_ctx, "\\%s", file_sys_path)) == NULL) {
+       if ((*nt_path = talloc_asprintf(mem_ctx, "\\%s", file_sys_path))
+               == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -78,7 +79,7 @@ NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx,
  prepare the local disc storage for "unix_path"
 ****************************************************************/
 
-static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx, 
+static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx,
                                        const char *unix_path)
 {
        const char *top_dir = lock_path(GPO_CACHE_DIR);
@@ -93,7 +94,7 @@ static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx,
        }
 
        while (next_token(&unix_path, tok, "/", sizeof(tok))) {
-       
+
                if (strequal(tok, GPO_CACHE_DIR)) {
                        break;
                }
@@ -116,15 +117,17 @@ static NTSTATUS gpo_prepare_local_store(TALLOC_CTX *mem_ctx,
  download a full GPO via CIFS
 ****************************************************************/
 
-NTSTATUS gpo_fetch_files(TALLOC_CTX *mem_ctx, 
-                        struct cli_state *cli, 
+NTSTATUS gpo_fetch_files(TALLOC_CTX *mem_ctx,
+                        struct cli_state *cli,
                         struct GROUP_POLICY_OBJECT *gpo)
 {
        NTSTATUS result;
-       char *server, *service, *nt_path, *unix_path, *nt_ini_path, *unix_ini_path;
+       char *server, *service, *nt_path, *unix_path;
+       char *nt_ini_path, *unix_ini_path;
 
-       result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path, 
-                                        &server, &service, &nt_path, &unix_path);
+       result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
+                                        &server, &service, &nt_path,
+                                        &unix_path);
        if (!NT_STATUS_IS_OK(result)) {
                goto out;
        }
@@ -161,13 +164,13 @@ NTSTATUS gpo_fetch_files(TALLOC_CTX *mem_ctx,
  get the locally stored gpt.ini version number
 ****************************************************************/
 
-NTSTATUS gpo_get_sysvol_gpt_version(TALLOC_CTX *mem_ctx, 
-                                   const char *unix_path, 
-                                   uint32 *sysvol_version,
+NTSTATUS gpo_get_sysvol_gpt_version(TALLOC_CTX *mem_ctx,
+                                   const char *unix_path,
+                                   uint32_t *sysvol_version,
                                    char **display_name)
 {
        NTSTATUS status;
-       uint32 version = 0;
+       uint32_t version = 0;
        char *local_path = NULL;
        char *name = NULL;
 
@@ -180,7 +183,8 @@ NTSTATUS gpo_get_sysvol_gpt_version(TALLOC_CTX *mem_ctx,
 
        status = parse_gpt_ini(mem_ctx, local_path, &version, &name);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10,("gpo_get_sysvol_gpt_version: failed to parse ini [%s]: %s\n", 
+               DEBUG(10,("gpo_get_sysvol_gpt_version: "
+                       "failed to parse ini [%s]: %s\n",
                        local_path, nt_errstr(status)));
                return status;
        }
index e3996f444fe67018a05b486bc7a03c71e7694063..cb49dcbda7f4c57fd80faad1c927aa816f899838 100644 (file)
@@ -1,18 +1,18 @@
-/* 
+/*
  *  Unix SMB/CIFS implementation.
  *  Group Policy Object Support
  *  Copyright (C) Guenther Deschner 2006
- *  
+ *
  *  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
  *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
@@ -25,13 +25,13 @@ struct sync_context {
        char *remote_path;
        char *local_path;
        pstring mask;
-       uint16 attribute;
+       uint16_t attribute;
 };
 
 static void gpo_sync_func(const char *mnt,
-                          file_info *info,
-                          const char *mask,
-                          void *state);
+                         file_info *info,
+                         const char *mask,
+                         void *state);
 
 NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx,
                       struct cli_state *cli,
@@ -56,7 +56,7 @@ NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx,
                result = map_nt_error_from_unix(errno);
                goto out;
        }
-        
+
        if ((data = (char *)SMB_MALLOC(read_size)) == NULL) {
                result = NT_STATUS_NO_MEMORY;
                goto out;
@@ -111,8 +111,12 @@ static BOOL gpo_sync_files(struct sync_context *ctx)
 {
        DEBUG(3,("calling cli_list with mask: %s\n", ctx->mask));
 
-       if (cli_list(ctx->cli, ctx->mask, ctx->attribute, gpo_sync_func, ctx) == -1) {
-               DEBUG(1,("listing [%s] failed with error: %s\n", 
+       if (cli_list(ctx->cli,
+                    ctx->mask,
+                    ctx->attribute,
+                    gpo_sync_func,
+                    ctx) == -1) {
+               DEBUG(1,("listing [%s] failed with error: %s\n",
                        ctx->mask, cli_errstr(ctx->cli)));
                return False;
        }
@@ -141,7 +145,7 @@ static void gpo_sync_func(const char *mnt,
                return;
        }
 
-       DEBUG(5,("gpo_sync_func: got mask: [%s], name: [%s]\n", 
+       DEBUG(5,("gpo_sync_func: got mask: [%s], name: [%s]\n",
                mask, info->name));
 
        if (info->mode & aDIR) {
@@ -158,12 +162,13 @@ static void gpo_sync_func(const char *mnt,
 
                result = gpo_copy_dir(unix_dir);
                if (!NT_STATUS_IS_OK(result)) {
-                       DEBUG(1,("failed to copy dir: %s\n", nt_errstr(result)));
+                       DEBUG(1,("failed to copy dir: %s\n",
+                               nt_errstr(result)));
                }
 
                old_nt_dir = ctx->remote_path;
                ctx->remote_path = nt_dir;
-               
+
                old_unix_dir = ctx->local_path;
                ctx->local_path = talloc_strdup(ctx->mem_ctx, unix_dir);
 
@@ -189,9 +194,11 @@ static void gpo_sync_func(const char *mnt,
        fstrcat(unix_filename, "/");
        fstrcat(unix_filename, info->name);
 
-       result = gpo_copy_file(ctx->mem_ctx, ctx->cli, nt_filename, unix_filename);
+       result = gpo_copy_file(ctx->mem_ctx, ctx->cli,
+                              nt_filename, unix_filename);
        if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(1,("failed to copy file: %s\n", nt_errstr(result)));
+               DEBUG(1,("failed to copy file: %s\n",
+                       nt_errstr(result)));
        }
 }
 
@@ -200,9 +207,9 @@ static void gpo_sync_func(const char *mnt,
  list a remote directory and download recursivly
 ****************************************************************/
 
-NTSTATUS gpo_sync_directories(TALLOC_CTX *mem_ctx, 
-                             struct cli_state *cli, 
-                             const char *nt_path, 
+NTSTATUS gpo_sync_directories(TALLOC_CTX *mem_ctx,
+                             struct cli_state *cli,
+                             const char *nt_path,
                              const char *local_path)
 {
        struct sync_context ctx;
diff --git a/source3/libgpo/gpo_ini.c b/source3/libgpo/gpo_ini.c
new file mode 100644 (file)
index 0000000..306d6f9
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Group Policy Support
+ *  Copyright (C) Guenther Deschner 2007
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "gpo_ini.h"
+
+/****************************************************************
+****************************************************************/
+
+static int gp_inifile_free_context(struct gp_inifile_context *ctx)
+{
+       if (!ctx) {
+               return 0;
+       }
+
+       if (ctx->generated_filename) {
+               unlink(ctx->generated_filename);
+               ctx->generated_filename = NULL;
+       }
+
+       if (ctx->dict) {
+               iniparser_freedict(ctx->dict);
+               ctx->dict = NULL;
+       }
+
+       ctx = NULL;
+
+       return 0;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx,
+                                      const char *filename_in,
+                                      char **filename_out)
+{
+       int tmp_fd = 0;
+       uint8 *data_in = NULL;
+       uint8 *data_out = NULL;
+       char *tmp_name = NULL;
+       NTSTATUS status;
+       size_t n = 0;
+
+       if (!filename_out) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       data_in = (uint8 *)file_load(filename_in, &n, 0);
+       if (!data_in) {
+               status = NT_STATUS_NO_SUCH_FILE;
+               goto out;
+       }
+
+       tmp_name = talloc_asprintf(mem_ctx, "%s/convert_file_from_ucs2.XXXXXX",
+               tmpdir());
+       if (!tmp_name) {
+               status = NT_STATUS_NO_MEMORY;
+               goto out;
+       }
+
+       tmp_fd = smb_mkstemp(tmp_name);
+       if (tmp_fd == -1) {
+               status = NT_STATUS_ACCESS_DENIED;
+               goto out;
+       }
+
+       n = convert_string_talloc(mem_ctx, CH_UTF16LE, CH_UNIX,
+                                 data_in, n, &data_out, False);
+
+       if (n == -1) {
+               status = NT_STATUS_INVALID_BUFFER_SIZE;
+               goto out;
+       }
+
+       /* skip utf8 BOM */
+       DEBUG(11,("convert_file_from_ucs2: "
+              "data_out[0]: 0x%x, data_out[1]: 0x%x, data_out[2]: 0x%x\n",
+               data_out[0], data_out[1], data_out[2]));
+
+       if ((data_out[0] == 0xef) && (data_out[1] == 0xbb) &&
+           (data_out[2] == 0xbf)) {
+               DEBUG(11,("convert_file_from_ucs2: "
+                        "%s skipping utf8 BOM\n", tmp_name));
+               data_out += 3;
+               n -= 3;
+       }
+
+       if (sys_write(tmp_fd, data_out, n) != n) {
+               status = map_nt_error_from_unix(errno);
+               goto out;
+       }
+
+       *filename_out = tmp_name;
+
+       status = NT_STATUS_OK;
+
+ out:
+       if (tmp_fd) {
+               close(tmp_fd);
+       }
+
+       SAFE_FREE(data_in);
+
+       return status;
+}
+
+/****************************************************************
+****************************************************************/
+
+ NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx,
+                                uint32_t flags,
+                                const char *unix_path,
+                                const char *suffix,
+                                struct gp_inifile_context **ctx_ret)
+{
+       struct gp_inifile_context *ctx = NULL;
+       NTSTATUS status;
+       dictionary *dict = NULL;
+       char *tmp_filename = NULL;
+       const char *ini_filename = NULL;
+
+       if (!unix_path || !ctx_ret) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       ctx = TALLOC_ZERO_P(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);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               goto failed;
+       }
+
+       status = convert_file_from_ucs2(mem_ctx, ini_filename,
+                                       &tmp_filename);
+       if (!NT_STATUS_IS_OK(status)) {
+               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;
+
+       return NT_STATUS_OK;
+
+ failed:
+
+       DEBUG(1,("gp_inifile_init_context failed: %s\n",
+               nt_errstr(status)));
+
+       TALLOC_FREE(ctx);
+
+       return status;
+}
+
+/****************************************************************
+ parse the local gpt.ini file
+****************************************************************/
+
+#define GPT_INI_SECTION_GENERAL "General"
+#define GPT_INI_PARAMETER_VERSION "Version"
+#define GPT_INI_PARAMETER_DISPLAYNAME "displayName"
+
+NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx,
+                      const char *filename,
+                      uint32_t *version,
+                      char **display_name)
+{
+       NTSTATUS result;
+       uint32_t v = 0;
+       char *name = NULL;
+       dictionary *dict = NULL;
+
+       if (!filename) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       dict = iniparser_load(filename);
+       if (!dict) {
+               return NT_STATUS_NO_SUCH_FILE;
+       }
+
+       if ((name = iniparser_getstring(dict, GPT_INI_SECTION_GENERAL
+                       ":"GPT_INI_PARAMETER_DISPLAYNAME, NULL)) == NULL) {
+               /* 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);
+               if (*display_name == NULL) {
+                       result = NT_STATUS_NO_MEMORY;
+                       goto out;
+               }
+       }
+
+       if ((v = iniparser_getint(dict, GPT_INI_SECTION_GENERAL
+                       ":"GPT_INI_PARAMETER_VERSION, Undefined)) == Undefined) {
+               DEBUG(10,("parse_gpt_ini: no version\n"));
+               result = NT_STATUS_INTERNAL_DB_CORRUPTION;
+               goto out;
+       }
+
+       if (version) {
+               *version = v;
+       }
+
+       result = NT_STATUS_OK;
+ out:
+       if (dict) {
+               iniparser_freedict(dict);
+       }
+
+       return result;
+}
diff --git a/source3/libgpo/gpo_ini.h b/source3/libgpo/gpo_ini.h
new file mode 100644 (file)
index 0000000..fa03dba
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Group Policy Support
+ *  Copyright (C) Guenther Deschner 2007
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* FIXME: get rid of iniparser */
+#include <iniparser.h>
+
+struct gp_inifile_context {
+       TALLOC_CTX *mem_ctx;
+       dictionary *dict;
+       const char *generated_filename;
+};
+
+/* prototypes */
+
+NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx, uint32_t flags,
+                                const char *unix_path, const char *suffix,
+                                struct gp_inifile_context **ctx_ret);
diff --git a/source3/libgpo/gpo_parse.c b/source3/libgpo/gpo_parse.c
deleted file mode 100644 (file)
index 8118ed7..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 
- *  Unix SMB/CIFS implementation.
- *  Group Policy Object Support
- *  Copyright (C) Guenther Deschner 2005-2006
- *  
- *  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
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *  
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *  
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-#include "iniparser/src/iniparser.h"
-
-/****************************************************************
- parse the local gpt.ini file
-****************************************************************/
-
-#define GPT_INI_SECTION_GENERAL "General"
-#define GPT_INI_PARAMETER_VERSION "Version"
-#define GPT_INI_PARAMETER_DISPLAYNAME "displayName"
-
-NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx, const char *filename, uint32 *version, char **display_name)
-{
-       NTSTATUS result;
-       uint32 v;
-       char *name = NULL;
-       dictionary *d;
-
-       d = iniparser_load(filename);
-       if (d == NULL) {
-               return NT_STATUS_NO_SUCH_FILE;
-       }
-
-       if ((name = iniparser_getstring(d, GPT_INI_SECTION_GENERAL
-                       ":"GPT_INI_PARAMETER_DISPLAYNAME, NULL)) == NULL) {
-               /* 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);
-               if (*display_name == NULL) {
-                       result = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-       }
-
-       if ((v = iniparser_getint(d, GPT_INI_SECTION_GENERAL
-                       ":"GPT_INI_PARAMETER_VERSION, Undefined)) == Undefined) {
-               DEBUG(10,("parse_gpt_ini: no version\n"));
-               result = NT_STATUS_INTERNAL_DB_CORRUPTION;
-               goto out;
-       }
-
-       if (version) {
-               *version = v;
-       }
-
-       result = NT_STATUS_OK;
- out:
-       if (d) {
-               iniparser_freedict(d);
-       }
-
-       return result;
-}
index c6e1b71885336c765ab48d8894f0b84d522b855f..16a578509ba4463d504b1c9cb86f5d1f6716f106 100644 (file)
@@ -662,4 +662,45 @@ NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads,
 
        return result;
 }
+
+/****************************************************************
+****************************************************************/
+
+NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx,
+                     uint32_t flags,
+                     const char *filename,
+                     const char *suffix,
+                     const char **filename_out)
+{
+       const char *tmp = NULL;
+       SMB_STRUCT_STAT sbuf;
+       const char *path = NULL;
+
+       if (flags & GPO_LIST_FLAG_MACHINE) {
+               path = "Machine";
+       } else {
+               path = "User";
+       }
+
+       tmp = talloc_asprintf(mem_ctx, "%s/%s/%s", filename,
+                             path, suffix);
+       NT_STATUS_HAVE_NO_MEMORY(tmp);
+
+       if (sys_stat(tmp, &sbuf) == 0) {
+               *filename_out = tmp;
+               return NT_STATUS_OK;
+       }
+
+       tmp = talloc_asprintf(mem_ctx, "%s/%s/%s", filename,
+                             strupper_static(path), suffix);
+       NT_STATUS_HAVE_NO_MEMORY(tmp);
+
+       if (sys_stat(tmp, &sbuf) == 0) {
+               *filename_out = tmp;
+               return NT_STATUS_OK;
+       }
+
+       return NT_STATUS_NO_SUCH_FILE;
+}
+
 #endif /* HAVE_LDAP */