1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

s3:winbind: Convert WINBINDD_CHECK_MACHACC to the new API

This commit is contained in:
Volker Lendecke 2009-09-06 09:32:34 +02:00
parent 99f8dcab0c
commit d9b7fd59b0
15 changed files with 451 additions and 76 deletions

View File

@ -1213,6 +1213,7 @@ WINBINDD_OBJ1 = \
winbindd/winbindd_getdcname.o \
winbindd/winbindd_list_users.o \
winbindd/winbindd_list_groups.o \
winbindd/winbindd_check_machine_acct.o \
auth/token_util.o \
../nsswitch/libwbclient/wb_reqtrans.o \
smbd/connection.o

View File

@ -2929,3 +2929,149 @@ NTSTATUS rpccli_wbint_LookupRids(struct rpc_pipe_client *cli,
return r.out.result;
}
struct rpccli_wbint_CheckMachineAccount_state {
struct wbint_CheckMachineAccount orig;
struct wbint_CheckMachineAccount tmp;
TALLOC_CTX *out_mem_ctx;
NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
};
static void rpccli_wbint_CheckMachineAccount_done(struct tevent_req *subreq);
struct tevent_req *rpccli_wbint_CheckMachineAccount_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct rpc_pipe_client *cli)
{
struct tevent_req *req;
struct rpccli_wbint_CheckMachineAccount_state *state;
struct tevent_req *subreq;
req = tevent_req_create(mem_ctx, &state,
struct rpccli_wbint_CheckMachineAccount_state);
if (req == NULL) {
return NULL;
}
state->out_mem_ctx = NULL;
state->dispatch_recv = cli->dispatch_recv;
/* In parameters */
/* Out parameters */
/* Result */
ZERO_STRUCT(state->orig.out.result);
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(wbint_CheckMachineAccount, &state->orig);
}
/* make a temporary copy, that we pass to the dispatch function */
state->tmp = state->orig;
subreq = cli->dispatch_send(state, ev, cli,
&ndr_table_wbint,
NDR_WBINT_CHECKMACHINEACCOUNT,
&state->tmp);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, rpccli_wbint_CheckMachineAccount_done, req);
return req;
}
static void rpccli_wbint_CheckMachineAccount_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct rpccli_wbint_CheckMachineAccount_state *state = tevent_req_data(
req, struct rpccli_wbint_CheckMachineAccount_state);
NTSTATUS status;
TALLOC_CTX *mem_ctx;
if (state->out_mem_ctx) {
mem_ctx = state->out_mem_ctx;
} else {
mem_ctx = state;
}
status = state->dispatch_recv(subreq, mem_ctx);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
/* Copy out parameters */
/* Copy result */
state->orig.out.result = state->tmp.out.result;
/* Reset temporary structure */
ZERO_STRUCT(state->tmp);
if (DEBUGLEVEL >= 10) {
NDR_PRINT_OUT_DEBUG(wbint_CheckMachineAccount, &state->orig);
}
tevent_req_done(req);
}
NTSTATUS rpccli_wbint_CheckMachineAccount_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
NTSTATUS *result)
{
struct rpccli_wbint_CheckMachineAccount_state *state = tevent_req_data(
req, struct rpccli_wbint_CheckMachineAccount_state);
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
tevent_req_received(req);
return status;
}
/* Steal possbile out parameters to the callers context */
talloc_steal(mem_ctx, state->out_mem_ctx);
/* Return result */
*result = state->orig.out.result;
tevent_req_received(req);
return NT_STATUS_OK;
}
NTSTATUS rpccli_wbint_CheckMachineAccount(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx)
{
struct wbint_CheckMachineAccount r;
NTSTATUS status;
/* In parameters */
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(wbint_CheckMachineAccount, &r);
}
status = cli->dispatch(cli,
mem_ctx,
&ndr_table_wbint,
NDR_WBINT_CHECKMACHINEACCOUNT,
&r);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_OUT_DEBUG(wbint_CheckMachineAccount, &r);
}
if (NT_STATUS_IS_ERR(status)) {
return status;
}
/* Return variables */
/* Return result */
return r.out.result;
}

View File

@ -232,4 +232,12 @@ NTSTATUS rpccli_wbint_LookupRids(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct wbint_RidArray *rids /* [in] [ref] */,
struct wbint_Principals *names /* [out] [ref] */);
struct tevent_req *rpccli_wbint_CheckMachineAccount_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct rpc_pipe_client *cli);
NTSTATUS rpccli_wbint_CheckMachineAccount_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
NTSTATUS *result);
NTSTATUS rpccli_wbint_CheckMachineAccount(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
#endif /* __CLI_WBINT__ */

View File

@ -2111,6 +2111,47 @@ _PUBLIC_ void ndr_print_wbint_LookupRids(struct ndr_print *ndr, const char *name
ndr->depth--;
}
static enum ndr_err_code ndr_push_wbint_CheckMachineAccount(struct ndr_push *ndr, int flags, const struct wbint_CheckMachineAccount *r)
{
if (flags & NDR_IN) {
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
}
static enum ndr_err_code ndr_pull_wbint_CheckMachineAccount(struct ndr_pull *ndr, int flags, struct wbint_CheckMachineAccount *r)
{
if (flags & NDR_IN) {
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
}
_PUBLIC_ void ndr_print_wbint_CheckMachineAccount(struct ndr_print *ndr, const char *name, int flags, const struct wbint_CheckMachineAccount *r)
{
ndr_print_struct(ndr, name, "wbint_CheckMachineAccount");
ndr->depth++;
if (flags & NDR_SET_VALUES) {
ndr->flags |= LIBNDR_PRINT_SET_VALUES;
}
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "wbint_CheckMachineAccount");
ndr->depth++;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "wbint_CheckMachineAccount");
ndr->depth++;
ndr_print_NTSTATUS(ndr, "result", r->out.result);
ndr->depth--;
}
ndr->depth--;
}
static const struct ndr_interface_call wbint_calls[] = {
{
"wbint_Ping",
@ -2256,6 +2297,14 @@ static const struct ndr_interface_call wbint_calls[] = {
(ndr_print_function_t) ndr_print_wbint_LookupRids,
false,
},
{
"wbint_CheckMachineAccount",
sizeof(struct wbint_CheckMachineAccount),
(ndr_push_flags_fn_t) ndr_push_wbint_CheckMachineAccount,
(ndr_pull_flags_fn_t) ndr_pull_wbint_CheckMachineAccount,
(ndr_print_function_t) ndr_print_wbint_CheckMachineAccount,
false,
},
{ NULL, 0, NULL, NULL, NULL, false }
};
@ -2285,7 +2334,7 @@ const struct ndr_interface_table ndr_table_wbint = {
NDR_WBINT_VERSION
},
.helpstring = NDR_WBINT_HELPSTRING,
.num_calls = 18,
.num_calls = 19,
.calls = wbint_calls,
.endpoints = &wbint_endpoints,
.authservices = &wbint_authservices

View File

@ -47,7 +47,9 @@ extern const struct ndr_interface_table ndr_table_wbint;
#define NDR_WBINT_LOOKUPRIDS (0x11)
#define NDR_WBINT_CALL_COUNT (18)
#define NDR_WBINT_CHECKMACHINEACCOUNT (0x12)
#define NDR_WBINT_CALL_COUNT (19)
enum ndr_err_code ndr_push_wbint_userinfo(struct ndr_push *ndr, int ndr_flags, const struct wbint_userinfo *r);
enum ndr_err_code ndr_pull_wbint_userinfo(struct ndr_pull *ndr, int ndr_flags, struct wbint_userinfo *r);
void ndr_print_wbint_userinfo(struct ndr_print *ndr, const char *name, const struct wbint_userinfo *r);
@ -84,4 +86,5 @@ void ndr_print_wbint_QueryUserList(struct ndr_print *ndr, const char *name, int
void ndr_print_wbint_QueryGroupList(struct ndr_print *ndr, const char *name, int flags, const struct wbint_QueryGroupList *r);
void ndr_print_wbint_DsGetDcName(struct ndr_print *ndr, const char *name, int flags, const struct wbint_DsGetDcName *r);
void ndr_print_wbint_LookupRids(struct ndr_print *ndr, const char *name, int flags, const struct wbint_LookupRids *r);
void ndr_print_wbint_CheckMachineAccount(struct ndr_print *ndr, const char *name, int flags, const struct wbint_CheckMachineAccount *r);
#endif /* _HEADER_NDR_wbint */

View File

@ -1464,9 +1464,82 @@ static bool api_wbint_LookupRids(pipes_struct *p)
return true;
}
static bool api_wbint_CheckMachineAccount(pipes_struct *p)
{
const struct ndr_interface_call *call;
struct ndr_pull *pull;
struct ndr_push *push;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
struct wbint_CheckMachineAccount *r;
call = &ndr_table_wbint.calls[NDR_WBINT_CHECKMACHINEACCOUNT];
r = talloc(talloc_tos(), struct wbint_CheckMachineAccount);
if (r == NULL) {
return false;
}
if (!prs_data_blob(&p->in_data.data, &blob, r)) {
talloc_free(r);
return false;
}
pull = ndr_pull_init_blob(&blob, r, NULL);
if (pull == NULL) {
talloc_free(r);
return false;
}
pull->flags |= LIBNDR_FLAG_REF_ALLOC;
ndr_err = call->ndr_pull(pull, NDR_IN, r);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(r);
return false;
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(wbint_CheckMachineAccount, r);
}
r->out.result = _wbint_CheckMachineAccount(p, r);
if (p->rng_fault_state) {
talloc_free(r);
/* Return true here, srv_pipe_hnd.c will take care */
return true;
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_OUT_DEBUG(wbint_CheckMachineAccount, r);
}
push = ndr_push_init_ctx(r, NULL);
if (push == NULL) {
talloc_free(r);
return false;
}
ndr_err = call->ndr_push(push, NDR_OUT, r);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(r);
return false;
}
blob = ndr_push_blob(push);
if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) {
talloc_free(r);
return false;
}
talloc_free(r);
return true;
}
/* Tables */
static struct api_struct api_wbint_cmds[] =
static struct api_struct api_wbint_cmds[] =
{
{"WBINT_PING", NDR_WBINT_PING, api_wbint_Ping},
{"WBINT_LOOKUPSID", NDR_WBINT_LOOKUPSID, api_wbint_LookupSid},
@ -1486,6 +1559,7 @@ static struct api_struct api_wbint_cmds[] =
{"WBINT_QUERYGROUPLIST", NDR_WBINT_QUERYGROUPLIST, api_wbint_QueryGroupList},
{"WBINT_DSGETDCNAME", NDR_WBINT_DSGETDCNAME, api_wbint_DsGetDcName},
{"WBINT_LOOKUPRIDS", NDR_WBINT_LOOKUPRIDS, api_wbint_LookupRids},
{"WBINT_CHECKMACHINEACCOUNT", NDR_WBINT_CHECKMACHINEACCOUNT, api_wbint_CheckMachineAccount},
};
void wbint_get_pipe_fns(struct api_struct **fns, int *n_fns)
@ -1733,6 +1807,12 @@ NTSTATUS rpc_wbint_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, co
return NT_STATUS_OK;
}
case NDR_WBINT_CHECKMACHINEACCOUNT: {
struct wbint_CheckMachineAccount *r = (struct wbint_CheckMachineAccount *)_r;
r->out.result = _wbint_CheckMachineAccount(cli->pipes_struct, r);
return NT_STATUS_OK;
}
default:
return NT_STATUS_NOT_IMPLEMENTED;
}

View File

@ -19,6 +19,7 @@ NTSTATUS _wbint_QueryUserList(pipes_struct *p, struct wbint_QueryUserList *r);
NTSTATUS _wbint_QueryGroupList(pipes_struct *p, struct wbint_QueryGroupList *r);
NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r);
NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r);
NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p, struct wbint_CheckMachineAccount *r);
void wbint_get_pipe_fns(struct api_struct **fns, int *n_fns);
NTSTATUS rpc_wbint_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r);
void _wbint_Ping(pipes_struct *p, struct wbint_Ping *r);
@ -39,5 +40,6 @@ NTSTATUS _wbint_QueryUserList(pipes_struct *p, struct wbint_QueryUserList *r);
NTSTATUS _wbint_QueryGroupList(pipes_struct *p, struct wbint_QueryGroupList *r);
NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r);
NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r);
NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p, struct wbint_CheckMachineAccount *r);
NTSTATUS rpc_wbint_init(void);
#endif /* __SRV_WBINT__ */

View File

@ -270,4 +270,12 @@ struct wbint_LookupRids {
};
struct wbint_CheckMachineAccount {
struct {
NTSTATUS result;
} out;
};
#endif /* _HEADER_wbint */

View File

@ -143,4 +143,7 @@ interface wbint
[in] wbint_RidArray *rids,
[out] wbint_Principals *names
);
NTSTATUS wbint_CheckMachineAccount(
);
}

View File

@ -446,7 +446,6 @@ static struct winbindd_dispatch_table {
/* Miscellaneous */
{ WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct, "CHECK_MACHACC" },
{ WINBINDD_INFO, winbindd_info, "INFO" },
{ WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
"INTERFACE_VERSION" },
@ -537,6 +536,8 @@ static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
winbindd_list_users_send, winbindd_list_users_recv },
{ WINBINDD_LIST_GROUPS, "LIST_GROUPS",
winbindd_list_groups_send, winbindd_list_groups_recv },
{ WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
{ 0, NULL, NULL, NULL }
};

View File

@ -0,0 +1,88 @@
/*
Unix SMB/CIFS implementation.
async implementation of WINBINDD_CHECK_MACHINE_ACCT
Copyright (C) Volker Lendecke 2009
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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "winbindd.h"
#include "librpc/gen_ndr/cli_wbint.h"
struct winbindd_check_machine_acct_state {
uint8_t dummy;
};
static void winbindd_check_machine_acct_done(struct tevent_req *subreq);
struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct winbindd_cli_state *cli,
struct winbindd_request *request)
{
struct tevent_req *req, *subreq;
struct winbindd_check_machine_acct_state *state;
struct winbindd_domain *domain;
req = tevent_req_create(mem_ctx, &state,
struct winbindd_check_machine_acct_state);
if (req == NULL) {
return NULL;
}
domain = find_our_domain();
if (domain->internal) {
/*
* Internal domains are passdb based, we can always
* contact them.
*/
tevent_req_done(req);
return tevent_req_post(req, ev);
}
subreq = rpccli_wbint_CheckMachineAccount_send(state, ev,
domain->child.rpccli);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, winbindd_check_machine_acct_done, req);
return req;
}
static void winbindd_check_machine_acct_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct winbindd_check_machine_acct_state *state = tevent_req_data(
req, struct winbindd_check_machine_acct_state);
NTSTATUS status, result;
status = rpccli_wbint_CheckMachineAccount_recv(subreq, state, &result);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
if (!NT_STATUS_IS_OK(result)) {
tevent_req_nterror(req, result);
return;
}
tevent_req_done(req);
}
NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req,
struct winbindd_response *presp)
{
return tevent_req_simple_recv_ntstatus(req);
}

View File

@ -74,10 +74,6 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
.name = "PAM_CHAUTHTOK",
.struct_cmd = WINBINDD_PAM_CHAUTHTOK,
.struct_fn = winbindd_dual_pam_chauthtok,
},{
.name = "CHECK_MACHACC",
.struct_cmd = WINBINDD_CHECK_MACHACC,
.struct_fn = winbindd_dual_check_machine_acct,
},{
.name = "DUAL_USERINFO",
.struct_cmd = WINBINDD_DUAL_USERINFO,

View File

@ -395,3 +395,55 @@ NTSTATUS _wbint_LookupRids(pipes_struct *p, struct wbint_LookupRids *r)
r->out.names->principals = result;
return NT_STATUS_OK;
}
NTSTATUS _wbint_CheckMachineAccount(pipes_struct *p,
struct wbint_CheckMachineAccount *r)
{
struct winbindd_domain *domain;
int num_retries = 0;
NTSTATUS status;
again:
domain = wb_child_domain();
if (domain == NULL) {
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
invalidate_cm_connection(&domain->conn);
{
struct rpc_pipe_client *netlogon_pipe;
status = cm_connect_netlogon(domain, &netlogon_pipe);
}
/* There is a race condition between fetching the trust account
password and the periodic machine password change. So it's
possible that the trust account password has been changed on us.
We are returned NT_STATUS_ACCESS_DENIED if this happens. */
#define MAX_RETRIES 3
if ((num_retries < MAX_RETRIES)
&& NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
num_retries++;
goto again;
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
goto done;
}
/* Pass back result code - zero for success, other values for
specific failures. */
DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(status) ?
"good" : "bad"));
done:
DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
("Checking the trust account password returned %s\n",
nt_errstr(status)));
return status;
}

View File

@ -26,74 +26,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
/* Check the machine account password is valid */
void winbindd_check_machine_acct(struct winbindd_cli_state *state)
{
DEBUG(3, ("[%5lu]: check machine account\n",
(unsigned long)state->pid));
sendto_domain(state, find_our_domain());
}
enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
int num_retries = 0;
struct winbindd_domain *contact_domain;
DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
/* Get trust account password */
again:
contact_domain = find_our_domain();
/* This call does a cli_nt_setup_creds() which implicitly checks
the trust account password. */
invalidate_cm_connection(&contact_domain->conn);
{
struct rpc_pipe_client *netlogon_pipe;
result = cm_connect_netlogon(contact_domain, &netlogon_pipe);
}
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
goto done;
}
/* There is a race condition between fetching the trust account
password and the periodic machine password change. So it's
possible that the trust account password has been changed on us.
We are returned NT_STATUS_ACCESS_DENIED if this happens. */
#define MAX_RETRIES 8
if ((num_retries < MAX_RETRIES) &&
NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
num_retries++;
goto again;
}
/* Pass back result code - zero for success, other values for
specific failures. */
DEBUG(3, ("secret is %s\n", NT_STATUS_IS_OK(result) ?
"good" : "bad"));
done:
set_auth_errors(state->response, result);
DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n",
state->response->data.auth.nt_status_string));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
/* Constants and helper functions for determining domain trust types */
enum trust_type {

View File

@ -962,5 +962,11 @@ struct tevent_req *winbindd_list_groups_send(TALLOC_CTX *mem_ctx,
NTSTATUS winbindd_list_groups_recv(struct tevent_req *req,
struct winbindd_response *response);
struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct winbindd_cli_state *cli,
struct winbindd_request *request);
NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req,
struct winbindd_response *presp);
#endif /* _WINBINDD_PROTO_H_ */