diff options
-rw-r--r-- | source4/auth/auth_simple.c | 90 | ||||
-rw-r--r-- | source4/auth/config.mk | 3 | ||||
-rw-r--r-- | source4/dsdb/samdb/cracknames.c | 54 | ||||
-rw-r--r-- | source4/ldap_server/ldap_bind.c | 44 |
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); |