summaryrefslogtreecommitdiff
path: root/source4/libnet
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-06-18 12:33:46 +1000
committerAndrew Bartlett <abartlet@samba.org>2009-06-18 13:49:30 +1000
commit58e8db912d2213a594714ac29866396098662557 (patch)
tree1fba34e4ef93aa73e9839ad876460e6aa157a2fb /source4/libnet
parent19413c52495877d54c90c60229568d0077fda30b (diff)
downloadsamba-58e8db912d2213a594714ac29866396098662557.tar.gz
samba-58e8db912d2213a594714ac29866396098662557.tar.bz2
samba-58e8db912d2213a594714ac29866396098662557.zip
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
Diffstat (limited to 'source4/libnet')
-rw-r--r--source4/libnet/libnet_domain.c4
-rw-r--r--source4/libnet/libnet_join.c2
-rw-r--r--source4/libnet/libnet_passwd.c6
-rw-r--r--source4/libnet/libnet_rpc.c19
-rw-r--r--source4/libnet/libnet_rpc.h1
-rw-r--r--source4/libnet/libnet_samsync.c2
-rw-r--r--source4/libnet/libnet_share.c6
-rw-r--r--source4/libnet/libnet_time.c2
8 files changed, 35 insertions, 7 deletions
diff --git a/source4/libnet/libnet_domain.c b/source4/libnet/libnet_domain.c
index eb6920d88e..43a6a0e10b 100644
--- a/source4/libnet/libnet_domain.c
+++ b/source4/libnet/libnet_domain.c
@@ -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;
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 0a4e357925..81578a1a88 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -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);
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index 2c96916937..e558c93d75 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -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)) {
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index a0d93287a5..66e12d0da1 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -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 */
diff --git a/source4/libnet/libnet_rpc.h b/source4/libnet/libnet_rpc.h
index b3e1620c75..fb2628409f 100644
--- a/source4/libnet/libnet_rpc.h
+++ b/source4/libnet/libnet_rpc.h
@@ -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;
diff --git a/source4/libnet/libnet_samsync.c b/source4/libnet/libnet_samsync.c
index 4d512d6034..1d5e41de05 100644
--- a/source4/libnet/libnet_samsync.c
+++ b/source4/libnet/libnet_samsync.c
@@ -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);
diff --git a/source4/libnet/libnet_share.c b/source4/libnet/libnet_share.c
index 0bf6749a9c..e9ad83db36 100644
--- a/source4/libnet/libnet_share.c
+++ b/source4/libnet/libnet_share.c
@@ -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;
diff --git a/source4/libnet/libnet_time.c b/source4/libnet/libnet_time.c
index 61a451d3fd..37648459db 100644
--- a/source4/libnet/libnet_time.c
+++ b/source4/libnet/libnet_time.c
@@ -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;