mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
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)
This commit is contained in:
parent
7301471a6a
commit
e762e32389
@ -66,6 +66,7 @@ RPCLIBDIR = $(LIBDIR)/rpc
|
||||
IDMAPLIBDIR = $(LIBDIR)/idmap
|
||||
CHARSETLIBDIR = $(LIBDIR)/charset
|
||||
AUTHLIBDIR = $(LIBDIR)/auth
|
||||
CONFIGLIBDIR = $(LIBDIR)/config
|
||||
CONFIGDIR = @configdir@
|
||||
VARDIR = @localstatedir@
|
||||
MANDIR = @mandir@
|
||||
@ -154,7 +155,8 @@ RPC_MODULES = @RPC_MODULES@
|
||||
IDMAP_MODULES = @IDMAP_MODULES@
|
||||
CHARSET_MODULES = @CHARSET_MODULES@
|
||||
AUTH_MODULES = @AUTH_MODULES@
|
||||
MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES)
|
||||
CONFIG_MODULES = @CONFIG_MODULES@
|
||||
MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSET_MODULES) $(AUTH_MODULES) $(CONFIG_MODULES)
|
||||
|
||||
######################################################################
|
||||
# object file lists
|
||||
@ -163,7 +165,7 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSE
|
||||
TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o
|
||||
TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o tdb/tdbback.o
|
||||
|
||||
SMBLDAP_OBJ = @SMBLDAP@
|
||||
SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@
|
||||
|
||||
LIB_OBJ = lib/version.o lib/charcnv.o lib/debug.o lib/fault.o \
|
||||
lib/getsmbpass.o lib/interface.o lib/md4.o \
|
||||
@ -198,7 +200,7 @@ POPT_LIB_OBJ = lib/popt_common.o
|
||||
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
|
||||
ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o
|
||||
|
||||
PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o
|
||||
PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o param/modconf.o
|
||||
|
||||
KRBCLIENT_OBJ = libads/kerberos.o
|
||||
|
||||
@ -340,6 +342,8 @@ AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/auth_compat.o \
|
||||
|
||||
MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o
|
||||
|
||||
CONFIG_LDAP_OBJ = param/config_ldap.o
|
||||
|
||||
SMBD_OBJ_MAIN = smbd/server.o
|
||||
|
||||
BUILDOPT_OBJ = smbd/build_options.o
|
||||
@ -1155,6 +1159,11 @@ bin/cap.@SHLIBEXT@: $(VFS_CAP_OBJ:.o=.@PICSUFFIX@)
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_CAP_OBJ:.o=.@PICSUFFIX@) \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/config_ldap.@SHLIBEXT@: $(CONFIG_LDAP_OBJ:.o=.@PICSUFFIX@)
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(CONFIG_LDAP_OBJ:.o=.@PICSUFFIX@) \
|
||||
@SMBLDAP@ @LDAP_LIBS@ @SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
|
||||
@ -1223,6 +1232,7 @@ installmodules: modules installdirs
|
||||
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES)
|
||||
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES)
|
||||
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES)
|
||||
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CONFIGLIBDIR) $(CONFIG_MODULES)
|
||||
@# These symlinks are required for the 'probing' of modules.
|
||||
@# This mechanism should go at some point..
|
||||
@$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ ldapsam_compat.@SHLIBEXT@
|
||||
|
@ -162,6 +162,7 @@ AC_SUBST(SMBWRAPPER)
|
||||
AC_SUBST(EXTRA_BIN_PROGS)
|
||||
AC_SUBST(EXTRA_SBIN_PROGS)
|
||||
AC_SUBST(EXTRA_ALL_TARGETS)
|
||||
AC_SUBST(CONFIG_LIBS)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug Turn on compiler debugging information (default=no)],
|
||||
@ -299,7 +300,7 @@ dnl These have to be built static:
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_epmapper auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin pdb_gums gums_tdbsam2"
|
||||
|
||||
dnl These are preferably build shared, and static if dlopen() is not available
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437"
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap charset_CP850 charset_CP437 config_ldap"
|
||||
|
||||
if test "x$developer" = xyes; then
|
||||
default_static_modules="$default_static_modules rpc_echo"
|
||||
@ -2288,6 +2289,8 @@ AC_MSG_RESULT($with_ldap_support)
|
||||
|
||||
SMBLDAP=""
|
||||
AC_SUBST(SMBLDAP)
|
||||
SMBLDAPUTIL=""
|
||||
AC_SUBST(SMBLDAPUTIL)
|
||||
if test x"$with_ldap_support" != x"no"; then
|
||||
|
||||
##################################################################
|
||||
@ -2343,7 +2346,9 @@ if test x"$with_ldap_support" != x"no"; then
|
||||
if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then
|
||||
AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
|
||||
default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
|
||||
default_shared_modules="$default_shared_modules config_ldap";
|
||||
SMBLDAP="lib/smbldap.o"
|
||||
SMBLDAPUTIL="lib/smbldap_util.o"
|
||||
with_ldap_support=yes
|
||||
AC_MSG_CHECKING(whether LDAP support is used)
|
||||
AC_MSG_RESULT(yes)
|
||||
@ -4194,6 +4199,9 @@ SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
|
||||
SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
|
||||
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
|
||||
|
||||
SMB_MODULE(config_ldap, param/config_ldap.o, "bin/config_ldap.$SHLIBEXT", CONFIG, [ CONFIG_LIBS="$CONFIG_LIBS $LDAP_LIBS" "$SMBLDAP" ])
|
||||
SMB_SUBSYSTEM(CONFIG, param/modconf.o)
|
||||
|
||||
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
|
||||
|
||||
#################################################
|
||||
|
@ -890,6 +890,7 @@ struct smb_ldap_privates;
|
||||
/* forward declarations from smbldap.c */
|
||||
|
||||
#include "smbldap.h"
|
||||
#include "modconf.h"
|
||||
|
||||
/***** automatically generated prototypes *****/
|
||||
#ifndef NO_PROTO_H
|
||||
|
34
source3/include/modconf.h
Normal file
34
source3/include/modconf.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef _MODCONF_H_
|
||||
#define _MODCONF_H_
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
ModConf headers
|
||||
|
||||
Copyright (C) Simo Sorce 2003
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define SAMBA_CONFIG_INTERFACE_VERSION 1
|
||||
|
||||
/* Filled out by config backends */
|
||||
struct config_functions {
|
||||
NTSTATUS (*init)(char *params);
|
||||
NTSTATUS (*load)(BOOL (*sfunc)(const char *),BOOL (*pfunc)(const char *, const char *));
|
||||
NTSTATUS (*close)(void);
|
||||
};
|
||||
#endif /* _MODCONF_H_ */
|
@ -1153,181 +1153,6 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Add the sambaDomain to LDAP, so we don't have to search for this stuff
|
||||
again. This is a once-add operation for now.
|
||||
|
||||
TODO: Add other attributes, and allow modification.
|
||||
*********************************************************************/
|
||||
static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
|
||||
const char *domain_name)
|
||||
{
|
||||
fstring sid_string;
|
||||
fstring algorithmic_rid_base_string;
|
||||
pstring filter, dn;
|
||||
LDAPMod **mods = NULL;
|
||||
int rc;
|
||||
int ldap_op;
|
||||
LDAPMessage *result = NULL;
|
||||
int num_result;
|
||||
char **attr_list;
|
||||
uid_t u_low, u_high;
|
||||
gid_t g_low, g_high;
|
||||
uint32 rid_low, rid_high;
|
||||
|
||||
slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name, LDAP_OBJ_DOMINFO);
|
||||
|
||||
attr_list = get_attr_list( dominfo_attr_list );
|
||||
rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
|
||||
free_attr_list( attr_list );
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
num_result = ldap_count_entries(ldap_state->ldap_struct, result);
|
||||
|
||||
if (num_result > 1) {
|
||||
DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
|
||||
ldap_msgfree(result);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Check if we need to add an entry */
|
||||
DEBUG(3,("Adding new domain\n"));
|
||||
ldap_op = LDAP_MOD_ADD;
|
||||
|
||||
pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name, lp_ldap_suffix());
|
||||
|
||||
/* Free original search */
|
||||
ldap_msgfree(result);
|
||||
|
||||
/* make the changes - the entry *must* not already have samba attributes */
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name);
|
||||
|
||||
/* If we don't have an entry, then ask secrets.tdb for what it thinks.
|
||||
It may choose to make it up */
|
||||
|
||||
sid_to_string(sid_string, get_global_sam_sid());
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string);
|
||||
|
||||
slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base());
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
|
||||
algorithmic_rid_base_string);
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
|
||||
|
||||
/* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set.
|
||||
TODO: fix all the places where the line between idmap and normal operations
|
||||
needed by smbd gets fuzzy --jerry 2003-08-11 */
|
||||
|
||||
if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high)
|
||||
&& get_free_rid_range(&rid_low, &rid_high) )
|
||||
{
|
||||
fstring rid_str;
|
||||
|
||||
fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE );
|
||||
DEBUG(10,("setting next available user rid [%s]\n", rid_str));
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD,
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
|
||||
rid_str);
|
||||
|
||||
fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE );
|
||||
DEBUG(10,("setting next available group rid [%s]\n", rid_str));
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD,
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
|
||||
rid_str);
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch(ldap_op)
|
||||
{
|
||||
case LDAP_MOD_ADD:
|
||||
rc = smbldap_add(ldap_state, dn, mods);
|
||||
break;
|
||||
case LDAP_MOD_REPLACE:
|
||||
rc = smbldap_modify(ldap_state, dn, mods);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (rc!=LDAP_SUCCESS) {
|
||||
char *ld_error = NULL;
|
||||
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
|
||||
DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n",
|
||||
ldap_op == LDAP_MOD_ADD ? "add" : "modify",
|
||||
dn, ldap_err2string(rc),
|
||||
ld_error?ld_error:"unknown"));
|
||||
SAFE_FREE(ld_error);
|
||||
|
||||
ldap_mods_free(mods, True);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DEBUG(2,("added: domain = %s in the LDAP database\n", domain_name));
|
||||
ldap_mods_free(mods, True);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Search for the domain info entry
|
||||
*********************************************************************/
|
||||
NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
|
||||
LDAPMessage ** result, const char *domain_name,
|
||||
BOOL try_add)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
pstring filter;
|
||||
int rc;
|
||||
char **attr_list;
|
||||
int count;
|
||||
|
||||
pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
|
||||
LDAP_OBJ_DOMINFO,
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name);
|
||||
|
||||
DEBUG(2, ("Searching for:[%s]\n", filter));
|
||||
|
||||
|
||||
attr_list = get_attr_list( dominfo_attr_list );
|
||||
rc = smbldap_search_suffix(ldap_state, filter, attr_list , result);
|
||||
free_attr_list( attr_list );
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
|
||||
DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
|
||||
} else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) {
|
||||
DEBUG(3, ("Got no domain info entries for domain\n"));
|
||||
ldap_msgfree(*result);
|
||||
*result = NULL;
|
||||
if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name))) {
|
||||
return smbldap_search_domain_info(ldap_state, result, domain_name, False);
|
||||
}
|
||||
else {
|
||||
DEBUG(0, ("Adding domain info for %s failed with %s\n",
|
||||
domain_name, nt_errstr(ret)));
|
||||
return ret;
|
||||
}
|
||||
} else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) {
|
||||
DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
|
||||
count, domain_name));
|
||||
ldap_msgfree(*result);
|
||||
*result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Return a copy of the DN for a LDAPMessage. Convert from utf8 to CH_UNIX.
|
||||
********************************************************************/
|
||||
|
203
source3/lib/smbldap_util.c
Normal file
203
source3/lib/smbldap_util.c
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
Unix SMB/CIFS mplementation.
|
||||
LDAP protocol helper functions for SAMBA
|
||||
Copyright (C) Jean François Micouleau 1998
|
||||
Copyright (C) Gerald Carter 2001-2003
|
||||
Copyright (C) Shahms King 2001
|
||||
Copyright (C) Andrew Bartlett 2002-2003
|
||||
Copyright (C) Stefan (metze) Metzmacher 2002-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"
|
||||
#include "smbldap.h"
|
||||
|
||||
/**********************************************************************
|
||||
Add the sambaDomain to LDAP, so we don't have to search for this stuff
|
||||
again. This is a once-add operation for now.
|
||||
|
||||
TODO: Add other attributes, and allow modification.
|
||||
*********************************************************************/
|
||||
static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
|
||||
const char *domain_name)
|
||||
{
|
||||
fstring sid_string;
|
||||
fstring algorithmic_rid_base_string;
|
||||
pstring filter, dn;
|
||||
LDAPMod **mods = NULL;
|
||||
int rc;
|
||||
int ldap_op;
|
||||
LDAPMessage *result = NULL;
|
||||
int num_result;
|
||||
char **attr_list;
|
||||
uid_t u_low, u_high;
|
||||
gid_t g_low, g_high;
|
||||
uint32 rid_low, rid_high;
|
||||
|
||||
slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name, LDAP_OBJ_DOMINFO);
|
||||
|
||||
attr_list = get_attr_list( dominfo_attr_list );
|
||||
rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
|
||||
free_attr_list( attr_list );
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
num_result = ldap_count_entries(ldap_state->ldap_struct, result);
|
||||
|
||||
if (num_result > 1) {
|
||||
DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
|
||||
ldap_msgfree(result);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* Check if we need to add an entry */
|
||||
DEBUG(3,("Adding new domain\n"));
|
||||
ldap_op = LDAP_MOD_ADD;
|
||||
|
||||
pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name, lp_ldap_suffix());
|
||||
|
||||
/* Free original search */
|
||||
ldap_msgfree(result);
|
||||
|
||||
/* make the changes - the entry *must* not already have samba attributes */
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name);
|
||||
|
||||
/* If we don't have an entry, then ask secrets.tdb for what it thinks.
|
||||
It may choose to make it up */
|
||||
|
||||
sid_to_string(sid_string, get_global_sam_sid());
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), sid_string);
|
||||
|
||||
slprintf(algorithmic_rid_base_string, sizeof(algorithmic_rid_base_string) - 1, "%i", algorithmic_rid_base());
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
|
||||
algorithmic_rid_base_string);
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
|
||||
|
||||
/* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set.
|
||||
TODO: fix all the places where the line between idmap and normal operations
|
||||
needed by smbd gets fuzzy --jerry 2003-08-11 */
|
||||
|
||||
if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high)
|
||||
&& get_free_rid_range(&rid_low, &rid_high) )
|
||||
{
|
||||
fstring rid_str;
|
||||
|
||||
fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE );
|
||||
DEBUG(10,("setting next available user rid [%s]\n", rid_str));
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD,
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
|
||||
rid_str);
|
||||
|
||||
fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE );
|
||||
DEBUG(10,("setting next available group rid [%s]\n", rid_str));
|
||||
smbldap_set_mod(&mods, LDAP_MOD_ADD,
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
|
||||
rid_str);
|
||||
|
||||
}
|
||||
|
||||
|
||||
switch(ldap_op)
|
||||
{
|
||||
case LDAP_MOD_ADD:
|
||||
rc = smbldap_add(ldap_state, dn, mods);
|
||||
break;
|
||||
case LDAP_MOD_REPLACE:
|
||||
rc = smbldap_modify(ldap_state, dn, mods);
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (rc!=LDAP_SUCCESS) {
|
||||
char *ld_error = NULL;
|
||||
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
|
||||
DEBUG(1,("failed to %s domain dn= %s with: %s\n\t%s\n",
|
||||
ldap_op == LDAP_MOD_ADD ? "add" : "modify",
|
||||
dn, ldap_err2string(rc),
|
||||
ld_error?ld_error:"unknown"));
|
||||
SAFE_FREE(ld_error);
|
||||
|
||||
ldap_mods_free(mods, True);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DEBUG(2,("added: domain = %s in the LDAP database\n", domain_name));
|
||||
ldap_mods_free(mods, True);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Search for the domain info entry
|
||||
*********************************************************************/
|
||||
NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
|
||||
LDAPMessage ** result, const char *domain_name,
|
||||
BOOL try_add)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
pstring filter;
|
||||
int rc;
|
||||
char **attr_list;
|
||||
int count;
|
||||
|
||||
pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
|
||||
LDAP_OBJ_DOMINFO,
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name);
|
||||
|
||||
DEBUG(2, ("Searching for:[%s]\n", filter));
|
||||
|
||||
|
||||
attr_list = get_attr_list( dominfo_attr_list );
|
||||
rc = smbldap_search_suffix(ldap_state, filter, attr_list , result);
|
||||
free_attr_list( attr_list );
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
|
||||
DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
|
||||
} else if (ldap_count_entries(ldap_state->ldap_struct, *result) < 1) {
|
||||
DEBUG(3, ("Got no domain info entries for domain\n"));
|
||||
ldap_msgfree(*result);
|
||||
*result = NULL;
|
||||
if (try_add && NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state, domain_name))) {
|
||||
return smbldap_search_domain_info(ldap_state, result, domain_name, False);
|
||||
}
|
||||
else {
|
||||
DEBUG(0, ("Adding domain info for %s failed with %s\n",
|
||||
domain_name, nt_errstr(ret)));
|
||||
return ret;
|
||||
}
|
||||
} else if ((count = ldap_count_entries(ldap_state->ldap_struct, *result)) > 1) {
|
||||
DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
|
||||
count, domain_name));
|
||||
ldap_msgfree(*result);
|
||||
*result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
354
source3/param/config_ldap.c
Normal file
354
source3/param/config_ldap.c
Normal file
@ -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);
|
||||
}
|
@ -95,6 +95,7 @@ struct _param_opt_struct {
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *szConfigBackend;
|
||||
char *smb_ports;
|
||||
char *dos_charset;
|
||||
char *unix_charset;
|
||||
@ -755,6 +756,7 @@ static const struct enum_list enum_map_to_guest[] = {
|
||||
static struct parm_struct parm_table[] = {
|
||||
{N_("Base Options"), P_SEP, P_SEPARATOR},
|
||||
|
||||
{"config backend", P_STRING, P_GLOBAL, &Globals.szConfigBackend, NULL, NULL, FLAG_ADVANCED},
|
||||
{"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
|
||||
{"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
|
||||
{"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
|
||||
@ -1302,6 +1304,8 @@ static void init_globals(void)
|
||||
|
||||
DEBUG(3, ("Initialising global parameters\n"));
|
||||
|
||||
string_set(&Globals.szConfigBackend, NULL);
|
||||
|
||||
string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
|
||||
string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
|
||||
|
||||
@ -1604,6 +1608,7 @@ static char *lp_string(const char *s)
|
||||
#define FN_LOCAL_INTEGER(fn_name,val) \
|
||||
int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
|
||||
|
||||
FN_GLOBAL_STRING(lp_config_backend, &Globals.szConfigBackend)
|
||||
FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
|
||||
FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
|
||||
FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
|
||||
@ -3952,6 +3957,11 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
|
||||
if (iServiceIndex >= 0)
|
||||
bRetval = service_ok(iServiceIndex);
|
||||
|
||||
if (lp_config_backend()) {
|
||||
modconf_init(lp_config_backend());
|
||||
modconf_load(do_section, do_parameter);
|
||||
}
|
||||
|
||||
lp_add_auto_services(lp_auto_services());
|
||||
|
||||
if (add_ipc) {
|
||||
|
96
source3/param/modconf.c
Normal file
96
source3/param/modconf.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Configuration Modules Support
|
||||
Copyright (C) Simo Sorce 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_IDMAP
|
||||
|
||||
struct modconf_struct {
|
||||
char *name;
|
||||
struct config_functions *fns;
|
||||
};
|
||||
|
||||
static struct modconf_struct module;
|
||||
|
||||
NTSTATUS smb_register_config(int version, const char *name, struct config_functions *fns)
|
||||
{
|
||||
if ((version != SAMBA_CONFIG_INTERFACE_VERSION)) {
|
||||
DEBUG(0, ("smb_register_config: Failed to register config module.\n"
|
||||
"The module has been compiled with a different interface version (%d).\n"
|
||||
"The supported version is: %d\n",
|
||||
version, SAMBA_CONFIG_INTERFACE_VERSION));
|
||||
return NT_STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
if (!name || !name[0]) {
|
||||
DEBUG(0,("smb_register_config: Name missing!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
module.name = smb_xstrdup(name);
|
||||
module.fns = fns;
|
||||
DEBUG(5, ("smb_register_config: Successfully registeres config backend '%s'\n", name));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* Init the configuration module
|
||||
*********************************************************************/
|
||||
|
||||
BOOL modconf_init(const char *config_backend)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
BOOL bret = False;
|
||||
char *name;
|
||||
char *params;
|
||||
|
||||
/* nothing to do */
|
||||
if (!config_backend)
|
||||
return True;
|
||||
|
||||
name = smb_xstrdup(config_backend);
|
||||
if ((params = strchr(name, ':')) != NULL ) {
|
||||
*params = '\0';
|
||||
params++;
|
||||
}
|
||||
|
||||
ret = smb_probe_module("config", name);
|
||||
|
||||
if (NT_STATUS_IS_OK(ret) && NT_STATUS_IS_OK(module.fns->init(params)))
|
||||
bret = True;
|
||||
|
||||
SAFE_FREE(name);
|
||||
return bret;
|
||||
}
|
||||
|
||||
BOOL modconf_load(BOOL (*sfunc)(const char *),BOOL (*pfunc)(const char *, const char *))
|
||||
{
|
||||
if (module.fns) {
|
||||
if (NT_STATUS_IS_OK(module.fns->load(sfunc, pfunc))) {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
NTSTATUS modconf_close(void)
|
||||
{
|
||||
return module.fns->close();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user