From 073e9f42f0c5f5de5d736ec7843d80a274c891ce Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 16 Jan 2009 12:06:49 -0600 Subject: ads_connect: Return immediately on a failed GC connection. ads_connect_gc() feeds an explicit server to ads_connect(). However, if the resulting connection fails, the latter function was attempting to find a DC on its own and continuing the connection. This resulting in GC searches being sent over a connection using port 389 which would fail when using the base search suffix outside of the domain naming context. The fix is to fail immediately in ads_connect() since the GC lookup ordering is handled already in ads_connect_gc(). --- source3/libads/ldap.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index a598580941b..f6da54f35ba 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -581,9 +581,20 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) TALLOC_FREE(s); } - if (ads->server.ldap_server && - ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) { - goto got_connection; + if (ads->server.ldap_server) + { + if (ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) { + goto got_connection; + } + + /* The choice of which GC use is handled one level up in + ads_connect_gc(). If we continue on from here with + ads_find_dc() we will get GC searches on port 389 which + doesn't work. --jerry */ + + if (ads->server.gc == true) { + return ADS_ERROR(LDAP_OPERATIONS_ERROR); + } } ntstatus = ads_find_dc(ads); -- cgit From fb904194c9f696b72d862e51e7ba688decdda192 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jan 2009 11:55:01 -0800 Subject: "First thing, kill all the language lawyers" :-). Ensure possible insane compilers can't kill us later. Jeremy. --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b46ff2c462d..98c25c1e24f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1889,6 +1889,7 @@ const char *get_mydnsfullname(void) bool is_myname_or_ipaddr(const char *s) { TALLOC_CTX *ctx = talloc_tos(); + char addr[INET6_ADDRSTRLEN]; char *name = NULL; const char *dnsname; char *servername = NULL; @@ -1941,7 +1942,6 @@ bool is_myname_or_ipaddr(const char *s) /* Use DNS to resolve the name, but only the first address */ struct sockaddr_storage ss; if (interpret_string_addr(&ss, servername, 0)) { - char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &ss); -- cgit From 3fe974c4feed33187294a0cb922c20f7dbfeaf43 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 16 Jan 2009 12:26:46 -0800 Subject: Fix a segfault if ? is there but the options are NULL. This is the case if SMBC_parse_path is called by SMBC_stat_ctx. --- source3/libsmb/libsmb_path.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 2c3a5f8866b..b0970d46db4 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -286,7 +286,7 @@ SMBC_parse_path(TALLOC_CTX *ctx, DEBUG(4, ("Found options '%s'", q)); /* Copy the options */ - if (*pp_options != NULL) { + if (pp_options && *pp_options != NULL) { TALLOC_FREE(*pp_options); *pp_options = talloc_strdup(ctx, q); } -- cgit From 1c77c7f3d5b6cb29fac4606299c237c0e299f836 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 16 Jan 2009 16:41:36 -0500 Subject: Treat file names in POSIX-like case-sensitive fashion by default *** THIS COMMIT CAUSES A CHANGE OF DEFAULT BEHAVIOR IN libsmbclient!!! *** - libsmbclient now calls cli_set_case_sensitive() for a new CLI. By default, it requests case-sensitive, but the old behavior of case-insensitive can be requested with smbc_setOptionCaseSensitive(context, False); The change of behavior is considered a bug fix, as it was previously possible to accidentally overwrite a file that had the same case-insensitive name but a different case-sensitive name as a previously-existing file, while creating a new file. Derrell --- source3/include/libsmb_internal.h | 5 +++++ source3/include/libsmbclient.h | 9 +++++++++ source3/libsmb/libsmb_context.c | 1 + source3/libsmb/libsmb_server.c | 7 +++++++ source3/libsmb/libsmb_setget.c | 14 ++++++++++++++ 5 files changed, 36 insertions(+) diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h index b4881169396..8b410b4f7f9 100644 --- a/source3/include/libsmb_internal.h +++ b/source3/include/libsmb_internal.h @@ -176,6 +176,11 @@ struct SMBC_internal_data { */ smbc_smb_encrypt_level smb_encryption_level; + /* + * Should we request case sensitivity of file names? + */ + bool case_sensitive; + struct smbc_server_cache * server_cache; /* POSIX emulation functions */ diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index a8b27b709e4..4a8accbf4e5 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -550,6 +550,15 @@ smbc_getOptionSmbEncryptionLevel(SMBCCTX *c); void smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level); +/** Get whether to treat file names as case-sensitive. */ +smbc_bool +smbc_getOptionCaseSensitive(SMBCCTX *c); + +/** Set whether to treat file names as case-sensitive. */ +void +smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b); + + /** * Get from how many local master browsers should the list of workgroups be * retrieved. It can take up to 12 minutes or longer after a server becomes a diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 66329e28605..ca8ceedbc23 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -69,6 +69,7 @@ smbc_new_context(void) smbc_setOptionFullTimeNames(context, False); smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE); + smbc_setOptionCaseSensitive(context, True); smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ smbc_setOptionUrlEncodeReaddirEntries(context, False); smbc_setOptionOneSharePerServer(context, False); diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index f4714346d1d..e2cc07118b7 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -356,6 +356,13 @@ again: return NULL; } + /* POSIX-like - always request case-sensitivity by default. */ + if (smbc_getOptionCaseSensitive(context)) { + cli_set_case_sensitive(c, True); + } else { + cli_set_case_sensitive(c, False); + } + if (smbc_getOptionUseKerberos(context)) { c->use_kerberos = True; } diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c index d0823bd77ec..bca2a80d14b 100644 --- a/source3/libsmb/libsmb_setget.c +++ b/source3/libsmb/libsmb_setget.c @@ -193,6 +193,20 @@ smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level) c->internal->smb_encryption_level = level; } +/** Get whether to treat file names as case-sensitive. */ +smbc_bool +smbc_getOptionCaseSensitive(SMBCCTX *c) +{ + return c->internal->case_sensitive; +} + +/** Set whether to treat file names as case-sensitive. */ +void +smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b) +{ + c->internal->case_sensitive = b; +} + /** * Get from how many local master browsers should the list of workgroups be * retrieved. It can take up to 12 minutes or longer after a server becomes a -- cgit From c6b4f3526a262b22d5a97a3152f378778a497a26 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 16 Jan 2009 20:26:46 -0500 Subject: [Bug 6022] smbc_urlencode and smbc_urldecode were not exported - Since the revamp of libsmbclient, there has still been an external declaration for smbc_urlencode and smbc_urldecode in libsmbclient.h, yet those functions were renamed and made private. The two choices were to remove the function names from libsmbclient.h or to make them public again. The reported requested that they be public. This commit makes it so. Derrell --- source3/include/libsmb_internal.h | 10 ---------- source3/libsmb/libsmb_dir.c | 2 +- source3/libsmb/libsmb_path.c | 8 ++++---- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h index 8b410b4f7f9..67add074bfc 100644 --- a/source3/include/libsmb_internal.h +++ b/source3/include/libsmb_internal.h @@ -401,16 +401,6 @@ SMBC_errno(SMBCCTX *context, /* Functions in libsmb_path.c */ -int -SMBC_urldecode(char *dest, - char *src, - size_t max_dest_len); - -int -SMBC_urlencode(char *dest, - char *src, - int max_dest_len); - int SMBC_parse_path(TALLOC_CTX *ctx, SMBCCTX *context, diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 770014b6f62..e9b7b4f95a9 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -895,7 +895,7 @@ smbc_readdir_internal(SMBCCTX * context, /* url-encode the name. get back remaining buffer space */ max_namebuf_len = - SMBC_urlencode(dest->name, src->name, max_namebuf_len); + smbc_urlencode(dest->name, src->name, max_namebuf_len); /* We now know the name length */ dest->namelen = strlen(dest->name); diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index b0970d46db4..6d69924231b 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -41,7 +41,7 @@ hex2int( unsigned int _char ) } /* - * SMBC_urldecode() + * smbc_urldecode() * and urldecode_talloc() (internal fn.) * * Convert strings of %xx to their single character equivalent. Each 'x' must @@ -122,7 +122,7 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) } int -SMBC_urldecode(char *dest, +smbc_urldecode(char *dest, char *src, size_t max_dest_len) { @@ -138,7 +138,7 @@ SMBC_urldecode(char *dest, } /* - * SMBC_urlencode() + * smbc_urlencode() * * Convert any characters not specifically allowed in a URL into their %xx * equivalent. @@ -146,7 +146,7 @@ SMBC_urldecode(char *dest, * Returns the remaining buffer length. */ int -SMBC_urlencode(char *dest, +smbc_urlencode(char *dest, char *src, int max_dest_len) { -- cgit From 9b3c38f4afe2b15159c8659b5916740493f7b60c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 11:26:06 +0100 Subject: Slightly simplify the paths after rpc_api_pipe() --- source3/rpc_client/cli_pipe.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 99bd85af5d1..28bbfa57b66 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2175,13 +2175,11 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, prs_init_empty(rbuf, talloc_tos(), UNMARSHALL); nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP); + prs_mem_free(&rpc_out); if (!NT_STATUS_IS_OK(nt_status)) { - prs_mem_free(&rpc_out); return nt_status; } - prs_mem_free(&rpc_out); - /* Get the auth blob from the reply. */ if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) { DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n")); @@ -2257,13 +2255,11 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /* send data on \PIPE\. receive a response */ status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK); + prs_mem_free(&rpc_out); if (!NT_STATUS_IS_OK(status)) { - prs_mem_free(&rpc_out); return status; } - prs_mem_free(&rpc_out); - DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n", rpccli_pipe_txt(debug_ctx(), cli))); -- cgit From 6d300399b52e0921ce205ef2f053b722b21edeeb Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 17 Jan 2009 13:33:25 -0500 Subject: Determine case sensitivity based on file system attributes. - Most of the time, we can determine from the file system we're connecting to whether it supports case sensitivity. In those cases, we now set the internal case sensitivity flag automatically. For those cases where the request to retrieve file system attributes fails, we'll use the user-specified option value. Derrell --- source3/include/libsmbclient.h | 16 ++++++++-- source3/libsmb/libsmb_context.c | 2 +- source3/libsmb/libsmb_server.c | 71 ++++++++++++++++++++++++++++++++++++----- source3/libsmb/libsmb_setget.c | 16 ++++++++-- 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index 4a8accbf4e5..b2d9483a0b9 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -550,11 +550,23 @@ smbc_getOptionSmbEncryptionLevel(SMBCCTX *c); void smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level); -/** Get whether to treat file names as case-sensitive. */ +/** + * Get whether to treat file names as case-sensitive if we can't determine + * when connecting to the remote share whether the file system is case + * sensitive. This defaults to FALSE since it's most likely that if we can't + * retrieve the file system attributes, it's a very old file system that does + * not support case sensitivity. + */ smbc_bool smbc_getOptionCaseSensitive(SMBCCTX *c); -/** Set whether to treat file names as case-sensitive. */ +/** + * Set whether to treat file names as case-sensitive if we can't determine + * when connecting to the remote share whether the file system is case + * sensitive. This defaults to FALSE since it's most likely that if we can't + * retrieve the file system attributes, it's a very old file system that does + * not support case sensitivity. + */ void smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b); diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index ca8ceedbc23..c2c33e53025 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -69,7 +69,7 @@ smbc_new_context(void) smbc_setOptionFullTimeNames(context, False); smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE); - smbc_setOptionCaseSensitive(context, True); + smbc_setOptionCaseSensitive(context, False); smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ smbc_setOptionUrlEncodeReaddirEntries(context, False); smbc_setOptionOneSharePerServer(context, False); diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index e2cc07118b7..0ece5bb649e 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -245,6 +245,8 @@ SMBC_server(TALLOC_CTX *ctx, int tried_reverse = 0; int port_try_first; int port_try_next; + int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0); + uint32 fs_attrs = 0; const char *username_used; NTSTATUS status; @@ -310,6 +312,38 @@ SMBC_server(TALLOC_CTX *ctx, srv = NULL; } + /* Determine if this share supports case sensitivity */ + if (is_ipc) { + DEBUG(4, + ("IPC$ so ignore case sensitivity\n")); + } else if (!cli_get_fs_attr_info(c, &fs_attrs)) { + DEBUG(4, ("Could not retrieve " + "case sensitivity flag: %s.\n", + cli_errstr(c))); + + /* + * We can't determine the case sensitivity of + * the share. We have no choice but to use the + * user-specified case sensitivity setting. + */ + if (smbc_getOptionCaseSensitive(context)) { + cli_set_case_sensitive(c, True); + } else { + cli_set_case_sensitive(c, False); + } + } else { + DEBUG(4, + ("Case sensitive: %s\n", + (fs_attrs & FILE_CASE_SENSITIVE_SEARCH + ? "True" + : "False"))); + cli_set_case_sensitive( + c, + (fs_attrs & FILE_CASE_SENSITIVE_SEARCH + ? True + : False)); + } + /* * Regenerate the dev value since it's based on both * server and share @@ -356,13 +390,6 @@ again: return NULL; } - /* POSIX-like - always request case-sensitivity by default. */ - if (smbc_getOptionCaseSensitive(context)) { - cli_set_case_sensitive(c, True); - } else { - cli_set_case_sensitive(c, False); - } - if (smbc_getOptionUseKerberos(context)) { c->use_kerberos = True; } @@ -377,7 +404,7 @@ again: * Force use of port 139 for first try if share is $IPC, empty, or * null, so browse lists can work */ - if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) { + if (share == NULL || *share == '\0' || is_ipc) { port_try_first = 139; port_try_next = 445; } else { @@ -483,6 +510,34 @@ again: DEBUG(4,(" tconx ok\n")); + /* Determine if this share supports case sensitivity */ + if (is_ipc) { + DEBUG(4, ("IPC$ so ignore case sensitivity\n")); + } else if (!cli_get_fs_attr_info(c, &fs_attrs)) { + DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n", + cli_errstr(c))); + + /* + * We can't determine the case sensitivity of the share. We + * have no choice but to use the user-specified case + * sensitivity setting. + */ + if (smbc_getOptionCaseSensitive(context)) { + cli_set_case_sensitive(c, True); + } else { + cli_set_case_sensitive(c, False); + } + } else { + DEBUG(4, ("Case sensitive: %s\n", + (fs_attrs & FILE_CASE_SENSITIVE_SEARCH + ? "True" + : "False"))); + cli_set_case_sensitive(c, + (fs_attrs & FILE_CASE_SENSITIVE_SEARCH + ? True + : False)); + } + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(c, diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c index bca2a80d14b..9de49a5b3f6 100644 --- a/source3/libsmb/libsmb_setget.c +++ b/source3/libsmb/libsmb_setget.c @@ -193,14 +193,26 @@ smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level) c->internal->smb_encryption_level = level; } -/** Get whether to treat file names as case-sensitive. */ +/** + * Get whether to treat file names as case-sensitive if we can't determine + * when connecting to the remote share whether the file system is case + * sensitive. This defaults to FALSE since it's most likely that if we can't + * retrieve the file system attributes, it's a very old file system that does + * not support case sensitivity. + */ smbc_bool smbc_getOptionCaseSensitive(SMBCCTX *c) { return c->internal->case_sensitive; } -/** Set whether to treat file names as case-sensitive. */ +/** + * Set whether to treat file names as case-sensitive if we can't determine + * when connecting to the remote share whether the file system is case + * sensitive. This defaults to FALSE since it's most likely that if we can't + * retrieve the file system attributes, it's a very old file system that does + * not support case sensitivity. + */ void smbc_setOptionCaseSensitive(SMBCCTX *c, smbc_bool b) { -- cgit From 142b2a61f8a77b3065ce4c78b459ab714d6d190a Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sat, 17 Jan 2009 14:40:12 -0800 Subject: pidl: Remove "max" and make "range" smarter about unsigned types This eliminates a warning in pidl generated code, while preserving cross-platform idl compatibility. --- pidl/lib/Parse/Pidl/Compat.pm | 1 - pidl/lib/Parse/Pidl/NDR.pm | 1 - pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 16 +++++++++------- pidl/lib/Parse/Pidl/Typelist.pm | 15 ++++++++++++++- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Compat.pm b/pidl/lib/Parse/Pidl/Compat.pm index 58ba136591b..1b49c439c43 100644 --- a/pidl/lib/Parse/Pidl/Compat.pm +++ b/pidl/lib/Parse/Pidl/Compat.pm @@ -67,7 +67,6 @@ my %supported_properties = ( # array "range" => ["ELEMENT"], - "max" => ["ELEMENT"], "size_is" => ["ELEMENT"], "string" => ["ELEMENT"], "noheader" => ["ELEMENT"], diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm index 89632437c10..5ee26d16b68 100644 --- a/pidl/lib/Parse/Pidl/NDR.pm +++ b/pidl/lib/Parse/Pidl/NDR.pm @@ -921,7 +921,6 @@ my %property_list = ( # array "range" => ["ELEMENT"], - "max" => ["ELEMENT"], "size_is" => ["ELEMENT"], "string" => ["ELEMENT"], "noheader" => ["ELEMENT"], diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index e2b14c10b1e..44d21f0b4a6 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -857,14 +857,16 @@ sub ParseDataPull($$$$$$$) if (my $range = has_property($e, "range")) { $var_name = get_value_of($var_name); + my $signed = Parse::Pidl::Typelist::is_signed($l->{DATA_TYPE}); my ($low, $high) = split(/,/, $range, 2); - $self->pidl("if ($var_name < $low || $var_name > $high) {"); - $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");"); - $self->pidl("}"); - } - if (my $max = has_property($e, "max")) { - $var_name = get_value_of($var_name); - $self->pidl("if ($var_name > $max) {"); + if ($low < 0 and not $signed) { + warning(0, "$low is invalid for the range of an unsigned type"); + } + if ($low == 0 and not $signed) { + $self->pidl("if ($var_name > $high) {"); + } else { + $self->pidl("if ($var_name < $low || $var_name > $high) {"); + } $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");"); $self->pidl("}"); } diff --git a/pidl/lib/Parse/Pidl/Typelist.pm b/pidl/lib/Parse/Pidl/Typelist.pm index 0e3fd8de444..4f9d982c215 100644 --- a/pidl/lib/Parse/Pidl/Typelist.pm +++ b/pidl/lib/Parse/Pidl/Typelist.pm @@ -8,7 +8,7 @@ package Parse::Pidl::Typelist; require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(hasType getType resolveType mapTypeName scalar_is_reference expandAlias - mapScalarType addType typeIs is_scalar enum_type_fn + mapScalarType addType typeIs is_signed is_scalar enum_type_fn bitmap_type_fn mapType typeHasBody ); use vars qw($VERSION); @@ -145,6 +145,19 @@ sub hasType($) return 0; } +sub is_signed($) +{ + my $t = shift; + + return ($t eq "int8" + or $t eq "int16" + or $t eq "int32" + or $t eq "dlong" + or $t eq "int" + or $t eq "long" + or $t eq "short"); +} + sub is_scalar($) { sub is_scalar($); -- cgit From 4a40857836ef2678d2e55c2b1cc9745b88812c4e Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sat, 17 Jan 2009 14:42:20 -0800 Subject: librpc: Remove usage of max and replace with improved range. --- librpc/idl/eventlog.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index fbdec28be73..51b3ea706e3 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -40,7 +40,7 @@ import "lsa.idl", "security.idl"; time_t time_written; uint32 event_id; eventlogEventTypes event_type; - [max(256)] uint16 num_of_strings; + [range(0,256)] uint16 num_of_strings; uint16 event_category; uint16 reserved_flags; uint32 closing_record_number; -- cgit From 44ae09b82e509db390ad4e884ae3310a3508cf46 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sat, 17 Jan 2009 15:19:08 -0800 Subject: librpc: Re-run make idl_full --- librpc/gen_ndr/eventlog.h | 2 +- librpc/gen_ndr/ndr_drsuapi.c | 48 +++++++++++++++++++++---------------------- librpc/gen_ndr/ndr_eventlog.c | 2 +- librpc/gen_ndr/ndr_lsa.c | 34 +++++++++++++++--------------- librpc/gen_ndr/ndr_netlogon.c | 4 ++-- librpc/gen_ndr/ndr_samr.c | 6 +++--- librpc/gen_ndr/ndr_security.c | 4 ++-- librpc/gen_ndr/ndr_svcctl.c | 40 ++++++++++++++++++------------------ 8 files changed, 70 insertions(+), 70 deletions(-) diff --git a/librpc/gen_ndr/eventlog.h b/librpc/gen_ndr/eventlog.h index 65178d203c9..9c9a2ed2185 100644 --- a/librpc/gen_ndr/eventlog.h +++ b/librpc/gen_ndr/eventlog.h @@ -47,7 +47,7 @@ struct eventlog_Record { time_t time_written; uint32_t event_id; enum eventlogEventTypes event_type; - uint16_t num_of_strings;/* [max(256)] */ + uint16_t num_of_strings;/* [range(0,256)] */ uint16_t event_category; uint16_t reserved_flags; uint32_t closing_record_number; diff --git a/librpc/gen_ndr/ndr_drsuapi.c b/librpc/gen_ndr/ndr_drsuapi.c index 369a1d44e01..336f56f6ad2 100644 --- a/librpc/gen_ndr/ndr_drsuapi.c +++ b/librpc/gen_ndr/ndr_drsuapi.c @@ -811,7 +811,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsReplicaCursorCtrEx(struct ndr_pull * NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 0x100000) { + if (r->count > 0x100000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved2)); @@ -1166,7 +1166,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_drsuapi_DsReplicaOIDMapping_Ctr(struct ndr_p if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_mappings)); - if (r->num_mappings < 0 || r->num_mappings > 0x100000) { + if (r->num_mappings > 0x100000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_mappings)); @@ -1700,7 +1700,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsReplicaCursor2CtrEx(struct ndr_pull NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 0x100000) { + if (r->count > 0x100000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved2)); @@ -1764,7 +1764,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsAttributeValue(struct ndr_pull *ndr, if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->__ndr_size)); - if (r->__ndr_size < 0 || r->__ndr_size > 10485760) { + if (r->__ndr_size > 10485760) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_blob)); @@ -1830,7 +1830,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsAttributeValueCtr(struct ndr_pull *n if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_values)); - if (r->num_values < 0 || r->num_values > 10485760) { + if (r->num_values > 10485760) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_values)); @@ -2074,7 +2074,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsReplicaAttributeCtr(struct ndr_pull if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_attributes)); - if (r->num_attributes < 0 || r->num_attributes > 1048576) { + if (r->num_attributes > 1048576) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_attributes)); @@ -2278,7 +2278,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_drsuapi_DsReplicaMetaDataCtr(struct ndr_pull NDR_CHECK(ndr_pull_array_size(ndr, &r->meta_data)); NDR_CHECK(ndr_pull_align(ndr, 8)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1048576) { + if (r->count > 1048576) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->meta_data, ndr_get_array_size(ndr, &r->meta_data)); @@ -2710,7 +2710,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_drsuapi_DsGetNCChangesCtr6(struct ndr_pull * NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->nc_object_count)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->nc_linked_attributes_count)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->linked_attributes_count)); - if (r->linked_attributes_count < 0 || r->linked_attributes_count > 1048576) { + if (r->linked_attributes_count > 1048576) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_linked_attributes)); @@ -3837,11 +3837,11 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetMembershipsCtr1(struct ndr_pull * NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->status)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_memberships)); - if (r->num_memberships < 0 || r->num_memberships > 10000) { + if (r->num_memberships > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_sids)); - if (r->num_sids < 0 || r->num_sids > 10000) { + if (r->num_sids > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info_array)); @@ -4324,7 +4324,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetNT4ChangeLogRequest1(struct ndr_p NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length)); - if (r->length < 0 || r->length > 0x00A00000) { + if (r->length > 0x00A00000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); @@ -4479,11 +4479,11 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetNT4ChangeLogInfo1(struct ndr_pull if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 8)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length1)); - if (r->length1 < 0 || r->length1 > 0x00A00000) { + if (r->length1 > 0x00A00000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length2)); - if (r->length2 < 0 || r->length2 > 0x00A00000) { + if (r->length2 > 0x00A00000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->unknown1)); @@ -5320,7 +5320,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsWriteAccountSpnRequest1(struct ndr_p r->object_dn = NULL; } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_spn_names)); @@ -6217,7 +6217,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetDCInfoCtr1(struct ndr_pull *ndr, if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); @@ -6585,7 +6585,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetDCInfoCtr2(struct ndr_pull *ndr, if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); @@ -6956,7 +6956,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetDCInfoCtr3(struct ndr_pull *ndr, if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); @@ -7133,7 +7133,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsGetDCConnectionCtr01(struct ndr_pull if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_array)); @@ -7537,7 +7537,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsAddEntryExtraErrorBuffer(struct ndr_ if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); - if (r->size < 0 || r->size > 10485760) { + if (r->size > 10485760) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); @@ -8097,7 +8097,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsAddEntryCtr2(struct ndr_pull *ndr, i NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1)); NDR_CHECK(ndr_pull_drsuapi_DsAddEntryErrorInfoX(ndr, NDR_SCALARS, &r->error)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_objects)); @@ -8227,7 +8227,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsAddEntryCtr3(struct ndr_pull *ndr, i r->error = NULL; } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_objects)); @@ -10709,7 +10709,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsReplicaConnection04Ctr(struct ndr_pu NDR_CHECK(ndr_pull_array_size(ndr, &r->array)); NDR_CHECK(ndr_pull_align(ndr, 8)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 10000) { + if (r->count > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved)); @@ -10858,7 +10858,7 @@ static enum ndr_err_code ndr_pull_drsuapi_DsReplica06Ctr(struct ndr_pull *ndr, i NDR_CHECK(ndr_pull_array_size(ndr, &r->array)); NDR_CHECK(ndr_pull_align(ndr, 8)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 256) { + if (r->count > 256) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->reserved)); @@ -11863,7 +11863,7 @@ static enum ndr_err_code ndr_pull_drsuapi_QuerySitesByCostCtr1(struct ndr_pull * if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_info)); - if (r->num_info < 0 || r->num_info > 10000) { + if (r->num_info > 10000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); diff --git a/librpc/gen_ndr/ndr_eventlog.c b/librpc/gen_ndr/ndr_eventlog.c index edcdf2e3f49..ddc93f910b2 100644 --- a/librpc/gen_ndr/ndr_eventlog.c +++ b/librpc/gen_ndr/ndr_eventlog.c @@ -974,7 +974,7 @@ static enum ndr_err_code ndr_pull_eventlog_ReadEventLogW(struct ndr_pull *ndr, i NDR_CHECK(ndr_pull_eventlogReadFlags(ndr, NDR_SCALARS, &r->in.flags)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offset)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.number_of_bytes)); - if (r->in.number_of_bytes < 0 || r->in.number_of_bytes > 0x7FFFF) { + if (r->in.number_of_bytes > 0x7FFFF) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->out.data, r->in.number_of_bytes); diff --git a/librpc/gen_ndr/ndr_lsa.c b/librpc/gen_ndr/ndr_lsa.c index 9169adfe81e..793404a3be7 100644 --- a/librpc/gen_ndr/ndr_lsa.c +++ b/librpc/gen_ndr/ndr_lsa.c @@ -1819,7 +1819,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_SidArray(struct ndr_pull *ndr, int ndr_f if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_sids)); - if (r->num_sids < 0 || r->num_sids > 1000) { + if (r->num_sids > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sids)); @@ -2060,7 +2060,7 @@ static enum ndr_err_code ndr_pull_lsa_TransSidArray(struct ndr_pull *ndr, int nd if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sids)); @@ -2147,7 +2147,7 @@ static enum ndr_err_code ndr_pull_lsa_RefDomainList(struct ndr_pull *ndr, int nd if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); @@ -2306,7 +2306,7 @@ static enum ndr_err_code ndr_pull_lsa_TransNameArray(struct ndr_pull *ndr, int n if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_names)); @@ -2422,7 +2422,7 @@ static enum ndr_err_code ndr_pull_lsa_PrivilegeSet(struct ndr_pull *ndr, int ndr NDR_CHECK(ndr_pull_array_size(ndr, &r->set)); NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown)); @@ -2580,7 +2580,7 @@ static enum ndr_err_code ndr_pull_lsa_DATA_BUF2(struct ndr_pull *ndr, int ndr_fl if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->size)); - if (r->size < 0 || r->size > 65536) { + if (r->size > 65536) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); @@ -3924,7 +3924,7 @@ static enum ndr_err_code ndr_pull_lsa_RightSet(struct ndr_pull *ndr, int ndr_fla if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 256) { + if (r->count > 256) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_names)); @@ -4338,7 +4338,7 @@ static enum ndr_err_code ndr_pull_lsa_TransNameArray2(struct ndr_pull *ndr, int if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_names)); @@ -4463,7 +4463,7 @@ static enum ndr_err_code ndr_pull_lsa_TransSidArray2(struct ndr_pull *ndr, int n if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sids)); @@ -4609,7 +4609,7 @@ static enum ndr_err_code ndr_pull_lsa_TransSidArray3(struct ndr_pull *ndr, int n if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1000) { + if (r->count > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sids)); @@ -4690,7 +4690,7 @@ static enum ndr_err_code ndr_pull_lsa_ForestTrustBinaryData(struct ndr_pull *ndr if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length)); - if (r->length < 0 || r->length > 131072) { + if (r->length > 131072) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); @@ -5021,7 +5021,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_ForestTrustInformation(struct ndr_pull * if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 4000) { + if (r->count > 4000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_entries)); @@ -6032,7 +6032,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_EnumAccounts(struct ndr_pull *ndr, int f NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_entries)); - if (r->in.num_entries < 0 || r->in.num_entries > 8192) { + if (r->in.num_entries > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC(ndr, r->out.resume_handle); @@ -6375,7 +6375,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int fl NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_names)); - if (r->in.num_names < 0 || r->in.num_names > 1000) { + if (r->in.num_names > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.names)); @@ -10842,7 +10842,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int f NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_names)); - if (r->in.num_names < 0 || r->in.num_names > 1000) { + if (r->in.num_names > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.names)); @@ -11496,7 +11496,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int f NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_names)); - if (r->in.num_names < 0 || r->in.num_names > 1000) { + if (r->in.num_names > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.names)); @@ -12234,7 +12234,7 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames4(struct ndr_pull *ndr, int fla ZERO_STRUCT(r->out); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_names)); - if (r->in.num_names < 0 || r->in.num_names > 1000) { + if (r->in.num_names > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.names)); diff --git a/librpc/gen_ndr/ndr_netlogon.c b/librpc/gen_ndr/ndr_netlogon.c index 050ee24ed59..751967a60e0 100644 --- a/librpc/gen_ndr/ndr_netlogon.c +++ b/librpc/gen_ndr/ndr_netlogon.c @@ -13751,7 +13751,7 @@ static enum ndr_err_code ndr_pull_netr_DsRAddressToSitenamesW(struct ndr_pull *n NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.count)); - if (r->in.count < 0 || r->in.count > 32000) { + if (r->in.count > 32000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.addresses)); @@ -14294,7 +14294,7 @@ static enum ndr_err_code ndr_pull_netr_DsRAddressToSitenamesExW(struct ndr_pull NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_name_0, 0); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.count)); - if (r->in.count < 0 || r->in.count > 32000) { + if (r->in.count > 32000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.addresses)); diff --git a/librpc/gen_ndr/ndr_samr.c b/librpc/gen_ndr/ndr_samr.c index 83b091608ea..33c70ce1ff6 100644 --- a/librpc/gen_ndr/ndr_samr.c +++ b/librpc/gen_ndr/ndr_samr.c @@ -1191,7 +1191,7 @@ static enum ndr_err_code ndr_pull_samr_Ids(struct ndr_pull *ndr, int ndr_flags, if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - if (r->count < 0 || r->count > 1024) { + if (r->count > 1024) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_ids)); @@ -7211,7 +7211,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_samr_LookupNames(struct ndr_pull *ndr, int f NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.domain_handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domain_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_names)); - if (r->in.num_names < 0 || r->in.num_names > 1000) { + if (r->in.num_names > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.names)); @@ -7353,7 +7353,7 @@ static enum ndr_err_code ndr_pull_samr_LookupRids(struct ndr_pull *ndr, int flag NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.domain_handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domain_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.num_rids)); - if (r->in.num_rids < 0 || r->in.num_rids > 1000) { + if (r->in.num_rids > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_size(ndr, &r->in.rids)); diff --git a/librpc/gen_ndr/ndr_security.c b/librpc/gen_ndr/ndr_security.c index 64c134dcb84..c227170779a 100644 --- a/librpc/gen_ndr/ndr_security.c +++ b/librpc/gen_ndr/ndr_security.c @@ -498,7 +498,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_acl(struct ndr_pull *ndr, int ndr_f NDR_CHECK(ndr_pull_security_acl_revision(ndr, NDR_SCALARS, &r->revision)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_aces)); - if (r->num_aces < 0 || r->num_aces > 1000) { + if (r->num_aces > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->aces, r->num_aces); @@ -797,7 +797,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_sec_desc_buf(struct ndr_pull *ndr, int ndr_f if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sd_size)); - if (r->sd_size < 0 || r->sd_size > 0x40000) { + if (r->sd_size > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd)); diff --git a/librpc/gen_ndr/ndr_svcctl.c b/librpc/gen_ndr/ndr_svcctl.c index 72fee1ae234..fc59371697f 100644 --- a/librpc/gen_ndr/ndr_svcctl.c +++ b/librpc/gen_ndr/ndr_svcctl.c @@ -1164,7 +1164,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_SERVICE_FAILURE_ACTIONS(struct ndr_pull *ndr ndr->flags = _flags_save_string; } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_actions)); - if (r->num_actions < 0 || r->num_actions > 1024) { + if (r->num_actions > 1024) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_actions)); @@ -1627,7 +1627,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceObjectSecurity(struct ndr_p NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.security_flags)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buffer_size)); - if (r->in.buffer_size < 0 || r->in.buffer_size > 0x40000) { + if (r->in.buffer_size > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buffer_size); @@ -1647,7 +1647,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceObjectSecurity(struct ndr_p _mem_save_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.needed)); - if (*r->out.needed < 0 || *r->out.needed > 0x40000) { + if (*r->out.needed > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -2729,7 +2729,7 @@ static enum ndr_err_code ndr_pull_svcctl_EnumDependentServicesW(struct ndr_pull NDR_PULL_SET_MEM_CTX(ndr, _mem_save_service_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.state)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); - if (r->in.buf_size < 0 || r->in.buf_size > 0x40000) { + if (r->in.buf_size > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->out.service_status, r->in.buf_size); @@ -2751,7 +2751,7 @@ static enum ndr_err_code ndr_pull_svcctl_EnumDependentServicesW(struct ndr_pull _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); - if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 0x40000) { + if (*r->out.bytes_needed > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -2761,7 +2761,7 @@ static enum ndr_err_code ndr_pull_svcctl_EnumDependentServicesW(struct ndr_pull _mem_save_services_returned_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.services_returned, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.services_returned)); - if (*r->out.services_returned < 0 || *r->out.services_returned > 0x40000) { + if (*r->out.services_returned > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_services_returned_0, LIBNDR_FLAG_REF_ALLOC); @@ -2870,7 +2870,7 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type)); NDR_CHECK(ndr_pull_svcctl_ServiceState(ndr, NDR_SCALARS, &r->in.state)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); - if (r->in.buf_size < 0 || r->in.buf_size > 0x40000) { + if (r->in.buf_size > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); @@ -2904,7 +2904,7 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); - if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 0x40000) { + if (*r->out.bytes_needed > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -2914,7 +2914,7 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd _mem_save_services_returned_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.services_returned, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.services_returned)); - if (*r->out.services_returned < 0 || *r->out.services_returned > 0x40000) { + if (*r->out.services_returned > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_services_returned_0, LIBNDR_FLAG_REF_ALLOC); @@ -3251,7 +3251,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceConfigW(struct ndr_pull *nd NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); - if (r->in.buf_size < 0 || r->in.buf_size > 8192) { + if (r->in.buf_size > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC(ndr, r->out.query); @@ -3273,7 +3273,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceConfigW(struct ndr_pull *nd _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); - if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) { + if (*r->out.bytes_needed > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -6087,7 +6087,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceConfig2W(struct ndr_pull *n NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_svcctl_ConfigLevel(ndr, NDR_SCALARS, &r->in.info_level)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); - if (r->in.buf_size < 0 || r->in.buf_size > 8192) { + if (r->in.buf_size > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); @@ -6107,7 +6107,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceConfig2W(struct ndr_pull *n _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); - if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) { + if (*r->out.bytes_needed > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -6195,7 +6195,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceStatusEx(struct ndr_pull *n NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_svcctl_StatusLevel(ndr, NDR_SCALARS, &r->in.info_level)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); - if (r->in.buf_size < 0 || r->in.buf_size > 8192) { + if (r->in.buf_size > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); @@ -6215,7 +6215,7 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceStatusEx(struct ndr_pull *n _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); - if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) { + if (*r->out.bytes_needed > 8192) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -6536,7 +6536,7 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type)); NDR_CHECK(ndr_pull_svcctl_ServiceState(ndr, NDR_SCALARS, &r->in.state)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); - if (r->in.buf_size < 0 || r->in.buf_size > 0x40000) { + if (r->in.buf_size > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); @@ -6549,7 +6549,7 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_resume_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.resume_handle, 0); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle)); - if (*r->in.resume_handle < 0 || *r->in.resume_handle > 0x40000) { + if (*r->in.resume_handle > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); @@ -6591,7 +6591,7 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); - if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 0x40000) { + if (*r->out.bytes_needed > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); @@ -6601,7 +6601,7 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_service_returned_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.service_returned, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.service_returned)); - if (*r->out.service_returned < 0 || *r->out.service_returned > 0x40000) { + if (*r->out.service_returned > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_service_returned_0, LIBNDR_FLAG_REF_ALLOC); @@ -6615,7 +6615,7 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_resume_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.resume_handle, 0); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.resume_handle)); - if (*r->out.resume_handle < 0 || *r->out.resume_handle > 0x40000) { + if (*r->out.resume_handle > 0x40000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); -- cgit From 8b618d0ba997a9b2254ae2ea530a80dd14631d59 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Jan 2009 13:15:23 +0100 Subject: Fix some real bugs found by "type-punned" gcc warnings Type-casting does not the right thing if used the way it used to be. The function arguments have not been uint32_t's, but the type cast made the calling routine believe so. Not good... The assignment xxx=account_policy_temp does however type-convert properly, potentially cutting off the top-bits. --- source3/rpc_server/srv_samr_nt.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 9984bf0cfcd..5f616ecd19c 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -1918,6 +1918,7 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p, uint32 reject_reason; struct samr_DomInfo1 *dominfo = NULL; struct samr_ChangeReject *reject = NULL; + uint32_t tmp; DEBUG(5,("_samr_ChangePasswordUser3: %d\n", __LINE__)); @@ -1967,11 +1968,11 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p, /* AS ROOT !!! */ - pdb_get_account_policy(AP_MIN_PASSWORD_LEN, - (uint32_t *)&dominfo->min_password_length); + pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp); + dominfo->min_password_length = tmp; - pdb_get_account_policy(AP_PASSWORD_HISTORY, - (uint32_t *)&dominfo->password_history_length); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp); + dominfo->password_history_length = tmp; pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &dominfo->password_properties); @@ -2833,10 +2834,11 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, /* AS ROOT !!! */ pdb_get_account_policy(AP_MIN_PASSWORD_LEN, - (uint32_t *)&dom_info->info1.min_password_length); + &account_policy_temp); + dom_info->info1.min_password_length = account_policy_temp; - pdb_get_account_policy(AP_PASSWORD_HISTORY, - (uint32_t *)&dom_info->info1.password_history_length); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp); + dom_info->info1.password_history_length = account_policy_temp; pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &dom_info->info1.password_properties); @@ -2965,7 +2967,8 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, u_reset_time = account_policy_temp * 60; pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, - (uint32_t *)&dom_info->info12.lockout_threshold); + &account_policy_temp); + dom_info->info12.lockout_threshold = account_policy_temp; /* !AS ROOT */ -- cgit From 30413f12b97149cde7aacfc8e7f2d9b63fa9da5c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 15 Jan 2009 21:56:03 +0100 Subject: Make rpc_read async --- source3/rpc_client/cli_pipe.c | 241 +++++++++++++++++++++++++++--------------- 1 file changed, 154 insertions(+), 87 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 28bbfa57b66..1f7e3326122 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -172,57 +172,6 @@ static uint32 get_rpc_call_id(void) return ++call_id; } -/******************************************************************* - Read from a RPC named pipe - ********************************************************************/ -static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name, - int fnum, char *buf, size_t size, - ssize_t *pnum_read) -{ - ssize_t num_read; - - num_read = cli_read(cli, fnum, buf, 0, size); - - DEBUG(5,("rpc_read_np: num_read = %d, to read: %u\n", (int)num_read, - (unsigned int)size)); - - /* - * A dos error of ERRDOS/ERRmoredata is not an error. - */ - if (cli_is_dos_error(cli)) { - uint32 ecode; - uint8 eclass; - cli_dos_error(cli, &eclass, &ecode); - if (eclass != ERRDOS && ecode != ERRmoredata) { - DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read " - "on fnum 0x%x\n", eclass, (unsigned int)ecode, - cli_errstr(cli), fnum)); - return dos_to_ntstatus(eclass, ecode); - } - } - - /* - * Likewise for NT_STATUS_BUFFER_TOO_SMALL - */ - if (cli_is_nt_error(cli)) { - if (!NT_STATUS_EQUAL(cli_nt_error(cli), - NT_STATUS_BUFFER_TOO_SMALL)) { - DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum " - "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum)); - return cli_nt_error(cli); - } - } - - if (num_read == -1) { - DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned " - "-1\n", fnum)); - return cli_get_nt_error(cli); - } - - *pnum_read = num_read; - return NT_STATUS_OK; -} - /* * Realloc pdu to have a least "size" bytes */ @@ -254,53 +203,171 @@ static bool rpc_grow_buffer(prs_struct *pdu, size_t size) Reads the whole size or give an error message ********************************************************************/ -static NTSTATUS rpc_read(struct rpc_pipe_client *cli, - char *pdata, size_t size) +struct rpc_read_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + char *data; + size_t size; + size_t num_read; +}; + +static void rpc_read_np_done(struct async_req *subreq); +static void rpc_read_sock_done(struct async_req *subreq); + +static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + char *data, size_t size) { - ssize_t num_read = 0; + struct async_req *result, *subreq; + struct rpc_read_state *state; - DEBUG(5, ("rpc_read: data_to_read: %u\n", (unsigned int)size)); + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; + } + state = talloc(result, struct rpc_read_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; - while (num_read < size) { - ssize_t thistime = 0; - NTSTATUS status; + state->ev = ev; + state->cli = cli; + state->data = data; + state->size = size; + state->num_read = 0; - switch (cli->transport_type) { - case NCACN_NP: - status = rpc_read_np(cli->trans.np.cli, - cli->trans.np.pipe_name, - cli->trans.np.fnum, - pdata + num_read, - size - num_read, &thistime); - break; - case NCACN_IP_TCP: - case NCACN_UNIX_STREAM: - status = NT_STATUS_OK; - thistime = sys_read(cli->trans.sock.fd, - pdata + num_read, - size - num_read); - if (thistime == -1) { - status = map_nt_error_from_unix(errno); - } - break; - default: - DEBUG(0, ("unknown transport type %d\n", - cli->transport_type)); - return NT_STATUS_INTERNAL_ERROR; - } + DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size)); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (cli->transport_type == NCACN_NP) { + subreq = cli_read_andx_send( + state, ev, cli->trans.np.cli, + cli->trans.np.fnum, 0, size); + if (subreq == NULL) { + DEBUG(10, ("cli_read_andx_send failed\n")); + goto fail; } - if (thistime == 0) { - return NT_STATUS_END_OF_FILE; + subreq->async.fn = rpc_read_np_done; + subreq->async.priv = result; + return result; + } + + if ((cli->transport_type == NCACN_IP_TCP) + || (cli->transport_type == NCACN_UNIX_STREAM)) { + subreq = recvall_send(state, ev, cli->trans.sock.fd, + data, size, 0); + if (subreq == NULL) { + DEBUG(10, ("recvall_send failed\n")); + goto fail; } + subreq->async.fn = rpc_read_sock_done; + subreq->async.priv = result; + return result; + } - num_read += thistime; + if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} +static void rpc_read_np_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_read_state); + NTSTATUS status; + ssize_t received; + uint8_t *rcvbuf; + + status = cli_read_andx_recv(subreq, &received, &rcvbuf); + /* + * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a + * child of that. + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { + status = NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(subreq); + async_req_error(req, status); + return; } - return NT_STATUS_OK; + memcpy(state->data + state->num_read, rcvbuf, received); + TALLOC_FREE(subreq); + + state->num_read += received; + + if (state->num_read == state->size) { + async_req_done(req); + return; + } + + subreq = cli_read_andx_send( + state, state->ev, state->cli->trans.np.cli, + state->cli->trans.np.fnum, 0, + state->size - state->num_read); + + if (async_req_nomem(subreq, req)) { + return; + } + + subreq->async.fn = rpc_read_np_done; + subreq->async.priv = req; +} + +static void rpc_read_sock_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + NTSTATUS status; + + status = recvall_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + async_req_done(req); +} + +static NTSTATUS rpc_read_recv(struct async_req *req) +{ + return async_req_simple_recv(req); +} + +static NTSTATUS rpc_read(struct rpc_pipe_client *cli, + char *pdata, size_t size) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = rpc_read_send(frame, ev, cli, pdata, size); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = rpc_read_recv(req); + fail: + TALLOC_FREE(frame); + return status; } /**************************************************************************** -- cgit From 5d71fe8043799abf098131fd924c35b49111bf54 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 16 Jan 2009 14:46:41 +0100 Subject: Make cli_pipe_get_current_pdu async, rename it to get_current_pdu --- source3/rpc_client/cli_pipe.c | 226 +++++++++++++++++++++++++++++++++++------- 1 file changed, 190 insertions(+), 36 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1f7e3326122..809fb1a9eb9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -370,58 +370,212 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, return status; } +static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli, + struct rpc_hdr_info *prhdr, + prs_struct *pdu) +{ + /* + * This next call sets the endian bit correctly in current_pdu. We + * will propagate this to rbuf later. + */ + + if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) { + DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + if (prhdr->frag_len > cli->max_recv_frag) { + DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d," + " we only allow %d\n", (int)prhdr->frag_len, + (int)cli->max_recv_frag)); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + return NT_STATUS_OK; +} + /**************************************************************************** Try and get a PDU's worth of data from current_pdu. If not, then read more from the wire. ****************************************************************************/ -static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu) +struct get_complete_pdu_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + struct rpc_hdr_info *prhdr; + prs_struct *pdu; +}; + +static void get_complete_pdu_got_header(struct async_req *subreq); +static void get_complete_pdu_got_rest(struct async_req *subreq); + +static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct rpc_hdr_info *prhdr, + prs_struct *pdu) { - NTSTATUS ret = NT_STATUS_OK; - uint32 current_pdu_len = prs_data_size(current_pdu); + struct async_req *result, *subreq; + struct get_complete_pdu_state *state; + uint32_t pdu_len; + NTSTATUS status; - /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */ - if (current_pdu_len < RPC_HEADER_LEN) { - if (!rpc_grow_buffer(current_pdu, RPC_HEADER_LEN)) { - return NT_STATUS_NO_MEMORY; - } - ret = rpc_read(cli, - prs_data_p(current_pdu) + current_pdu_len, - RPC_HEADER_LEN - current_pdu_len); - if (!NT_STATUS_IS_OK(ret)) { - return ret; - } - current_pdu_len = RPC_HEADER_LEN; + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; } + state = talloc(result, struct get_complete_pdu_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; - /* This next call sets the endian bit correctly in current_pdu. */ - /* We will propagate this to rbuf later. */ - if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) { - DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n")); - return NT_STATUS_BUFFER_TOO_SMALL; + state->ev = ev; + state->cli = cli; + state->prhdr = prhdr; + state->pdu = pdu; + + pdu_len = prs_data_size(pdu); + if (pdu_len < RPC_HEADER_LEN) { + if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq = rpc_read_send(state, state->ev, state->cli, + prs_data_p(state->pdu) + pdu_len, + RPC_HEADER_LEN - pdu_len); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = get_complete_pdu_got_header; + subreq->async.priv = result; + return result; } - if (prhdr->frag_len > cli->max_recv_frag) { - DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d," - " we only allow %d\n", (int)prhdr->frag_len, - (int)cli->max_recv_frag)); - return NT_STATUS_BUFFER_TOO_SMALL; + status = parse_rpc_header(cli, prhdr, pdu); + if (!NT_STATUS_IS_OK(status)) { + goto post_status; } - /* Ensure we have frag_len bytes of data. */ - if (current_pdu_len < prhdr->frag_len) { - if (!rpc_grow_buffer(current_pdu, prhdr->frag_len)) { - return NT_STATUS_NO_MEMORY; + /* + * Ensure we have frag_len bytes of data. + */ + if (pdu_len < prhdr->frag_len) { + if (!rpc_grow_buffer(pdu, prhdr->frag_len)) { + status = NT_STATUS_NO_MEMORY; + goto post_status; } - ret = rpc_read(cli, - prs_data_p(current_pdu) + current_pdu_len, - prhdr->frag_len - current_pdu_len); - if (!NT_STATUS_IS_OK(ret)) { - return ret; + subreq = rpc_read_send(state, state->ev, state->cli, + prs_data_p(pdu) + pdu_len, + prhdr->frag_len - pdu_len); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; } + subreq->async.fn = get_complete_pdu_got_rest; + subreq->async.priv = result; + return result; } - return NT_STATUS_OK; + status = NT_STATUS_OK; + post_status: + if (async_post_status(result, ev, status)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} + +static void get_complete_pdu_got_header(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct get_complete_pdu_state *state = talloc_get_type_abort( + req->private_data, struct get_complete_pdu_state); + NTSTATUS status; + + status = rpc_read_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + status = parse_rpc_header(state->cli, state->prhdr, state->pdu); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) { + async_req_error(req, NT_STATUS_NO_MEMORY); + return; + } + + /* + * We're here in this piece of code because we've read exactly + * RPC_HEADER_LEN bytes into state->pdu. + */ + + subreq = rpc_read_send(state, state->ev, state->cli, + prs_data_p(state->pdu) + RPC_HEADER_LEN, + state->prhdr->frag_len - RPC_HEADER_LEN); + if (async_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = get_complete_pdu_got_rest; + subreq->async.priv = req; +} + +static void get_complete_pdu_got_rest(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + NTSTATUS status; + + status = rpc_read_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +static NTSTATUS get_complete_pdu_recv(struct async_req *req) +{ + return async_req_simple_recv(req); +} + +static NTSTATUS get_complete_pdu(struct rpc_pipe_client *cli, + struct rpc_hdr_info *prhdr, + prs_struct *pdu) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = get_complete_pdu_send(frame, ev, cli, prhdr, pdu); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = get_complete_pdu_recv(req); + fail: + TALLOC_FREE(frame); + return status; } /**************************************************************************** @@ -1087,7 +1241,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, uint32 ret_data_len = 0; /* Ensure we have enough data for a pdu. */ - ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu); + ret = get_complete_pdu(cli, &rhdr, ¤t_pdu); if (!NT_STATUS_IS_OK(ret)) { goto err; } -- cgit From 173d6c84a68691f8bc00749509b8e3665bc159ee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 16 Jan 2009 14:47:21 +0100 Subject: Remove sync rpc_read wrapper --- source3/rpc_client/cli_pipe.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 809fb1a9eb9..4db30bb8c33 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -342,34 +342,6 @@ static NTSTATUS rpc_read_recv(struct async_req *req) return async_req_simple_recv(req); } -static NTSTATUS rpc_read(struct rpc_pipe_client *cli, - char *pdata, size_t size) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct event_context *ev; - struct async_req *req; - NTSTATUS status = NT_STATUS_NO_MEMORY; - - ev = event_context_init(frame); - if (ev == NULL) { - goto fail; - } - - req = rpc_read_send(frame, ev, cli, pdata, size); - if (req == NULL) { - goto fail; - } - - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } - - status = rpc_read_recv(req); - fail: - TALLOC_FREE(frame); - return status; -} - static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli, struct rpc_hdr_info *prhdr, prs_struct *pdu) -- cgit From 6d47418bc1f3de56e8ed78f2e908eb634230fee9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 16 Jan 2009 17:07:52 +0100 Subject: Make cli_api_pipe async Also move the transport switch to this routine --- source3/rpc_client/cli_pipe.c | 317 +++++++++++++++++++++++++++++------------- 1 file changed, 218 insertions(+), 99 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4db30bb8c33..d0411e5422c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1041,26 +1041,202 @@ static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -static bool cli_api_pipe(struct cli_state *cli, const char *pipe_name, - uint16 *setup, uint32 setup_count, - uint32 max_setup_count, - char *params, uint32 param_count, - uint32 max_param_count, - char *data, uint32 data_count, - uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count) -{ - cli_send_trans(cli, SMBtrans, - pipe_name, - 0,0, /* fid, flags */ - setup, setup_count, max_setup_count, - params, param_count, max_param_count, - data, data_count, max_data_count); - - return (cli_receive_trans(cli, SMBtrans, - rparam, (unsigned int *)rparam_count, - rdata, (unsigned int *)rdata_count)); +struct cli_api_pipe_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + uint32_t max_rdata_len; + uint8_t *rdata; + uint32_t rdata_len; +}; + +static void cli_api_pipe_np_trans_done(struct async_req *subreq); +static void cli_api_pipe_sock_send_done(struct async_req *subreq); +static void cli_api_pipe_sock_read_done(struct async_req *subreq); + +static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len) +{ + struct async_req *result, *subreq; + struct cli_api_pipe_state *state; + NTSTATUS status; + + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; + } + state = talloc(result, struct cli_api_pipe_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; + + state->ev = ev; + state->cli = cli; + state->max_rdata_len = max_rdata_len; + + if (state->max_rdata_len < RPC_HEADER_LEN) { + /* + * For a RPC reply we always need at least RPC_HEADER_LEN + * bytes. We check this here because we will receive + * RPC_HEADER_LEN bytes in cli_trans_sock_send_done. + */ + status = NT_STATUS_INVALID_PARAMETER; + goto post_status; + } + + if (cli->transport_type == NCACN_NP) { + + uint16_t setup[2]; + SSVAL(setup+0, 0, TRANSACT_DCERPCCMD); + SSVAL(setup+1, 0, cli->trans.np.fnum); + + subreq = cli_trans_send( + state, ev, cli->trans.np.cli, SMBtrans, + "\\PIPE\\", 0, 0, 0, setup, 2, 0, + NULL, 0, 0, data, data_len, max_rdata_len); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = cli_api_pipe_np_trans_done; + subreq->async.priv = result; + return result; + } + + if ((cli->transport_type == NCACN_IP_TCP) + || (cli->transport_type == NCACN_UNIX_STREAM)) { + subreq = sendall_send(state, ev, cli->trans.sock.fd, + data, data_len, 0); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = cli_api_pipe_sock_send_done; + subreq->async.priv = result; + return result; + } + + status = NT_STATUS_INVALID_PARAMETER; + + post_status: + if (async_post_status(result, ev, status)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} + +static void cli_api_pipe_np_trans_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct cli_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct cli_api_pipe_state); + NTSTATUS status; + + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, + &state->rdata, &state->rdata_len); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +static void cli_api_pipe_sock_send_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct cli_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct cli_api_pipe_state); + NTSTATUS status; + + status = sendall_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN); + if (async_req_nomem(state->rdata, req)) { + return; + } + state->rdata_len = RPC_HEADER_LEN; + + subreq = recvall_send(state, state->ev, state->cli->trans.sock.fd, + state->rdata, RPC_HEADER_LEN, 0); + if (async_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = cli_api_pipe_sock_read_done; + subreq->async.priv = req; +} + +static void cli_api_pipe_sock_read_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + NTSTATUS status; + + status = recvall_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, + uint8_t **prdata, uint32_t *prdata_len) +{ + struct cli_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct cli_api_pipe_state); + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + + *prdata = talloc_move(mem_ctx, &state->rdata); + *prdata_len = state->rdata_len; + return NT_STATUS_OK; +} + +static NTSTATUS cli_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, + uint8_t *data, uint32_t data_len, + uint32_t max_rdata_len, + uint8_t **prdata, uint32_t *prdata_len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = cli_api_pipe_send(frame, ev, cli, data, data_len, max_rdata_len); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = cli_api_pipe_recv(req, mem_ctx, prdata, prdata_len); + fail: + TALLOC_FREE(frame); + return status; } /**************************************************************************** @@ -1094,13 +1270,11 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */ uint8 expected_pkt_type) { - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - char *rparam = NULL; - uint32 rparam_len = 0; - char *pdata = prs_data_p(data); + NTSTATUS ret; uint32 data_len = prs_offset(data); - char *prdata = NULL; - uint32 rdata_len = 0; + uint8_t *rdata = NULL; + uint8_t *rdata_copy; + uint32_t rdata_len = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN; uint32 current_rbuf_offset = 0; prs_struct current_pdu; @@ -1115,78 +1289,17 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); - switch (cli->transport_type) { - case NCACN_NP: { - uint16 setup[2]; - /* Create setup parameters - must be in native byte order. */ - setup[0] = TRANSACT_DCERPCCMD; - setup[1] = cli->trans.np.fnum; /* Pipe file handle. */ - - /* - * Send the last (or only) fragment of an RPC request. For - * small amounts of data (about 1024 bytes or so) the RPC - * request and response appears in a SMBtrans request and - * response. - */ - - if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\", - setup, 2, 0, /* Setup, length, max */ - NULL, 0, 0, /* Params, length, max */ - pdata, data_len, max_data, /* data, length, - * max */ - &rparam, &rparam_len, /* return params, - * len */ - &prdata, &rdata_len)) /* return data, len */ - { - DEBUG(0, ("rpc_api_pipe: %s returned critical error. " - "Error was %s\n", - rpccli_pipe_txt(debug_ctx(), cli), - cli_errstr(cli->trans.np.cli))); - ret = cli_get_nt_error(cli->trans.np.cli); - SAFE_FREE(rparam); - SAFE_FREE(prdata); - goto err; - } - break; - } - case NCACN_IP_TCP: - case NCACN_UNIX_STREAM: - { - ssize_t nwritten, nread; - nwritten = write_data(cli->trans.sock.fd, pdata, data_len); - if (nwritten == -1) { - ret = map_nt_error_from_unix(errno); - DEBUG(0, ("rpc_api_pipe: write_data returned %s\n", - strerror(errno))); - goto err; - } - rparam = NULL; - prdata = SMB_MALLOC_ARRAY(char, 1); - if (prdata == NULL) { - return NT_STATUS_NO_MEMORY; - } - nread = sys_read(cli->trans.sock.fd, prdata, 1); - if (nread == 0) { - SAFE_FREE(prdata); - } - if (nread == -1) { - ret = NT_STATUS_END_OF_FILE; - goto err; - } - rdata_len = nread; - break; + ret = cli_api_pipe(talloc_tos(), cli, + (uint8_t *)prs_data_p(data), prs_offset(data), + cli->max_recv_frag + ? cli->max_recv_frag : RPC_MAX_PDU_FRAG_LEN, + &rdata, &rdata_len); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(ret))); + return ret; } - default: - DEBUG(0, ("unknown transport type %d\n", - cli->transport_type)); - return NT_STATUS_INTERNAL_ERROR; - } - - /* Throw away returned params - we know we won't use them. */ - - SAFE_FREE(rparam); - if (prdata == NULL) { + if (rdata == NULL) { DEBUG(3,("rpc_api_pipe: %s failed to return data.\n", rpccli_pipe_txt(debug_ctx(), cli))); /* Yes - some calls can truely return no data... */ @@ -1195,10 +1308,16 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, } /* - * Give this memory as dynamic to the current pdu. + * Give this memory as dynamic to the current pdu. Duplicating it + * sucks, but prs_struct doesn't know about talloc :-( */ - - prs_give_memory(¤t_pdu, prdata, rdata_len, True); + rdata_copy = (uint8_t *)memdup(rdata, rdata_len); + TALLOC_FREE(rdata); + if (rdata_copy == NULL) { + prs_mem_free(¤t_pdu); + return NT_STATUS_NO_MEMORY; + } + prs_give_memory(¤t_pdu, (char *)rdata_copy, rdata_len, true); /* Ensure we can mess with the return prs_struct. */ SMB_ASSERT(UNMARSHALLING(rbuf)); -- cgit From 5987c8269779ca2a7207c37a94b0e841a380d7d1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 16 Jan 2009 17:31:56 +0100 Subject: Always check the max send sizein rpc_api_pipe, not just with DEVELOPER --- source3/rpc_client/cli_pipe.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d0411e5422c..d6f18846b1d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1275,14 +1275,13 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, uint8_t *rdata = NULL; uint8_t *rdata_copy; uint32_t rdata_len = 0; - uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN; uint32 current_rbuf_offset = 0; prs_struct current_pdu; -#ifdef DEVELOPER - /* Ensure we're not sending too much. */ - SMB_ASSERT(data_len <= max_data); -#endif + if (data_len > cli->max_xmit_frag) { + /* Ensure we're not sending too much. */ + return NT_STATUS_INVALID_PARAMETER; + } /* Set up the current pdu parse struct. */ prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL); @@ -1291,9 +1290,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, ret = cli_api_pipe(talloc_tos(), cli, (uint8_t *)prs_data_p(data), prs_offset(data), - cli->max_recv_frag - ? cli->max_recv_frag : RPC_MAX_PDU_FRAG_LEN, - &rdata, &rdata_len); + cli->max_recv_frag, &rdata, &rdata_len); if (!NT_STATUS_IS_OK(ret)) { DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(ret))); return ret; -- cgit From 5e6f3eaae9435b1ab7b36726e7b898d4994fcebf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 12:18:29 +0100 Subject: Move initialization of the reply prs_struct to rpc_api_pipe --- source3/include/proto.h | 2 +- source3/include/rpc_client.h | 3 +-- source3/librpc/rpc/dcerpc.c | 3 ++- source3/rpc_client/cli_pipe.c | 23 ++++++++++------------- source3/rpc_client/ndr.c | 4 +--- 5 files changed, 15 insertions(+), 20 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d644b09a6ac..9210a5cfe23 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5197,7 +5197,7 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, /* The following definitions come from rpc_client/cli_pipe.c */ -NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, +NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, prs_struct *out_data); diff --git a/source3/include/rpc_client.h b/source3/include/rpc_client.h index 684044b8719..61b861c3b4e 100644 --- a/source3/include/rpc_client.h +++ b/source3/include/rpc_client.h @@ -49,9 +49,8 @@ if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \ return WERR_NOMEM;\ }\ - prs_init_empty( &r_ps, ctx, UNMARSHALL );\ if ( q_io_fn("", &q_in, &q_ps, 0) ) {\ - NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(pcli, opnum, &q_ps, &r_ps); \ + NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(ctx, pcli, opnum, &q_ps, &r_ps); \ if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\ prs_mem_free( &q_ps );\ prs_mem_free( &r_ps );\ diff --git a/source3/librpc/rpc/dcerpc.c b/source3/librpc/rpc/dcerpc.c index 69bfc6f329a..21a2004422c 100644 --- a/source3/librpc/rpc/dcerpc.c +++ b/source3/librpc/rpc/dcerpc.c @@ -84,7 +84,8 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) prs_init_empty( &r_ps, req, UNMARSHALL ); - status = rpc_api_pipe_req(req->pipe->rpc_cli, req->opnum, &req->q_ps, &r_ps); + status = rpc_api_pipe_req(req, req->pipe->rpc_cli, req->opnum, + &req->q_ps, &r_ps); prs_mem_free( &req->q_ps ); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d6f18846b1d..b93f6ed844d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1265,7 +1265,7 @@ static NTSTATUS cli_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, ****************************************************************************/ -static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, +static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */ prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */ uint8 expected_pkt_type) @@ -1284,7 +1284,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, } /* Set up the current pdu parse struct. */ - prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL); + prs_init_empty(¤t_pdu, talloc_tos(), UNMARSHALL); DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); @@ -1316,9 +1316,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, } prs_give_memory(¤t_pdu, (char *)rdata_copy, rdata_len, true); - /* Ensure we can mess with the return prs_struct. */ - SMB_ASSERT(UNMARSHALLING(rbuf)); - SMB_ASSERT(prs_data_size(rbuf) == 0); + /* Initialize the incoming PDU */ + prs_init_empty(rbuf, mem_ctx, UNMARSHALL); /* Make rbuf dynamic with no memory. */ prs_give_memory(rbuf, 0, 0, True); @@ -1952,7 +1951,7 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, and deals with signing/sealing details. ********************************************************************/ -NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, +NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, prs_struct *out_data) @@ -2055,7 +2054,8 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, /* Actually send the packet. */ if (flags & RPC_FLG_LAST) { /* Last packet - send the data, get the reply and return. */ - ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE); + ret = rpc_api_pipe(mem_ctx, cli, &outgoing_pdu, + out_data, RPC_RESPONSE); prs_mem_free(&outgoing_pdu); if ((DEBUGLEVEL >= 50) @@ -2481,9 +2481,9 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, /* Initialize the returning data struct. */ prs_mem_free(rbuf); - prs_init_empty(rbuf, talloc_tos(), UNMARSHALL); - nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP); + nt_status = rpc_api_pipe(talloc_tos(), cli, &rpc_out, rbuf, + RPC_ALTCONTRESP); prs_mem_free(&rpc_out); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -2559,11 +2559,8 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return status; } - /* Initialize the incoming data struct. */ - prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL); - /* send data on \PIPE\. receive a response */ - status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK); + status = rpc_api_pipe(talloc_tos(), cli, &rpc_out, &rbuf, RPC_BINDACK); prs_mem_free(&rpc_out); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source3/rpc_client/ndr.c b/source3/rpc_client/ndr.c index 9ada47a3f5d..9c3205eca3e 100644 --- a/source3/rpc_client/ndr.c +++ b/source3/rpc_client/ndr.c @@ -59,9 +59,7 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, talloc_free(push); - prs_init_empty( &r_ps, mem_ctx, UNMARSHALL ); - - status = rpc_api_pipe_req(cli, opnum, &q_ps, &r_ps); + status = rpc_api_pipe_req(mem_ctx, cli, opnum, &q_ps, &r_ps); prs_mem_free( &q_ps ); -- cgit From 761d164420dc4d16e8a0a937146e359130979df9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 12:50:02 +0100 Subject: Rename the async version of get_complete_pdu to get_complete_frag --- source3/rpc_client/cli_pipe.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b93f6ed844d..4c0cb78a04c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -371,24 +371,24 @@ static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli, from the wire. ****************************************************************************/ -struct get_complete_pdu_state { +struct get_complete_frag_state { struct event_context *ev; struct rpc_pipe_client *cli; struct rpc_hdr_info *prhdr; prs_struct *pdu; }; -static void get_complete_pdu_got_header(struct async_req *subreq); -static void get_complete_pdu_got_rest(struct async_req *subreq); +static void get_complete_frag_got_header(struct async_req *subreq); +static void get_complete_frag_got_rest(struct async_req *subreq); -static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx, +static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct rpc_pipe_client *cli, struct rpc_hdr_info *prhdr, prs_struct *pdu) { struct async_req *result, *subreq; - struct get_complete_pdu_state *state; + struct get_complete_frag_state *state; uint32_t pdu_len; NTSTATUS status; @@ -396,7 +396,7 @@ static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx, if (result == NULL) { return NULL; } - state = talloc(result, struct get_complete_pdu_state); + state = talloc(result, struct get_complete_frag_state); if (state == NULL) { goto fail; } @@ -420,7 +420,7 @@ static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = get_complete_pdu_got_header; + subreq->async.fn = get_complete_frag_got_header; subreq->async.priv = result; return result; } @@ -445,7 +445,7 @@ static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = get_complete_pdu_got_rest; + subreq->async.fn = get_complete_frag_got_rest; subreq->async.priv = result; return result; } @@ -460,12 +460,12 @@ static struct async_req *get_complete_pdu_send(TALLOC_CTX *mem_ctx, return NULL; } -static void get_complete_pdu_got_header(struct async_req *subreq) +static void get_complete_frag_got_header(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); - struct get_complete_pdu_state *state = talloc_get_type_abort( - req->private_data, struct get_complete_pdu_state); + struct get_complete_frag_state *state = talloc_get_type_abort( + req->private_data, struct get_complete_frag_state); NTSTATUS status; status = rpc_read_recv(subreq); @@ -497,11 +497,11 @@ static void get_complete_pdu_got_header(struct async_req *subreq) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = get_complete_pdu_got_rest; + subreq->async.fn = get_complete_frag_got_rest; subreq->async.priv = req; } -static void get_complete_pdu_got_rest(struct async_req *subreq) +static void get_complete_frag_got_rest(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); @@ -516,7 +516,7 @@ static void get_complete_pdu_got_rest(struct async_req *subreq) async_req_done(req); } -static NTSTATUS get_complete_pdu_recv(struct async_req *req) +static NTSTATUS get_complete_frag_recv(struct async_req *req) { return async_req_simple_recv(req); } @@ -535,7 +535,7 @@ static NTSTATUS get_complete_pdu(struct rpc_pipe_client *cli, goto fail; } - req = get_complete_pdu_send(frame, ev, cli, prhdr, pdu); + req = get_complete_frag_send(frame, ev, cli, prhdr, pdu); if (req == NULL) { goto fail; } @@ -544,7 +544,7 @@ static NTSTATUS get_complete_pdu(struct rpc_pipe_client *cli, event_loop_once(ev); } - status = get_complete_pdu_recv(req); + status = get_complete_frag_recv(req); fail: TALLOC_FREE(frame); return status; -- cgit From f6740aa7ad1b553410ffbc9fb54916d6a385a753 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 13:33:34 +0100 Subject: Make rpc_api_pipe async --- source3/rpc_client/cli_pipe.c | 284 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4c0cb78a04c..c924436faa4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1265,6 +1265,8 @@ static NTSTATUS cli_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, ****************************************************************************/ +#if 0 + static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */ prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */ @@ -1398,6 +1400,288 @@ static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, prs_mem_free(rbuf); return ret; } +#endif + +struct rpc_api_pipe_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + uint8_t expected_pkt_type; + + prs_struct incoming_frag; + struct rpc_hdr_info rhdr; + + prs_struct incoming_pdu; /* Incoming reply */ + uint32_t incoming_pdu_offset; +}; + +static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state) +{ + prs_mem_free(&state->incoming_frag); + prs_mem_free(&state->incoming_pdu); + return 0; +} + +static void rpc_api_pipe_trans_done(struct async_req *subreq); +static void rpc_api_pipe_got_pdu(struct async_req *subreq); + +static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + prs_struct *data, /* Outgoing PDU */ + uint8_t expected_pkt_type) +{ + struct async_req *result, *subreq; + struct rpc_api_pipe_state *state; + NTSTATUS status; + + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; + } + state = talloc(result, struct rpc_api_pipe_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; + + state->ev = ev; + state->cli = cli; + state->expected_pkt_type = expected_pkt_type; + state->incoming_pdu_offset = 0; + + prs_init_empty(&state->incoming_frag, state, UNMARSHALL); + + prs_init_empty(&state->incoming_pdu, state, UNMARSHALL); + /* Make incoming_pdu dynamic with no memory. */ + prs_give_memory(&state->incoming_pdu, 0, 0, true); + + talloc_set_destructor(state, rpc_api_pipe_state_destructor); + + /* + * Ensure we're not sending too much. + */ + if (prs_offset(data) > cli->max_xmit_frag) { + status = NT_STATUS_INVALID_PARAMETER; + goto post_status; + } + + DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); + + subreq = cli_api_pipe_send(state, ev, cli, + (uint8_t *)prs_data_p(data), + prs_offset(data), cli->max_recv_frag); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = rpc_api_pipe_trans_done; + subreq->async.priv = result; + return result; + + post_status: + if (async_post_status(result, ev, status)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_api_pipe_trans_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct rpc_api_pipe_state); + NTSTATUS status; + uint8_t *rdata = NULL; + uint32_t rdata_len = 0; + char *rdata_copy; + + status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status))); + async_req_error(req, status); + return; + } + + if (rdata == NULL) { + DEBUG(3,("rpc_api_pipe: %s failed to return data.\n", + rpccli_pipe_txt(debug_ctx(), state->cli))); + async_req_done(req); + return; + } + + /* + * Give the memory received from cli_trans as dynamic to the current + * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc + * :-( + */ + rdata_copy = (char *)memdup(rdata, rdata_len); + TALLOC_FREE(rdata); + if (async_req_nomem(rdata_copy, req)) { + return; + } + prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true); + + /* Ensure we have enough data for a pdu. */ + subreq = get_complete_frag_send(state, state->ev, state->cli, + &state->rhdr, &state->incoming_frag); + if (async_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = rpc_api_pipe_got_pdu; + subreq->async.priv = req; +} + +static void rpc_api_pipe_got_pdu(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct rpc_api_pipe_state); + NTSTATUS status; + char *rdata = NULL; + uint32_t rdata_len = 0; + + status = get_complete_frag_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5, ("get_complete_frag failed: %s\n", + nt_errstr(status))); + async_req_error(req, status); + return; + } + + status = cli_pipe_validate_current_pdu( + state->cli, &state->rhdr, &state->incoming_frag, + state->expected_pkt_type, &rdata, &rdata_len, + &state->incoming_pdu); + + DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n", + (unsigned)prs_data_size(&state->incoming_frag), + (unsigned)state->incoming_pdu_offset, + nt_errstr(status))); + + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + if ((state->rhdr.flags & RPC_FLG_FIRST) + && (state->rhdr.pack_type[0] == 0)) { + /* + * Set the data type correctly for big-endian data on the + * first packet. + */ + DEBUG(10,("rpc_api_pipe: On %s PDU data format is " + "big-endian.\n", + rpccli_pipe_txt(debug_ctx(), state->cli))); + prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN); + } + /* + * Check endianness on subsequent packets. + */ + if (state->incoming_frag.bigendian_data + != state->incoming_pdu.bigendian_data) { + DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to " + "%s\n", + state->incoming_pdu.bigendian_data?"big":"little", + state->incoming_frag.bigendian_data?"big":"little")); + async_req_error(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + /* Now copy the data portion out of the pdu into rbuf. */ + if (!prs_force_grow(&state->incoming_pdu, rdata_len)) { + async_req_error(req, NT_STATUS_NO_MEMORY); + return; + } + + memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset, + rdata, (size_t)rdata_len); + state->incoming_pdu_offset += rdata_len; + + status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr, + &state->incoming_frag); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + if (state->rhdr.flags & RPC_FLG_LAST) { + DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n", + rpccli_pipe_txt(debug_ctx(), state->cli), + (unsigned)prs_data_size(&state->incoming_pdu))); + async_req_done(req); + return; + } + + subreq = get_complete_frag_send(state, state->ev, state->cli, + &state->rhdr, &state->incoming_frag); + if (async_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = rpc_api_pipe_got_pdu; + subreq->async.priv = req; +} + +static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, + prs_struct *reply_pdu) +{ + struct rpc_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct rpc_api_pipe_state); + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + + *reply_pdu = state->incoming_pdu; + reply_pdu->mem_ctx = mem_ctx; + + /* + * Prevent state->incoming_pdu from being freed in + * rpc_api_pipe_state_destructor() + */ + prs_init_empty(&state->incoming_pdu, state, UNMARSHALL); + + return NT_STATUS_OK; +} + +static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, + prs_struct *data, /* Outgoing pdu fragment, + * already formatted for + * send. */ + prs_struct *rbuf, /* Incoming reply - return as + * an NDR stream. */ + uint8 expected_pkt_type) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = rpc_api_pipe_send(frame, ev, cli, data, expected_pkt_type); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = rpc_api_pipe_recv(req, mem_ctx, rbuf); + fail: + TALLOC_FREE(frame); + return status; +} /******************************************************************* Creates krb5 auth bind. -- cgit From f96335afc0602e5874e11c505a4087e32873060e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 13:58:36 +0100 Subject: Remove unused sync functions --- source3/rpc_client/cli_pipe.c | 196 ------------------------------------------ 1 file changed, 196 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c924436faa4..3a5932297f8 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -521,35 +521,6 @@ static NTSTATUS get_complete_frag_recv(struct async_req *req) return async_req_simple_recv(req); } -static NTSTATUS get_complete_pdu(struct rpc_pipe_client *cli, - struct rpc_hdr_info *prhdr, - prs_struct *pdu) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct event_context *ev; - struct async_req *req; - NTSTATUS status = NT_STATUS_NO_MEMORY; - - ev = event_context_init(frame); - if (ev == NULL) { - goto fail; - } - - req = get_complete_frag_send(frame, ev, cli, prhdr, pdu); - if (req == NULL) { - goto fail; - } - - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } - - status = get_complete_frag_recv(req); - fail: - TALLOC_FREE(frame); - return status; -} - /**************************************************************************** NTLMSSP specific sign/seal. Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process. @@ -1209,36 +1180,6 @@ static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -static NTSTATUS cli_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, - uint8_t *data, uint32_t data_len, - uint32_t max_rdata_len, - uint8_t **prdata, uint32_t *prdata_len) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct event_context *ev; - struct async_req *req; - NTSTATUS status = NT_STATUS_NO_MEMORY; - - ev = event_context_init(frame); - if (ev == NULL) { - goto fail; - } - - req = cli_api_pipe_send(frame, ev, cli, data, data_len, max_rdata_len); - if (req == NULL) { - goto fail; - } - - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } - - status = cli_api_pipe_recv(req, mem_ctx, prdata, prdata_len); - fail: - TALLOC_FREE(frame); - return status; -} - /**************************************************************************** Send data on an rpc pipe via trans. The prs_struct data must be the last pdu fragment of an NDR data stream. @@ -1265,143 +1206,6 @@ static NTSTATUS cli_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, ****************************************************************************/ -#if 0 - -static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, - prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */ - prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */ - uint8 expected_pkt_type) -{ - NTSTATUS ret; - uint32 data_len = prs_offset(data); - uint8_t *rdata = NULL; - uint8_t *rdata_copy; - uint32_t rdata_len = 0; - uint32 current_rbuf_offset = 0; - prs_struct current_pdu; - - if (data_len > cli->max_xmit_frag) { - /* Ensure we're not sending too much. */ - return NT_STATUS_INVALID_PARAMETER; - } - - /* Set up the current pdu parse struct. */ - prs_init_empty(¤t_pdu, talloc_tos(), UNMARSHALL); - - DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); - - ret = cli_api_pipe(talloc_tos(), cli, - (uint8_t *)prs_data_p(data), prs_offset(data), - cli->max_recv_frag, &rdata, &rdata_len); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(ret))); - return ret; - } - - if (rdata == NULL) { - DEBUG(3,("rpc_api_pipe: %s failed to return data.\n", - rpccli_pipe_txt(debug_ctx(), cli))); - /* Yes - some calls can truely return no data... */ - prs_mem_free(¤t_pdu); - return NT_STATUS_OK; - } - - /* - * Give this memory as dynamic to the current pdu. Duplicating it - * sucks, but prs_struct doesn't know about talloc :-( - */ - rdata_copy = (uint8_t *)memdup(rdata, rdata_len); - TALLOC_FREE(rdata); - if (rdata_copy == NULL) { - prs_mem_free(¤t_pdu); - return NT_STATUS_NO_MEMORY; - } - prs_give_memory(¤t_pdu, (char *)rdata_copy, rdata_len, true); - - /* Initialize the incoming PDU */ - prs_init_empty(rbuf, mem_ctx, UNMARSHALL); - - /* Make rbuf dynamic with no memory. */ - prs_give_memory(rbuf, 0, 0, True); - - while(1) { - RPC_HDR rhdr; - char *ret_data = NULL; - uint32 ret_data_len = 0; - - /* Ensure we have enough data for a pdu. */ - ret = get_complete_pdu(cli, &rhdr, ¤t_pdu); - if (!NT_STATUS_IS_OK(ret)) { - goto err; - } - - /* We pass in rbuf here so if the alloc hint is set correctly - we can set the output size and avoid reallocs. */ - - ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type, - &ret_data, &ret_data_len, rbuf); - - DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n", - prs_data_size(¤t_pdu), current_rbuf_offset )); - - if (!NT_STATUS_IS_OK(ret)) { - goto err; - } - - if ((rhdr.flags & RPC_FLG_FIRST)) { - if (rhdr.pack_type[0] == 0) { - /* Set the data type correctly for big-endian data on the first packet. */ - DEBUG(10,("rpc_api_pipe: On %s " - "PDU data format is big-endian.\n", - rpccli_pipe_txt(debug_ctx(), cli))); - - prs_set_endian_data(rbuf, RPC_BIG_ENDIAN); - } else { - /* Check endianness on subsequent packets. */ - if (current_pdu.bigendian_data != rbuf->bigendian_data) { - DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n", - rbuf->bigendian_data ? "big" : "little", - current_pdu.bigendian_data ? "big" : "little" )); - ret = NT_STATUS_INVALID_PARAMETER; - goto err; - } - } - } - - /* Now copy the data portion out of the pdu into rbuf. */ - if (!prs_force_grow(rbuf, ret_data_len)) { - ret = NT_STATUS_NO_MEMORY; - goto err; - } - memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len); - current_rbuf_offset += ret_data_len; - - /* See if we've finished with all the data in current_pdu yet ? */ - ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu); - if (!NT_STATUS_IS_OK(ret)) { - goto err; - } - - if (rhdr.flags & RPC_FLG_LAST) { - break; /* We're done. */ - } - } - - DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n", - rpccli_pipe_txt(debug_ctx(), cli), - (unsigned int)prs_data_size(rbuf) )); - - prs_mem_free(¤t_pdu); - return NT_STATUS_OK; - - err: - - prs_mem_free(¤t_pdu); - prs_mem_free(rbuf); - return ret; -} -#endif - struct rpc_api_pipe_state { struct event_context *ev; struct rpc_pipe_client *cli; -- cgit From c655f19e1fa3a1443fd16927d37035a4f4cf46aa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 15:07:52 +0100 Subject: Add rpc_write_send/recv --- source3/rpc_client/cli_pipe.c | 131 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3a5932297f8..2cb9f08a53e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -342,6 +342,137 @@ static NTSTATUS rpc_read_recv(struct async_req *req) return async_req_simple_recv(req); } +struct rpc_write_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + const char *data; + size_t size; + size_t num_written; +}; + +static void rpc_write_np_done(struct async_req *subreq); +static void rpc_write_sock_done(struct async_req *subreq); + +static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + const char *data, size_t size) +{ + struct async_req *result, *subreq; + struct rpc_write_state *state; + + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; + } + state = talloc(result, struct rpc_write_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; + + state->ev = ev; + state->cli = cli; + state->data = data; + state->size = size; + state->num_written = 0; + + DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size)); + + if (cli->transport_type == NCACN_NP) { + subreq = cli_write_andx_send( + state, ev, cli->trans.np.cli, + cli->trans.np.fnum, 8, /* 8 means message mode. */ + (uint8_t *)data, 0, size); + if (subreq == NULL) { + DEBUG(10, ("cli_write_andx_send failed\n")); + goto fail; + } + subreq->async.fn = rpc_write_np_done; + subreq->async.priv = result; + return result; + } + + if ((cli->transport_type == NCACN_IP_TCP) + || (cli->transport_type == NCACN_UNIX_STREAM)) { + subreq = sendall_send(state, ev, cli->trans.sock.fd, + data, size, 0); + if (subreq == NULL) { + DEBUG(10, ("sendall_send failed\n")); + goto fail; + } + subreq->async.fn = rpc_write_sock_done; + subreq->async.priv = result; + return result; + } + + if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_write_np_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_write_state); + NTSTATUS status; + size_t written; + + status = cli_write_andx_recv(subreq, &written); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + state->num_written += written; + + if (state->num_written == state->size) { + async_req_done(req); + return; + } + + subreq = cli_write_andx_send( + state, state->ev, state->cli->trans.np.cli, + state->cli->trans.np.fnum, 8, + (uint8_t *)(state->data + state->num_written), + 0, state->size - state->num_written); + + if (async_req_nomem(subreq, req)) { + return; + } + + subreq->async.fn = rpc_write_np_done; + subreq->async.priv = req; +} + +static void rpc_write_sock_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + NTSTATUS status; + + status = sendall_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + async_req_done(req); +} + +static NTSTATUS rpc_write_recv(struct async_req *req) +{ + return async_req_simple_recv(req); +} + + static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli, struct rpc_hdr_info *prhdr, prs_struct *pdu) -- cgit From 8a1c6c2c994b2eac05e8cbc3c692d7367b687d32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 17:52:22 +0100 Subject: Tiny simplification of prs_set_offset --- source3/rpc_parse/parse_prs.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index d549265fa11..1332a8311a1 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -361,13 +361,10 @@ uint32 prs_offset(prs_struct *ps) bool prs_set_offset(prs_struct *ps, uint32 offset) { - if(offset <= ps->data_offset) { - ps->data_offset = offset; - return True; - } - - if(!prs_grow(ps, offset - ps->data_offset)) + if ((offset > ps->data_offset) + && !prs_grow(ps, offset - ps->data_offset)) { return False; + } ps->data_offset = offset; return True; -- cgit From 396ed3b36359367e1efd49395cd9e6dc6f7c98fc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 17:52:35 +0100 Subject: Add async rpc_api_pipe_req --- source3/include/proto.h | 7 + source3/rpc_client/cli_pipe.c | 308 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 315 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9210a5cfe23..72b95d44c3a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5197,6 +5197,13 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, /* The following definitions come from rpc_client/cli_pipe.c */ +struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t op_num, + prs_struct *req_data); +NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, + prs_struct *reply_pdu); NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2cb9f08a53e..bedd652fd68 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2170,6 +2170,8 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, and deals with signing/sealing details. ********************************************************************/ +#if 0 + NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, @@ -2335,6 +2337,312 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, } } } + +#endif + +struct rpc_api_pipe_req_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + uint8_t op_num; + uint32_t call_id; + prs_struct *req_data; + uint32_t req_data_sent; + prs_struct outgoing_frag; + prs_struct reply_pdu; +}; + +static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s) +{ + prs_mem_free(&s->outgoing_frag); + prs_mem_free(&s->reply_pdu); + return 0; +} + +static void rpc_api_pipe_req_write_done(struct async_req *subreq); +static void rpc_api_pipe_req_done(struct async_req *subreq); +static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, + bool *is_last_frag); + +struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t op_num, + prs_struct *req_data) +{ + struct async_req *result, *subreq; + struct rpc_api_pipe_req_state *state; + NTSTATUS status; + bool is_last_frag; + + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; + } + state = talloc(result, struct rpc_api_pipe_req_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; + + state->ev = ev; + state->cli = cli; + state->op_num = op_num; + state->req_data = req_data; + state->req_data_sent = 0; + state->call_id = get_rpc_call_id(); + + if (cli->max_xmit_frag + < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) { + /* Server is screwed up ! */ + status = NT_STATUS_INVALID_PARAMETER; + goto post_status; + } + + prs_init_empty(&state->reply_pdu, state, UNMARSHALL); + + if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag, + state, MARSHALL)) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + + talloc_set_destructor(state, rpc_api_pipe_req_state_destructor); + + status = prepare_next_frag(state, &is_last_frag); + if (!NT_STATUS_IS_OK(status)) { + goto post_status; + } + + if (is_last_frag) { + subreq = rpc_api_pipe_send(state, ev, state->cli, + &state->outgoing_frag, + RPC_RESPONSE); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = rpc_api_pipe_req_done; + subreq->async.priv = result; + } else { + subreq = rpc_write_send(state, ev, cli, + prs_data_p(&state->outgoing_frag), + prs_offset(&state->outgoing_frag)); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = rpc_api_pipe_req_write_done; + subreq->async.priv = result; + } + return result; + + post_status: + if (async_post_status(result, ev, status)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} + +static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, + bool *is_last_frag) +{ + RPC_HDR hdr; + RPC_HDR_REQ hdr_req; + uint32_t data_sent_thistime; + uint16_t auth_len; + uint16_t frag_len; + uint8_t flags = 0; + uint32_t ss_padding; + uint32_t data_left; + char pad[8] = { 0, }; + NTSTATUS status; + + data_left = prs_offset(state->req_data) - state->req_data_sent; + + data_sent_thistime = calculate_data_len_tosend( + state->cli, data_left, &frag_len, &auth_len, &ss_padding); + + if (state->req_data_sent == 0) { + flags = RPC_FLG_FIRST; + } + + if (data_sent_thistime == data_left) { + flags |= RPC_FLG_LAST; + } + + if (!prs_set_offset(&state->outgoing_frag, 0)) { + return NT_STATUS_NO_MEMORY; + } + + /* Create and marshall the header and request header. */ + init_rpc_hdr(&hdr, RPC_REQUEST, flags, state->call_id, frag_len, + auth_len); + + if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) { + return NT_STATUS_NO_MEMORY; + } + + /* Create the rpc request RPC_HDR_REQ */ + init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data), + state->op_num); + + if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req, + &state->outgoing_frag, 0)) { + return NT_STATUS_NO_MEMORY; + } + + /* Copy in the data, plus any ss padding. */ + if (!prs_append_some_prs_data(&state->outgoing_frag, + state->req_data, state->req_data_sent, + data_sent_thistime)) { + return NT_STATUS_NO_MEMORY; + } + + /* Copy the sign/seal padding data. */ + if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) { + return NT_STATUS_NO_MEMORY; + } + + /* Generate any auth sign/seal and add the auth footer. */ + switch (state->cli->auth->auth_type) { + case PIPE_AUTH_TYPE_NONE: + status = NT_STATUS_OK; + break; + case PIPE_AUTH_TYPE_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding, + &state->outgoing_frag); + break; + case PIPE_AUTH_TYPE_SCHANNEL: + status = add_schannel_auth_footer(state->cli, &hdr, ss_padding, + &state->outgoing_frag); + break; + default: + status = NT_STATUS_INVALID_PARAMETER; + break; + } + + state->req_data_sent += data_sent_thistime; + *is_last_frag = ((flags & RPC_FLG_LAST) != 0); + + return status; +} + +static void rpc_api_pipe_req_write_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_api_pipe_req_state *state = talloc_get_type_abort( + req->private_data, struct rpc_api_pipe_req_state); + NTSTATUS status; + bool is_last_frag; + + status = rpc_write_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + status = prepare_next_frag(state, &is_last_frag); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + if (is_last_frag) { + subreq = rpc_api_pipe_send(state, state->ev, state->cli, + &state->outgoing_frag, + RPC_RESPONSE); + if (async_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = rpc_api_pipe_req_done; + subreq->async.priv = req; + } else { + subreq = rpc_write_send(state, state->ev, state->cli, + prs_data_p(&state->outgoing_frag), + prs_offset(&state->outgoing_frag)); + if (async_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = rpc_api_pipe_req_write_done; + subreq->async.priv = req; + } +} + +static void rpc_api_pipe_req_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_api_pipe_req_state *state = talloc_get_type_abort( + req->private_data, struct rpc_api_pipe_req_state); + NTSTATUS status; + + status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, + prs_struct *reply_pdu) +{ + struct rpc_api_pipe_req_state *state = talloc_get_type_abort( + req->private_data, struct rpc_api_pipe_req_state); + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + + *reply_pdu = state->reply_pdu; + reply_pdu->mem_ctx = mem_ctx; + + /* + * Prevent state->req_pdu from being freed in + * rpc_api_pipe_req_state_destructor() + */ + prs_init_empty(&state->reply_pdu, state, UNMARSHALL); + + return NT_STATUS_OK; +} + +NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, + uint8 op_num, + prs_struct *in_data, + prs_struct *out_data) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = rpc_api_pipe_req_recv(req, mem_ctx, out_data); + fail: + TALLOC_FREE(frame); + return status; +} + #if 0 /**************************************************************************** Set the handle state. -- cgit From 3f9f188877de8a4c0b2883e2360f2834c41b66c1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 17:53:05 +0100 Subject: Remove sync rpc_api_pipe_req --- source3/rpc_client/cli_pipe.c | 170 ------------------------------------------ 1 file changed, 170 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bedd652fd68..35c3a9301f2 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2170,176 +2170,6 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, and deals with signing/sealing details. ********************************************************************/ -#if 0 - -NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, - uint8 op_num, - prs_struct *in_data, - prs_struct *out_data) -{ - NTSTATUS ret; - uint32 data_left = prs_offset(in_data); - uint32 alloc_hint = prs_offset(in_data); - uint32 data_sent_thistime = 0; - uint32 current_data_offset = 0; - uint32 call_id = get_rpc_call_id(); - char pad[8]; - prs_struct outgoing_pdu; - - memset(pad, '\0', 8); - - if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) { - /* Server is screwed up ! */ - return NT_STATUS_INVALID_PARAMETER; - } - - if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL)) - return NT_STATUS_NO_MEMORY; - - while (1) { - RPC_HDR hdr; - RPC_HDR_REQ hdr_req; - uint16 auth_len = 0; - uint16 frag_len = 0; - uint8 flags = 0; - uint32 ss_padding = 0; - ssize_t num_written; - - data_sent_thistime = calculate_data_len_tosend(cli, data_left, - &frag_len, &auth_len, &ss_padding); - - if (current_data_offset == 0) { - flags = RPC_FLG_FIRST; - } - - if (data_sent_thistime == data_left) { - flags |= RPC_FLG_LAST; - } - - /* Create and marshall the header and request header. */ - init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len); - - if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) { - prs_mem_free(&outgoing_pdu); - return NT_STATUS_NO_MEMORY; - } - - /* Create the rpc request RPC_HDR_REQ */ - init_rpc_hdr_req(&hdr_req, alloc_hint, op_num); - - if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) { - prs_mem_free(&outgoing_pdu); - return NT_STATUS_NO_MEMORY; - } - - /* Copy in the data, plus any ss padding. */ - if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) { - prs_mem_free(&outgoing_pdu); - return NT_STATUS_NO_MEMORY; - } - - /* Copy the sign/seal padding data. */ - if (ss_padding) { - if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) { - prs_mem_free(&outgoing_pdu); - return NT_STATUS_NO_MEMORY; - } - } - - /* Generate any auth sign/seal and add the auth footer. */ - if (auth_len) { - switch (cli->auth->auth_type) { - case PIPE_AUTH_TYPE_NONE: - break; - case PIPE_AUTH_TYPE_NTLMSSP: - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu); - if (!NT_STATUS_IS_OK(ret)) { - prs_mem_free(&outgoing_pdu); - return ret; - } - break; - case PIPE_AUTH_TYPE_SCHANNEL: - ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu); - if (!NT_STATUS_IS_OK(ret)) { - prs_mem_free(&outgoing_pdu); - return ret; - } - break; - default: - smb_panic("bad auth type"); - break; /* notreached */ - } - } - - /* Actually send the packet. */ - if (flags & RPC_FLG_LAST) { - /* Last packet - send the data, get the reply and return. */ - ret = rpc_api_pipe(mem_ctx, cli, &outgoing_pdu, - out_data, RPC_RESPONSE); - prs_mem_free(&outgoing_pdu); - - if ((DEBUGLEVEL >= 50) - && (cli->transport_type == NCACN_NP)) { - char *dump_name = NULL; - /* Also capture received data */ - if (asprintf(&dump_name, "%s/reply_%s_%d", - get_dyn_LOGFILEBASE(), - cli->trans.np.pipe_name, op_num) > 0) { - prs_dump(dump_name, op_num, out_data); - SAFE_FREE(dump_name); - } - } - - return ret; - } - - switch (cli->transport_type) { - case NCACN_NP: - num_written = cli_write(cli->trans.np.cli, - cli->trans.np.fnum, - 8, /* 8 means message mode. */ - prs_data_p(&outgoing_pdu), - (off_t)0, - (size_t)hdr.frag_len); - - if (num_written != hdr.frag_len) { - prs_mem_free(&outgoing_pdu); - return cli_get_nt_error(cli->trans.np.cli); - } - break; - case NCACN_IP_TCP: - case NCACN_UNIX_STREAM: - num_written = write_data( - cli->trans.sock.fd, - prs_data_p(&outgoing_pdu), - (size_t)hdr.frag_len); - if (num_written != hdr.frag_len) { - NTSTATUS status; - status = map_nt_error_from_unix(errno); - prs_mem_free(&outgoing_pdu); - return status; - } - break; - default: - DEBUG(0, ("unknown transport type %d\n", - cli->transport_type)); - return NT_STATUS_INTERNAL_ERROR; - } - - current_data_offset += data_sent_thistime; - data_left -= data_sent_thistime; - - /* Reset the marshalling position back to zero. */ - if (!prs_set_offset(&outgoing_pdu, 0)) { - prs_mem_free(&outgoing_pdu); - return NT_STATUS_NO_MEMORY; - } - } -} - -#endif - struct rpc_api_pipe_req_state { struct event_context *ev; struct rpc_pipe_client *cli; -- cgit From ecb5184ce57259c709d728ed5f7be1bdf666bbcc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Jan 2009 19:19:04 +0100 Subject: Fix an uninitialized variable --- source3/rpc_client/cli_pipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 35c3a9301f2..c32124f678d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2148,6 +2148,7 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, RPC_HDR_AUTH_LEN - *p_auth_len; data_len = MIN(data_space, data_left); + *p_ss_padding = 0; if (data_len % 8) { *p_ss_padding = 8 - (data_len % 8); } -- cgit From 28c35b4c0456ce62bf1a492ad9c1b223e2f31816 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Jan 2009 12:12:15 +0100 Subject: Make rpc_pipe_bind async --- source3/include/proto.h | 5 + source3/rpc_client/cli_pipe.c | 447 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 452 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 72b95d44c3a..71ad2590850 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5208,6 +5208,11 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, prs_struct *out_data); +struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth); +NTSTATUS rpc_pipe_bind_recv(struct async_req *req); NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, struct cli_pipe_auth_data *auth); unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c32124f678d..63d3689620f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1585,6 +1585,7 @@ static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +#if 0 static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, prs_struct *data, /* Outgoing pdu fragment, * already formatted for @@ -1617,6 +1618,7 @@ static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, TALLOC_FREE(frame); return status; } +#endif /******************************************************************* Creates krb5 auth bind. @@ -2613,6 +2615,7 @@ static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli, Create and send the third packet in an RPC auth. ****************************************************************************/ +#if 0 static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, RPC_HDR *phdr, prs_struct *rbuf, @@ -2709,6 +2712,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, data_blob_free(&server_response); return NT_STATUS_OK; } +#endif /******************************************************************* Creates a DCE/RPC bind alter context authentication request which @@ -2756,6 +2760,7 @@ static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id, and gets a response. ********************************************************************/ +#if 0 static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, RPC_HDR *phdr, prs_struct *rbuf, @@ -2879,11 +2884,13 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, return NT_STATUS_OK; } +#endif /**************************************************************************** Do an rpc bind. ****************************************************************************/ +#if 0 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, struct cli_pipe_auth_data *auth) { @@ -3013,6 +3020,446 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, prs_mem_free(&rbuf); return NT_STATUS_OK; } +#endif + +struct rpc_pipe_bind_state { + struct event_context *ev; + struct rpc_pipe_client *cli; + prs_struct rpc_out; + uint32_t rpc_call_id; +}; + +static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state) +{ + prs_mem_free(&state->rpc_out); + return 0; +} + +static void rpc_pipe_bind_step_one_done(struct async_req *subreq); +static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, + struct rpc_pipe_bind_state *state, + struct rpc_hdr_info *phdr, + prs_struct *reply_pdu); +static void rpc_bind_auth3_write_done(struct async_req *subreq); +static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, + struct rpc_pipe_bind_state *state, + struct rpc_hdr_info *phdr, + prs_struct *reply_pdu); +static void rpc_bind_ntlmssp_api_done(struct async_req *subreq); + +struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth) +{ + struct async_req *result, *subreq; + struct rpc_pipe_bind_state *state; + NTSTATUS status; + + result = async_req_new(mem_ctx); + if (result == NULL) { + return NULL; + } + state = talloc(result, struct rpc_pipe_bind_state); + if (state == NULL) { + goto fail; + } + result->private_data = state; + + DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n", + rpccli_pipe_txt(debug_ctx(), cli), + (unsigned int)auth->auth_type, + (unsigned int)auth->auth_level )); + + state->ev = ev; + state->cli = cli; + state->rpc_call_id = get_rpc_call_id(); + + prs_init_empty(&state->rpc_out, state, MARSHALL); + talloc_set_destructor(state, rpc_pipe_bind_state_destructor); + + cli->auth = talloc_move(cli, &auth); + + /* Marshall the outgoing data. */ + status = create_rpc_bind_req(cli, &state->rpc_out, + state->rpc_call_id, + &cli->abstract_syntax, + &cli->transfer_syntax, + cli->auth->auth_type, + cli->auth->auth_level); + + if (!NT_STATUS_IS_OK(status)) { + goto post_status; + } + + subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out, + RPC_BINDACK); + if (subreq == NULL) { + status = NT_STATUS_NO_MEMORY; + goto post_status; + } + subreq->async.fn = rpc_pipe_bind_step_one_done; + subreq->async.priv = result; + return result; + + post_status: + if (async_post_status(result, ev, status)) { + return result; + } + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_pipe_bind_step_one_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_pipe_bind_state *state = talloc_get_type_abort( + req->private_data, struct rpc_pipe_bind_state); + prs_struct reply_pdu; + struct rpc_hdr_info hdr; + struct rpc_hdr_ba_info hdr_ba; + NTSTATUS status; + + status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n", + rpccli_pipe_txt(debug_ctx(), state->cli), + nt_errstr(status))); + async_req_error(req, status); + return; + } + + /* Unmarshall the RPC header */ + if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) { + DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n")); + async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL); + return; + } + + if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) { + DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall " + "RPC_HDR_BA.\n")); + async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL); + return; + } + + if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) { + DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n")); + async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL); + return; + } + + state->cli->max_xmit_frag = hdr_ba.bba.max_tsize; + state->cli->max_recv_frag = hdr_ba.bba.max_rsize; + + /* + * For authenticated binds we may need to do 3 or 4 leg binds. + */ + + switch(state->cli->auth->auth_type) { + + case PIPE_AUTH_TYPE_NONE: + case PIPE_AUTH_TYPE_SCHANNEL: + /* Bind complete. */ + async_req_done(req); + break; + + case PIPE_AUTH_TYPE_NTLMSSP: + /* Need to send AUTH3 packet - no reply. */ + status = rpc_finish_auth3_bind_send(req, state, &hdr, + &reply_pdu); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + } + break; + + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + /* Need to send alter context request and reply. */ + status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr, + &reply_pdu); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + } + break; + + case PIPE_AUTH_TYPE_KRB5: + /* */ + + default: + DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", + (unsigned int)state->cli->auth->auth_type)); + async_req_error(req, NT_STATUS_INTERNAL_ERROR); + } +} + +static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, + struct rpc_pipe_bind_state *state, + struct rpc_hdr_info *phdr, + prs_struct *reply_pdu) +{ + DATA_BLOB server_response = data_blob_null; + DATA_BLOB client_reply = data_blob_null; + struct rpc_hdr_auth_info hdr_auth; + struct async_req *subreq; + NTSTATUS status; + + if ((phdr->auth_len == 0) + || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!prs_set_offset( + reply_pdu, + phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* TODO - check auth_type/auth_level match. */ + + server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len); + prs_copy_data_out((char *)server_response.data, reply_pdu, + phdr->auth_len); + + status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state, + server_response, &client_reply); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server " + "blob failed: %s.\n", nt_errstr(status))); + return status; + } + + prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL); + + status = create_rpc_bind_auth3(state->cli, state->rpc_call_id, + state->cli->auth->auth_type, + state->cli->auth->auth_level, + &client_reply, &state->rpc_out); + data_blob_free(&client_reply); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + subreq = rpc_write_send(state, state->ev, state->cli, + prs_data_p(&state->rpc_out), + prs_offset(&state->rpc_out)); + if (subreq == NULL) { + return NT_STATUS_NO_MEMORY; + } + subreq->async.fn = rpc_bind_auth3_write_done; + subreq->async.priv = req; + return NT_STATUS_OK; +} + +static void rpc_bind_auth3_write_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + NTSTATUS status; + + status = rpc_write_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, + struct rpc_pipe_bind_state *state, + struct rpc_hdr_info *phdr, + prs_struct *reply_pdu) +{ + DATA_BLOB server_spnego_response = data_blob_null; + DATA_BLOB server_ntlm_response = data_blob_null; + DATA_BLOB client_reply = data_blob_null; + DATA_BLOB tmp_blob = data_blob_null; + RPC_HDR_AUTH hdr_auth; + struct async_req *subreq; + NTSTATUS status; + + if ((phdr->auth_len == 0) + || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* Process the returned NTLMSSP blob first. */ + if (!prs_set_offset( + reply_pdu, + phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) { + return NT_STATUS_INVALID_PARAMETER; + } + + server_spnego_response = data_blob(NULL, phdr->auth_len); + prs_copy_data_out((char *)server_spnego_response.data, + reply_pdu, phdr->auth_len); + + /* + * The server might give us back two challenges - tmp_blob is for the + * second. + */ + if (!spnego_parse_challenge(server_spnego_response, + &server_ntlm_response, &tmp_blob)) { + data_blob_free(&server_spnego_response); + data_blob_free(&server_ntlm_response); + data_blob_free(&tmp_blob); + return NT_STATUS_INVALID_PARAMETER; + } + + /* We're finished with the server spnego response and the tmp_blob. */ + data_blob_free(&server_spnego_response); + data_blob_free(&tmp_blob); + + status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state, + server_ntlm_response, &client_reply); + + /* Finished with the server_ntlm response */ + data_blob_free(&server_ntlm_response); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update " + "using server blob failed.\n")); + data_blob_free(&client_reply); + return status; + } + + /* SPNEGO wrap the client reply. */ + tmp_blob = spnego_gen_auth(client_reply); + data_blob_free(&client_reply); + client_reply = tmp_blob; + tmp_blob = data_blob_null; + + /* Now prepare the alter context pdu. */ + prs_init_empty(&state->rpc_out, state, MARSHALL); + + status = create_rpc_alter_context(state->rpc_call_id, + &state->cli->abstract_syntax, + &state->cli->transfer_syntax, + state->cli->auth->auth_level, + &client_reply, + &state->rpc_out); + data_blob_free(&client_reply); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + subreq = rpc_api_pipe_send(state, state->ev, state->cli, + &state->rpc_out, RPC_ALTCONTRESP); + if (subreq == NULL) { + return NT_STATUS_NO_MEMORY; + } + subreq->async.fn = rpc_bind_ntlmssp_api_done; + subreq->async.priv = req; + return NT_STATUS_OK; +} + +static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_pipe_bind_state *state = talloc_get_type_abort( + req->private_data, struct rpc_pipe_bind_state); + DATA_BLOB server_spnego_response = data_blob_null; + DATA_BLOB tmp_blob = data_blob_null; + prs_struct reply_pdu; + struct rpc_hdr_info hdr; + struct rpc_hdr_auth_info hdr_auth; + NTSTATUS status; + + status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + /* Get the auth blob from the reply. */ + if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) { + DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to " + "unmarshall RPC_HDR.\n")); + async_req_error(req, NT_STATUS_BUFFER_TOO_SMALL); + return; + } + + if (!prs_set_offset( + &reply_pdu, + hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) { + async_req_error(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) { + async_req_error(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + server_spnego_response = data_blob(NULL, hdr.auth_len); + prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu, + hdr.auth_len); + + /* Check we got a valid auth response. */ + if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, + OID_NTLMSSP, &tmp_blob)) { + data_blob_free(&server_spnego_response); + data_blob_free(&tmp_blob); + async_req_error(req, NT_STATUS_INVALID_PARAMETER); + return; + } + + data_blob_free(&server_spnego_response); + data_blob_free(&tmp_blob); + + DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " + "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli))); + async_req_done(req); +} + +NTSTATUS rpc_pipe_bind_recv(struct async_req *req) +{ + return async_req_simple_recv(req); +} + +NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = rpc_pipe_bind_send(frame, ev, cli, auth); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = rpc_pipe_bind_recv(req); + fail: + TALLOC_FREE(frame); + return status; +} unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, unsigned int timeout) -- cgit From a158ebbe49d431259f002ae8272c39e5792adf4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Jan 2009 12:15:33 +0100 Subject: Remove unused functions --- source3/rpc_client/cli_pipe.c | 401 ------------------------------------------ 1 file changed, 401 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 63d3689620f..85085ad5045 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1585,41 +1585,6 @@ static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -#if 0 -static NTSTATUS rpc_api_pipe(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, - prs_struct *data, /* Outgoing pdu fragment, - * already formatted for - * send. */ - prs_struct *rbuf, /* Incoming reply - return as - * an NDR stream. */ - uint8 expected_pkt_type) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct event_context *ev; - struct async_req *req; - NTSTATUS status = NT_STATUS_NO_MEMORY; - - ev = event_context_init(frame); - if (ev == NULL) { - goto fail; - } - - req = rpc_api_pipe_send(frame, ev, cli, data, expected_pkt_type); - if (req == NULL) { - goto fail; - } - - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } - - status = rpc_api_pipe_recv(req, mem_ctx, rbuf); - fail: - TALLOC_FREE(frame); - return status; -} -#endif - /******************************************************************* Creates krb5 auth bind. ********************************************************************/ @@ -2611,109 +2576,6 @@ static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli, return NT_STATUS_OK; } -/**************************************************************************** - Create and send the third packet in an RPC auth. -****************************************************************************/ - -#if 0 -static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, - RPC_HDR *phdr, - prs_struct *rbuf, - uint32 rpc_call_id, - enum pipe_auth_type auth_type, - enum pipe_auth_level auth_level) -{ - DATA_BLOB server_response = data_blob_null; - DATA_BLOB client_reply = data_blob_null; - RPC_HDR_AUTH hdr_auth; - NTSTATUS nt_status; - prs_struct rpc_out; - ssize_t ret; - - if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* Process the returned NTLMSSP blob first. */ - if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* TODO - check auth_type/auth_level match. */ - - server_response = data_blob(NULL, phdr->auth_len); - prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len); - - nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, - server_response, - &client_reply); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n")); - data_blob_free(&server_response); - return nt_status; - } - - prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL); - - nt_status = create_rpc_bind_auth3(cli, rpc_call_id, - auth_type, auth_level, - &client_reply, &rpc_out); - - if (!NT_STATUS_IS_OK(nt_status)) { - prs_mem_free(&rpc_out); - data_blob_free(&client_reply); - data_blob_free(&server_response); - return nt_status; - } - - switch (cli->transport_type) { - case NCACN_NP: - /* 8 here is named pipe message mode. */ - ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum, - 0x8, prs_data_p(&rpc_out), 0, - (size_t)prs_offset(&rpc_out)); - break; - - if (ret != (ssize_t)prs_offset(&rpc_out)) { - nt_status = cli_get_nt_error(cli->trans.np.cli); - } - case NCACN_IP_TCP: - case NCACN_UNIX_STREAM: - ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out), - (size_t)prs_offset(&rpc_out)); - if (ret != (ssize_t)prs_offset(&rpc_out)) { - nt_status = map_nt_error_from_unix(errno); - } - break; - default: - DEBUG(0, ("unknown transport type %d\n", cli->transport_type)); - return NT_STATUS_INTERNAL_ERROR; - } - - if (ret != (ssize_t)prs_offset(&rpc_out)) { - DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n", - nt_errstr(nt_status))); - prs_mem_free(&rpc_out); - data_blob_free(&client_reply); - data_blob_free(&server_response); - return nt_status; - } - - DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n", - rpccli_pipe_txt(debug_ctx(), cli))); - - prs_mem_free(&rpc_out); - data_blob_free(&client_reply); - data_blob_free(&server_response); - return NT_STATUS_OK; -} -#endif - /******************************************************************* Creates a DCE/RPC bind alter context authentication request which may contain a spnego auth blobl @@ -2755,273 +2617,10 @@ static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id, return ret; } -/******************************************************************* - Third leg of the SPNEGO bind mechanism - sends alter context PDU - and gets a response. - ********************************************************************/ - -#if 0 -static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, - RPC_HDR *phdr, - prs_struct *rbuf, - uint32 rpc_call_id, - const RPC_IFACE *abstract, - const RPC_IFACE *transfer, - enum pipe_auth_type auth_type, - enum pipe_auth_level auth_level) -{ - DATA_BLOB server_spnego_response = data_blob_null; - DATA_BLOB server_ntlm_response = data_blob_null; - DATA_BLOB client_reply = data_blob_null; - DATA_BLOB tmp_blob = data_blob_null; - RPC_HDR_AUTH hdr_auth; - NTSTATUS nt_status; - prs_struct rpc_out; - - if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* Process the returned NTLMSSP blob first. */ - if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) { - return NT_STATUS_INVALID_PARAMETER; - } - - server_spnego_response = data_blob(NULL, phdr->auth_len); - prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len); - - /* The server might give us back two challenges - tmp_blob is for the second. */ - if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) { - data_blob_free(&server_spnego_response); - data_blob_free(&server_ntlm_response); - data_blob_free(&tmp_blob); - return NT_STATUS_INVALID_PARAMETER; - } - - /* We're finished with the server spnego response and the tmp_blob. */ - data_blob_free(&server_spnego_response); - data_blob_free(&tmp_blob); - - nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, - server_ntlm_response, - &client_reply); - - /* Finished with the server_ntlm response */ - data_blob_free(&server_ntlm_response); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n")); - data_blob_free(&client_reply); - return nt_status; - } - - /* SPNEGO wrap the client reply. */ - tmp_blob = spnego_gen_auth(client_reply); - data_blob_free(&client_reply); - client_reply = tmp_blob; - tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */ - - /* Now prepare the alter context pdu. */ - prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL); - - nt_status = create_rpc_alter_context(rpc_call_id, - abstract, - transfer, - auth_level, - &client_reply, - &rpc_out); - - data_blob_free(&client_reply); - - if (!NT_STATUS_IS_OK(nt_status)) { - prs_mem_free(&rpc_out); - return nt_status; - } - - /* Initialize the returning data struct. */ - prs_mem_free(rbuf); - - nt_status = rpc_api_pipe(talloc_tos(), cli, &rpc_out, rbuf, - RPC_ALTCONTRESP); - prs_mem_free(&rpc_out); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - /* Get the auth blob from the reply. */ - if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) { - DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n")); - return NT_STATUS_BUFFER_TOO_SMALL; - } - - if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) { - return NT_STATUS_INVALID_PARAMETER; - } - - server_spnego_response = data_blob(NULL, phdr->auth_len); - prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len); - - /* Check we got a valid auth response. */ - if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) { - data_blob_free(&server_spnego_response); - data_blob_free(&tmp_blob); - return NT_STATUS_INVALID_PARAMETER; - } - - data_blob_free(&server_spnego_response); - data_blob_free(&tmp_blob); - - DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " - "%s.\n", rpccli_pipe_txt(debug_ctx(), cli))); - - return NT_STATUS_OK; -} -#endif - /**************************************************************************** Do an rpc bind. ****************************************************************************/ -#if 0 -NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, - struct cli_pipe_auth_data *auth) -{ - RPC_HDR hdr; - RPC_HDR_BA hdr_ba; - prs_struct rpc_out; - prs_struct rbuf; - uint32 rpc_call_id; - NTSTATUS status; - - DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n", - rpccli_pipe_txt(debug_ctx(), cli), - (unsigned int)auth->auth_type, - (unsigned int)auth->auth_level )); - - cli->auth = talloc_move(cli, &auth); - - prs_init_empty(&rpc_out, talloc_tos(), MARSHALL); - - rpc_call_id = get_rpc_call_id(); - - /* Marshall the outgoing data. */ - status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id, - &cli->abstract_syntax, - &cli->transfer_syntax, - cli->auth->auth_type, - cli->auth->auth_level); - - if (!NT_STATUS_IS_OK(status)) { - prs_mem_free(&rpc_out); - return status; - } - - /* send data on \PIPE\. receive a response */ - status = rpc_api_pipe(talloc_tos(), cli, &rpc_out, &rbuf, RPC_BINDACK); - prs_mem_free(&rpc_out); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n", - rpccli_pipe_txt(debug_ctx(), cli))); - - /* Unmarshall the RPC header */ - if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) { - DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n")); - prs_mem_free(&rbuf); - return NT_STATUS_BUFFER_TOO_SMALL; - } - - if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) { - DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n")); - prs_mem_free(&rbuf); - return NT_STATUS_BUFFER_TOO_SMALL; - } - - if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) { - DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); - prs_mem_free(&rbuf); - return NT_STATUS_BUFFER_TOO_SMALL; - } - - cli->max_xmit_frag = hdr_ba.bba.max_tsize; - cli->max_recv_frag = hdr_ba.bba.max_rsize; - - /* For authenticated binds we may need to do 3 or 4 leg binds. */ - switch(cli->auth->auth_type) { - - case PIPE_AUTH_TYPE_NONE: - case PIPE_AUTH_TYPE_SCHANNEL: - /* Bind complete. */ - break; - - case PIPE_AUTH_TYPE_NTLMSSP: - /* Need to send AUTH3 packet - no reply. */ - status = rpc_finish_auth3_bind( - cli, &hdr, &rbuf, rpc_call_id, - cli->auth->auth_type, - cli->auth->auth_level); - if (!NT_STATUS_IS_OK(status)) { - prs_mem_free(&rbuf); - return status; - } - break; - - case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - /* Need to send alter context request and reply. */ - status = rpc_finish_spnego_ntlmssp_bind( - cli, &hdr, &rbuf, rpc_call_id, - &cli->abstract_syntax, &cli->transfer_syntax, - cli->auth->auth_type, cli->auth->auth_level); - if (!NT_STATUS_IS_OK(status)) { - prs_mem_free(&rbuf); - return status; - } - break; - - case PIPE_AUTH_TYPE_KRB5: - /* */ - - default: - DEBUG(0,("cli_finish_bind_auth: unknown auth type " - "%u\n", (unsigned int)cli->auth->auth_type)); - prs_mem_free(&rbuf); - return NT_STATUS_INVALID_INFO_CLASS; - } - - /* For NTLMSSP ensure the server gave us the auth_level we wanted. */ - if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP - || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { - if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { - if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { - DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n")); - prs_mem_free(&rbuf); - return NT_STATUS_INVALID_PARAMETER; - } - } - if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { - if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { - DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n")); - prs_mem_free(&rbuf); - return NT_STATUS_INVALID_PARAMETER; - } - } - } - - prs_mem_free(&rbuf); - return NT_STATUS_OK; -} -#endif - struct rpc_pipe_bind_state { struct event_context *ev; struct rpc_pipe_client *cli; -- cgit From c45b6ec29a5b3a39b83209e970b645e5ed0a411c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Jan 2009 12:22:14 +0100 Subject: Add code to torture the fragmentation code a bit --- source3/rpc_client/cli_pipe.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 85085ad5045..f3affd1cd89 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1367,6 +1367,7 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, { struct async_req *result, *subreq; struct rpc_api_pipe_state *state; + uint16_t max_recv_frag; NTSTATUS status; result = async_req_new(mem_ctx); @@ -1402,9 +1403,14 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); - subreq = cli_api_pipe_send(state, ev, cli, - (uint8_t *)prs_data_p(data), - prs_offset(data), cli->max_recv_frag); + max_recv_frag = cli->max_recv_frag; + +#ifdef DEVELOPER + max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32); +#endif + + subreq = cli_api_pipe_send(state, ev, cli, (uint8_t *)prs_data_p(data), + prs_offset(data), max_recv_frag); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; goto post_status; @@ -2085,6 +2091,12 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, { uint32 data_space, data_len; +#ifdef DEVELOPER + if ((data_left > 0) && (sys_random() % 2)) { + data_left = MAX(data_left/2, 1); + } +#endif + switch (cli->auth->auth_level) { case PIPE_AUTH_LEVEL_NONE: case PIPE_AUTH_LEVEL_CONNECT: -- cgit