1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

s3-winbindd: add wbint_ChangeMachineAccount implementation.

Guenther
This commit is contained in:
Günther Deschner 2009-10-06 18:26:33 +02:00
parent 0c37c23869
commit a3306e352d
14 changed files with 471 additions and 6 deletions

View File

@ -1221,6 +1221,7 @@ WINBINDD_OBJ1 = \
winbindd/winbindd_list_users.o \
winbindd/winbindd_list_groups.o \
winbindd/winbindd_check_machine_acct.o \
winbindd/winbindd_change_machine_acct.o \
winbindd/winbindd_set_mapping.o \
winbindd/winbindd_remove_mapping.o \
winbindd/winbindd_set_hwm.o \

View File

@ -3075,6 +3075,152 @@ NTSTATUS rpccli_wbint_CheckMachineAccount(struct rpc_pipe_client *cli,
return r.out.result;
}
struct rpccli_wbint_ChangeMachineAccount_state {
struct wbint_ChangeMachineAccount orig;
struct wbint_ChangeMachineAccount tmp;
TALLOC_CTX *out_mem_ctx;
NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
};
static void rpccli_wbint_ChangeMachineAccount_done(struct tevent_req *subreq);
struct tevent_req *rpccli_wbint_ChangeMachineAccount_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct rpc_pipe_client *cli)
{
struct tevent_req *req;
struct rpccli_wbint_ChangeMachineAccount_state *state;
struct tevent_req *subreq;
req = tevent_req_create(mem_ctx, &state,
struct rpccli_wbint_ChangeMachineAccount_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_ChangeMachineAccount, &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_CHANGEMACHINEACCOUNT,
&state->tmp);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, rpccli_wbint_ChangeMachineAccount_done, req);
return req;
}
static void rpccli_wbint_ChangeMachineAccount_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct rpccli_wbint_ChangeMachineAccount_state *state = tevent_req_data(
req, struct rpccli_wbint_ChangeMachineAccount_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_ChangeMachineAccount, &state->orig);
}
tevent_req_done(req);
}
NTSTATUS rpccli_wbint_ChangeMachineAccount_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
NTSTATUS *result)
{
struct rpccli_wbint_ChangeMachineAccount_state *state = tevent_req_data(
req, struct rpccli_wbint_ChangeMachineAccount_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_ChangeMachineAccount(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx)
{
struct wbint_ChangeMachineAccount r;
NTSTATUS status;
/* In parameters */
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(wbint_ChangeMachineAccount, &r);
}
status = cli->dispatch(cli,
mem_ctx,
&ndr_table_wbint,
NDR_WBINT_CHANGEMACHINEACCOUNT,
&r);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_OUT_DEBUG(wbint_ChangeMachineAccount, &r);
}
if (NT_STATUS_IS_ERR(status)) {
return status;
}
/* Return variables */
/* Return result */
return r.out.result;
}
struct rpccli_wbint_SetMapping_state {
struct wbint_SetMapping orig;
struct wbint_SetMapping tmp;

View File

@ -240,6 +240,14 @@ NTSTATUS rpccli_wbint_CheckMachineAccount_recv(struct tevent_req *req,
NTSTATUS *result);
NTSTATUS rpccli_wbint_CheckMachineAccount(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
struct tevent_req *rpccli_wbint_ChangeMachineAccount_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct rpc_pipe_client *cli);
NTSTATUS rpccli_wbint_ChangeMachineAccount_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
NTSTATUS *result);
NTSTATUS rpccli_wbint_ChangeMachineAccount(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
struct tevent_req *rpccli_wbint_SetMapping_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct rpc_pipe_client *cli,

View File

@ -2190,6 +2190,47 @@ _PUBLIC_ void ndr_print_wbint_CheckMachineAccount(struct ndr_print *ndr, const c
ndr->depth--;
}
static enum ndr_err_code ndr_push_wbint_ChangeMachineAccount(struct ndr_push *ndr, int flags, const struct wbint_ChangeMachineAccount *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_ChangeMachineAccount(struct ndr_pull *ndr, int flags, struct wbint_ChangeMachineAccount *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_ChangeMachineAccount(struct ndr_print *ndr, const char *name, int flags, const struct wbint_ChangeMachineAccount *r)
{
ndr_print_struct(ndr, name, "wbint_ChangeMachineAccount");
ndr->depth++;
if (flags & NDR_SET_VALUES) {
ndr->flags |= LIBNDR_PRINT_SET_VALUES;
}
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "wbint_ChangeMachineAccount");
ndr->depth++;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "wbint_ChangeMachineAccount");
ndr->depth++;
ndr_print_NTSTATUS(ndr, "result", r->out.result);
ndr->depth--;
}
ndr->depth--;
}
static enum ndr_err_code ndr_push_wbint_SetMapping(struct ndr_push *ndr, int flags, const struct wbint_SetMapping *r)
{
if (flags & NDR_IN) {
@ -2516,6 +2557,14 @@ static const struct ndr_interface_call wbint_calls[] = {
(ndr_print_function_t) ndr_print_wbint_CheckMachineAccount,
false,
},
{
"wbint_ChangeMachineAccount",
sizeof(struct wbint_ChangeMachineAccount),
(ndr_push_flags_fn_t) ndr_push_wbint_ChangeMachineAccount,
(ndr_pull_flags_fn_t) ndr_pull_wbint_ChangeMachineAccount,
(ndr_print_function_t) ndr_print_wbint_ChangeMachineAccount,
false,
},
{
"wbint_SetMapping",
sizeof(struct wbint_SetMapping),
@ -2569,7 +2618,7 @@ const struct ndr_interface_table ndr_table_wbint = {
NDR_WBINT_VERSION
},
.helpstring = NDR_WBINT_HELPSTRING,
.num_calls = 22,
.num_calls = 23,
.calls = wbint_calls,
.endpoints = &wbint_endpoints,
.authservices = &wbint_authservices

View File

@ -49,13 +49,15 @@ extern const struct ndr_interface_table ndr_table_wbint;
#define NDR_WBINT_CHECKMACHINEACCOUNT (0x12)
#define NDR_WBINT_SETMAPPING (0x13)
#define NDR_WBINT_CHANGEMACHINEACCOUNT (0x13)
#define NDR_WBINT_REMOVEMAPPING (0x14)
#define NDR_WBINT_SETMAPPING (0x14)
#define NDR_WBINT_SETHWM (0x15)
#define NDR_WBINT_REMOVEMAPPING (0x15)
#define NDR_WBINT_CALL_COUNT (22)
#define NDR_WBINT_SETHWM (0x16)
#define NDR_WBINT_CALL_COUNT (23)
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);
@ -96,6 +98,7 @@ void ndr_print_wbint_QueryGroupList(struct ndr_print *ndr, const char *name, int
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);
void ndr_print_wbint_ChangeMachineAccount(struct ndr_print *ndr, const char *name, int flags, const struct wbint_ChangeMachineAccount *r);
void ndr_print_wbint_SetMapping(struct ndr_print *ndr, const char *name, int flags, const struct wbint_SetMapping *r);
void ndr_print_wbint_RemoveMapping(struct ndr_print *ndr, const char *name, int flags, const struct wbint_RemoveMapping *r);
void ndr_print_wbint_SetHWM(struct ndr_print *ndr, const char *name, int flags, const struct wbint_SetHWM *r);

View File

@ -1537,6 +1537,79 @@ static bool api_wbint_CheckMachineAccount(pipes_struct *p)
return true;
}
static bool api_wbint_ChangeMachineAccount(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_ChangeMachineAccount *r;
call = &ndr_table_wbint.calls[NDR_WBINT_CHANGEMACHINEACCOUNT];
r = talloc(talloc_tos(), struct wbint_ChangeMachineAccount);
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_ChangeMachineAccount, r);
}
r->out.result = _wbint_ChangeMachineAccount(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_ChangeMachineAccount, 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;
}
static bool api_wbint_SetMapping(pipes_struct *p)
{
const struct ndr_interface_call *call;
@ -1779,6 +1852,7 @@ static struct api_struct api_wbint_cmds[] =
{"WBINT_DSGETDCNAME", NDR_WBINT_DSGETDCNAME, api_wbint_DsGetDcName},
{"WBINT_LOOKUPRIDS", NDR_WBINT_LOOKUPRIDS, api_wbint_LookupRids},
{"WBINT_CHECKMACHINEACCOUNT", NDR_WBINT_CHECKMACHINEACCOUNT, api_wbint_CheckMachineAccount},
{"WBINT_CHANGEMACHINEACCOUNT", NDR_WBINT_CHANGEMACHINEACCOUNT, api_wbint_ChangeMachineAccount},
{"WBINT_SETMAPPING", NDR_WBINT_SETMAPPING, api_wbint_SetMapping},
{"WBINT_REMOVEMAPPING", NDR_WBINT_REMOVEMAPPING, api_wbint_RemoveMapping},
{"WBINT_SETHWM", NDR_WBINT_SETHWM, api_wbint_SetHWM},
@ -2035,6 +2109,12 @@ NTSTATUS rpc_wbint_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, co
return NT_STATUS_OK;
}
case NDR_WBINT_CHANGEMACHINEACCOUNT: {
struct wbint_ChangeMachineAccount *r = (struct wbint_ChangeMachineAccount *)_r;
r->out.result = _wbint_ChangeMachineAccount(cli->pipes_struct, r);
return NT_STATUS_OK;
}
case NDR_WBINT_SETMAPPING: {
struct wbint_SetMapping *r = (struct wbint_SetMapping *)_r;
r->out.result = _wbint_SetMapping(cli->pipes_struct, r);

View File

@ -20,6 +20,7 @@ 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 _wbint_ChangeMachineAccount(pipes_struct *p, struct wbint_ChangeMachineAccount *r);
NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r);
NTSTATUS _wbint_RemoveMapping(pipes_struct *p, struct wbint_RemoveMapping *r);
NTSTATUS _wbint_SetHWM(pipes_struct *p, struct wbint_SetHWM *r);
@ -44,6 +45,7 @@ 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 _wbint_ChangeMachineAccount(pipes_struct *p, struct wbint_ChangeMachineAccount *r);
NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r);
NTSTATUS _wbint_RemoveMapping(pipes_struct *p, struct wbint_RemoveMapping *r);
NTSTATUS _wbint_SetHWM(pipes_struct *p, struct wbint_SetHWM *r);

View File

@ -294,6 +294,14 @@ struct wbint_CheckMachineAccount {
};
struct wbint_ChangeMachineAccount {
struct {
NTSTATUS result;
} out;
};
struct wbint_SetMapping {
struct {
struct dom_sid *sid;/* [ref] */

View File

@ -147,6 +147,9 @@ interface wbint
NTSTATUS wbint_CheckMachineAccount(
);
NTSTATUS wbint_ChangeMachineAccount(
);
typedef [public] enum {
WBINT_ID_TYPE_NOT_SPECIFIED,
WBINT_ID_TYPE_UID,
@ -169,4 +172,4 @@ interface wbint
[in] wbint_IdType type,
[in] hyper id
);
}
}

View File

@ -547,6 +547,8 @@ static struct winbindd_async_dispatch_table async_priv_table[] = {
winbindd_remove_mapping_send, winbindd_remove_mapping_recv },
{ WINBINDD_SET_HWM, "SET_HWM",
winbindd_set_hwm_send, winbindd_set_hwm_recv },
{ WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
{ 0, NULL, NULL, NULL }
};

View File

@ -4360,6 +4360,7 @@ static bool wcache_opnum_cacheable(uint32_t opnum)
case NDR_WBINT_ALLOCATEUID:
case NDR_WBINT_ALLOCATEGID:
case NDR_WBINT_CHECKMACHINEACCOUNT:
case NDR_WBINT_CHANGEMACHINEACCOUNT:
return false;
}
return true;

View File

@ -0,0 +1,93 @@
/*
Unix SMB/CIFS implementation.
async implementation of WINBINDD_CHANGE_MACHINE_ACCT
Copyright (C) Volker Lendecke 2009
Copyright (C) Guenther Deschner 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_change_machine_acct_state {
uint8_t dummy;
};
static void winbindd_change_machine_acct_done(struct tevent_req *subreq);
struct tevent_req *winbindd_change_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_change_machine_acct_state *state;
struct winbindd_domain *domain;
req = tevent_req_create(mem_ctx, &state,
struct winbindd_change_machine_acct_state);
if (req == NULL) {
return NULL;
}
domain = find_domain_from_name(request->domain_name);
if (domain == NULL) {
tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
return tevent_req_post(req, ev);
}
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_ChangeMachineAccount_send(state, ev,
domain->child.rpccli);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq, winbindd_change_machine_acct_done, req);
return req;
}
static void winbindd_change_machine_acct_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct winbindd_change_machine_acct_state *state = tevent_req_data(
req, struct winbindd_change_machine_acct_state);
NTSTATUS status, result;
status = rpccli_wbint_ChangeMachineAccount_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_change_machine_acct_recv(struct tevent_req *req,
struct winbindd_response *presp)
{
return tevent_req_simple_recv_ntstatus(req);
}

View File

@ -4,6 +4,7 @@
In-Child server implementation of the routines defined in wbint.idl
Copyright (C) Volker Lendecke 2009
Copyright (C) Guenther Deschner 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
@ -448,6 +449,67 @@ again:
return status;
}
NTSTATUS _wbint_ChangeMachineAccount(pipes_struct *p,
struct wbint_ChangeMachineAccount *r)
{
struct winbindd_domain *domain;
int num_retries = 0;
NTSTATUS status;
struct rpc_pipe_client *netlogon_pipe;
TALLOC_CTX *tmp_ctx;
again:
domain = wb_child_domain();
if (domain == NULL) {
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
invalidate_cm_connection(&domain->conn);
{
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;
}
tmp_ctx = talloc_new(p->mem_ctx);
status = trust_pw_find_change_and_store_it(netlogon_pipe,
tmp_ctx,
domain->name);
talloc_destroy(tmp_ctx);
/* Pass back result code - zero for success, other values for
specific failures. */
DEBUG(3,("domain %s secret %s\n", domain->name,
NT_STATUS_IS_OK(status) ? "changed" : "unchanged"));
done:
DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2,
("Changing the trust account password for domain %s returned %s\n",
domain->name, nt_errstr(status)));
return status;
}
NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r)
{
struct id_map map;

View File

@ -995,6 +995,13 @@ struct tevent_req *winbindd_check_machine_acct_send(TALLOC_CTX *mem_ctx,
NTSTATUS winbindd_check_machine_acct_recv(struct tevent_req *req,
struct winbindd_response *presp);
struct tevent_req *winbindd_change_machine_acct_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct winbindd_cli_state *cli,
struct winbindd_request *request);
NTSTATUS winbindd_change_machine_acct_recv(struct tevent_req *req,
struct winbindd_response *presp);
struct tevent_req *winbindd_set_mapping_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct winbindd_cli_state *cli,