mirror of
https://github.com/samba-team/samba.git
synced 2025-02-22 05:57:43 +03:00
s4:libnet Allow 'net password change' to work on expired passwords
We need to pass down flags to the DCE/RPC layer to allow fallback to anonymous connections, as we can't log in with an expired password. The anonymous connection can then change the password with SAMR. Andrew Bartlett
This commit is contained in:
parent
19413c5249
commit
58e8db912d
@ -427,6 +427,8 @@ struct composite_context* libnet_DomainOpenLsa_send(struct libnet_context *ctx,
|
||||
/* check, if there's lsa pipe opened already, before opening a handle */
|
||||
if (ctx->lsa.pipe == NULL) {
|
||||
|
||||
ZERO_STRUCT(s->rpcconn);
|
||||
|
||||
/* attempting to connect a domain controller */
|
||||
s->rpcconn.level = LIBNET_RPC_CONNECT_DC;
|
||||
s->rpcconn.in.name = talloc_strdup(c, io->in.domain_name);
|
||||
@ -1179,6 +1181,8 @@ struct composite_context* libnet_DomainList_send(struct libnet_context *ctx,
|
||||
|
||||
/* check whether samr pipe has already been opened */
|
||||
if (ctx->samr.pipe == NULL) {
|
||||
ZERO_STRUCT(s->rpcconn);
|
||||
|
||||
/* prepare rpc connect call */
|
||||
s->rpcconn.level = LIBNET_RPC_CONNECT_SERVER;
|
||||
s->rpcconn.in.name = s->hostname;
|
||||
|
@ -479,7 +479,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
connect_with_info = talloc(tmp_ctx, struct libnet_RpcConnect);
|
||||
connect_with_info = talloc_zero(tmp_ctx, struct libnet_RpcConnect);
|
||||
if (!connect_with_info) {
|
||||
r->out.error_string = NULL;
|
||||
talloc_free(tmp_ctx);
|
||||
|
@ -53,10 +53,13 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
|
||||
struct samr_DomInfo1 *dominfo = NULL;
|
||||
struct samr_ChangeReject *reject = NULL;
|
||||
|
||||
ZERO_STRUCT(c);
|
||||
|
||||
/* prepare connect to the SAMR pipe of the users domain PDC */
|
||||
c.level = LIBNET_RPC_CONNECT_PDC;
|
||||
c.in.name = r->samr.in.domain_name;
|
||||
c.in.dcerpc_iface = &ndr_table_samr;
|
||||
c.in.dcerpc_flags = DCERPC_ANON_FALLBACK;
|
||||
|
||||
/* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
|
||||
status = libnet_RpcConnect(ctx, mem_ctx, &c);
|
||||
@ -504,11 +507,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
|
||||
struct policy_handle u_handle;
|
||||
union libnet_SetPassword r2;
|
||||
|
||||
ZERO_STRUCT(c);
|
||||
/* prepare connect to the SAMR pipe of users domain PDC */
|
||||
c.level = LIBNET_RPC_CONNECT_PDC;
|
||||
c.in.name = r->samr.in.domain_name;
|
||||
c.in.dcerpc_iface = &ndr_table_samr;
|
||||
|
||||
|
||||
/* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
|
||||
status = libnet_RpcConnect(ctx, mem_ctx, &c);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
|
@ -106,6 +106,12 @@ static struct composite_context* libnet_RpcConnectSrv_send(struct libnet_context
|
||||
return c;
|
||||
}
|
||||
|
||||
switch (r->level) {
|
||||
case LIBNET_RPC_CONNECT_SERVER:
|
||||
case LIBNET_RPC_CONNECT_SERVER_ADDRESS:
|
||||
b->flags = r->in.dcerpc_flags;
|
||||
}
|
||||
|
||||
if (r->level == LIBNET_RPC_CONNECT_SERVER_ADDRESS) {
|
||||
b->target_hostname = talloc_reference(b, r->in.name);
|
||||
if (composite_nomem(b->target_hostname, c)) {
|
||||
@ -323,6 +329,7 @@ static void continue_lookup_dc(struct composite_context *ctx)
|
||||
s->r2.in.name = talloc_strdup(s, s->connect_name);
|
||||
s->r2.in.address = talloc_steal(s, s->f.out.dcs[0].address);
|
||||
s->r2.in.dcerpc_iface = s->r.in.dcerpc_iface;
|
||||
s->r2.in.dcerpc_flags = s->r.in.dcerpc_flags;
|
||||
|
||||
/* send rpc connect request to the server */
|
||||
rpc_connect_req = libnet_RpcConnectSrv_send(s->ctx, c, &s->r2, s->monitor_fn);
|
||||
@ -478,14 +485,18 @@ static struct composite_context* libnet_RpcConnectDCInfo_send(struct libnet_cont
|
||||
s->r = *r;
|
||||
ZERO_STRUCT(s->r.out);
|
||||
|
||||
|
||||
/* proceed to pure rpc connection if the binding string is provided,
|
||||
otherwise try to connect domain controller */
|
||||
if (r->in.binding == NULL) {
|
||||
s->rpc_conn.in.name = r->in.name;
|
||||
s->rpc_conn.level = LIBNET_RPC_CONNECT_DC;
|
||||
/* Pass on any binding flags (such as anonymous fallback) that have been set */
|
||||
s->rpc_conn.in.dcerpc_flags = r->in.dcerpc_flags;
|
||||
|
||||
s->rpc_conn.in.name = r->in.name;
|
||||
s->rpc_conn.level = LIBNET_RPC_CONNECT_DC;
|
||||
} else {
|
||||
s->rpc_conn.in.binding = r->in.binding;
|
||||
s->rpc_conn.level = LIBNET_RPC_CONNECT_BINDING;
|
||||
s->rpc_conn.in.binding = r->in.binding;
|
||||
s->rpc_conn.level = LIBNET_RPC_CONNECT_BINDING;
|
||||
}
|
||||
|
||||
/* we need to query information on lsarpc interface first */
|
||||
|
@ -45,6 +45,7 @@ struct libnet_RpcConnect {
|
||||
const char *address;
|
||||
const char *binding;
|
||||
const struct ndr_interface_table *dcerpc_iface;
|
||||
int dcerpc_flags;
|
||||
} in;
|
||||
struct {
|
||||
struct dcerpc_pipe *dcerpc_pipe;
|
||||
|
@ -77,7 +77,7 @@ NTSTATUS libnet_SamSync_netlogon(struct libnet_context *ctx, TALLOC_CTX *mem_ctx
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
c = talloc(samsync_ctx, struct libnet_RpcConnect);
|
||||
c = talloc_zero(samsync_ctx, struct libnet_RpcConnect);
|
||||
if (!c) {
|
||||
r->out.error_string = NULL;
|
||||
talloc_free(samsync_ctx);
|
||||
|
@ -37,6 +37,8 @@ NTSTATUS libnet_ListShares(struct libnet_context *ctx,
|
||||
struct srvsvc_NetShareCtr501 ctr501;
|
||||
struct srvsvc_NetShareCtr502 ctr502;
|
||||
|
||||
ZERO_STRUCT(c);
|
||||
|
||||
c.level = LIBNET_RPC_CONNECT_SERVER;
|
||||
c.in.name = r->in.server_name;
|
||||
c.in.dcerpc_iface = &ndr_table_srvsvc;
|
||||
@ -121,6 +123,8 @@ NTSTATUS libnet_AddShare(struct libnet_context *ctx,
|
||||
struct srvsvc_NetShareAdd s;
|
||||
union srvsvc_NetShareInfo info;
|
||||
|
||||
ZERO_STRUCT(c);
|
||||
|
||||
c.level = LIBNET_RPC_CONNECT_SERVER;
|
||||
c.in.name = r->in.server_name;
|
||||
c.in.dcerpc_iface = &ndr_table_srvsvc;
|
||||
@ -170,6 +174,8 @@ NTSTATUS libnet_DelShare(struct libnet_context *ctx,
|
||||
struct libnet_RpcConnect c;
|
||||
struct srvsvc_NetShareDel s;
|
||||
|
||||
ZERO_STRUCT(c);
|
||||
|
||||
c.level = LIBNET_RPC_CONNECT_SERVER;
|
||||
c.in.name = r->in.server_name;
|
||||
c.in.dcerpc_iface = &ndr_table_srvsvc;
|
||||
|
@ -33,6 +33,8 @@ static NTSTATUS libnet_RemoteTOD_srvsvc(struct libnet_context *ctx, TALLOC_CTX *
|
||||
struct srvsvc_NetRemoteTODInfo *info = NULL;
|
||||
struct tm tm;
|
||||
|
||||
ZERO_STRUCT(c);
|
||||
|
||||
/* prepare connect to the SRVSVC pipe of a timeserver */
|
||||
c.level = LIBNET_RPC_CONNECT_SERVER;
|
||||
c.in.name = r->srvsvc.in.server_name;
|
||||
|
@ -142,6 +142,8 @@ struct dcerpc_pipe {
|
||||
|
||||
#define DCERPC_SCHANNEL (1<<9)
|
||||
|
||||
#define DCERPC_ANON_FALLBACK (1<<10)
|
||||
|
||||
/* use a 128 bit session key */
|
||||
#define DCERPC_SCHANNEL_128 (1<<12)
|
||||
|
||||
|
@ -130,10 +130,10 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT
|
||||
* provide proper credentials - user supplied, but allow a
|
||||
* fallback to anonymous if this is an schannel connection
|
||||
* (might be NT4 not allowing machine logins at session
|
||||
* setup).
|
||||
* setup) or if asked to do so by the caller (perhaps a SAMR password change?)
|
||||
*/
|
||||
s->conn.in.credentials = s->io.creds;
|
||||
if (s->io.binding->flags & DCERPC_SCHANNEL) {
|
||||
if (s->io.binding->flags & (DCERPC_SCHANNEL|DCERPC_ANON_FALLBACK)) {
|
||||
conn->in.fallback_to_anonymous = true;
|
||||
} else {
|
||||
conn->in.fallback_to_anonymous = false;
|
||||
|
@ -42,6 +42,8 @@ static bool test_connect_service(struct libnet_context *ctx,
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct libnet_RpcConnect connect_r;
|
||||
ZERO_STRUCT(connect_r);
|
||||
|
||||
connect_r.level = level;
|
||||
connect_r.in.binding = binding_string;
|
||||
connect_r.in.name = hostname;
|
||||
|
Loading…
x
Reference in New Issue
Block a user