summaryrefslogtreecommitdiff
path: root/source4/auth
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-02-03 11:10:56 +0000
committerStefan Metzmacher <metze@samba.org>2004-02-03 11:10:56 +0000
commit1c798aba40fb0e389c7a54ad3d8f7d45876f2809 (patch)
tree3ee4790e25089106db52b1f16d20583f7bf90b9e /source4/auth
parenta9b28120b84fd63e333d5be26fe8116c85f12c87 (diff)
downloadsamba-1c798aba40fb0e389c7a54ad3d8f7d45876f2809.tar.gz
samba-1c798aba40fb0e389c7a54ad3d8f7d45876f2809.tar.bz2
samba-1c798aba40fb0e389c7a54ad3d8f7d45876f2809.zip
- port AUTH and PASSDB subsystems to new
SMB_SUBSYSTEM() scheme - some const fixes in ntvfs metze (This used to be commit af89a78123068767b1d134969c5651a0fd978b0d)
Diffstat (limited to 'source4/auth')
-rw-r--r--source4/auth/auth.c174
-rw-r--r--source4/auth/auth.h175
-rw-r--r--source4/auth/auth_builtin.c76
-rw-r--r--source4/auth/auth_sam.c41
-rw-r--r--source4/auth/auth_unix.c18
-rw-r--r--source4/auth/config.m49
6 files changed, 397 insertions, 96 deletions
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;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;
+}
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)