summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-12-19 06:56:45 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:47:30 -0500
commit6bd8be867130686946e687512d7a4a68934217e1 (patch)
tree706672e72e96e9b2f676933273b448d0c49b5167
parenta30726581e594013ae9b61a42dab813051999548 (diff)
downloadsamba-6bd8be867130686946e687512d7a4a68934217e1.tar.gz
samba-6bd8be867130686946e687512d7a4a68934217e1.tar.bz2
samba-6bd8be867130686946e687512d7a4a68934217e1.zip
r12360: Add simple bind support into our LDAP server.
Needs changes to our client code for automated testing. Andrew Bartlett (This used to be commit e751d814149d847ff1699542a4fa81eb8ca129ec)
-rw-r--r--source4/auth/auth_simple.c90
-rw-r--r--source4/auth/config.mk3
-rw-r--r--source4/dsdb/samdb/cracknames.c54
-rw-r--r--source4/ldap_server/ldap_bind.c44
4 files changed, 188 insertions, 3 deletions
diff --git a/source4/auth/auth_simple.c b/source4/auth/auth_simple.c
new file mode 100644
index 0000000000..7976560bf1
--- /dev/null
+++ b/source4/auth/auth_simple.c
@@ -0,0 +1,90 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ auth functions
+
+ Copyright (C) Simo Sorce 2005
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Andrew Bartlett 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "auth/auth.h"
+#include "lib/events/events.h"
+
+NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
+ const char *nt4_domain,
+ const char *nt4_username,
+ const char *password,
+ struct auth_session_info **session_info)
+{
+ struct auth_context *auth_context;
+ struct auth_usersupplied_info *user_info;
+ struct auth_serversupplied_info *server_info;
+ NTSTATUS nt_status;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+
+ if (!tmp_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nt_status = auth_context_create(tmp_ctx, lp_auth_methods(), &auth_context,
+ event_context_find(mem_ctx));
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(tmp_ctx);
+ return nt_status;
+ }
+
+ user_info = talloc(tmp_ctx, struct auth_usersupplied_info);
+ if (!user_info) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ user_info->mapped_state = True;
+ user_info->client.account_name = nt4_username;
+ user_info->mapped.account_name = nt4_username;
+ user_info->client.domain_name = nt4_domain;
+ user_info->mapped.domain_name = nt4_domain;
+
+ user_info->workstation_name = NULL;
+
+ user_info->remote_host = NULL;
+
+ user_info->password_state = AUTH_PASSWORD_PLAIN;
+ user_info->password.plaintext = talloc_strdup(user_info, password);
+
+ user_info->flags = USER_INFO_CASE_INSENSITIVE_USERNAME |
+ USER_INFO_DONT_CHECK_UNIX_ACCOUNT;
+
+ user_info->logon_parameters = 0;
+
+ nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(tmp_ctx);
+ return nt_status;
+ }
+
+ nt_status = auth_generate_session_info(tmp_ctx, server_info, session_info);
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ talloc_steal(mem_ctx, *session_info);
+ }
+
+ return nt_status;
+}
+
diff --git a/source4/auth/config.mk b/source4/auth/config.mk
index 876d43a6ef..d572c5e89a 100644
--- a/source4/auth/config.mk
+++ b/source4/auth/config.mk
@@ -72,6 +72,7 @@ INIT_OBJ_FILES = \
ADD_OBJ_FILES = \
auth_util.o \
auth_sam_reply.o \
- ntlm_check.o
+ ntlm_check.o \
+ auth_simple.o
# End SUBSYSTEM AUTH
#######################
diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c
index a377e3fe1d..c95ab047e3 100644
--- a/source4/dsdb/samdb/cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -850,3 +850,57 @@ NTSTATUS crack_service_principal_name(struct ldb_context *sam_ctx,
return NT_STATUS_OK;
}
+
+NTSTATUS crack_dn_to_nt4_name(TALLOC_CTX *mem_ctx,
+ const char *dn,
+ const char **nt4_domain, const char **nt4_account)
+{
+ WERROR werr;
+ struct drsuapi_DsNameInfo1 info1;
+ struct ldb_context *ldb;
+ char *p;
+
+ ldb = samdb_connect(mem_ctx, system_session(mem_ctx));
+ if (ldb == NULL) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ werr = DsCrackNameOneName(ldb, mem_ctx, 0,
+ DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
+ DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
+ dn,
+ &info1);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werror_to_ntstatus(werr);
+ }
+ switch (info1.status) {
+ case DRSUAPI_DS_NAME_STATUS_OK:
+ break;
+ case DRSUAPI_DS_NAME_STATUS_NOT_FOUND:
+ case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY:
+ case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE:
+ return NT_STATUS_NO_SUCH_USER;
+ case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR:
+ default:
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ *nt4_domain = talloc_strdup(mem_ctx, info1.result_name);
+
+ p = strchr(*nt4_domain, '\\');
+ if (!p) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ p[0] = '\0';
+
+ if (p[1]) {
+ *nt4_account = talloc_strdup(mem_ctx, &p[1]);
+ }
+
+ if (!*nt4_account || !*nt4_domain) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+
+}
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 6525840232..4350f3abe8 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -30,8 +30,22 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
struct ldapsrv_reply *reply;
struct ldap_BindResponse *resp;
+ int result;
+ const char *errstr;
+ const char *nt4_domain, *nt4_account;
+
+ struct auth_session_info *session_info;
+
+ NTSTATUS status;
+
DEBUG(10, ("BindSimple dn: %s\n",req->dn));
+ status = crack_dn_to_nt4_name(call, req->dn, &nt4_domain, &nt4_account);
+ if (NT_STATUS_IS_OK(status)) {
+ status = authenticate_username_pw(call, nt4_domain, nt4_account,
+ req->creds.password, &session_info);
+ }
+
/* When we add authentication here, we also need to handle telling the backends */
reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
@@ -39,11 +53,37 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
return NT_STATUS_NO_MEMORY;
}
+ if (NT_STATUS_IS_OK(status)) {
+ struct ldapsrv_partition *part;
+ result = LDAP_SUCCESS;
+ errstr = NULL;
+
+ talloc_free(call->conn->session_info);
+ call->conn->session_info = session_info;
+ for (part = call->conn->partitions; part; part = part->next) {
+ if (!part->ops->Bind) {
+ continue;
+ }
+ status = part->ops->Bind(part, call->conn);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = LDAP_OPERATIONS_ERROR;
+ errstr = talloc_asprintf(reply, "Simple Bind: Failed to advise partition %s of new credentials: %s", part->base_dn, nt_errstr(status));
+ }
+ }
+ } else {
+ status = auth_nt_status_squash(status);
+
+ result = LDAP_INVALID_CREDENTIALS;
+ errstr = talloc_asprintf(reply, "Simple Bind Failed: %s", nt_errstr(status));
+ }
+
resp = &reply->msg->r.BindResponse;
- resp->response.resultcode = 0;
+ resp->response.resultcode = result;
+ resp->response.errormessage = errstr;
resp->response.dn = NULL;
- resp->response.errormessage = NULL;
resp->response.referral = NULL;
+
+ /* This looks wrong... */
resp->SASL.secblob = data_blob(NULL, 0);
ldapsrv_queue_reply(call, reply);