From 1377cca5f4beb43cf67fcc65eed79f14178d6349 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Oct 2005 11:31:45 +0000 Subject: r10810: This adds the hooks required to communicate the current user from the authenticated session down into LDB. This associates a session info structure with the open LDB, allowing a future ldb_ntacl module to allow/deny operations on that basis. Along the way, I cleaned up a few things, and added new helper functions to assist. In particular the LSA pipe uses simpler queries for some of the setup. In ldap_server, I have removed the 'ldasrv:hacked' module, which hasn't been worked on (other than making it continue to compile) since January, and I think the features of this module are being put into ldb anyway. I have also changed the partitions in ldap_server to be initialised after the connection, with the private pointer used to associate the ldb with the incoming session. Andrew Bartlett (This used to be commit fd7203789a2c0929eecea8125b57b833a67fed71) --- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 3 +- source4/rpc_server/drsuapi/drsuapi_cracknames.c | 55 +++++++++++++++++++++++++ source4/rpc_server/dssetup/dcesrv_dssetup.c | 19 +++++---- source4/rpc_server/lsa/dcesrv_lsa.c | 40 ++++++------------ source4/rpc_server/netlogon/dcerpc_netlogon.c | 19 ++++----- source4/rpc_server/samr/dcesrv_samr.c | 5 ++- source4/rpc_server/samr/samr_password.c | 29 +++++++------ 7 files changed, 108 insertions(+), 62 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 94a16d0a09..c8578a7cc1 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -25,6 +25,7 @@ #include "rpc_server/dcerpc_server.h" #include "rpc_server/common/common.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" +#include "auth/auth.h" /* drsuapi_DsBind @@ -43,7 +44,7 @@ static WERROR drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem b_state = talloc(dce_call->conn, struct drsuapi_bind_state); WERR_TALLOC_CHECK(b_state); - b_state->sam_ctx = samdb_connect(b_state); + b_state->sam_ctx = samdb_connect(b_state, dce_call->conn->auth_state.session_info); if (!b_state->sam_ctx) { talloc_free(b_state); return WERR_FOOBAR; diff --git a/source4/rpc_server/drsuapi/drsuapi_cracknames.c b/source4/rpc_server/drsuapi/drsuapi_cracknames.c index 866faf49b9..fae84484ee 100644 --- a/source4/rpc_server/drsuapi/drsuapi_cracknames.c +++ b/source4/rpc_server/drsuapi/drsuapi_cracknames.c @@ -41,6 +41,11 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1); +static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, + uint32_t format_offered, uint32_t format_desired, + const struct ldb_dn *name_dn, const char *name, + struct drsuapi_DsNameInfo1 *info1); + static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, const char *alias_from, @@ -349,6 +354,14 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX WERR_TALLOC_CHECK(result_filter); break; } + case DRSUAPI_DS_NAME_FORMAT_DISPLAY: { + domain_filter = NULL; + + result_filter = talloc_asprintf(mem_ctx, "(|(displayName=%s)(samAccountName=%s))", + name, name); + WERR_TALLOC_CHECK(result_filter); + break; + } case DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY: { struct dom_sid *sid = dom_sid_parse_talloc(mem_ctx, name); @@ -424,6 +437,11 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX } } + + if (format_flags & DRSUAPI_DS_NAME_FLAG_SYNTACTICAL_ONLY) { + return DsCrackNameOneSyntactical(mem_ctx, format_offered, format_desired, + name_dn, name, info1); + } return DsCrackNameOneFilter(b_state, mem_ctx, smb_krb5_context, @@ -433,6 +451,32 @@ static WERROR DsCrackNameOneName(struct drsuapi_bind_state *b_state, TALLOC_CTX info1); } +static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, + uint32_t format_offered, uint32_t format_desired, + const struct ldb_dn *name_dn, const char *name, + struct drsuapi_DsNameInfo1 *info1) +{ + if (format_offered != DRSUAPI_DS_NAME_FORMAT_FQDN_1779) { + info1->status = DRSUAPI_DS_NAME_STATUS_NO_SYNTACTICAL_MAPPING; + return WERR_OK; + } + + switch (format_desired) { + case DRSUAPI_DS_NAME_FORMAT_CANONICAL: + break; + case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: + break; + default: + info1->status = DRSUAPI_DS_NAME_STATUS_NO_SYNTACTICAL_MAPPING; + return WERR_OK; + } + + + + return WERR_OK; + +} + static WERROR DsCrackNameOneFilter(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, @@ -616,6 +660,17 @@ static WERROR DsCrackNameOneFilter(struct drsuapi_bind_state *b_state, TALLOC_CT info1->status = DRSUAPI_DS_NAME_STATUS_OK; return WERR_OK; } + case DRSUAPI_DS_NAME_FORMAT_DISPLAY: { + info1->result_name = samdb_result_string(result_res[0], "displayName", NULL); + if (!info1->result_name) { + info1->result_name = samdb_result_string(result_res[0], "sAMAccountName", NULL); + } + if (!info1->result_name) { + info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; + } else { + info1->status = DRSUAPI_DS_NAME_STATUS_OK; + } + } default: return WERR_OK; } diff --git a/source4/rpc_server/dssetup/dcesrv_dssetup.c b/source4/rpc_server/dssetup/dcesrv_dssetup.c index fa219343c1..1d391f588f 100644 --- a/source4/rpc_server/dssetup/dcesrv_dssetup.c +++ b/source4/rpc_server/dssetup/dcesrv_dssetup.c @@ -25,8 +25,7 @@ #include "librpc/gen_ndr/ndr_samr.h" #include "librpc/gen_ndr/ndr_dssetup.h" #include "rpc_server/common/common.h" - - +#include "ldb/include/ldb.h" /* dssetup_DsRoleGetPrimaryDomainInformation */ @@ -82,13 +81,12 @@ static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state break; case ROLE_DOMAIN_BDC: case ROLE_DOMAIN_PDC: - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info); if (!sam_ctx) { return WERR_SERVER_UNAVAILABLE; } - ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, - "(&(objectClass=domainDNS)(!(objectClass=builtinDomain)))"); + ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &res, attrs); if (ret != 1) { return WERR_SERVER_UNAVAILABLE; } @@ -96,15 +94,18 @@ static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state flags = DS_ROLE_PRIMARY_DS_RUNNING; if (samdb_result_uint(res[0], "nTMixedDomain", 0) == 1) { - flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE; + flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE; } - - domain = samdb_result_string(res[0], "name", NULL); + + domain = samdb_search_string(sam_ctx, mem_ctx, NULL, "nETBIOSName", + "(&(objectclass=crossRef)(ncName=%s))", + ldb_dn_linearize(mem_ctx, samdb_base_dn(mem_ctx))); + dns_domain = samdb_result_string(res[0], "dnsDomain", NULL); forest = samdb_result_string(res[0], "dnsDomain", NULL); - flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT; domain_guid = samdb_result_guid(res[0], "objectGUID"); + flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT; break; } diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index ba28462d5e..e4b0e8c8ba 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -27,9 +27,9 @@ #include "rpc_server/dcerpc_server.h" #include "rpc_server/common/common.h" #include "lib/ldb/include/ldb.h" -#include "auth/auth.h" #include "system/time.h" #include "db_wrap.h" +#include "auth/auth.h" /* this type allows us to distinguish handle types @@ -220,9 +220,6 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ struct lsa_policy_state **_state) { struct lsa_policy_state *state; - const char *domain_attrs[] = {"nETBIOSName", "nCName", NULL}; - int ret_domain; - struct ldb_message **msgs_domain; state = talloc(mem_ctx, struct lsa_policy_state); if (!state) { @@ -230,7 +227,7 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ } /* make sure the sam database is accessible */ - state->sam_ldb = samdb_connect(state); + state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info); if (state->sam_ldb == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } @@ -247,16 +244,14 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ return NT_STATUS_NO_MEMORY; } - ret_domain = gendb_search(state->sam_ldb, mem_ctx, NULL, &msgs_domain, domain_attrs, - "(&(objectclass=crossRef)(ncName=%s))", ldb_dn_linearize(mem_ctx, state->domain_dn)); + state->domain_name + = samdb_search_string(state->sam_ldb, mem_ctx, NULL, "nETBIOSName", + "(&(objectclass=crossRef)(ncName=%s))", ldb_dn_linearize(mem_ctx, state->domain_dn)); - if (ret_domain == -1) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (ret_domain != 1) { + if (!state->domain_name) { return NT_STATUS_NO_SUCH_DOMAIN; } + talloc_steal(state, state->domain_name); /* work out the builtin_dn - useful for so many calls its worth fetching here */ @@ -273,23 +268,20 @@ static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ return NT_STATUS_NO_SUCH_DOMAIN; } - state->domain_sid = talloc_steal(state, - samdb_search_dom_sid(state->sam_ldb, state, - state->domain_dn, "objectSid", "dn=%s", - ldb_dn_linearize(mem_ctx, state->domain_dn))); + state->domain_sid = samdb_search_dom_sid(state->sam_ldb, state, + state->domain_dn, "objectSid", "dn=%s", + ldb_dn_linearize(mem_ctx, state->domain_dn)); if (!state->domain_sid) { return NT_STATUS_NO_SUCH_DOMAIN; } + talloc_steal(state, state->domain_sid); + state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN); if (!state->builtin_sid) { return NT_STATUS_NO_SUCH_DOMAIN; } - state->domain_name = talloc_strdup(state, - samdb_result_string(msgs_domain[0], "nETBIOSName", - lp_workgroup())); - *_state = state; return NT_STATUS_OK; @@ -2426,14 +2418,6 @@ static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX * return NT_STATUS_INVALID_PARAMETER; } - /* TODO: this check should go and we should rely on the calling code that this is valid */ - if (!dce_call->conn->auth_state.session_info || - !dce_call->conn->auth_state.session_info->server_info || - !dce_call->conn->auth_state.session_info->server_info->account_name || - !dce_call->conn->auth_state.session_info->server_info->domain_name) { - return NT_STATUS_INTERNAL_ERROR; - } - account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name); authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name); diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index cea645cd02..99701fc4f1 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -26,8 +26,8 @@ #include "rpc_server/dcerpc_server.h" #include "rpc_server/common/common.h" #include "librpc/gen_ndr/ndr_dcom.h" -#include "auth/auth.h" #include "lib/ldb/include/ldb.h" +#include "auth/auth.h" struct server_pipe_state { struct netr_Credential client_challenge; @@ -147,7 +147,7 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL return NT_STATUS_ACCESS_DENIED; } - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } @@ -159,7 +159,7 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL if (num_records == 0) { DEBUG(3,("Couldn't find user [%s] in samdb.\n", r->in.account_name)); - return NT_STATUS_NO_SUCH_USER; + return NT_STATUS_ACCESS_DENIED; } if (num_records > 1) { @@ -322,7 +322,7 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator); NT_STATUS_NOT_OK_RETURN(nt_status); - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } @@ -937,7 +937,7 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL return status; } - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info); if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } @@ -1034,7 +1034,7 @@ static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALL nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator); NT_STATUS_NOT_OK_RETURN(nt_status); - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } @@ -1167,7 +1167,7 @@ static WERROR netr_DrsGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CT ZERO_STRUCT(r->out); - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info); if (sam_ctx == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } @@ -1256,13 +1256,12 @@ static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, ZERO_STRUCT(r->out); - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info); if (sam_ctx == NULL) { return WERR_GENERAL_FAILURE; } - ret = gendb_search(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs, - "(&(objectClass=domainDNS)(dnsDomain=%s))", lp_realm()); + ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &dom_res, dom_attrs); if (ret == -1) { return WERR_GENERAL_FAILURE; } diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 249fb1c8a4..c985187cd9 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -60,12 +60,13 @@ static NTSTATUS samr_Connect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem } /* make sure the sam database is accessible */ - c_state->sam_ctx = samdb_connect(c_state); + c_state->sam_ctx = samdb_connect(c_state, dce_call->conn->auth_state.session_info); if (c_state->sam_ctx == NULL) { talloc_free(c_state); return NT_STATUS_INVALID_SYSTEM_SERVICE; } + handle = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_CONNECT); if (!handle) { talloc_free(c_state); @@ -3305,7 +3306,7 @@ static NTSTATUS samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX ZERO_STRUCT(r->out.info); - sam_ctx = samdb_connect(mem_ctx); + sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info); if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index ab99b69458..6fab231619 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -38,6 +38,7 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX { struct dcesrv_handle *h; struct samr_account_state *a_state; + struct ldb_context *sam_ctx; struct ldb_message **res, *msg; int ret; struct samr_Password new_lmPwdHash, new_ntPwdHash, checkHash; @@ -49,8 +50,14 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX a_state = h->data; + /* To change a password we need to open as system */ + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); + if (sam_ctx == NULL) { + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + /* fetch the old hashes */ - ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, + ret = gendb_search_dn(sam_ctx, mem_ctx, a_state->account_dn, &res, attrs); if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -113,7 +120,7 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX return NT_STATUS_NO_MEMORY; } - status = samdb_set_password(a_state->sam_ctx, mem_ctx, + status = samdb_set_password(sam_ctx, mem_ctx, a_state->account_dn, a_state->domain_state->domain_dn, msg, NULL, &new_lmPwdHash, &new_ntPwdHash, True, /* this is a user password change */ @@ -124,7 +131,7 @@ NTSTATUS samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, TALLOC_CTX } /* modify the samdb record */ - ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg); + ret = samdb_replace(sam_ctx, mem_ctx, msg); if (ret != 0) { return NT_STATUS_UNSUCCESSFUL; } @@ -142,7 +149,7 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_ char new_pass[512]; uint32_t new_pass_len; struct samr_CryptPassword *pwbuf = r->in.password; - void *sam_ctx; + struct ldb_context *sam_ctx; const struct ldb_dn *user_dn, *domain_dn; int ret; struct ldb_message **res, *mod; @@ -157,9 +164,8 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_ return NT_STATUS_WRONG_PASSWORD; } - /* this call doesn't take a policy handle, so we need to open - the sam db from scratch */ - sam_ctx = samdb_connect(mem_ctx); + /* To change a password we need to open as system */ + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); if (sam_ctx == NULL) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } @@ -260,7 +266,7 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, NTSTATUS status; char new_pass[512]; uint32_t new_pass_len; - void *sam_ctx = NULL; + struct ldb_context *sam_ctx; const struct ldb_dn *user_dn, *domain_dn = NULL; int ret; struct ldb_message **res, *mod; @@ -285,11 +291,10 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, goto failed; } - /* this call doesn't take a policy handle, so we need to open - the sam db from scratch */ - sam_ctx = samdb_connect(mem_ctx); + /* To change a password we need to open as system */ + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); if (sam_ctx == NULL) { - status = NT_STATUS_INVALID_SYSTEM_SERVICE; + return NT_STATUS_INVALID_SYSTEM_SERVICE; goto failed; } -- cgit