r12360: Add simple bind support into our LDAP server.
authorAndrew Bartlett <abartlet@samba.org>
Mon, 19 Dec 2005 06:56:45 +0000 (06:56 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:47:30 +0000 (13:47 -0500)
Needs changes to our client code for automated testing.

Andrew Bartlett

source/auth/auth_simple.c [new file with mode: 0644]
source/auth/config.mk
source/dsdb/samdb/cracknames.c
source/ldap_server/ldap_bind.c

diff --git a/source/auth/auth_simple.c b/source/auth/auth_simple.c
new file mode 100644 (file)
index 0000000..7976560
--- /dev/null
@@ -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;
+}
+
index 876d43a6ef91934f7a1c46b8be5e9054f38f1e9f..d572c5e89acc3468808fabfe9273ec7ff50f4e2f 100644 (file)
@@ -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
 #######################
index a377e3fe1d121d8353ca84a3b6299672a874a15e..c95ab047e3a26639485344ba49a45ac193ebaf08 100644 (file)
@@ -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;
+       
+}
index 65258402329e92f6fcd54476945134a07a393a82..4350f3abe8617ca9912cf1c74ccb91509a0425d8 100644 (file)
@@ -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);