1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-08 04:58:40 +03:00

- port AUTH and PASSDB subsystems to new

SMB_SUBSYSTEM() scheme

- some const fixes in ntvfs

metze
This commit is contained in:
Stefan Metzmacher -
parent 4597643e76
commit af89a78123
21 changed files with 583 additions and 282 deletions

View File

@ -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

View File

@ -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;
}
SAFE_FREE(module_name);
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;i<num_backends;i++) {
if (strcmp(backends[i].ops->name, 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;
}

View File

@ -1,5 +1,3 @@
#ifndef _SMBAUTH_H_
#define _SMBAUTH_H_
/*
Unix SMB/CIFS implementation.
Standardised Authentication types
@ -20,15 +18,26 @@
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 normal_string
typedef struct auth_str
{
int len;
char *str;
} AUTH_STR;
/* AUTH_UNISTR - unicode string or buffer */
typedef struct unicode_string
typedef struct auth_unistr
{
int len;
uchar *unistr;
@ -42,7 +51,6 @@ typedef struct unicode_string
typedef struct auth_usersupplied_info
{
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
DATA_BLOB plaintext_password;
@ -56,7 +64,6 @@ typedef struct auth_usersupplied_info
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
@ -87,7 +94,6 @@ typedef struct auth_serversupplied_info
SAM_ACCOUNT *sam_account;
void *pam_handle;
} auth_serversupplied_info;
struct auth_context {
@ -120,7 +126,7 @@ typedef struct auth_methods
void *my_private_data,
TALLOC_CTX *mem_ctx,
const struct auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info);
struct auth_serversupplied_info **server_info);
DATA_BLOB (*get_chal)(const struct auth_context *auth_context,
void **my_private_data,
@ -134,18 +140,8 @@ typedef struct auth_methods
/* 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;
@ -154,4 +150,26 @@ typedef struct auth_ntlmssp_state
struct ntlmssp_state *ntlmssp_state;
} AUTH_NTLMSSP_STATE;
#endif /* _SMBAUTH_H_ */
#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 */

View File

@ -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;
NTSTATUS ret;
struct auth_operations ops;
if (param == NULL) {
DEBUG(0, ("auth_init_plugin: The plugin module needs an argument!\n"));
return NT_STATUS_UNSUCCESSFUL;
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;
}

View File

@ -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;
}

View File

@ -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;
}

9
source/auth/config.m4 Normal file
View File

@ -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)

View File

@ -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)

View File

@ -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;
};

View File

@ -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"

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -19,22 +19,20 @@
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
****************************************************************/
#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 if *ANY* changes are made to the 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
typedef struct pdb_context
{
struct pdb_methods *pdb_methods;
struct pdb_methods *pwent_methods;
@ -101,15 +99,21 @@ typedef struct pdb_methods
} PDB_METHODS;
typedef NTSTATUS (*pdb_init_function)(struct pdb_context *,
struct pdb_methods **,
const char *);
struct pdb_init_function_entry {
struct passdb_ops {
/* the name of the backend */
const char *name;
/* Function to create a member of the pdb_methods list */
pdb_init_function init;
struct pdb_init_function_entry *prev, *next;
NTSTATUS (*init)(struct pdb_context *, struct pdb_methods **, const char *);
};
#endif /* _PASSDB_H */
/* 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 */

View File

@ -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;
}

View File

@ -24,80 +24,101 @@
#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}
};
/* the list of currently registered AUTH backends */
static struct {
const struct passdb_ops *ops;
} *backends = NULL;
static int num_backends;
static struct pdb_init_function_entry *backends;
static void lazy_initialize_passdb(void);
/*
register a AUTH backend.
static void lazy_initialize_passdb()
The 'name' can be later used by other backends to find the operations
structure for this backend.
*/
static NTSTATUS passdb_register(void *_ops)
{
const struct passdb_ops *ops = _ops;
struct passdb_ops *new_ops;
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;
}
backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1));
if (!backends) {
smb_panic("out of memory in passdb_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,("PASSDB backend '%s' registered\n",
ops->name));
return NT_STATUS_OK;
}
/*
return the operations structure for a named backend of the specified type
*/
const struct passdb_ops *passdb_backend_byname(const char *name)
{
int i;
static BOOL initialised = False;
if(!initialised) {
initialised = True;
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);
for (i=0;i<num_backends;i++) {
if (strcmp(backends[i].ops->name, name) == 0) {
return backends[i].ops;
}
}
}
BOOL smb_register_passdb(const char *name, pdb_init_function init, int version)
{
struct pdb_init_function_entry *entry = backends;
if(version != PASSDB_INTERFACE_VERSION)
return False;
DEBUG(5,("Attempting to register passdb backend %s\n", name));
/* 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;
}
entry = entry->next;
}
entry = smb_xmalloc(sizeof(struct pdb_init_function_entry));
entry->name = name;
entry->init = init;
DLIST_ADD(backends, entry);
DEBUG(5,("Successfully added passdb backend '%s'\n", name));
return True;
}
struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
{
struct pdb_init_function_entry *entry = backends;
while(entry) {
if (strequal(entry->name, name)) return entry;
entry = entry->next;
}
return NULL;
}
/*
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;
}
/*
initialise the PASSDB subsystem
*/
BOOL passdb_init(void)
{
NTSTATUS status;
status = register_subsystem("passdb", passdb_register);
if (!NT_STATUS_IS_OK(status)) {
return False;
}
/* 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)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@ -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;

View File

@ -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;
}
/* 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;
}
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;
}
#endif

View File

@ -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;
}

View File

@ -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;
}
#else
NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
NTSTATUS pdb_tdb_init(void)
{
DEBUG(0, ("tdbsam not compiled in!\n"));
return NT_STATUS_UNSUCCESSFUL;
NTSTATUS ret;
struct passdb_ops ops;
/* fill in our name */
ops.name = "tdbsam";
/* fill in all the operations */
ops.init = pdb_init_tdbsam;
/* 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 = "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;
}
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;
}
#endif

View File

@ -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;
}

View File

@ -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);