summaryrefslogtreecommitdiff
path: root/source3/param/config_ldap.c
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2003-11-15 00:47:29 +0000
committerSimo Sorce <idra@samba.org>2003-11-15 00:47:29 +0000
commite762e323897cd4ba3445016b6904136264082d25 (patch)
tree2268d5a8a60d321e8ec0a504d9f5510acc99061d /source3/param/config_ldap.c
parent7301471a6a12244cd398e3c81c310ffc2b663c53 (diff)
downloadsamba-e762e323897cd4ba3445016b6904136264082d25.tar.gz
samba-e762e323897cd4ba3445016b6904136264082d25.tar.bz2
samba-e762e323897cd4ba3445016b6904136264082d25.zip
Split smbldap in a core file and a utility file
Add module support for configuration loading Add a first implementation of config_ldap module to put samba configuration on ldap It worked on my test machine, please try it out and send bugfixes :-) have fun, Simo. INSTRUCTIONS: Just add something like this to your smb.conf file: config backend = config_ldap:ldap://localhost config_ldap:basedn = dc=samba,dc=org the config tree must follow this scheme: ou=foo, dc=samba, dc=org <- global section |- sambaOptionName=log level, ou=foo, ... <- options |- ... |- sambaShareName=testlc, ou=foo, ... == [testlc] |- sambaOptionName=path, sambaShareName=testlc, ou=foo, ... <- option here is a sample ldif: # foo, samba, org dn: ou=foo, dc=samba, dc=org objectClass: organizationalUnit objectClass: sambaConfig ou: foo description: Test Foo # log level, foo, samba, org dn: sambaOptionName=log level, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: log level sambaIntegerOption: 10 description: log level 10 is suitable for good debugging # testlc, foo, samba, org dn: sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaShare sambaShareName: testlc description: share to test ldap config module actually works # path, testlc, foo, samba, org dn: sambaOptionName=path, sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: path sambaStringOption: /tmp description: Path for share testlc # read only, testlc, foo, samba, org dn: sambaOptionName=read only, sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: read only sambaBoolOption: TRUE description: Share testlc is read only # guest ok, testlc, foo, samba, org dn: sambaOptionName=guest ok, sambaShareName=testlc, ou=foo, dc=samba, dc=org objectClass: sambaConfigOption sambaOptionName: guest ok sambaBoolOption: TRUE description: Guest users are allowed to connect to testlc share (This used to be commit 207968eafc2c2a185e50e2132702d7bab2142aba)
Diffstat (limited to 'source3/param/config_ldap.c')
-rw-r--r--source3/param/config_ldap.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/source3/param/config_ldap.c b/source3/param/config_ldap.c
new file mode 100644
index 0000000000..ad9b515381
--- /dev/null
+++ b/source3/param/config_ldap.c
@@ -0,0 +1,354 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ ModConfig LDAP backend
+
+ Copyright (C) Simo Sorce 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) Gerald Carter 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_CONFIG
+*/
+
+#include <lber.h>
+#include <ldap.h>
+
+#include "smbldap.h"
+
+#define LDAP_OBJ_SAMBA_CONFIG "sambaConfig"
+#define LDAP_OBJ_SAMBA_SHARE "sambaShare"
+#define LDAP_OBJ_SAMBA_OPTION "sambaConfigOption"
+
+#define LDAP_ATTR_LIST_END 0
+#define LDAP_ATTR_BOOL 1
+#define LDAP_ATTR_INTEGER 2
+#define LDAP_ATTR_STRING 3
+#define LDAP_ATTR_LIST 4
+#define LDAP_ATTR_NAME 5
+
+
+struct ldap_config_state {
+ struct smbldap_state *smbldap_state;
+ TALLOC_CTX *mem_ctx;
+};
+
+ATTRIB_MAP_ENTRY option_attr_list[] = {
+ { LDAP_ATTR_NAME, "sambaOptionName" },
+ { LDAP_ATTR_LIST, "sambaListOption" },
+ { LDAP_ATTR_STRING, "sambaStringOption" },
+ { LDAP_ATTR_INTEGER, "sambaIntegerOption" },
+ { LDAP_ATTR_BOOL, "sambaBoolOption" },
+ { LDAP_ATTR_LIST_END, NULL }
+};
+
+static struct ldap_config_state ldap_state;
+static char *config_base_dn;
+
+static NTSTATUS ldap_config_close(void);
+
+/*
+TODO:
+ search each section
+ start with global, then with others
+ for each section parse all options
+*/
+
+static NTSTATUS parse_section(
+ const char *dn,
+ BOOL (*pfunc)(const char *, const char *))
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ pstring filter;
+ pstring suffix;
+ pstring option_name;
+ pstring option_value;
+ char **attr_list = NULL;
+ char *temp;
+ int rc;
+ int count;
+
+ mem_ctx = talloc_init("parse_section");
+
+ /* search for the options */
+ pstr_sprintf(filter, "objectClass=%s",
+ LDAP_OBJ_SAMBA_OPTION);
+
+ DEBUG(0, ("Searching for:[%s]\n", filter));
+
+ attr_list = get_attr_list(option_attr_list);
+ rc = smbldap_search(ldap_state.smbldap_state,
+ dn, LDAP_SCOPE_ONELEVEL,
+ filter, attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("parse_section: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
+ goto done;
+ }
+
+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+ entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
+ while (entry) {
+ int o;
+
+ if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "sambaOptionName", option_name)) {
+ goto done;
+ }
+
+ option_value[0] = '\0';
+ for (o = 1; option_attr_list[o].name != NULL; o++) {
+ if (smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, option_attr_list[o].name, option_value)) {
+ break;
+ }
+ }
+ if (option_value[0] != '\0') {
+ if (!pfunc(option_name, option_value)) {
+ goto done;
+ }
+ } else {
+ DEBUG(0,("parse_section: Missing value for option: %s\n", option_name));
+ goto done;
+ }
+
+ entry = ldap_next_entry(ldap_state.smbldap_state->ldap_struct, entry);
+ }
+
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_destroy(mem_ctx);
+ free_attr_list(attr_list);
+ if (result) ldap_msgfree(result);
+
+ return ret;
+}
+
+/*****************************************************************************
+ load configuration from ldap
+*****************************************************************************/
+
+static NTSTATUS ldap_config_load(
+ BOOL (*sfunc)(const char *),
+ BOOL (*pfunc)(const char *, const char *))
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ pstring filter;
+ pstring suffix;
+ pstring attr_text;
+ char *config_dn = NULL;
+ char *temp;
+ int rc;
+ int count;
+ char *config_attr_list[] = {"description", NULL};
+ char *share_attr_list[] = {"sambaShareName", "description", NULL};
+ char **share_dn;
+ char **share_name;
+
+ mem_ctx = talloc_init("ldap_config_load");
+
+ /* search for the base config dn */
+ pstr_sprintf(filter, "objectClass=%s",
+ LDAP_OBJ_SAMBA_CONFIG);
+
+ DEBUG(0, ("Searching for:[%s]\n", filter));
+
+ rc = smbldap_search(ldap_state.smbldap_state,
+ config_base_dn, LDAP_SCOPE_SUBTREE,
+ filter, config_attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_config_load: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
+ goto done;
+ }
+
+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+ if (count != 1) {
+ DEBUG(0,("ldap_config_load: single %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
+ goto done;
+ }
+
+ if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result))) {
+ goto done;
+ }
+ config_dn = talloc_strdup(mem_ctx, temp);
+ SAFE_FREE(temp);
+ if (!config_dn) {
+ goto done;
+ }
+
+ entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
+
+ if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "description", attr_text)) {
+ DEBUG(0, ("ldap_config_load: no description field in %s object\n", LDAP_OBJ_SAMBA_CONFIG));
+ }
+
+ if (result) ldap_msgfree(result);
+/* TODO: finish up the last section, see loadparm's lp_load()*/
+
+ /* retrive the section list */
+ pstr_sprintf(filter, "objectClass=%s",
+ LDAP_OBJ_SAMBA_SHARE);
+
+ DEBUG(0, ("Searching for:[%s]\n", filter));
+
+ rc = smbldap_search(ldap_state.smbldap_state,
+ config_dn, LDAP_SCOPE_SUBTREE,
+ filter, share_attr_list, 0, &result);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(0,("ldap_config_load: %s object not found\n", LDAP_OBJ_SAMBA_CONFIG));
+ goto done;
+ }
+
+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+ DEBUG(0, ("config_ldap: Found %d shares\n", count));
+ if (count) {
+ int i;
+
+ share_dn = talloc(mem_ctx, (count + 1) * sizeof(char *));
+ share_name = talloc(mem_ctx, (count) * sizeof(char *));
+ if (!share_dn || !share_name) {
+ DEBUG(0,("config_ldap: Out of memory!\n"));
+ goto done;
+ }
+ entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
+ i = 0;
+ while (entry) {
+ if (!(temp = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, entry))) {
+ goto done;
+ }
+ if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, "sambaShareName", attr_text)) {
+ goto done;
+ }
+ share_dn[i] = talloc_strdup(mem_ctx, temp);
+ share_name[i] = talloc_strdup(mem_ctx, attr_text);
+ if (!share_dn[i] || !share_name[i]) {
+ DEBUG(0,("config_ldap: Out of memory!\n"));
+ goto done;
+ }
+
+ DEBUG(0, ("config_ldap: Found share [%s] (%s)\n", attr_text, temp));
+ SAFE_FREE(temp);
+
+ entry = ldap_next_entry(ldap_state.smbldap_state->ldap_struct, entry);
+ i++;
+ if (entry && (count == i)) {
+ DEBUG(0, ("Error too many entryes in ldap result\n"));
+ goto done;
+ }
+ }
+ share_dn[i] = NULL;
+ }
+
+ /* parse global section*/
+ if (!sfunc("global")) {
+ goto done;
+ }
+ if (!NT_STATUS_IS_OK(parse_section(config_dn, pfunc))) {
+ goto done;
+ } else { /* parse shares */
+ int i;
+
+ for (i = 0; share_dn[i] != NULL; i++) {
+ if (!sfunc(share_name[i])) {
+ goto done;
+ }
+ if (!NT_STATUS_IS_OK(parse_section(share_dn[i], pfunc))) {
+ goto done;
+ }
+ }
+ }
+
+done:
+ talloc_destroy(mem_ctx);
+ if (result) ldap_msgfree(result);
+
+ return ret;
+}
+
+/*****************************************************************************
+ Initialise config_ldap module
+*****************************************************************************/
+
+static NTSTATUS ldap_config_init(char *params)
+{
+ NTSTATUS nt_status;
+ const char *location;
+ const char *basedn;
+
+ ldap_state.mem_ctx = talloc_init("config_ldap");
+ if (!ldap_state.mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* we assume only location is passed through an inline parameter
+ * other options go via parametrical options */
+ if (params) {
+ location = params;
+ } else {
+ location = lp_parm_const_string(GLOBAL_SECTION_SNUM, "config_ldap", "url", "ldap://localhost");
+ }
+ DEBUG(0,("config_ldap: location=%s\n", location));
+ basedn = lp_parm_const_string(GLOBAL_SECTION_SNUM, "config_ldap", "basedn", NULL);
+ if (basedn) config_base_dn = smb_xstrdup(basedn);
+
+ if (!NT_STATUS_IS_OK(nt_status =
+ smbldap_init(ldap_state.mem_ctx, location,
+ &ldap_state.smbldap_state))) {
+ talloc_destroy(ldap_state.mem_ctx);
+ DEBUG(0,("config_ldap: smbldap_init failed!\n"));
+ return nt_status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*****************************************************************************
+ End the LDAP session
+*****************************************************************************/
+
+static NTSTATUS ldap_config_close(void)
+{
+
+ smbldap_free_struct(&(ldap_state).smbldap_state);
+ talloc_destroy(ldap_state.mem_ctx);
+
+ DEBUG(5,("The connection to the LDAP server was closed\n"));
+ /* maybe free the results here --metze */
+
+ return NT_STATUS_OK;
+}
+
+static struct config_functions functions = {
+ ldap_config_init,
+ ldap_config_load,
+ ldap_config_close
+};
+
+NTSTATUS config_ldap_init(void)
+{
+ return smb_register_config(SAMBA_CONFIG_INTERFACE_VERSION, "ldap", &functions);
+}