summaryrefslogtreecommitdiff
path: root/libcli
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2017-09-13 09:40:57 -0700
committerVolker Lendecke <vl@samba.org>2017-09-25 09:43:12 +0200
commitf6e39450f539e2014854debb485023e46a8f16d2 (patch)
treea0ee2b410c952b7422229e486079fb78775e945a /libcli
parentd61545a5b3531ecf22fa310a66ba85ae8165cadf (diff)
downloadsamba-f6e39450f539e2014854debb485023e46a8f16d2.tar.gz
netlogon_creds_cli: Protect netlogon_creds_cli_check by _lck
netlogon_creds_cli_lck provides the locking around the operation Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'libcli')
-rw-r--r--libcli/auth/netlogon_creds_cli.c101
1 files changed, 38 insertions, 63 deletions
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c
index 248fb371fed..081b18efb0e 100644
--- a/libcli/auth/netlogon_creds_cli.c
+++ b/libcli/auth/netlogon_creds_cli.c
@@ -1525,14 +1525,13 @@ struct netlogon_creds_cli_check_state {
union netr_Capabilities caps;
struct netlogon_creds_CredentialState *creds;
- struct netlogon_creds_CredentialState tmp_creds;
struct netr_Authenticator req_auth;
struct netr_Authenticator rep_auth;
};
static void netlogon_creds_cli_check_cleanup(struct tevent_req *req,
NTSTATUS status);
-static void netlogon_creds_cli_check_locked(struct tevent_req *subreq);
+static void netlogon_creds_cli_check_caps(struct tevent_req *subreq);
struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -1544,6 +1543,7 @@ struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx,
struct tevent_req *subreq;
enum dcerpc_AuthType auth_type;
enum dcerpc_AuthLevel auth_level;
+ NTSTATUS status;
req = tevent_req_create(mem_ctx, &state,
struct netlogon_creds_cli_check_state);
@@ -1555,6 +1555,17 @@ struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx,
state->context = context;
state->binding_handle = b;
+ if (context->db.lock != NETLOGON_CREDS_CLI_LCK_EXCLUSIVE) {
+ tevent_req_nterror(req, NT_STATUS_NOT_LOCKED);
+ return tevent_req_post(req, ev);
+ }
+
+ status = netlogon_creds_cli_get_internal(context, state,
+ &state->creds);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
state->srv_name_slash = talloc_asprintf(state, "\\\\%s",
context->server.computer);
if (tevent_req_nomem(state->srv_name_slash, req)) {
@@ -1578,14 +1589,29 @@ struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- subreq = netlogon_creds_cli_lock_send(state, state->ev,
- state->context);
+ /*
+ * we defer all callbacks in order to cleanup
+ * the database record.
+ */
+ tevent_req_defer_callback(req, state->ev);
+
+ netlogon_creds_client_authenticator(state->creds, &state->req_auth);
+ ZERO_STRUCT(state->rep_auth);
+
+ subreq = dcerpc_netr_LogonGetCapabilities_send(state, state->ev,
+ state->binding_handle,
+ state->srv_name_slash,
+ state->context->client.computer,
+ &state->req_auth,
+ &state->rep_auth,
+ 1,
+ &state->caps);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq,
- netlogon_creds_cli_check_locked,
+ netlogon_creds_cli_check_caps,
req);
return req;
@@ -1611,58 +1637,10 @@ static void netlogon_creds_cli_check_cleanup(struct tevent_req *req,
return;
}
- netlogon_creds_cli_delete(state->context, state->creds);
+ netlogon_creds_cli_delete_lck(state->context);
TALLOC_FREE(state->creds);
}
-static void netlogon_creds_cli_check_caps(struct tevent_req *subreq);
-
-static void netlogon_creds_cli_check_locked(struct tevent_req *subreq)
-{
- struct tevent_req *req =
- tevent_req_callback_data(subreq,
- struct tevent_req);
- struct netlogon_creds_cli_check_state *state =
- tevent_req_data(req,
- struct netlogon_creds_cli_check_state);
- NTSTATUS status;
-
- status = netlogon_creds_cli_lock_recv(subreq, state,
- &state->creds);
- TALLOC_FREE(subreq);
- if (tevent_req_nterror(req, status)) {
- return;
- }
-
- /*
- * we defer all callbacks in order to cleanup
- * the database record.
- */
- tevent_req_defer_callback(req, state->ev);
-
- state->tmp_creds = *state->creds;
- netlogon_creds_client_authenticator(&state->tmp_creds,
- &state->req_auth);
- ZERO_STRUCT(state->rep_auth);
-
- subreq = dcerpc_netr_LogonGetCapabilities_send(state, state->ev,
- state->binding_handle,
- state->srv_name_slash,
- state->context->client.computer,
- &state->req_auth,
- &state->rep_auth,
- 1,
- &state->caps);
- if (tevent_req_nomem(subreq, req)) {
- status = NT_STATUS_NO_MEMORY;
- netlogon_creds_cli_check_cleanup(req, status);
- return;
- }
- tevent_req_set_callback(subreq,
- netlogon_creds_cli_check_caps,
- req);
-}
-
static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
{
struct tevent_req *req =
@@ -1683,7 +1661,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
* Note that the negotiated flags are already checked
* for our required flags after the ServerAuthenticate3/2 call.
*/
- uint32_t negotiated = state->tmp_creds.negotiate_flags;
+ uint32_t negotiated = state->creds->negotiate_flags;
if (negotiated & NETLOGON_NEG_SUPPORTS_AES) {
/*
@@ -1738,7 +1716,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
* Note that the negotiated flags are already checked
* for our required flags after the ServerAuthenticate3/2 call.
*/
- uint32_t negotiated = state->tmp_creds.negotiate_flags;
+ uint32_t negotiated = state->creds->negotiate_flags;
if (negotiated & NETLOGON_NEG_SUPPORTS_AES) {
/*
@@ -1764,8 +1742,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
return;
}
- ok = netlogon_creds_client_check(&state->tmp_creds,
- &state->rep_auth.cred);
+ ok = netlogon_creds_client_check(state->creds, &state->rep_auth.cred);
if (!ok) {
status = NT_STATUS_ACCESS_DENIED;
tevent_req_nterror(req, status);
@@ -1778,7 +1755,7 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
return;
}
- if (state->caps.server_capabilities != state->tmp_creds.negotiate_flags) {
+ if (state->caps.server_capabilities != state->creds->negotiate_flags) {
status = NT_STATUS_DOWNGRADE_DETECTED;
tevent_req_nterror(req, status);
netlogon_creds_cli_check_cleanup(req, status);
@@ -1800,10 +1777,8 @@ static void netlogon_creds_cli_check_caps(struct tevent_req *subreq)
return;
}
- *state->creds = state->tmp_creds;
- status = netlogon_creds_cli_store(state->context,
- state->creds);
- TALLOC_FREE(state->creds);
+ status = netlogon_creds_cli_store_internal(state->context,
+ state->creds);
if (tevent_req_nterror(req, status)) {
return;
}