summaryrefslogtreecommitdiffstats
path: root/source4/libnet
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2013-11-07 21:40:55 -0800
committerKarolin Seeger <kseeger@samba.org>2013-12-09 07:05:46 +0100
commit0dc618189469bf389a583eb346ddc6acaad1c644 (patch)
treec2a788305792a22c554009077b5ffc9695bd5bbd /source4/libnet
parentb0ba4a562112fc707f540e1ff7c8e55ea02479c9 (diff)
downloadsamba-0dc618189469bf389a583eb346ddc6acaad1c644.tar.gz
samba-0dc618189469bf389a583eb346ddc6acaad1c644.tar.xz
samba-0dc618189469bf389a583eb346ddc6acaad1c644.zip
CVE-2013-4408:s3:Ensure LookupNames replies arrays are range checked.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10185 Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4/libnet')
-rw-r--r--source4/libnet/groupinfo.c9
-rw-r--r--source4/libnet/groupman.c10
-rw-r--r--source4/libnet/libnet_join.c12
-rw-r--r--source4/libnet/libnet_lookup.c5
-rw-r--r--source4/libnet/libnet_passwd.c10
-rw-r--r--source4/libnet/userinfo.c8
-rw-r--r--source4/libnet/userman.c24
7 files changed, 51 insertions, 27 deletions
diff --git a/source4/libnet/groupinfo.c b/source4/libnet/groupinfo.c
index 9060973e02e..5c8b0f734ca 100644
--- a/source4/libnet/groupinfo.c
+++ b/source4/libnet/groupinfo.c
@@ -88,11 +88,14 @@ static void continue_groupinfo_lookup(struct tevent_req *subreq)
s->monitor_fn(&msg);
}
-
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids->count == 0) {
- composite_error(c, NT_STATUS_NO_SUCH_USER);
+ if (s->lookup.out.rids->count != s->lookup.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
+ }
+ if (s->lookup.out.types->count != s->lookup.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
diff --git a/source4/libnet/groupman.c b/source4/libnet/groupman.c
index 9771ea54966..59a3f35d62c 100644
--- a/source4/libnet/groupman.c
+++ b/source4/libnet/groupman.c
@@ -219,13 +219,13 @@ static void continue_groupdel_name_found(struct tevent_req *subreq)
/* what to do when there's no group account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids->count) {
- c->status = NT_STATUS_NO_SUCH_GROUP;
+ if (s->lookupname.out.rids->count != s->lookupname.in.num_names) {
+ c->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
composite_error(c, c->status);
return;
-
- } else if (!s->lookupname.out.rids->count > 1) {
- c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
+ }
+ if (s->lookupname.out.types->count != s->lookupname.in.num_names) {
+ c->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
composite_error(c, c->status);
return;
}
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 09774038fb3..8c1b57ddde1 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -656,9 +656,17 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
"samr_LookupNames for [%s] returns %d RIDs",
r->in.account_name, ln.out.rids->count);
talloc_free(tmp_ctx);
- return NT_STATUS_INVALID_PARAMETER;
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
-
+
+ if (ln.out.types->count != 1) {
+ r->out.error_string = talloc_asprintf(mem_ctx,
+ "samr_LookupNames for [%s] returns %d RID TYPEs",
+ r->in.account_name, ln.out.types->count);
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
/* prepare samr_OpenUser */
ZERO_STRUCTP(u_handle);
ou.in.domain_handle = &d_handle;
diff --git a/source4/libnet/libnet_lookup.c b/source4/libnet/libnet_lookup.c
index cf2d70c41df..77072b7ecce 100644
--- a/source4/libnet/libnet_lookup.c
+++ b/source4/libnet/libnet_lookup.c
@@ -365,6 +365,11 @@ static void continue_name_found(struct tevent_req *subreq)
c->status = s->lookup.out.result;
if (!composite_is_ok(c)) return;
+ if (s->lookup.out.sids->count != s->lookup.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
+ }
+
composite_done(c);
}
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index 861d746fd11..77176bc16c7 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -627,10 +627,18 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
r->samr.out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
r->samr.in.account_name, ln.out.rids->count);
- status = NT_STATUS_INVALID_PARAMETER;
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
goto disconnect;
}
+ if (ln.out.types->count != 1) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "samr_LookupNames for [%s] returns %d RID TYPEs",
+ r->samr.in.account_name, ln.out.types->count);
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto disconnect;
+ }
+
/* prepare samr_OpenUser */
ZERO_STRUCT(u_handle);
ou.in.domain_handle = &d_handle;
diff --git a/source4/libnet/userinfo.c b/source4/libnet/userinfo.c
index 75c46e477d7..9530f9efdb5 100644
--- a/source4/libnet/userinfo.c
+++ b/source4/libnet/userinfo.c
@@ -90,8 +90,12 @@ static void continue_userinfo_lookup(struct tevent_req *subreq)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids->count == 0) {
- composite_error(c, NT_STATUS_NO_SUCH_USER);
+ if (s->lookup.out.rids->count != s->lookup.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
+ }
+ if (s->lookup.out.types->count != s->lookup.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index c1ee0179902..a7301eab6c6 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -237,14 +237,12 @@ static void continue_userdel_name_found(struct tevent_req *subreq)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids->count) {
- c->status = NT_STATUS_NO_SUCH_USER;
- composite_error(c, c->status);
+ if (s->lookupname.out.rids->count != s->lookupname.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
-
- } else if (!s->lookupname.out.rids->count > 1) {
- c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
- composite_error(c, c->status);
+ }
+ if (s->lookupname.out.types->count != s->lookupname.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
@@ -513,14 +511,12 @@ static void continue_usermod_name_found(struct tevent_req *subreq)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids->count) {
- c->status = NT_STATUS_NO_SUCH_USER;
- composite_error(c, c->status);
+ if (s->lookupname.out.rids->count != s->lookupname.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
-
- } else if (!s->lookupname.out.rids->count > 1) {
- c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
- composite_error(c, c->status);
+ }
+ if (s->lookupname.out.types->count != s->lookupname.in.num_names) {
+ composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}