summaryrefslogtreecommitdiff
path: root/source3/auth
diff options
context:
space:
mode:
Diffstat (limited to 'source3/auth')
-rw-r--r--source3/auth/auth.c76
-rw-r--r--source3/auth/auth_compat.c5
-rw-r--r--source3/auth/auth_ntlmssp.c6
-rw-r--r--source3/auth/auth_util.c40
-rw-r--r--source3/auth/auth_wbc.c150
5 files changed, 207 insertions, 70 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 505098c76a..fd4c503752 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -2,17 +2,17 @@
Unix SMB/CIFS implementation.
Password and authentication handling
Copyright (C) Andrew Bartlett 2001-2002
-
+
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 3 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, see <http://www.gnu.org/licenses/>.
*/
@@ -49,7 +49,7 @@ NTSTATUS smb_register_auth(int version, const char *name, auth_init_function ini
DEBUG(0,("There already is an auth method registered with the name %s!\n", name));
return NT_STATUS_OBJECT_NAME_COLLISION;
}
-
+
entry = SMB_XMALLOC_P(struct auth_init_function_entry);
entry->name = smb_xstrdup(name);
entry->init = init;
@@ -67,7 +67,7 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name
if (strcmp(entry->name, name)==0) return entry;
entry = entry->next;
}
-
+
return NULL;
}
@@ -76,7 +76,8 @@ static struct auth_init_function_entry *auth_find_backend_entry(const char *name
Returns a const char of length 8 bytes.
****************************************************************************/
-static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
+static void get_ntlm_challenge(struct auth_context *auth_context,
+ uint8_t chal[8])
{
DATA_BLOB challenge = data_blob_null;
const char *challenge_set_by = NULL;
@@ -86,7 +87,8 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
if (auth_context->challenge.length) {
DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n",
auth_context->challenge_set_by));
- return auth_context->challenge.data;
+ memcpy(chal, auth_context->challenge.data, 8);
+ return;
}
auth_context->challenge_may_be_modified = False;
@@ -108,7 +110,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
if (!mem_ctx) {
smb_panic("talloc_init() failed!");
}
-
+
challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
if (!challenge.length) {
DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n",
@@ -121,27 +123,27 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
}
talloc_destroy(mem_ctx);
}
-
+
if (!challenge_set_by) {
- uchar chal[8];
-
- generate_random_buffer(chal, sizeof(chal));
+ uchar tmp[8];
+
+ generate_random_buffer(tmp, sizeof(tmp));
auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
- chal, sizeof(chal));
-
+ tmp, sizeof(tmp));
+
challenge_set_by = "random";
auth_context->challenge_may_be_modified = True;
}
-
+
DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
DEBUG(5, ("challenge is: \n"));
dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
-
+
SMB_ASSERT(auth_context->challenge.length == 8);
auth_context->challenge_set_by=challenge_set_by;
- return auth_context->challenge.data;
+ memcpy(chal, auth_context->challenge.data, 8);
}
@@ -249,7 +251,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) {
NTSTATUS result;
-
+
mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name,
user_info->domain, user_info->smb_name);
@@ -281,7 +283,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
}
/* successful authentication */
-
+
if (NT_STATUS_IS_OK(nt_status)) {
unix_username = (*server_info)->unix_name;
if (!(*server_info)->guest) {
@@ -289,7 +291,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
become_root();
nt_status = smb_pam_accountcheck(unix_username);
unbecome_root();
-
+
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n",
unix_username));
@@ -298,7 +300,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
unix_username, nt_errstr(nt_status)));
}
}
-
+
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG((*server_info)->guest ? 5 : 2,
("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n",
@@ -307,17 +309,17 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
user_info->internal_username,
unix_username));
}
-
+
return nt_status;
}
-
+
/* failed authentication; check for guest lapping */
-
+
DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n",
user_info->smb_name, user_info->internal_username,
nt_errstr(nt_status)));
ZERO_STRUCTP(server_info);
-
+
return nt_status;
}
@@ -349,7 +351,7 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context)
TALLOC_CTX *mem_ctx;
mem_ctx = talloc_init("authentication context");
-
+
*auth_context = TALLOC_P(mem_ctx, struct auth_context);
if (!*auth_context) {
DEBUG(0,("make_auth_context: talloc failed!\n"));
@@ -362,7 +364,7 @@ static NTSTATUS make_auth_context(struct auth_context **auth_context)
(*auth_context)->check_ntlm_password = check_ntlm_password;
(*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
(*auth_context)->free = free_auth_context;
-
+
return NT_STATUS_OK;
}
@@ -382,21 +384,21 @@ bool load_auth_module(struct auth_context *auth_context,
static_init_auth;
initialised_static_modules = True;
}
-
+
DEBUG(5,("load_auth_module: Attempting to find an auth method to match %s\n",
module));
-
+
p = strchr(module_name, ':');
if (p) {
*p = 0;
module_params = p+1;
trim_char(module_params, ' ', ' ');
}
-
+
trim_char(module_name, ' ', ' ');
-
+
entry = auth_find_backend_entry(module_name);
-
+
if (entry == NULL) {
if (NT_STATUS_IS_OK(smb_probe_module("auth", module_name))) {
entry = auth_find_backend_entry(module_name);
@@ -434,7 +436,7 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context,
DEBUG(2,("make_auth_context_text_list: No auth method list!?\n"));
return NT_STATUS_UNSUCCESSFUL;
}
-
+
if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context)))
return nt_status;
@@ -443,9 +445,9 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context,
DLIST_ADD_END(list, t, auth_methods *);
}
}
-
+
(*auth_context)->auth_method_list = list;
-
+
return nt_status;
}
@@ -523,7 +525,7 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
} else {
DEBUG(5,("Using specified auth order\n"));
}
-
+
nt_status = make_auth_context_text_list(auth_context,
auth_method_list);
@@ -541,7 +543,7 @@ NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
return nt_status;
}
-
+
(*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8);
(*auth_context)->challenge_set_by = "fixed";
return nt_status;
diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c
index 00d9dea816..925c0d4f81 100644
--- a/source3/auth/auth_compat.c
+++ b/source3/auth/auth_compat.c
@@ -39,13 +39,14 @@ NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_pass
{
struct auth_context *plaintext_auth_context = NULL;
auth_usersupplied_info *user_info = NULL;
- const uint8 *chal;
+ uint8_t chal[8];
NTSTATUS nt_status;
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
return nt_status;
}
- chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
+ plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context,
+ chal);
if (!make_user_info_for_reply(&user_info,
smb_name, lp_workgroup(), chal,
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index 0d46b14f97..034d354a33 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -27,11 +27,13 @@
* @return an 8 byte random challenge
*/
-static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state)
+static void auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
+ uint8_t chal[8])
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
(AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
- return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context);
+ auth_ntlmssp_state->auth_context->get_ntlm_challenge(
+ auth_ntlmssp_state->auth_context, chal);
}
/**
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 0dab05b97c..c39aa8501d 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -710,8 +710,6 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
NTSTATUS status;
size_t i;
struct dom_sid tmp_sid;
- const char *name_to_use;
- bool force_nss;
/*
* If winbind is not around, we can not make much use of the SIDs the
@@ -719,22 +717,11 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
* mapped to some local unix user.
*/
- DEBUG(10, ("creating token for %s (SAM: %s)\n", server_info->unix_name,
- server_info->sam_account->username));
-
- force_nss = lp_force_username_map() && !server_info->nss_token;
if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
- server_info->nss_token || force_nss) {
- if (force_nss)
- name_to_use =
- pdb_get_username(server_info->sam_account);
- else
- name_to_use = server_info->unix_name;
-
+ (server_info->nss_token)) {
status = create_token_from_username(server_info,
- name_to_use,
+ server_info->unix_name,
server_info->guest,
- force_nss,
&server_info->utok.uid,
&server_info->utok.gid,
&server_info->unix_name,
@@ -819,7 +806,7 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
}
/*
- * Create an artificial NT token given just a username. (Initially indended
+ * Create an artificial NT token given just a username. (Initially intended
* for force user)
*
* We go through lookup_name() to avoid problems we had with 'winbind use
@@ -839,7 +826,6 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
bool is_guest,
- bool force_nss,
uid_t *uid, gid_t *gid,
char **found_username,
struct nt_user_token **token)
@@ -855,9 +841,6 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
size_t num_gids;
size_t i;
- DEBUG(10, ("creating token for %s,%s guest,%s forcing NSS lookup\n",
- username, is_guest ? "" : " not", force_nss ? "" : " not"));
-
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(0, ("talloc_new failed\n"));
@@ -876,13 +859,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
goto done;
}
- if (!sid_to_uid(&user_sid, uid)) {
- DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
- username, sid_string_dbg(&user_sid)));
- goto done;
- }
-
- if (sid_check_is_in_our_domain(&user_sid) && !force_nss) {
+ if (sid_check_is_in_our_domain(&user_sid)) {
bool ret;
/* This is a passdb user, so ask passdb */
@@ -924,7 +901,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
*found_username = talloc_strdup(mem_ctx,
pdb_get_username(sam_acct));
- } else if (force_nss || sid_check_is_in_unix_users(&user_sid)) {
+ } else if (sid_check_is_in_unix_users(&user_sid)) {
/* This is a unix user not in passdb. We need to ask nss
* directly, without consulting passdb */
@@ -939,6 +916,12 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
unix_user:
+ if (!sid_to_uid(&user_sid, uid)) {
+ DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
+ username, sid_string_dbg(&user_sid)));
+ goto done;
+ }
+
uid_to_unix_users_sid(*uid, &user_sid);
pass = getpwuid_alloc(tmp_ctx, *uid);
@@ -1080,7 +1063,6 @@ bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
}
status = create_token_from_username(mem_ctx, username, False,
- lp_force_username_map(),
&uid, &gid, &found_username,
&token);
diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c
new file mode 100644
index 0000000000..580c8b550d
--- /dev/null
+++ b/source3/auth/auth_wbc.c
@@ -0,0 +1,150 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind client authentication mechanism designed to defer all
+ authentication to the winbind daemon.
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Andrew Bartlett 2001 - 2002
+ Copyright (C) Dan Sledz 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This auth module is very similar to auth_winbind with 3 distinct
+ * differences.
+ *
+ * 1) Does not fallback to another auth module if winbindd is unavailable
+ * 2) Does not validate the domain of the user
+ * 3) Handles unencrypted passwords
+ *
+ * The purpose of this module is to defer all authentication decisions (ie:
+ * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc
+ * compatible daemon. This centeralizes all authentication decisions to a
+ * single provider.
+ *
+ * This auth backend is most useful when used in conjunction with pdb_wbc_sam.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_AUTH
+
+/* Authenticate a user with a challenge/response */
+
+static NTSTATUS check_wbc_security(const struct auth_context *auth_context,
+ void *my_private_data,
+ TALLOC_CTX *mem_ctx,
+ const auth_usersupplied_info *user_info,
+ auth_serversupplied_info **server_info)
+{
+ NTSTATUS nt_status;
+ wbcErr wbc_status;
+ struct wbcAuthUserParams params;
+ struct wbcAuthUserInfo *info = NULL;
+ struct wbcAuthErrorInfo *err = NULL;
+
+ if (!user_info || !auth_context || !server_info) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ /* Send off request */
+
+ params.account_name = user_info->smb_name;
+ params.domain_name = user_info->domain;
+ params.workstation_name = user_info->wksta_name;
+
+ params.flags = 0;
+ params.parameter_control= user_info->logon_parameters;
+
+ /* Handle plaintext */
+ if (!user_info->encrypted) {
+ DEBUG(3,("Checking plaintext password for %s.\n",
+ user_info->internal_username));
+ params.level = WBC_AUTH_USER_LEVEL_PLAIN;
+
+ params.password.plaintext = (char *)user_info->plaintext_password.data;
+ } else {
+ DEBUG(3,("Checking encrypted password for %s.\n",
+ user_info->internal_username));
+ params.level = WBC_AUTH_USER_LEVEL_RESPONSE;
+
+ memcpy(params.password.response.challenge,
+ auth_context->challenge.data,
+ sizeof(params.password.response.challenge));
+
+ params.password.response.nt_length = user_info->nt_resp.length;
+ params.password.response.nt_data = user_info->nt_resp.data;
+ params.password.response.lm_length = user_info->lm_resp.length;
+ params.password.response.lm_data = user_info->lm_resp.data;
+
+ }
+
+ /* we are contacting the privileged pipe */
+ become_root();
+ wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
+ unbecome_root();
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n",
+ wbc_status, wbcErrorString(wbc_status)));
+ }
+
+ if (wbc_status == WBC_ERR_NO_MEMORY) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (wbc_status == WBC_ERR_AUTH_ERROR) {
+ nt_status = NT_STATUS(err->nt_status);
+ wbcFreeMemory(err);
+ return nt_status;
+ }
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return NT_STATUS_LOGON_FAILURE;
+ }
+
+ DEBUG(10,("wbcAuthenticateUserEx succeeded\n"));
+
+ nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
+ user_info->smb_name,
+ user_info->domain,
+ info, server_info);
+ wbcFreeMemory(info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ (*server_info)->nss_token |= user_info->was_mapped;
+
+ return nt_status;
+}
+
+/* module initialisation */
+static NTSTATUS auth_init_wbc(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;
+ }
+
+ (*auth_method)->name = "wbc";
+ (*auth_method)->auth = check_wbc_security;
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS auth_wbc_init(void)
+{
+ return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc);
+}