From 1c798aba40fb0e389c7a54ad3d8f7d45876f2809 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Feb 2004 11:10:56 +0000 Subject: - port AUTH and PASSDB subsystems to new SMB_SUBSYSTEM() scheme - some const fixes in ntvfs metze (This used to be commit af89a78123068767b1d134969c5651a0fd978b0d) --- source4/Makefile.in | 25 ++---- source4/auth/auth.c | 174 +++++++++++++++++++++++++++++----------- source4/auth/auth.h | 175 +++++++++++++++++++++++++++++++++++++++++ source4/auth/auth_builtin.c | 76 ++++++++---------- source4/auth/auth_sam.c | 41 +++++++++- source4/auth/auth_unix.c | 18 ++++- source4/auth/config.m4 | 9 +++ source4/configure.in | 3 +- source4/include/auth.h | 157 ------------------------------------ source4/include/context.h | 4 +- source4/include/includes.h | 4 +- source4/include/passdb.h | 115 --------------------------- source4/libads/config.m4 | 1 - source4/ntvfs/ntvfs_base.c | 13 +-- source4/passdb/config.m4 | 15 ++++ source4/passdb/passdb.h | 119 ++++++++++++++++++++++++++++ source4/passdb/pdb_guest.c | 38 ++++++++- source4/passdb/pdb_interface.c | 153 +++++++++++++++++++---------------- source4/passdb/pdb_ldap.c | 47 +++++++---- source4/passdb/pdb_smbpasswd.c | 38 ++++++++- source4/passdb/pdb_tdb.c | 46 +++++++---- source4/passdb/pdb_unix.c | 23 +++++- source4/smbd/process.c | 13 ++- 23 files changed, 804 insertions(+), 503 deletions(-) create mode 100644 source4/auth/auth.h create mode 100644 source4/auth/config.m4 delete mode 100644 source4/include/auth.h delete mode 100644 source4/include/passdb.h create mode 100644 source4/passdb/passdb.h (limited to 'source4') diff --git a/source4/Makefile.in b/source4/Makefile.in index 125c9e96ac..cce4a4aefb 100644 --- a/source4/Makefile.in +++ b/source4/Makefile.in @@ -182,26 +182,17 @@ LIBSMB_OBJ = libcli/clireadwrite.o libcli/cliconnect.o \ libcli/clideltree.o \ $(LIBRAW_OBJ) -PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o - -PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ - passdb/machine_sid.o passdb/pdb_smbpasswd.o \ - passdb/pdb_tdb.o passdb/pdb_ldap.o \ - passdb/pdb_unix.o passdb/pdb_guest.o passdb/util_sam_sid.o \ - passdb/pdb_compat.o passdb/pdb_nisplus.o - -PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o - -AUTH_OBJ = auth/auth.o auth/auth_sam.o \ - auth/auth_unix.o auth/auth_util.o \ - auth/auth_builtin.o auth/auth_compat.o auth/auth_ntlmssp.o \ - $(PLAINTEXT_AUTH_OBJ) - SMBD_OBJ_MAIN = smbd/server.o SMB_OBJS = @SMB_OBJS@ SMB_LIBS = @SMB_LIBS@ +AUTH_OBJS = @AUTH_OBJS@ +AUTH_LIBS = @AUTH_LIBS@ + +PASSDB_OBJS = @PASSDB_OBJS@ +PASSDB_LIBS = @PASSDB_LIBS@ + NTVFS_OBJS = @NTVFS_OBJS@ NTVFS_LIBS = @NTVFS_LIBS@ @@ -212,7 +203,7 @@ SMBD_OBJ_SRV = smbd/process.o \ lib/server_mutex.o \ smbd/build_options.o \ smbd/rewrite.o \ - $(DCERPC_OBJS) $(SMB_OBJS) $(NTVFS_OBJS) @SMBD_EXTRA_OBJS@ + $(DCERPC_OBJS) $(SMB_OBJS) $(AUTH_OBJS) $(PASSDB_OBJS) $(NTVFS_OBJS) @SMBD_EXTRA_OBJS@ PROCESS_MODEL_OBJS = @PROCESS_MODEL_OBJS@ PROCESS_MODEL_LIBS = @PROCESS_MODEL_LIBS@ @@ -222,7 +213,7 @@ SMBD_OBJ_BASE = $(PROCESS_MODEL_OBJS) $(SMBD_OBJ_SRV) \ $(AUTH_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_OBJ) SMBD_OBJS = $(SMBD_OBJ_MAIN) $(SMBD_OBJ_BASE) @BUILD_POPT@ -SMBD_LIBS = $(LIBS) $(PROCESS_MODEL_LIBS) $(DCERPC_LIBS) $(NTVFS_LIBS) +SMBD_LIBS = $(LIBS) $(PROCESS_MODEL_LIBS) $(DCERPC_LIBS) $(AUTH_LIBS) $(PASSDB_LIBS) $(NTVFS_LIBS) CLIENT_OBJ1 = client/client.o client/clitar.o libcli/raw/clirewrite.o diff --git a/source4/auth/auth.c b/source4/auth/auth.c index 2dc14248f9..a41cf72b1f 100644 --- a/source4/auth/auth.c +++ b/source4/auth/auth.c @@ -23,28 +23,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -/** List of various built-in authentication modules */ - -static const struct auth_init_function_entry builtin_auth_init_functions[] = { - { "guest", auth_init_guest }, -/* { "rhosts", auth_init_rhosts }, */ -/* { "hostsequiv", auth_init_hostsequiv }, */ - { "sam", auth_init_sam }, - { "samstrict", auth_init_samstrict }, - { "samstrict_dc", auth_init_samstrict_dc }, - { "unix", auth_init_unix }, -/* { "smbserver", auth_init_smbserver }, */ -/* { "ntdomain", auth_init_ntdomain }, */ -/* { "trustdomain", auth_init_trustdomain }, */ -/* { "winbind", auth_init_winbind }, */ -#ifdef DEVELOPER - { "name_to_ntstatus", auth_init_name_to_ntstatus }, - { "fixed_challenge", auth_init_fixed_challenge }, -#endif - { "plugin", auth_init_plugin }, - { NULL, NULL} -}; - /**************************************************************************** Try to get a challenge out of the various authentication modules. Returns a const char of length 8 bytes. @@ -335,37 +313,40 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context))) return nt_status; - for (;*text_list; text_list++) { + for (;*text_list; text_list++) { + char *module_name = smb_xstrdup(*text_list); + char *module_params = NULL; + char *p; + const struct auth_operations *ops; + DEBUG(5,("make_auth_context_text_list: Attempting to find an auth method to match %s\n", *text_list)); - for (i = 0; builtin_auth_init_functions[i].name; i++) { - char *module_name = smb_xstrdup(*text_list); - char *module_params = NULL; - char *p; - - p = strchr(module_name, ':'); - if (p) { - *p = 0; - module_params = p+1; - trim_string(module_params, " ", " "); - } - trim_string(module_name, " ", " "); - - if (strequal(builtin_auth_init_functions[i].name, module_name)) { - DEBUG(5,("make_auth_context_text_list: Found auth method %s (at pos %d)\n", *text_list, i)); - if (NT_STATUS_IS_OK(builtin_auth_init_functions[i].init(*auth_context, module_params, &t))) { - DEBUG(5,("make_auth_context_text_list: auth method %s has a valid init\n", - *text_list)); - DLIST_ADD_END(list, t, auth_methods *); - } else { - DEBUG(0,("make_auth_context_text_list: auth method %s did not correctly init\n", - *text_list)); - } - break; - } + p = strchr(module_name, ':'); + if (p) { + *p = 0; + module_params = p+1; + trim_string(module_params, " ", " "); + } + + trim_string(module_name, " ", " "); + + ops = auth_backend_byname(module_name); + if (!ops) { + DEBUG(5,("make_auth_context_text_list: Found auth method %s (at pos %d)\n", *text_list, i)); SAFE_FREE(module_name); + break; + } + + if (NT_STATUS_IS_OK(ops->init(*auth_context, module_params, &t))) { + DEBUG(5,("make_auth_context_text_list: auth method %s has a valid init\n", + *text_list)); + DLIST_ADD_END(list, t, auth_methods *); + } else { + DEBUG(0,("make_auth_context_text_list: auth method %s did not correctly init\n", + *text_list)); } + SAFE_FREE(module_name); } (*auth_context)->auth_method_list = list; @@ -452,4 +433,101 @@ NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[ return nt_status; } +/* the list of currently registered AUTH backends */ +static struct { + const struct auth_operations *ops; +} *backends = NULL; +static int num_backends; + +/* + register a AUTH backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. +*/ +static NTSTATUS auth_register(void *_ops) +{ + const struct auth_operations *ops = _ops; + struct auth_operations *new_ops; + + if (auth_backend_byname(ops->name) != NULL) { + /* its already registered! */ + DEBUG(0,("AUTH backend '%s' already registered\n", + ops->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); + if (!backends) { + smb_panic("out of memory in auth_register"); + } + + new_ops = smb_xmemdup(ops, sizeof(*ops)); + new_ops->name = smb_xstrdup(ops->name); + + backends[num_backends].ops = new_ops; + + num_backends++; + + DEBUG(3,("AUTH backend '%s' registered\n", + ops->name)); + + return NT_STATUS_OK; +} + +/* + return the operations structure for a named backend of the specified type +*/ +const struct auth_operations *auth_backend_byname(const char *name) +{ + int i; + + for (i=0;iname, name) == 0) { + return backends[i].ops; + } + } + + return NULL; +} + +/* + return the AUTH interface version, and the size of some critical types + This can be used by backends to either detect compilation errors, or provide + multiple implementations for different smbd compilation options in one module +*/ +const struct auth_critical_sizes *auth_interface_version(void) +{ + static const struct auth_critical_sizes critical_sizes = { + AUTH_INTERFACE_VERSION, + sizeof(struct auth_operations), + sizeof(struct auth_methods), + sizeof(struct auth_context), + sizeof(struct auth_ntlmssp_state), + sizeof(struct auth_usersupplied_info), + sizeof(struct auth_serversupplied_info), + sizeof(struct auth_str), + sizeof(struct auth_unistr) + }; + + return &critical_sizes; +} + +/* + initialise the AUTH subsystem +*/ +BOOL auth_init(void) +{ + NTSTATUS status; + + status = register_subsystem("auth", auth_register); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + /* FIXME: Perhaps panic if a basic backend, such as SAM, fails to initialise? */ + static_init_auth; + DEBUG(3,("AUTH subsystem version %d initialised\n", AUTH_INTERFACE_VERSION)); + return True; +} diff --git a/source4/auth/auth.h b/source4/auth/auth.h new file mode 100644 index 0000000000..dc12d8196f --- /dev/null +++ b/source4/auth/auth.h @@ -0,0 +1,175 @@ +/* + Unix SMB/CIFS implementation. + Standardised Authentication types + Copyright (C) Andrew Bartlett 2001 + + 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. +*/ + +#ifndef _SAMBA_AUTH_H +#define _SAMBA_AUTH_H + +/* modules can use the following to determine if the interface has changed + * please increment the version number after each interface change + * with a comment and maybe update struct auth_critical_sizes. + */ +/* version 1 - version from samba 3.0 - metze */ +/* version 2 - initial samba4 version - metze */ +#define AUTH_INTERFACE_VERSION 2 + +/* AUTH_STR - string */ +typedef struct auth_str +{ + int len; + char *str; +} AUTH_STR; + +/* AUTH_UNISTR - unicode string or buffer */ +typedef struct auth_unistr +{ + int len; + uchar *unistr; +} AUTH_UNISTR; + +#define AUTH_FLAG_NONE 0x000000 +#define AUTH_FLAG_PLAINTEXT 0x000001 +#define AUTH_FLAG_LM_RESP 0x000002 +#define AUTH_FLAG_NTLM_RESP 0x000004 +#define AUTH_FLAG_NTLMv2_RESP 0x000008 + +typedef struct auth_usersupplied_info +{ + DATA_BLOB lm_resp; + DATA_BLOB nt_resp; + DATA_BLOB plaintext_password; + + BOOL encrypted; + + uint32 auth_flags; + + AUTH_STR client_domain; /* domain name string */ + AUTH_STR domain; /* domain name after mapping */ + AUTH_STR internal_username; /* username after mapping */ + AUTH_STR smb_name; /* username before mapping */ + AUTH_STR wksta_name; /* workstation name (netbios calling name) unicode string */ +} auth_usersupplied_info; + +#define SAM_FILL_NAME 0x01 +#define SAM_FILL_INFO3 0x02 +#define SAM_FILL_SAM 0x04 +#define SAM_FILL_UNIX 0x08 +#define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX) + +typedef struct auth_serversupplied_info +{ + BOOL guest; + + /* This groups info is needed for when we become_user() for this uid */ + int n_groups; + gid_t *groups; + + /* NT group information taken from the info3 structure */ + + NT_USER_TOKEN *ptok; + + uint8 session_key[16]; + uint8 first_8_lm_hash[8]; + DATA_BLOB nt_session_key; + DATA_BLOB lm_session_key; + + uint32 sam_fill_level; /* How far is this structure filled? */ + + SAM_ACCOUNT *sam_account; + + void *pam_handle; +} auth_serversupplied_info; + +struct auth_context { + DATA_BLOB challenge; + + /* Who set this up in the first place? */ + const char *challenge_set_by; + + BOOL challenge_may_be_modified; + + struct auth_methods *challenge_set_method; + /* What order are the various methods in? Try to stop it changing under us */ + struct auth_methods *auth_method_list; + + TALLOC_CTX *mem_ctx; + const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context); + NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context, + const struct auth_usersupplied_info *user_info, + struct auth_serversupplied_info **server_info); + NTSTATUS (*nt_status_squash)(NTSTATUS nt_status); + void (*free)(struct auth_context **auth_context); +}; + +typedef struct auth_methods +{ + struct auth_methods *prev, *next; + const char *name; /* What name got this module */ + + NTSTATUS (*auth)(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const struct auth_usersupplied_info *user_info, + struct auth_serversupplied_info **server_info); + + DATA_BLOB (*get_chal)(const struct auth_context *auth_context, + void **my_private_data, + TALLOC_CTX *mem_ctx); + + /* Used to keep tabs on things like the cli for SMB server authentication */ + void *private_data; + + /* Function to clean up the above arbitary structure */ + void (*free_private_data)(void **private_data); + + /* Function to send a keepalive message on the above structure */ + void (*send_keepalive)(void **private_data); +} auth_methods; + +typedef struct auth_ntlmssp_state +{ + TALLOC_CTX *mem_ctx; + struct auth_context *auth_context; + struct auth_serversupplied_info *server_info; + struct ntlmssp_state *ntlmssp_state; +} AUTH_NTLMSSP_STATE; + +#define auth_ops __XXX_ERROR_BLA +struct auth_operations { + /* the name of the backend */ + const char *name; + + /* Function to create a member of the authmethods list */ + NTSTATUS (*init)(struct auth_context *, const char *, struct auth_methods **); +}; + +/* this structure is used by backends to determine the size of some critical types */ +struct auth_critical_sizes { + int interface_version; + int sizeof_auth_operations; + int sizeof_auth_methods; + int sizeof_auth_context; + int sizeof_auth_ntlmssp_state; + int sizeof_auth_usersupplied_info; + int sizeof_auth_serversupplied_info; + int sizeof_auth_str; + int sizeof_auth_unistr; +}; + +#endif /* _SAMBA_AUTH_H */ diff --git a/source4/auth/auth_builtin.c b/source4/auth/auth_builtin.c index 61270fca10..d82a1ab56b 100644 --- a/source4/auth/auth_builtin.c +++ b/source4/auth/auth_builtin.c @@ -50,7 +50,7 @@ static NTSTATUS check_guest_security(const struct auth_context *auth_context, /* Guest modules initialisation */ -NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method) +static NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) return NT_STATUS_NO_MEMORY; @@ -101,7 +101,7 @@ static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_ /** Module initailisation function */ -NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) return NT_STATUS_NO_MEMORY; @@ -150,7 +150,7 @@ static DATA_BLOB auth_get_fixed_challenge(const struct auth_context *auth_contex /** Module initailisation function */ -NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) return NT_STATUS_NO_MEMORY; @@ -161,50 +161,38 @@ NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char return NT_STATUS_OK; } -/** - * Outsorce an auth module to an external loadable .so - * - * Only works on systems with dlopen() etc. - **/ - -/* Plugin modules initialisation */ - -NTSTATUS auth_init_plugin(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +NTSTATUS auth_builtin_init(void) { - void * dl_handle; - char *plugin_param, *plugin_name, *p; - auth_init_function plugin_init; - - if (param == NULL) { - DEBUG(0, ("auth_init_plugin: The plugin module needs an argument!\n")); - return NT_STATUS_UNSUCCESSFUL; + NTSTATUS ret; + struct auth_operations ops; + + ops.name = "guest"; + ops.init = auth_init_guest; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; } - plugin_name = smb_xstrdup(param); - p = strchr(plugin_name, ':'); - if (p) { - *p = 0; - plugin_param = p+1; - trim_string(plugin_param, " ", " "); - } else plugin_param = NULL; - - trim_string(plugin_name, " ", " "); - - DEBUG(5, ("auth_init_plugin: Trying to load auth plugin %s\n", plugin_name)); - dl_handle = sys_dlopen(plugin_name, RTLD_NOW ); - if (!dl_handle) { - DEBUG(0, ("auth_init_plugin: Failed to load auth plugin %s using sys_dlopen (%s)\n", - plugin_name, sys_dlerror())); - return NT_STATUS_UNSUCCESSFUL; - } - - plugin_init = (auth_init_function)sys_dlsym(dl_handle, "auth_init"); - if (!plugin_init){ - DEBUG(0, ("Failed to find function 'auth_init' using sys_dlsym in sam plugin %s (%s)\n", - plugin_name, sys_dlerror())); - return NT_STATUS_UNSUCCESSFUL; +#ifdef DEVELOPER + ops.name = "name_to_ntstatus"; + ops.init = auth_init_name_to_ntstatus; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; } - DEBUG(5, ("Starting sam plugin %s with paramater %s\n", plugin_name, plugin_param?plugin_param:"(null)")); - return plugin_init(auth_context, plugin_param, auth_method); + ops.name = "fixed_challenge"; + ops.init = auth_init_fixed_challenge; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; + } +#endif /* DEVELOPER */ + return ret; } diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c index 51462555f9..f25a5e4691 100644 --- a/source4/auth/auth_sam.c +++ b/source4/auth/auth_sam.c @@ -468,7 +468,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -509,7 +509,7 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context } /* module initialisation */ -NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -552,7 +552,7 @@ static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_cont } /* module initialisation */ -NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -562,3 +562,38 @@ NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *p (*auth_method)->name = "samstrict_dc"; return NT_STATUS_OK; } + +NTSTATUS auth_sam_init(void) +{ + NTSTATUS ret; + struct auth_operations ops; + + ops.name = "sam"; + ops.init = auth_init_sam; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; + } + + ops.name = "samstrict"; + ops.init = auth_init_samstrict; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; + } + + ops.name = "samstrict_dc"; + ops.init = auth_init_samstrict_dc; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/auth/auth_unix.c b/source4/auth/auth_unix.c index 4f44767a81..b7c3475e55 100644 --- a/source4/auth/auth_unix.c +++ b/source4/auth/auth_unix.c @@ -119,7 +119,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; @@ -130,3 +130,19 @@ NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, au return NT_STATUS_OK; } +NTSTATUS auth_unix_init(void) +{ + NTSTATUS ret; + struct auth_operations ops; + + ops.name = "unix"; + ops.init = auth_init_unix; + ret = register_backend("auth", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' auth backend!\n", + ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/auth/config.m4 b/source4/auth/config.m4 new file mode 100644 index 0000000000..cb547301f5 --- /dev/null +++ b/source4/auth/config.m4 @@ -0,0 +1,9 @@ +dnl # AUTH Server subsystem + +SMB_MODULE(auth_sam,AUTH,STATIC,[auth/auth_sam.o]) +SMB_MODULE(auth_builtin,AUTH,STATIC,[auth/auth_builtin.o]) +SMB_MODULE(auth_unix,AUTH,STATIC,[auth/auth_unix.o]) + +SMB_SUBSYSTEM(AUTH,auth/auth.o, + [auth/auth_ntlmssp.o auth/auth_util.o auth/pampass.o auth/pass_check.o auth/auth_compat.o], + auth/auth_public_proto.h) diff --git a/source4/configure.in b/source4/configure.in index bb6ec6bb03..f356d4a655 100644 --- a/source4/configure.in +++ b/source4/configure.in @@ -1718,7 +1718,6 @@ AC_SUBST(SMBD_EXTRA_OBJS) AC_SUBST(SMBD_EXTRA_LIBS) sinclude(libads/config.m4) -sinclude(passdb/config.m4) ############################################### # test for where we get crypt() from @@ -1987,6 +1986,8 @@ fi ]) sinclude(lib/iconv.m4) sinclude(smbd/process_model.m4) sinclude(smb_server/config.m4) +sinclude(auth/config.m4) +sinclude(passdb/config.m4) sinclude(ntvfs/config.m4) sinclude(rpc_server/config.m4) diff --git a/source4/include/auth.h b/source4/include/auth.h deleted file mode 100644 index 84faba2b0d..0000000000 --- a/source4/include/auth.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef _SMBAUTH_H_ -#define _SMBAUTH_H_ -/* - Unix SMB/CIFS implementation. - Standardised Authentication types - Copyright (C) Andrew Bartlett 2001 - - 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. -*/ - -/* AUTH_STR - string */ -typedef struct normal_string -{ - int len; - char *str; -} AUTH_STR; - -/* AUTH_UNISTR - unicode string or buffer */ -typedef struct unicode_string -{ - int len; - uchar *unistr; -} AUTH_UNISTR; - -#define AUTH_FLAG_NONE 0x000000 -#define AUTH_FLAG_PLAINTEXT 0x000001 -#define AUTH_FLAG_LM_RESP 0x000002 -#define AUTH_FLAG_NTLM_RESP 0x000004 -#define AUTH_FLAG_NTLMv2_RESP 0x000008 - -typedef struct auth_usersupplied_info -{ - - DATA_BLOB lm_resp; - DATA_BLOB nt_resp; - DATA_BLOB plaintext_password; - - BOOL encrypted; - - uint32 auth_flags; - - AUTH_STR client_domain; /* domain name string */ - AUTH_STR domain; /* domain name after mapping */ - AUTH_STR internal_username; /* username after mapping */ - AUTH_STR smb_name; /* username before mapping */ - AUTH_STR wksta_name; /* workstation name (netbios calling name) unicode string */ - -} auth_usersupplied_info; - -#define SAM_FILL_NAME 0x01 -#define SAM_FILL_INFO3 0x02 -#define SAM_FILL_SAM 0x04 -#define SAM_FILL_UNIX 0x08 -#define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX) - -typedef struct auth_serversupplied_info -{ - BOOL guest; - - /* This groups info is needed for when we become_user() for this uid */ - int n_groups; - gid_t *groups; - - /* NT group information taken from the info3 structure */ - - NT_USER_TOKEN *ptok; - - uint8 session_key[16]; - uint8 first_8_lm_hash[8]; - DATA_BLOB nt_session_key; - DATA_BLOB lm_session_key; - - uint32 sam_fill_level; /* How far is this structure filled? */ - - SAM_ACCOUNT *sam_account; - - void *pam_handle; - -} auth_serversupplied_info; - -struct auth_context { - DATA_BLOB challenge; - - /* Who set this up in the first place? */ - const char *challenge_set_by; - - BOOL challenge_may_be_modified; - - struct auth_methods *challenge_set_method; - /* What order are the various methods in? Try to stop it changing under us */ - struct auth_methods *auth_method_list; - - TALLOC_CTX *mem_ctx; - const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context); - NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context, - const struct auth_usersupplied_info *user_info, - struct auth_serversupplied_info **server_info); - NTSTATUS (*nt_status_squash)(NTSTATUS nt_status); - void (*free)(struct auth_context **auth_context); -}; - -typedef struct auth_methods -{ - struct auth_methods *prev, *next; - const char *name; /* What name got this module */ - - NTSTATUS (*auth)(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const struct auth_usersupplied_info *user_info, - auth_serversupplied_info **server_info); - - DATA_BLOB (*get_chal)(const struct auth_context *auth_context, - void **my_private_data, - TALLOC_CTX *mem_ctx); - - /* Used to keep tabs on things like the cli for SMB server authentication */ - void *private_data; - - /* Function to clean up the above arbitary structure */ - void (*free_private_data)(void **private_data); - - /* Function to send a keepalive message on the above structure */ - void (*send_keepalive)(void **private_data); - -} auth_methods; - -typedef NTSTATUS (*auth_init_function)(struct auth_context *, const char *, struct auth_methods **); - -struct auth_init_function_entry { - const char *name; - /* Function to create a member of the authmethods list */ - - auth_init_function init; -}; - -typedef struct auth_ntlmssp_state -{ - TALLOC_CTX *mem_ctx; - struct auth_context *auth_context; - struct auth_serversupplied_info *server_info; - struct ntlmssp_state *ntlmssp_state; -} AUTH_NTLMSSP_STATE; - -#endif /* _SMBAUTH_H_ */ diff --git a/source4/include/context.h b/source4/include/context.h index 7b156ed382..5c7d117050 100644 --- a/source4/include/context.h +++ b/source4/include/context.h @@ -71,7 +71,7 @@ struct tcon_context { BOOL admin_user; /* the NTVFS operations - see source/ntvfs/ and include/ntvfs.h for details */ - struct ntvfs_ops *ntvfs_ops; + const struct ntvfs_ops *ntvfs_ops; /* the reported filesystem type */ char *fs_type; @@ -359,7 +359,7 @@ struct server_context { struct event_context *events; /* process model specific operations */ - struct model_ops *model_ops; + const struct model_ops *model_ops; }; diff --git a/source4/include/includes.h b/source4/include/includes.h index 2391a59b67..351f7e1ad8 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -742,8 +742,8 @@ extern int errno; #include "libcli/auth/ntlmssp.h" -#include "auth.h" -#include "passdb.h" +#include "auth/auth.h" +#include "passdb/passdb.h" #include "module.h" diff --git a/source4/include/passdb.h b/source4/include/passdb.h deleted file mode 100644 index 25fe5d5300..0000000000 --- a/source4/include/passdb.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - Unix SMB/CIFS implementation. - passdb structures and parameters - Copyright (C) Gerald Carter 2001 - Copyright (C) Luke Kenneth Casson Leighton 1998 - 2000 - - 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. -*/ - -#ifndef _PASSDB_H -#define _PASSDB_H - - -/***************************************************************** - Functions to be implemented by the new (v2) passdb API -****************************************************************/ - -/* - * This next constant specifies the version number of the PASSDB interface - * this SAMBA will load. Increment this if *ANY* changes are made to the interface. - */ - -#define PASSDB_INTERFACE_VERSION 4 - -typedef struct pdb_context -{ - struct pdb_methods *pdb_methods; - struct pdb_methods *pwent_methods; - - /* These functions are wrappers for the functions listed above. - They may do extra things like re-reading a SAM_ACCOUNT on update */ - - NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update); - - void (*pdb_endsampwent)(struct pdb_context *); - - NTSTATUS (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user); - - NTSTATUS (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username); - - NTSTATUS (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid); - - NTSTATUS (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); - - NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); - - NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username); - - NTSTATUS (*pdb_delete_group_mapping_entry)(struct pdb_context *context, - DOM_SID sid); - - void (*free_fn)(struct pdb_context **); - - TALLOC_CTX *mem_ctx; - -} PDB_CONTEXT; - -typedef struct pdb_methods -{ - const char *name; /* What name got this module */ - struct pdb_context *parent; - - /* Use macros from dlinklist.h on these two */ - struct pdb_methods *next; - struct pdb_methods *prev; - - NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update); - - void (*endsampwent)(struct pdb_methods *); - - NTSTATUS (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user); - - NTSTATUS (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username); - - NTSTATUS (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid); - - NTSTATUS (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass); - - NTSTATUS (*update_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass); - - NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username); - - NTSTATUS (*delete_group_mapping_entry)(struct pdb_methods *methods, - DOM_SID sid); - - void *private_data; /* Private data of some kind */ - - void (*free_private_data)(void **); - -} PDB_METHODS; - -typedef NTSTATUS (*pdb_init_function)(struct pdb_context *, - struct pdb_methods **, - const char *); - -struct pdb_init_function_entry { - const char *name; - /* Function to create a member of the pdb_methods list */ - pdb_init_function init; - struct pdb_init_function_entry *prev, *next; -}; - -#endif /* _PASSDB_H */ diff --git a/source4/libads/config.m4 b/source4/libads/config.m4 index c0b926b851..a7a882f048 100644 --- a/source4/libads/config.m4 +++ b/source4/libads/config.m4 @@ -70,7 +70,6 @@ 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]) - SMB_MODULE_DEFAULT(STATIC,pdb_ldap) with_ldap_support=yes AC_MSG_CHECKING(whether LDAP support is used) AC_MSG_RESULT(yes) diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 3e1f77edce..7ed8c738b6 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -30,7 +30,7 @@ * can be more than one backend with the same name, as long as they * have different typesx */ static struct { - struct ntvfs_ops *ops; + const struct ntvfs_ops *ops; } *backends = NULL; static int num_backends; @@ -44,7 +44,8 @@ static int num_backends; */ static NTSTATUS ntvfs_register(void *_ops) { - struct ntvfs_ops *ops = _ops; + const struct ntvfs_ops *ops = _ops; + struct ntvfs_ops *new_ops; if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ @@ -58,8 +59,10 @@ static NTSTATUS ntvfs_register(void *_ops) smb_panic("out of memory in ntvfs_register"); } - backends[num_backends].ops = smb_xmemdup(ops, sizeof(*ops)); - backends[num_backends].ops->name = smb_xstrdup(ops->name); + new_ops = smb_xmemdup(ops, sizeof(*ops)); + new_ops->name = smb_xstrdup(ops->name); + + backends[num_backends].ops = new_ops; num_backends++; @@ -73,7 +76,7 @@ static NTSTATUS ntvfs_register(void *_ops) /* return the operations structure for a named backend of the specified type */ -struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) +const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) { int i; diff --git a/source4/passdb/config.m4 b/source4/passdb/config.m4 index e69de29bb2..328726481a 100644 --- a/source4/passdb/config.m4 +++ b/source4/passdb/config.m4 @@ -0,0 +1,15 @@ +dnl # PASSDB Server subsystem + +SMB_MODULE(pdb_smbpasswd,PASSDB,STATIC,[passdb/pdb_smbpasswd.o]) +SMB_MODULE(pdb_tdb,PASSDB,NOT,[passdb/pdb_tdb.o]) +SMB_MODULE(pdb_guest,PASSDB,STATIC,[passdb/pdb_guest.o]) +SMB_MODULE(pdb_unix,PASSDB,STATIC,[passdb/pdb_unix.o]) + +if test x"$with_ldap_support" = x"yes"; then + SMB_MODULE_DEFAULT(STATIC,pdb_ldap) +fi +SMB_MODULE(pdb_ldap,PASSDB,NOT,[passdb/pdb_ldap.o],[],[$LDAP_LIBS]) + +SMB_SUBSYSTEM(PASSDB,passdb/pdb_interface.o, + [passdb/passdb.o passdb/machine_sid.o passdb/util_sam_sid.o passdb/pdb_get_set.o passdb/pdb_compat.o], + passdb/passdb_public_proto.h) diff --git a/source4/passdb/passdb.h b/source4/passdb/passdb.h new file mode 100644 index 0000000000..7b7f221065 --- /dev/null +++ b/source4/passdb/passdb.h @@ -0,0 +1,119 @@ +/* + Unix SMB/CIFS implementation. + passdb structures and parameters + Copyright (C) Gerald Carter 2001 + Copyright (C) Luke Kenneth Casson Leighton 1998 - 2000 + + 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. +*/ + +#ifndef _SAMBA_PASSDB_H +#define _SAMBA_PASSDB_H + +/* + * This next constant specifies the version number of the PASSDB interface + * this SAMBA will load. Increment this with a comment if *ANY* changes are made + * to the interface and maybe update struct auth_critical_sizes + */ +/* version 2 - init versioning of the interface - metze */ +/* version 3 - value states of SAM_ACCOUNT entries - metze */ +/* version 4 - add group mapping api - vlendec */ +#define PASSDB_INTERFACE_VERSION 4 + +typedef struct pdb_context +{ + struct pdb_methods *pdb_methods; + struct pdb_methods *pwent_methods; + + /* These functions are wrappers for the functions listed above. + They may do extra things like re-reading a SAM_ACCOUNT on update */ + + NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update); + + void (*pdb_endsampwent)(struct pdb_context *); + + NTSTATUS (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user); + + NTSTATUS (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username); + + NTSTATUS (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid); + + NTSTATUS (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); + + NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); + + NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username); + + NTSTATUS (*pdb_delete_group_mapping_entry)(struct pdb_context *context, + DOM_SID sid); + + void (*free_fn)(struct pdb_context **); + + TALLOC_CTX *mem_ctx; + +} PDB_CONTEXT; + +typedef struct pdb_methods +{ + const char *name; /* What name got this module */ + struct pdb_context *parent; + + /* Use macros from dlinklist.h on these two */ + struct pdb_methods *next; + struct pdb_methods *prev; + + NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update); + + void (*endsampwent)(struct pdb_methods *); + + NTSTATUS (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user); + + NTSTATUS (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username); + + NTSTATUS (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid); + + NTSTATUS (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass); + + NTSTATUS (*update_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass); + + NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username); + + NTSTATUS (*delete_group_mapping_entry)(struct pdb_methods *methods, + DOM_SID sid); + + void *private_data; /* Private data of some kind */ + + void (*free_private_data)(void **); + +} PDB_METHODS; + +struct passdb_ops { + /* the name of the backend */ + const char *name; + + /* Function to create a member of the pdb_methods list */ + NTSTATUS (*init)(struct pdb_context *, struct pdb_methods **, const char *); +}; + +/* this structure is used by modules to determine the size of some critical types */ +struct passdb_critical_sizes { + int interface_version; + int sizeof_passdb_ops; + int sizeof_pdb_methods; + int sizeof_pdb_context; + int sizeof_SAM_ACCOUNT; +}; + +#endif /* _SAMBA_PASSDB_H */ diff --git a/source4/passdb/pdb_guest.c b/source4/passdb/pdb_guest.c index 3f0f06d18d..11da975501 100644 --- a/source4/passdb/pdb_guest.c +++ b/source4/passdb/pdb_guest.c @@ -100,7 +100,7 @@ static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT return guestsam_getsampwrid(my_methods, user, rid); } -NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; @@ -121,3 +121,39 @@ NTSTATUS pdb_init_guestsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, c /* There's not very much to initialise here */ return NT_STATUS_OK; } + +NTSTATUS pdb_guest_init(void) +{ + NTSTATUS ret; + struct passdb_ops ops; + + ZERO_STRUCT(ops); + + /* fill in our name */ + ops.name = "guestsam"; + /* fill in all the operations */ + ops.init = pdb_init_guestsam; + + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } + + /* fill in our name */ + ops.name = "guest"; + /* fill in all the operations */ + ops.init = pdb_init_guestsam; + + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/passdb/pdb_interface.c b/source4/passdb/pdb_interface.c index 5b2c081275..ecdd7b6486 100644 --- a/source4/passdb/pdb_interface.c +++ b/source4/passdb/pdb_interface.c @@ -24,78 +24,99 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB -/** List of various built-in passdb modules */ -static const struct { - const char *name; - /* Function to create a member of the pdb_methods list */ - pdb_init_function init; -} builtin_pdb_init_functions[] = { - { "smbpasswd", pdb_init_smbpasswd }, - { "smbpasswd_nua", pdb_init_smbpasswd_nua }, - { "tdbsam", pdb_init_tdbsam }, - { "tdbsam_nua", pdb_init_tdbsam_nua }, - { "ldapsam", pdb_init_ldapsam }, - { "ldapsam_nua", pdb_init_ldapsam_nua }, - { "unixsam", pdb_init_unixsam }, - { "guest", pdb_init_guestsam }, - { "nisplussam", pdb_init_nisplussam }, - { NULL, NULL} -}; - -static struct pdb_init_function_entry *backends; -static void lazy_initialize_passdb(void); - -static void lazy_initialize_passdb() +/* the list of currently registered AUTH backends */ +static struct { + const struct passdb_ops *ops; +} *backends = NULL; +static int num_backends; + +/* + register a AUTH backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. +*/ +static NTSTATUS passdb_register(void *_ops) { - int i; - static BOOL initialised = False; + const struct passdb_ops *ops = _ops; + struct passdb_ops *new_ops; - if(!initialised) { - initialised = True; + if (passdb_backend_byname(ops->name) != NULL) { + /* its already registered! */ + DEBUG(0,("PASSDB backend '%s' already registered\n", + ops->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } - for(i = 0; builtin_pdb_init_functions[i].name; i++) { - smb_register_passdb(builtin_pdb_init_functions[i].name, builtin_pdb_init_functions[i].init, PASSDB_INTERFACE_VERSION); - } + backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); + if (!backends) { + smb_panic("out of memory in passdb_register"); } -} -BOOL smb_register_passdb(const char *name, pdb_init_function init, int version) -{ - struct pdb_init_function_entry *entry = backends; + new_ops = smb_xmemdup(ops, sizeof(*ops)); + new_ops->name = smb_xstrdup(ops->name); - if(version != PASSDB_INTERFACE_VERSION) - return False; + backends[num_backends].ops = new_ops; + + num_backends++; - DEBUG(5,("Attempting to register passdb backend %s\n", name)); + DEBUG(3,("PASSDB backend '%s' registered\n", + ops->name)); + + return NT_STATUS_OK; +} - /* Check for duplicates */ - while(entry) { - if(strcasecmp(name, entry->name) == 0) { - DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name)); - return False; +/* + return the operations structure for a named backend of the specified type +*/ +const struct passdb_ops *passdb_backend_byname(const char *name) +{ + int i; + + for (i=0;iname, name) == 0) { + return backends[i].ops; } - entry = entry->next; } - entry = smb_xmalloc(sizeof(struct pdb_init_function_entry)); - entry->name = name; - entry->init = init; + return NULL; +} - DLIST_ADD(backends, entry); - DEBUG(5,("Successfully added passdb backend '%s'\n", name)); - return True; +/* + return the PASSDB interface version, and the size of some critical types + This can be used by backends to either detect compilation errors, or provide + multiple implementations for different smbd compilation options in one module +*/ +const struct passdb_critical_sizes *passdb_interface_version(void) +{ + static const struct passdb_critical_sizes critical_sizes = { + PASSDB_INTERFACE_VERSION, + sizeof(struct passdb_ops), + sizeof(struct pdb_methods), + sizeof(struct pdb_context), + sizeof(SAM_ACCOUNT) + }; + + return &critical_sizes; } -struct pdb_init_function_entry *pdb_find_backend_entry(const char *name) +/* + initialise the PASSDB subsystem +*/ +BOOL passdb_init(void) { - struct pdb_init_function_entry *entry = backends; + NTSTATUS status; - while(entry) { - if (strequal(entry->name, name)) return entry; - entry = entry->next; + status = register_subsystem("passdb", passdb_register); + if (!NT_STATUS_IS_OK(status)) { + return False; } - return NULL; + /* FIXME: Perhaps panic if a basic backend, such as SAM, fails to initialise? */ + static_init_passdb; + + DEBUG(3,("PASSDB subsystem version %d initialised\n", PASSDB_INTERFACE_VERSION)); + return True; } static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update) @@ -300,18 +321,16 @@ static void free_pdb_context(struct pdb_context **context) static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected) { char *module_name = smb_xstrdup(selected); - char *module_location = NULL, *p; - struct pdb_init_function_entry *entry; + char *module_param = NULL, *p; + const struct passdb_ops *ops; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - lazy_initialize_passdb(); - p = strchr(module_name, ':'); if (p) { *p = 0; - module_location = p+1; - trim_string(module_location, " ", " "); + module_param = p+1; + trim_string(module_param, " ", " "); } trim_string(module_name, " ", " "); @@ -319,20 +338,18 @@ static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_c DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name)); - entry = pdb_find_backend_entry(module_name); - + ops = passdb_backend_byname(module_name); /* No such backend found */ - if(!entry) { + if(!ops) { SAFE_FREE(module_name); return NT_STATUS_INVALID_PARAMETER; } - - DEBUG(5,("Found pdb backend %s\n", module_name)); - nt_status = entry->init(context, methods, module_location); + DEBUG(5,("Found PASSDB backend %s\n", module_name)); + nt_status = ops->init(context, methods, module_param); if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(5,("pdb backend %s has a valid init\n", selected)); + DEBUG(5,("PASSDB backend %s has a valid init\n", selected)); } else { - DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status))); + DEBUG(0,("PASSDB backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status))); } SAFE_FREE(module_name); return nt_status; diff --git a/source4/passdb/pdb_ldap.c b/source4/passdb/pdb_ldap.c index 6bab5b9bca..5f7db7f5de 100644 --- a/source4/passdb/pdb_ldap.c +++ b/source4/passdb/pdb_ldap.c @@ -28,7 +28,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB -#ifdef HAVE_LDAP /* TODO: * persistent connections: if using NSS LDAP, many connections are made * however, using only one within Samba would be nice @@ -1979,7 +1978,7 @@ static void free_private_data(void **vp) /* No need to free any further, as it is talloc()ed */ } -NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct ldapsam_privates *ldap_state; @@ -2036,7 +2035,7 @@ NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co return NT_STATUS_OK; } -NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct ldapsam_privates *ldap_state; @@ -2064,20 +2063,36 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method return NT_STATUS_OK; } - -#else - -NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +NTSTATUS pdb_ldap_init(void) { - DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n")); - return NT_STATUS_UNSUCCESSFUL; -} + NTSTATUS ret; + struct passdb_ops ops; + + /* fill in our name */ + ops.name = "ldapsam"; + /* fill in all the operations */ + ops.init = pdb_init_ldapsam; + + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } -NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n")); - return NT_STATUS_UNSUCCESSFUL; -} + /* fill in our name */ + ops.name = "ldapsam_nua"; + /* fill in all the operations */ + ops.init = pdb_init_ldapsam_nua; + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } -#endif + return ret; +} diff --git a/source4/passdb/pdb_smbpasswd.c b/source4/passdb/pdb_smbpasswd.c index 6f8c8a6fcc..0811c23484 100644 --- a/source4/passdb/pdb_smbpasswd.c +++ b/source4/passdb/pdb_smbpasswd.c @@ -1508,7 +1508,7 @@ static void free_private_data(void **vp) } -NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct smbpasswd_privates *privates; @@ -1557,7 +1557,7 @@ NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, return NT_STATUS_OK; } -NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct smbpasswd_privates *privates; @@ -1579,3 +1579,37 @@ NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth return NT_STATUS_OK; } + +NTSTATUS pdb_smbpasswd_init(void) +{ + NTSTATUS ret; + struct passdb_ops ops; + + /* fill in our name */ + ops.name = "smbpasswd"; + /* fill in all the operations */ + ops.init = pdb_init_smbpasswd; + + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } + + /* fill in our name */ + ops.name = "smbpasswd_nua"; + /* fill in all the operations */ + ops.init = pdb_init_smbpasswd_nua; + + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/passdb/pdb_tdb.c b/source4/passdb/pdb_tdb.c index c48c9567b1..a3fda1f47e 100644 --- a/source4/passdb/pdb_tdb.c +++ b/source4/passdb/pdb_tdb.c @@ -37,8 +37,6 @@ static int tdbsam_debug_level = DBGC_ALL; #endif -#ifdef WITH_TDB_SAM - #define PDB_VERSION "20010830" #define PASSDB_FILE_NAME "passdb.tdb" #define TDB_FORMAT_STRING "ddddddBBBBBBBBBBBBddBBwdwdBdd" @@ -906,7 +904,7 @@ static void free_private_data(void **vp) } -NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct tdbsam_privates *tdb_state; @@ -960,7 +958,7 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con return NT_STATUS_OK; } -NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct tdbsam_privates *tdb_state; @@ -988,20 +986,36 @@ NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, return NT_STATUS_OK; } +NTSTATUS pdb_tdb_init(void) +{ + NTSTATUS ret; + struct passdb_ops ops; -#else + /* fill in our name */ + ops.name = "tdbsam"; + /* fill in all the operations */ + ops.init = pdb_init_tdbsam; -NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - DEBUG(0, ("tdbsam not compiled in!\n")); - return NT_STATUS_UNSUCCESSFUL; -} + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } -NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - DEBUG(0, ("tdbsam_nua not compiled in!\n")); - return NT_STATUS_UNSUCCESSFUL; -} + /* fill in our name */ + ops.name = "tdbsam_nua"; + /* fill in all the operations */ + ops.init = pdb_init_tdbsam_nua; + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } -#endif + return ret; +} diff --git a/source4/passdb/pdb_unix.c b/source4/passdb/pdb_unix.c index b42843d802..a1552981f1 100644 --- a/source4/passdb/pdb_unix.c +++ b/source4/passdb/pdb_unix.c @@ -88,7 +88,7 @@ static NTSTATUS unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT return unixsam_getsampwrid(my_methods, user, rid); } -NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; @@ -108,3 +108,24 @@ NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co /* There's not very much to initialise here */ return NT_STATUS_OK; } + +NTSTATUS pdb_unix_init(void) +{ + NTSTATUS ret; + struct passdb_ops ops; + + /* fill in our name */ + ops.name = "unixsam"; + /* fill in all the operations */ + ops.init = pdb_init_unixsam; + + /* register ourselves with the PASSDB subsystem. */ + ret = register_backend("passdb", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register '%s' PASSDB backend!\n", + ops.name)); + return ret; + } + + return ret; +} diff --git a/source4/smbd/process.c b/source4/smbd/process.c index 38f76417f6..592a0efc99 100644 --- a/source4/smbd/process.c +++ b/source4/smbd/process.c @@ -44,9 +44,6 @@ void smbd_process_init(void) if (!init_registry()) exit(1); - if(!initialize_password_db(False)) - exit(1); - /* possibly reload the services file. */ reload_services(NULL, True); @@ -73,6 +70,16 @@ void smbd_process_init(void) if (!init_change_notify()) exit(1); + /* Setup the AUTH subsystem */ + if (!auth_init()) + exit(1); + + /* Setup the PASSDB subsystem */ + if (!passdb_init()) + exit(1); + if(!initialize_password_db(False)) + exit(1); + /* Setup the NTVFS subsystem */ if (!ntvfs_init()) exit(1); -- cgit