diff options
56 files changed, 929 insertions, 338 deletions
diff --git a/docs-xml/manpages-3/net.8.xml b/docs-xml/manpages-3/net.8.xml index 31fe69d8d3..75f85e1c55 100644 --- a/docs-xml/manpages-3/net.8.xml +++ b/docs-xml/manpages-3/net.8.xml @@ -395,7 +395,7 @@ current network.</para> <title>RAP PRINTQ</title> <refsect3> -<title>RAP PRINTQ LIST <replaceable>QUEUE_NAME</replaceable></title> +<title>RAP PRINTQ INFO <replaceable>QUEUE_NAME</replaceable></title> <para>Lists the specified print queue and print jobs on the server. If the <replaceable>QUEUE_NAME</replaceable> is omitted, all diff --git a/lib/torture/config.mk b/lib/torture/config.mk index 8a7f2a3b6b..abd89260f6 100644 --- a/lib/torture/config.mk +++ b/lib/torture/config.mk @@ -4,6 +4,7 @@ PUBLIC_DEPENDENCIES = \ LIBSAMBA-HOSTCONFIG \ LIBSAMBA-UTIL \ LIBTALLOC +CFLAGS = -I$(libtorturesrcdir) -I$(libtorturesrcdir)/../ torture_VERSION = 0.0.1 torture_SOVERSION = 0 diff --git a/lib/torture/torture.h b/lib/torture/torture.h index f16d2707bb..73ea1eb643 100644 --- a/lib/torture/torture.h +++ b/lib/torture/torture.h @@ -284,6 +284,21 @@ void torture_result(struct torture_context *test, } \ } while(0) +#define torture_assert_data_blob_equal(torture_ctx,got,expected,cmt)\ + do { const DATA_BLOB __got = (got), __expected = (expected); \ + if (__got.length != __expected.length) { \ + torture_result(torture_ctx, TORTURE_FAIL, \ + __location__": "#got".len %d did not match "#expected" len %d: %s", \ + (int)__got.length, (int)__expected.length, cmt); \ + return false; \ + } \ + if (memcmp(__got.data, __expected.data, __got.length) != 0) { \ + torture_result(torture_ctx, TORTURE_FAIL, \ + __location__": "#got" of len %d did not match"#expected": %s", (int)__got.length, cmt); \ + return false; \ + } \ + } while(0) + #define torture_assert_file_contains_text(torture_ctx,filename,expected,cmt)\ do { \ char *__got; \ diff --git a/lib/util/util.c b/lib/util/util.c index 4e2a5aab09..7548d30b7e 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -701,10 +701,14 @@ _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_ char *hex_buffer; hex_buffer = talloc_array(mem_ctx, char, (len*2)+1); + if (!hex_buffer) { + return NULL; + } for (i = 0; i < len; i++) slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]); + talloc_set_name_const(hex_buffer, hex_buffer); return hex_buffer; } diff --git a/librpc/idl/ntsvcs.idl b/librpc/idl/ntsvcs.idl index d50243534e..be7fcdff13 100644 --- a/librpc/idl/ntsvcs.idl +++ b/librpc/idl/ntsvcs.idl @@ -70,7 +70,7 @@ interface ntsvcs /******************/ /* Function: 0x0a */ - [todo] WERROR PNP_GetDeviceList( + WERROR PNP_GetDeviceList( [in,unique] [string,charset(UTF16)] uint16 *filter, [out,ref] [size_is(*length),length_is(*length)] uint16 *buffer, [in,out,ref] uint32 *length, diff --git a/librpc/idl/svcctl.idl b/librpc/idl/svcctl.idl index fa8e10988c..4b88f5e5f4 100644 --- a/librpc/idl/svcctl.idl +++ b/librpc/idl/svcctl.idl @@ -89,13 +89,19 @@ import "misc.idl", "security.idl"; /*****************/ /* Function 0x01 */ - typedef enum { - FIXME=1 + /* Service Controls */ + + typedef [v1_enum] enum { + SVCCTL_CONTROL_STOP = 0x00000001, + SVCCTL_CONTROL_PAUSE = 0x00000002, + SVCCTL_CONTROL_CONTINUE = 0x00000003, + SVCCTL_CONTROL_INTERROGATE = 0x00000004, + SVCCTL_CONTROL_SHUTDOWN = 0x00000005 } SERVICE_CONTROL; WERROR svcctl_ControlService( [in,ref] policy_handle *handle, - [in] uint32 control, + [in] SERVICE_CONTROL control, [out,ref] SERVICE_STATUS *service_status ); @@ -218,10 +224,10 @@ import "misc.idl", "security.idl"; [in,ref] policy_handle *handle, [in] uint32 type, [in] uint32 state, - [in] uint32 buf_size, - [out,size_is(buf_size)] uint8 service[*], - [out,ref] uint32 *bytes_needed, - [out,ref] uint32 *services_returned, + [out,ref,size_is(buf_size)] uint8 *service, + [in] [range(0,262144)] uint32 buf_size, + [out,ref] [range(0,262144)] uint32 *bytes_needed, + [out,ref] [range(0,262144)] uint32 *services_returned, [in,out,unique] uint32 *resume_handle ); @@ -535,9 +541,9 @@ import "misc.idl", "security.idl"; WERROR svcctl_QueryServiceConfig2W( [in,ref] policy_handle *handle, [in] uint32 info_level, - [out] uint8 buffer[buf_size], - [in] uint32 buf_size, - [out,ref] uint32 *bytes_needed + [out,ref,size_is(buf_size)] uint8 *buffer, + [in] [range(0,8192)] uint32 buf_size, + [out,ref] [range(0,8192)] uint32 *bytes_needed ); /*****************/ @@ -545,9 +551,9 @@ import "misc.idl", "security.idl"; WERROR svcctl_QueryServiceStatusEx( [in,ref] policy_handle *handle, [in] uint32 info_level, - [out] uint8 buffer[buf_size], - [in] uint32 buf_size, - [out,ref] uint32 *bytes_needed + [out,ref,size_is(buf_size)] uint8 *buffer, + [in] [range(0,8192)] uint32 buf_size, + [out,ref] [range(0,8192)] uint32 *bytes_needed ); /*****************/ @@ -572,12 +578,12 @@ import "misc.idl", "security.idl"; [in] uint32 info_level, [in] uint32 type, [in] uint32 state, - [out] uint8 services[buf_size], - [in] uint32 buf_size, - [out,ref] uint32 *bytes_needed, - [out,ref] uint32 *service_returned, - [in,out,unique] uint32 *resume_handle, - [out,ref] [string,charset(UTF16)] uint16 **group_name + [out,ref,size_is(buf_size)] uint8 *services, + [in] [range(0,262144)] uint32 buf_size, + [out,ref] [range(0,262144)] uint32 *bytes_needed, + [out,ref] [range(0,262144)] uint32 *service_returned, + [in,out,unique] [range(0,262144)] uint32 *resume_handle, + [in,unique] [string,charset(UTF16)] uint16 *group_name ); /*****************/ diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h index 127f6734e3..eafaf688af 100644 --- a/librpc/ndr/libndr.h +++ b/librpc/ndr/libndr.h @@ -511,6 +511,7 @@ enum ndr_err_code ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const ch /* GUIDs */ bool GUID_equal(const struct GUID *u1, const struct GUID *u2); +NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid); NTSTATUS GUID_from_string(const char *s, struct GUID *guid); NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid); struct GUID GUID_zero(void); @@ -518,6 +519,7 @@ bool GUID_all_zero(const struct GUID *u); int GUID_compare(const struct GUID *u1, const struct GUID *u2); char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid); char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid); +char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid); char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid); struct GUID GUID_random(void); diff --git a/librpc/ndr/uuid.c b/librpc/ndr/uuid.c index 1e6ee0a3db..aa24ac4494 100644 --- a/librpc/ndr/uuid.c +++ b/librpc/ndr/uuid.c @@ -23,33 +23,66 @@ #include "includes.h" #include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/ndr_misc.h" /** build a GUID from a string */ -_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid) +_PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid) { NTSTATUS status = NT_STATUS_INVALID_PARAMETER; uint32_t time_low; uint32_t time_mid, time_hi_and_version; uint32_t clock_seq[2]; uint32_t node[6]; + uint8_t buf16[16]; + DATA_BLOB blob16 = data_blob_const(buf16, sizeof(buf16)); int i; - if (s == NULL) { + if (s->data == NULL) { return NT_STATUS_INVALID_PARAMETER; } - if (11 == sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + if (s->length == 36 && + 11 == sscanf((const char *)s->data, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", &time_low, &time_mid, &time_hi_and_version, &clock_seq[0], &clock_seq[1], &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { status = NT_STATUS_OK; - } else if (11 == sscanf(s, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - &time_low, &time_mid, &time_hi_and_version, - &clock_seq[0], &clock_seq[1], - &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { + } else if (s->length == 38 + && 11 == sscanf((const char *)s->data, + "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + &time_low, &time_mid, &time_hi_and_version, + &clock_seq[0], &clock_seq[1], + &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { status = NT_STATUS_OK; + } else if (s->length == 32) { + size_t rlen = strhex_to_str((char *)blob16.data, blob16.length, + (const char *)s->data, s->length); + if (rlen == blob16.length) { + /* goto the ndr_pull_struct_blob() path */ + status = NT_STATUS_OK; + s = &blob16; + } + } + + if (s->length == 16) { + enum ndr_err_code ndr_err; + struct GUID guid2; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_new(NULL); + NT_STATUS_HAVE_NO_MEMORY(mem_ctx); + + ndr_err = ndr_pull_struct_blob(s, mem_ctx, NULL, &guid2, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(mem_ctx); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + *guid = guid2; + return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { @@ -71,6 +104,16 @@ _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid) /** build a GUID from a string */ +_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid) +{ + DATA_BLOB blob = data_blob_string_const(s); + return GUID_from_data_blob(&blob, guid); + return NT_STATUS_OK; +} + +/** + build a GUID from a string +*/ _PUBLIC_ NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid) { NTSTATUS status = NT_STATUS_INVALID_PARAMETER; @@ -208,6 +251,31 @@ _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid) return ret; } +_PUBLIC_ char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid) +{ + char *ret; + DATA_BLOB guid_blob; + enum ndr_err_code ndr_err; + TALLOC_CTX *tmp_mem; + + tmp_mem = talloc_new(mem_ctx); + if (!tmp_mem) { + return NULL; + } + ndr_err = ndr_push_struct_blob(&guid_blob, tmp_mem, + NULL, + guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(tmp_mem); + return NULL; + } + + ret = data_blob_hex_string(mem_ctx, &guid_blob); + talloc_free(tmp_mem); + return ret; +} + _PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid) { return talloc_asprintf(mem_ctx, diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c index b755431034..a660989d19 100644 --- a/librpc/rpc/binding.c +++ b/librpc/rpc/binding.c @@ -251,8 +251,8 @@ _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struc if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ NTSTATUS status; - - status = GUID_from_string(s, &b->object.uuid); + DATA_BLOB blob = data_blob(s, 36); + status = GUID_from_data_blob(&blob, &b->object.uuid); if (NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Failed parsing UUID\n")); diff --git a/release-scripts/create-tarball b/release-scripts/create-tarball index 04728d835d..ab27f08222 100755 --- a/release-scripts/create-tarball +++ b/release-scripts/create-tarball @@ -137,7 +137,7 @@ function createReleaseTag return 0 fi - if [ "x`git-tag -l ${OPT_TAG}`" != "x" ]; then + if [ "x`git tag -l ${OPT_TAG}`" != "x" ]; then echo -n "Tag exists. Do you wish to overwrite? (y/N): " read answer @@ -155,7 +155,7 @@ function createReleaseTag fi fi - git-tag -u ${OPT_KEYID} ${OPT_TAG} + git tag -u ${OPT_KEYID} ${OPT_TAG} exitOnError $? "Failed to create tag" return 0 @@ -170,7 +170,7 @@ function main cd $TOPDIR - git-checkout ${OPT_BRANCH} + git checkout ${OPT_BRANCH} exitOnError $? "Invalid branch name \"${OPT_BRANCH}\"" (cd source3 && ./script/mkversion.sh) @@ -188,7 +188,7 @@ function main echo "Creating release tarball for Samba $version" /bin/rm -rf ../samba-${version} - git-archive --format=tar --prefix=samba-${version}/ HEAD | (cd .. && tar xf -) + git archive --format=tar --prefix=samba-${version}/ HEAD | (cd .. && tar xf -) exitOnError $? "Failed to create release directory tree" pushd ../samba-${version} diff --git a/source3/include/proto.h b/source3/include/proto.h index 5f9203a21f..33425849d1 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -8459,7 +8459,8 @@ bool user_ok_token(const char *username, const char *domain, struct nt_user_token *token, int snum); bool is_share_read_only_for_token(const char *username, const char *domain, - struct nt_user_token *token, int snum); + struct nt_user_token *token, + connection_struct *conn); /* The following definitions come from smbd/srvstr.c */ diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index 27858405e7..7dd849d5b4 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -103,14 +103,6 @@ #define SVCCTL_DEMAND_START 0x00000003 #define SVCCTL_DISABLED 0x00000004 -/* Service Controls */ - -#define SVCCTL_CONTROL_STOP 0x00000001 -#define SVCCTL_CONTROL_PAUSE 0x00000002 -#define SVCCTL_CONTROL_CONTINUE 0x00000003 -#define SVCCTL_CONTROL_INTERROGATE 0x00000004 -#define SVCCTL_CONTROL_SHUTDOWN 0x00000005 - #define SVC_HANDLE_IS_SCM 0x0000001 #define SVC_HANDLE_IS_SERVICE 0x0000002 #define SVC_HANDLE_IS_DBLOCK 0x0000003 diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c index 4b0cc06d94..0341641a4c 100644 --- a/source3/libnet/libnet_samsync_keytab.c +++ b/source3/libnet/libnet_samsync_keytab.c @@ -90,7 +90,7 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx, ctx->dns_domain_name); entry.password = data_blob_talloc(mem_ctx, r->ntpassword.hash, 16); entry.kvno = ads_get_kvno(ctx->ads, entry.name); - entry.enctype = ENCTYPE_NULL; + entry.enctype = ENCTYPE_ARCFOUR_HMAC; NT_STATUS_HAVE_NO_MEMORY(entry.name); NT_STATUS_HAVE_NO_MEMORY(entry.principal); diff --git a/source3/librpc/gen_ndr/cli_svcctl.c b/source3/librpc/gen_ndr/cli_svcctl.c index e5fd4dac87..9f11a40d7e 100644 --- a/source3/librpc/gen_ndr/cli_svcctl.c +++ b/source3/librpc/gen_ndr/cli_svcctl.c @@ -53,7 +53,7 @@ NTSTATUS rpccli_svcctl_CloseServiceHandle(struct rpc_pipe_client *cli, NTSTATUS rpccli_svcctl_ControlService(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, - uint32_t control /* [in] */, + enum SERVICE_CONTROL control /* [in] */, struct SERVICE_STATUS *service_status /* [out] [ref] */, WERROR *werror) { @@ -702,10 +702,10 @@ NTSTATUS rpccli_svcctl_EnumServicesStatusW(struct rpc_pipe_client *cli, struct policy_handle *handle /* [in] [ref] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint32_t buf_size /* [in] */, - uint8_t *service /* [out] [size_is(buf_size)] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *services_returned /* [out] [ref] */, + uint8_t *service /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *services_returned /* [out] [ref,range(0,262144)] */, uint32_t *resume_handle /* [in,out] [unique] */, WERROR *werror) { @@ -1976,9 +1976,9 @@ NTSTATUS rpccli_svcctl_QueryServiceConfig2W(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror) { struct svcctl_QueryServiceConfig2W r; @@ -2027,9 +2027,9 @@ NTSTATUS rpccli_svcctl_QueryServiceStatusEx(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror) { struct svcctl_QueryServiceStatusEx r; @@ -2144,12 +2144,12 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, uint32_t info_level /* [in] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint8_t *services /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *service_returned /* [out] [ref] */, - uint32_t *resume_handle /* [in,out] [unique] */, - const char **group_name /* [out] [ref,charset(UTF16)] */, + uint8_t *services /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *service_returned /* [out] [ref,range(0,262144)] */, + uint32_t *resume_handle /* [in,out] [unique,range(0,262144)] */, + const char *group_name /* [in] [unique,charset(UTF16)] */, WERROR *werror) { struct EnumServicesStatusExW r; @@ -2162,6 +2162,7 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, r.in.state = state; r.in.buf_size = buf_size; r.in.resume_handle = resume_handle; + r.in.group_name = group_name; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(EnumServicesStatusExW, &r); @@ -2192,7 +2193,6 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, if (resume_handle && r.out.resume_handle) { *resume_handle = *r.out.resume_handle; } - *group_name = *r.out.group_name; /* Return result */ if (werror) { diff --git a/source3/librpc/gen_ndr/cli_svcctl.h b/source3/librpc/gen_ndr/cli_svcctl.h index 02abbadf1e..78c9bf40d8 100644 --- a/source3/librpc/gen_ndr/cli_svcctl.h +++ b/source3/librpc/gen_ndr/cli_svcctl.h @@ -8,7 +8,7 @@ NTSTATUS rpccli_svcctl_CloseServiceHandle(struct rpc_pipe_client *cli, NTSTATUS rpccli_svcctl_ControlService(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, - uint32_t control /* [in] */, + enum SERVICE_CONTROL control /* [in] */, struct SERVICE_STATUS *service_status /* [out] [ref] */, WERROR *werror); NTSTATUS rpccli_svcctl_DeleteService(struct rpc_pipe_client *cli, @@ -104,10 +104,10 @@ NTSTATUS rpccli_svcctl_EnumServicesStatusW(struct rpc_pipe_client *cli, struct policy_handle *handle /* [in] [ref] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint32_t buf_size /* [in] */, - uint8_t *service /* [out] [size_is(buf_size)] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *services_returned /* [out] [ref] */, + uint8_t *service /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *services_returned /* [out] [ref,range(0,262144)] */, uint32_t *resume_handle /* [in,out] [unique] */, WERROR *werror); NTSTATUS rpccli_svcctl_OpenSCManagerW(struct rpc_pipe_client *cli, @@ -292,17 +292,17 @@ NTSTATUS rpccli_svcctl_QueryServiceConfig2W(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror); NTSTATUS rpccli_svcctl_QueryServiceStatusEx(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror); NTSTATUS rpccli_EnumServicesStatusExA(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, @@ -323,12 +323,12 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, uint32_t info_level /* [in] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint8_t *services /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *service_returned /* [out] [ref] */, - uint32_t *resume_handle /* [in,out] [unique] */, - const char **group_name /* [out] [ref,charset(UTF16)] */, + uint8_t *services /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *service_returned /* [out] [ref,range(0,262144)] */, + uint32_t *resume_handle /* [in,out] [unique,range(0,262144)] */, + const char *group_name /* [in] [unique,charset(UTF16)] */, WERROR *werror); NTSTATUS rpccli_svcctl_SCSendTSMessage(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/librpc/gen_ndr/ndr_svcctl.c b/source3/librpc/gen_ndr/ndr_svcctl.c index d04c89b9a1..2bccde9ba0 100644 --- a/source3/librpc/gen_ndr/ndr_svcctl.c +++ b/source3/librpc/gen_ndr/ndr_svcctl.c @@ -297,6 +297,34 @@ _PUBLIC_ void ndr_print_svcctl_ServerType(struct ndr_print *ndr, const char *nam ndr->depth--; } +static enum ndr_err_code ndr_push_SERVICE_CONTROL(struct ndr_push *ndr, int ndr_flags, enum SERVICE_CONTROL r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_SERVICE_CONTROL(struct ndr_pull *ndr, int ndr_flags, enum SERVICE_CONTROL *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_SERVICE_CONTROL(struct ndr_print *ndr, const char *name, enum SERVICE_CONTROL r) +{ + const char *val = NULL; + + switch (r) { + case SVCCTL_CONTROL_STOP: val = "SVCCTL_CONTROL_STOP"; break; + case SVCCTL_CONTROL_PAUSE: val = "SVCCTL_CONTROL_PAUSE"; break; + case SVCCTL_CONTROL_CONTINUE: val = "SVCCTL_CONTROL_CONTINUE"; break; + case SVCCTL_CONTROL_INTERROGATE: val = "SVCCTL_CONTROL_INTERROGATE"; break; + case SVCCTL_CONTROL_SHUTDOWN: val = "SVCCTL_CONTROL_SHUTDOWN"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + static enum ndr_err_code ndr_push_svcctl_MgrAccessMask(struct ndr_push *ndr, int ndr_flags, uint32_t r) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); @@ -646,7 +674,7 @@ static enum ndr_err_code ndr_push_svcctl_ControlService(struct ndr_push *ndr, in return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.control)); + NDR_CHECK(ndr_push_SERVICE_CONTROL(ndr, NDR_SCALARS, r->in.control)); } if (flags & NDR_OUT) { if (r->out.service_status == NULL) { @@ -672,7 +700,7 @@ static enum ndr_err_code ndr_pull_svcctl_ControlService(struct ndr_pull *ndr, in NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); 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.control)); + NDR_CHECK(ndr_pull_SERVICE_CONTROL(ndr, NDR_SCALARS, &r->in.control)); NDR_PULL_ALLOC(ndr, r->out.service_status); ZERO_STRUCTP(r->out.service_status); } @@ -703,7 +731,7 @@ _PUBLIC_ void ndr_print_svcctl_ControlService(struct ndr_print *ndr, const char ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->in.handle); ndr->depth--; - ndr_print_uint32(ndr, "control", r->in.control); + ndr_print_SERVICE_CONTROL(ndr, "control", r->in.control); ndr->depth--; } if (flags & NDR_OUT) { @@ -2095,6 +2123,9 @@ static enum ndr_err_code ndr_push_svcctl_EnumServicesStatusW(struct ndr_push *nd } } if (flags & NDR_OUT) { + if (r->out.service == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.service, r->in.buf_size)); if (r->out.bytes_needed == NULL) { @@ -2134,6 +2165,9 @@ 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_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 > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { NDR_PULL_ALLOC(ndr, r->in.resume_handle); @@ -2146,6 +2180,8 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); } + NDR_PULL_ALLOC_N(ndr, r->out.service, r->in.buf_size); + memset(r->out.service, 0, (r->in.buf_size) * sizeof(*r->out.service)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); NDR_PULL_ALLOC(ndr, r->out.services_returned); @@ -2153,7 +2189,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_array_size(ndr, &r->out.service)); - NDR_PULL_ALLOC_N(ndr, r->out.service, ndr_get_array_size(ndr, &r->out.service)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.service, ndr_get_array_size(ndr, &r->out.service)); + } NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.service, ndr_get_array_size(ndr, &r->out.service))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); @@ -2161,6 +2199,9 @@ 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 > 262144) { + 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); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.services_returned); @@ -2168,6 +2209,9 @@ 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 > 262144) { + 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); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { @@ -2217,7 +2261,10 @@ _PUBLIC_ void ndr_print_svcctl_EnumServicesStatusW(struct ndr_print *ndr, const if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_EnumServicesStatusW"); ndr->depth++; + ndr_print_ptr(ndr, "service", r->out.service); + ndr->depth++; ndr_print_array_uint8(ndr, "service", r->out.service, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5305,6 +5352,10 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceConfig2W(struct ndr_push *n NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); } if (flags & NDR_OUT) { + if (r->out.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); if (r->out.bytes_needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5331,20 +5382,34 @@ 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_uint32(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) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); + memset(r->out.buffer, 0, (r->in.buf_size) * sizeof(*r->out.buffer)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); } if (flags & NDR_OUT) { - NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); } _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) { + 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); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -5370,7 +5435,10 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceConfig2W(struct ndr_print *ndr, const if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_QueryServiceConfig2W"); ndr->depth++; + ndr_print_ptr(ndr, "buffer", r->out.buffer); + ndr->depth++; ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5392,6 +5460,10 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceStatusEx(struct ndr_push *n NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); } if (flags & NDR_OUT) { + if (r->out.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); if (r->out.bytes_needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5418,20 +5490,34 @@ 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_uint32(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) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); + memset(r->out.buffer, 0, (r->in.buf_size) * sizeof(*r->out.buffer)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); } if (flags & NDR_OUT) { - NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); } _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) { + 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); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -5457,7 +5543,10 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceStatusEx(struct ndr_print *ndr, const if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_QueryServiceStatusEx"); ndr->depth++; + ndr_print_ptr(ndr, "buffer", r->out.buffer); + ndr->depth++; ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5688,8 +5777,19 @@ static enum ndr_err_code ndr_push_EnumServicesStatusExW(struct ndr_push *ndr, in if (r->in.resume_handle) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.resume_handle)); } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.group_name)); + if (r->in.group_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.group_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.group_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.group_name, ndr_charset_length(r->in.group_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } } if (flags & NDR_OUT) { + if (r->out.services == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.services, r->in.buf_size)); if (r->out.bytes_needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5703,16 +5803,6 @@ static enum ndr_err_code ndr_push_EnumServicesStatusExW(struct ndr_push *ndr, in if (r->out.resume_handle) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.resume_handle)); } - if (r->out.group_name == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.group_name)); - if (*r->out.group_name) { - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.group_name, CH_UTF16))); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.group_name, CH_UTF16))); - NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.group_name, ndr_charset_length(*r->out.group_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - } NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -5727,7 +5817,6 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in TALLOC_CTX *_mem_save_service_returned_0; TALLOC_CTX *_mem_save_resume_handle_0; TALLOC_CTX *_mem_save_group_name_0; - TALLOC_CTX *_mem_save_group_name_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -5742,6 +5831,9 @@ 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_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 > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { NDR_PULL_ALLOC(ndr, r->in.resume_handle); @@ -5752,24 +5844,51 @@ 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 > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_name)); + if (_ptr_group_name) { + NDR_PULL_ALLOC(ndr, r->in.group_name); + } else { + r->in.group_name = NULL; + } + if (r->in.group_name) { + _mem_save_group_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.group_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.group_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->in.group_name)); + if (ndr_get_array_length(ndr, &r->in.group_name) > ndr_get_array_size(ndr, &r->in.group_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.group_name), ndr_get_array_length(ndr, &r->in.group_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.group_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.group_name, ndr_get_array_length(ndr, &r->in.group_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_0, 0); + } + NDR_PULL_ALLOC_N(ndr, r->out.services, r->in.buf_size); + memset(r->out.services, 0, (r->in.buf_size) * sizeof(*r->out.services)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); NDR_PULL_ALLOC(ndr, r->out.service_returned); ZERO_STRUCTP(r->out.service_returned); - NDR_PULL_ALLOC(ndr, r->out.group_name); - ZERO_STRUCTP(r->out.group_name); } if (flags & NDR_OUT) { - NDR_PULL_ALLOC_N(ndr, r->out.services, r->in.buf_size); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.services, r->in.buf_size)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.services)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.services, ndr_get_array_size(ndr, &r->out.services)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.services, ndr_get_array_size(ndr, &r->out.services))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); } _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 > 262144) { + 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); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.service_returned); @@ -5777,6 +5896,9 @@ 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 > 262144) { + 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); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { @@ -5788,33 +5910,15 @@ 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)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); - } - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.group_name); - } - _mem_save_group_name_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.group_name, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_name)); - if (_ptr_group_name) { - NDR_PULL_ALLOC(ndr, *r->out.group_name); - } else { - *r->out.group_name = NULL; - } - if (*r->out.group_name) { - _mem_save_group_name_1 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, *r->out.group_name, 0); - NDR_CHECK(ndr_pull_array_size(ndr, r->out.group_name)); - NDR_CHECK(ndr_pull_array_length(ndr, r->out.group_name)); - if (ndr_get_array_length(ndr, r->out.group_name) > ndr_get_array_size(ndr, r->out.group_name)) { - return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, r->out.group_name), ndr_get_array_length(ndr, r->out.group_name)); + if (*r->out.resume_handle < 0 || *r->out.resume_handle > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } - NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, r->out.group_name), sizeof(uint16_t))); - NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, r->out.group_name, ndr_get_array_length(ndr, r->out.group_name), sizeof(uint16_t), CH_UTF16)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.services) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.services, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -5843,12 +5947,21 @@ _PUBLIC_ void ndr_print_EnumServicesStatusExW(struct ndr_print *ndr, const char ndr_print_uint32(ndr, "resume_handle", *r->in.resume_handle); } ndr->depth--; + ndr_print_ptr(ndr, "group_name", r->in.group_name); + ndr->depth++; + if (r->in.group_name) { + ndr_print_string(ndr, "group_name", r->in.group_name); + } + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "EnumServicesStatusExW"); ndr->depth++; + ndr_print_ptr(ndr, "services", r->out.services); + ndr->depth++; ndr_print_array_uint8(ndr, "services", r->out.services, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5863,15 +5976,6 @@ _PUBLIC_ void ndr_print_EnumServicesStatusExW(struct ndr_print *ndr, const char ndr_print_uint32(ndr, "resume_handle", *r->out.resume_handle); } ndr->depth--; - ndr_print_ptr(ndr, "group_name", r->out.group_name); - ndr->depth++; - ndr_print_ptr(ndr, "group_name", *r->out.group_name); - ndr->depth++; - if (*r->out.group_name) { - ndr_print_string(ndr, "group_name", *r->out.group_name); - } - ndr->depth--; - ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } diff --git a/source3/librpc/gen_ndr/ndr_svcctl.h b/source3/librpc/gen_ndr/ndr_svcctl.h index 0bebd3401a..8d7739a7db 100644 --- a/source3/librpc/gen_ndr/ndr_svcctl.h +++ b/source3/librpc/gen_ndr/ndr_svcctl.h @@ -106,6 +106,7 @@ void ndr_print_ENUM_SERVICE_STATUS(struct ndr_print *ndr, const char *name, cons enum ndr_err_code ndr_push_svcctl_ServerType(struct ndr_push *ndr, int ndr_flags, uint32_t r); enum ndr_err_code ndr_pull_svcctl_ServerType(struct ndr_pull *ndr, int ndr_flags, uint32_t *r); void ndr_print_svcctl_ServerType(struct ndr_print *ndr, const char *name, uint32_t r); +void ndr_print_SERVICE_CONTROL(struct ndr_print *ndr, const char *name, enum SERVICE_CONTROL r); void ndr_print_svcctl_MgrAccessMask(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_svcctl_ServiceAccessMask(struct ndr_print *ndr, const char *name, uint32_t r); enum ndr_err_code ndr_push_QUERY_SERVICE_CONFIG(struct ndr_push *ndr, int ndr_flags, const struct QUERY_SERVICE_CONFIG *r); diff --git a/source3/librpc/gen_ndr/srv_svcctl.c b/source3/librpc/gen_ndr/srv_svcctl.c index 2349b4fd93..f37111137e 100644 --- a/source3/librpc/gen_ndr/srv_svcctl.c +++ b/source3/librpc/gen_ndr/srv_svcctl.c @@ -3445,12 +3445,6 @@ static bool api_EnumServicesStatusExW(pipes_struct *p) } r->out.resume_handle = r->in.resume_handle; - r->out.group_name = talloc_zero(r, const char *); - if (r->out.group_name == NULL) { - talloc_free(r); - return false; - } - r->out.result = _EnumServicesStatusExW(p, r); if (p->rng_fault_state) { diff --git a/source3/librpc/gen_ndr/svcctl.h b/source3/librpc/gen_ndr/svcctl.h index b098eb1c42..9baa122e56 100644 --- a/source3/librpc/gen_ndr/svcctl.h +++ b/source3/librpc/gen_ndr/svcctl.h @@ -81,11 +81,19 @@ struct ENUM_SERVICE_STATUS { enum SERVICE_CONTROL #ifndef USE_UINT_ENUMS { - FIXME=1 + SVCCTL_CONTROL_STOP=0x00000001, + SVCCTL_CONTROL_PAUSE=0x00000002, + SVCCTL_CONTROL_CONTINUE=0x00000003, + SVCCTL_CONTROL_INTERROGATE=0x00000004, + SVCCTL_CONTROL_SHUTDOWN=0x00000005 } #else { __donnot_use_enum_SERVICE_CONTROL=0x7FFFFFFF} -#define FIXME ( 1 ) +#define SVCCTL_CONTROL_STOP ( 0x00000001 ) +#define SVCCTL_CONTROL_PAUSE ( 0x00000002 ) +#define SVCCTL_CONTROL_CONTINUE ( 0x00000003 ) +#define SVCCTL_CONTROL_INTERROGATE ( 0x00000004 ) +#define SVCCTL_CONTROL_SHUTDOWN ( 0x00000005 ) #endif ; @@ -137,7 +145,7 @@ struct svcctl_CloseServiceHandle { struct svcctl_ControlService { struct { struct policy_handle *handle;/* [ref] */ - uint32_t control; + enum SERVICE_CONTROL control; } in; struct { @@ -333,14 +341,14 @@ struct svcctl_EnumServicesStatusW { struct policy_handle *handle;/* [ref] */ uint32_t type; uint32_t state; - uint32_t buf_size; + uint32_t buf_size;/* [range(0,262144)] */ uint32_t *resume_handle;/* [unique] */ } in; struct { - uint8_t *service;/* [size_is(buf_size)] */ - uint32_t *bytes_needed;/* [ref] */ - uint32_t *services_returned;/* [ref] */ + uint8_t *service;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,262144)] */ + uint32_t *services_returned;/* [ref,range(0,262144)] */ uint32_t *resume_handle;/* [unique] */ WERROR result; } out; @@ -721,12 +729,12 @@ struct svcctl_QueryServiceConfig2W { struct { struct policy_handle *handle;/* [ref] */ uint32_t info_level; - uint32_t buf_size; + uint32_t buf_size;/* [range(0,8192)] */ } in; struct { - uint8_t *buffer; - uint32_t *bytes_needed;/* [ref] */ + uint8_t *buffer;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,8192)] */ WERROR result; } out; @@ -737,12 +745,12 @@ struct svcctl_QueryServiceStatusEx { struct { struct policy_handle *handle;/* [ref] */ uint32_t info_level; - uint32_t buf_size; + uint32_t buf_size;/* [range(0,8192)] */ } in; struct { - uint8_t *buffer; - uint32_t *bytes_needed;/* [ref] */ + uint8_t *buffer;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,8192)] */ WERROR result; } out; @@ -777,16 +785,16 @@ struct EnumServicesStatusExW { uint32_t info_level; uint32_t type; uint32_t state; - uint32_t buf_size; - uint32_t *resume_handle;/* [unique] */ + uint32_t buf_size;/* [range(0,262144)] */ + const char *group_name;/* [unique,charset(UTF16)] */ + uint32_t *resume_handle;/* [unique,range(0,262144)] */ } in; struct { - uint8_t *services; - uint32_t *bytes_needed;/* [ref] */ - uint32_t *service_returned;/* [ref] */ - const char **group_name;/* [ref,charset(UTF16)] */ - uint32_t *resume_handle;/* [unique] */ + uint8_t *services;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,262144)] */ + uint32_t *service_returned;/* [ref,range(0,262144)] */ + uint32_t *resume_handle;/* [unique,range(0,262144)] */ WERROR result; } out; diff --git a/source3/locale/pam_winbind/de.po b/source3/locale/pam_winbind/de.po index 642d9d3e12..5a7223d63d 100644 --- a/source3/locale/pam_winbind/de.po +++ b/source3/locale/pam_winbind/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: @PACKAGE@\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-11-13 17:21+0100\n" +"POT-Creation-Date: 2008-11-17 12:00+0100\n" "PO-Revision-Date: 2008-11-13 14:29+0100\n" "Last-Translator: Guenther Deschner <gd@samba.org>\n" "MIME-Version: 1.0\n" @@ -60,25 +60,20 @@ msgid "You are not allowed to logon at this time" msgstr "Sie können sich zum jetzigen Zeitpunkt nicht anmelden" #: ../../nsswitch/pam_winbind.c:601 -#, fuzzy -msgid "Your account has expired. " -msgstr "Ihr Passwort ist abgelaufen" - -#: ../../nsswitch/pam_winbind.c:602 ../../nsswitch/pam_winbind.c:605 ../../nsswitch/pam_winbind.c:608 -msgid "Please contact your System administrator" -msgstr "Bitte kontaktieren Sie ihren System-Administrator" +msgid "Your account has expired. Please contact your System administrator" +msgstr "Ihr Benutzerkonto ist abgelaufen. Bitte kontaktieren Sie ihren System-Administrator" #: ../../nsswitch/pam_winbind.c:604 -msgid "Your account is disabled. " -msgstr "Ihr Account ist deaktiviert. " +msgid "Your account is disabled. Please contact your System administrator" +msgstr "Ihr Benutzerkonto ist deaktiviert. Bitte kontaktieren Sie ihren System-Administrator" #: ../../nsswitch/pam_winbind.c:607 -msgid "Your account has been locked. " -msgstr "Ihr Account wurde gesperrt. " +msgid "Your account has been locked. Please contact your System administrator" +msgstr "Ihr Benutzerkonto wurde gesperrt. Bitte kontaktieren Sie ihren System-Administrator" #: ../../nsswitch/pam_winbind.c:610 ../../nsswitch/pam_winbind.c:612 ../../nsswitch/pam_winbind.c:614 msgid "Invalid Trust Account" -msgstr "Ungültiger Maschinen-Account" +msgstr "Ungültiges Maschinen-Konto" #: ../../nsswitch/pam_winbind.c:616 msgid "Access is denied" @@ -103,7 +98,7 @@ msgstr "Tag" #: ../../nsswitch/pam_winbind.c:1253 msgid "Grace login. Please change your password as soon you're online again" -msgstr "" +msgstr "Kulanzanmeldung. Bitte ändern sie ihr Passwort sobald sie wieder online sind" #: ../../nsswitch/pam_winbind.c:1263 msgid "Domain Controller unreachable, using cached credentials instead. Network resources may be unavailable" @@ -115,7 +110,7 @@ msgid "" "with the domain controller. Please verify the system time.\n" msgstr "" "Anforderung eines Kerberos Tickets aufgrund Zeitunterscheid zum \n" -"Domänen-Controller fehlgeschlagen. Bitte überprüfen Sie die System Zeit.\n" +"Domänen-Controller fehlgeschlagen. Bitte überprüfen Sie die Systemzeit.\n" #: ../../nsswitch/pam_winbind.c:1356 msgid "Your password " @@ -133,7 +128,7 @@ msgstr "kann keines der %d vorherigen Passwörter enthalten; " #: ../../nsswitch/pam_winbind.c:1382 msgid "must contain capitals, numerals or punctuation; and cannot contain your account or full name; " -msgstr "muß Großbuchstaben, Ziffern oder Punktzeichen enthalten; kann nicht den Anmelde- oder Vollnamen enthalten; " +msgstr "muß Großbuchstaben, Ziffern oder Punktzeichen enthalten; kann nicht den Benutzer- oder vollen Namen enthalten; " #: ../../nsswitch/pam_winbind.c:1392 msgid "Please type a different password. Type a password which meets these requirements in both text boxes." diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c index d4ddf32e3a..58c83e5e1b 100644 --- a/source3/modules/vfs_readonly.c +++ b/source3/modules/vfs_readonly.c @@ -64,12 +64,25 @@ static int readonly_connect(vfs_handle_struct *handle, "period", period_def); if (period && period[0] && period[1]) { + int i; time_t current_time = time(NULL); time_t begin_period = get_date(period[0], ¤t_time); time_t end_period = get_date(period[1], ¤t_time); if ((current_time >= begin_period) && (current_time <= end_period)) { + connection_struct *conn = handle->conn; + handle->conn->read_only = True; + + /* Wipe out the VUID cache. */ + for (i=0; i< VUID_CACHE_SIZE; i++) { + struct vuid_cache_entry *ent = ent = &conn->vuid_cache.array[i]; + ent->vuid = UID_FIELD_INVALID; + TALLOC_FREE(ent->server_info); + ent->read_only = false; + ent->admin_user = false; + } + conn->vuid_cache.next_entry = 0; } return SMB_VFS_NEXT_CONNECT(handle, service, user); diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index d8c476f96f..e7ecedaaed 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -117,9 +117,17 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path, struct file_id id; uint8 id_buf[16]; + tmp = talloc_asprintf(talloc_tos(), "%s/.streams", handle->conn->connectpath); + + if (tmp == NULL) { + errno = ENOMEM; + goto fail; + } + const char *rootdir = lp_parm_const_string( SNUM(handle->conn), "streams_depot", "directory", - handle->conn->connectpath); + tmp); + TALLOC_FREE(tmp); if (base_sbuf == NULL) { if (SMB_VFS_NEXT_STAT(handle, base_path, &sbuf) == -1) { diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index c164f8e72a..1daa05ea17 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -598,14 +598,14 @@ static const struct ntstatus_errors { {"NT_STATUS_INVALID_LOGON_HOURS", N_("You are not allowed to logon at this time")}, {"NT_STATUS_ACCOUNT_EXPIRED", - N_("Your account has expired. ") - N_("Please contact your System administrator")}, /* SCNR */ + N_("Your account has expired. " + "Please contact your System administrator")}, /* SCNR */ {"NT_STATUS_ACCOUNT_DISABLED", - N_("Your account is disabled. ") - N_("Please contact your System administrator")}, /* SCNR */ + N_("Your account is disabled. " + "Please contact your System administrator")}, /* SCNR */ {"NT_STATUS_ACCOUNT_LOCKED_OUT", - N_("Your account has been locked. ") - N_("Please contact your System administrator")}, /* SCNR */ + N_("Your account has been locked. " + "Please contact your System administrator")}, /* SCNR */ {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", N_("Invalid Trust Account")}, {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index 4beab6488b..0bed13e522 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -517,11 +517,9 @@ WERROR _svcctl_ControlService(pipes_struct *p, return info->ops->service_status( info->name, r->out.service_status ); + default: + return WERR_ACCESS_DENIED; } - - /* default control action */ - - return WERR_ACCESS_DENIED; } /******************************************************************** diff --git a/source3/rpcclient/cmd_ntsvcs.c b/source3/rpcclient/cmd_ntsvcs.c index 7a25352943..11f16d3462 100644 --- a/source3/rpcclient/cmd_ntsvcs.c +++ b/source3/rpcclient/cmd_ntsvcs.c @@ -122,15 +122,15 @@ static WERROR cmd_ntsvcs_get_hw_prof_info(struct rpc_pipe_client *cli, WERROR werr; uint32_t idx = 0; struct PNP_HwProfInfo info; - uint32_t unknown1 = 0, unknown2 = 0; + uint32_t size = 0, flags = 0; ZERO_STRUCT(info); status = rpccli_PNP_GetHwProfInfo(cli, mem_ctx, idx, &info, - unknown1, - unknown2, + size, + flags, &werr); if (!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c index f5f79c86e5..9dbacc2998 100644 --- a/source3/smbd/share_access.c +++ b/source3/smbd/share_access.c @@ -252,9 +252,11 @@ bool user_ok_token(const char *username, const char *domain, bool is_share_read_only_for_token(const char *username, const char *domain, - struct nt_user_token *token, int snum) + struct nt_user_token *token, + connection_struct *conn) { - bool result = lp_readonly(snum); + int snum = SNUM(conn); + bool result = conn->read_only; if (lp_readlist(snum) != NULL) { if (token_contains_name_in_list(username, domain, diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 045de6f2d3..c238f40cfd 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -88,7 +88,8 @@ static bool check_user_ok(connection_struct *conn, uint16_t vuid, readonly_share = is_share_read_only_for_token( server_info->unix_name, pdb_get_domain(server_info->sam_account), - server_info->ptok, snum); + server_info->ptok, + conn); if (!readonly_share && !share_access_check(server_info->ptok, lp_servicename(snum), diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c index 570e951aee..dd757abd1a 100644 --- a/source3/utils/net_rap.c +++ b/source3/utils/net_rap.c @@ -612,7 +612,7 @@ int net_rap_printq_usage(struct net_context *c, int argc, const char **argv) d_printf( "net rap printq [misc. options] [targets]\n" "\tor\n" - "net rap printq list [<queue_name>] [misc. options] [targets]\n" + "net rap printq info [<queue_name>] [misc. options] [targets]\n" "\tlists the specified queue and jobs on the target server.\n" "\tIf the queue name is not specified, all queues are listed.\n\n"); d_printf( @@ -726,9 +726,10 @@ int net_rap_printq(struct net_context *c, int argc, const char **argv) "info", rap_printq_info, NET_TRANSPORT_RAP, - "Display info about print job", - "net rap printq info\n" - " Display info about print job" + "Display info about print queues and jobs", + "net rap printq info [queue]\n" + " Display info about print jobs in queue.\n" + " If queue is not specified, all queues are listed" }, { "delete", diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c index 0cf4540cfe..101854ae94 100644 --- a/source3/winbindd/winbindd_passdb.c +++ b/source3/winbindd/winbindd_passdb.c @@ -639,13 +639,13 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain, sid_type_lookup(lsa_names[i].type))); continue; } - if (!((*names)[i] = talloc_strdup((*names), + if (!((*names)[num_mapped] = talloc_strdup((*names), lsa_names[i].name))) { TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; } - (*name_types)[i] = lsa_names[i].type; + (*name_types)[num_mapped] = lsa_names[i].type; num_mapped += 1; } diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk index 8bc8b6e000..bd188192a0 100644 --- a/source4/dsdb/config.mk +++ b/source4/dsdb/config.mk @@ -6,7 +6,7 @@ mkinclude samdb/ldb_modules/config.mk # Start SUBSYSTEM SAMDB [SUBSYSTEM::SAMDB] PUBLIC_DEPENDENCIES = HEIMDAL_KRB5 -PRIVATE_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \ +PRIVATE_DEPENDENCIES = LIBNDR NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \ auth_system_session LDAP_ENCODE LIBCLI_AUTH LIBNDR \ SAMDB_SCHEMA LDB_WRAP SAMDB_COMMON diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 00e4f1af92..1387066256 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -2,7 +2,7 @@ # Start MODULE ldb_objectguid [MODULE::ldb_objectguid] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR NDR_MISC +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR INIT_FUNCTION = LDB_MODULE(objectguid) # End MODULE ldb_objectguid ################################################ @@ -14,7 +14,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o [MODULE::ldb_repl_meta_data] SUBSYSTEM = LIBLDB PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \ - LIBNDR NDR_MISC NDR_DRSUAPI \ + LIBNDR NDR_DRSUAPI \ NDR_DRSBLOBS LIBNDR INIT_FUNCTION = LDB_MODULE(repl_meta_data) # End MODULE ldb_repl_meta_data @@ -75,7 +75,7 @@ ldb_pdc_fsmo_OBJ_FILES = \ # Start MODULE ldb_samldb [MODULE::ldb_samldb] SUBSYSTEM = LIBLDB -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE NDR_MISC SAMDB +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE SAMDB INIT_FUNCTION = LDB_MODULE(samldb) # # End MODULE ldb_samldb @@ -102,7 +102,7 @@ ldb_samba3sam_OBJ_FILES = \ [MODULE::ldb_simple_ldap_map] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(entryuuid),LDB_MODULE(nsuniqueid) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR NDR_MISC +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR ENABLE = YES ALIASES = entryuuid nsuniqueid # End MODULE ldb_entryuuid diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index dd199c0137..f16eb215a6 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -249,10 +249,14 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request * return ldb_next_request(module, req); } - /* start with the first one */ - return la_do_mod_request(ac); + /* start with the original request */ + return la_down_req(ac); } +/* For a delete or rename, we need to find out what linked attributes + * are currently on this DN, and then deal with them. This is the + * callback to the base search */ + static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares) { const struct dsdb_attribute *schema_attr; @@ -349,8 +353,8 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are talloc_free(ares); - /* All mods set up, start with the first one */ - ret = la_do_mod_request(ac); + /* Start with the original request */ + ret = la_down_req(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } @@ -539,8 +543,8 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques } else { if (ac->ops) { - /* Jump directly to handling the modifies */ - ret = la_do_mod_request(ac); + /* Start with the original request */ + ret = la_down_req(ac); } else { /* nothing to do for this module, proceed */ talloc_free(ac); @@ -732,12 +736,8 @@ static int la_op_search_callback(struct ldb_request *req, talloc_free(ares); - if (ac->ops) { - /* start the mod requests chain */ - ret = la_do_mod_request(ac); - } else { - ret = la_down_req(ac); - } + /* start the mod requests chain */ + ret = la_down_req(ac); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } @@ -840,11 +840,13 @@ static int la_mod_callback(struct ldb_request *req, struct ldb_reply *ares) talloc_free(os); } - /* as last op run the original request */ + /* If we still have modifies in the queue, then run them */ if (ac->ops) { ret = la_do_mod_request(ac); } else { - ret = la_down_req(ac); + /* Otherwise, we are done! */ + ret = ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); } if (ret != LDB_SUCCESS) { @@ -898,6 +900,7 @@ static int la_down_req(struct la_context *ac) return ldb_next_request(ac->module, down_req); } +/* Having done the original operation, then try to fix up all the linked attributes */ static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares) { struct la_context *ac; @@ -920,9 +923,13 @@ static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares) return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } - - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); + /* If we have modfies to make, then run them */ + if (ac->ops) { + return la_do_mod_request(ac); + } else { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } } _PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 7d00851792..1d240a33fe 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -414,10 +414,10 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } - /* Need to object to this, but cn=rootdse doesn't have an objectClass... */ + /* the objectClass must be specified on add */ if (ldb_msg_find_element(req->op.add.message, "objectClass") == NULL) { - return ldb_next_request(module, req); + return LDB_ERR_OBJECT_CLASS_VIOLATION; } ac = oc_init_context(module, req); diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c index 0266654811..df409a8ae3 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c +++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c @@ -38,6 +38,10 @@ static int generate_attributeTypes(struct ldb_context *ldb, struct ldb_message * const struct dsdb_schema *schema); static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message *msg, const struct dsdb_schema *schema); +static int generate_extendedAttributeInfo(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema); +static int generate_extendedClassInfo(struct ldb_context *ldb, struct ldb_message *msg, + const struct dsdb_schema *schema); static const struct { const char *attr; @@ -54,6 +58,14 @@ static const struct { { .attr = "dITContentRules", .fn = generate_dITContentRules + }, + { + .attr = "extendedAttributeInfo", + .fn = generate_extendedAttributeInfo + }, + { + .attr = "extendedClassInfo", + .fn = generate_extendedClassInfo } }; @@ -322,7 +334,51 @@ static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message return LDB_SUCCESS; } +static int generate_extendedAttributeInfo(struct ldb_context *ldb, + struct ldb_message *msg, + const struct dsdb_schema *schema) +{ + const struct dsdb_attribute *attribute; + int ret; + + for (attribute = schema->attributes; attribute; attribute = attribute->next) { + char *val = schema_attribute_to_extendedInfo(msg, attribute); + if (!val) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_msg_add_string(msg, "extendedAttributeInfo", val); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +static int generate_extendedClassInfo(struct ldb_context *ldb, + struct ldb_message *msg, + const struct dsdb_schema *schema) +{ + const struct dsdb_class *sclass; + int ret; + + for (sclass = schema->classes; sclass; sclass = sclass->next) { + char *val = schema_class_to_extendedInfo(msg, sclass); + if (!val) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_msg_add_string(msg, "extendedClassInfo", val); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} /* Add objectClasses, attributeTypes and dITContentRules from the schema object (they are not stored in the database) diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 7162edcb3d..fa1af2ad61 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -50,7 +50,7 @@ class MapBaseTestCase(TestCaseInTempDir): "@TO": "sambaDomainName=TESTS," + s3.basedn}) ldb.add({"dn": "@MODULES", - "@LIST": "rootdse,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"}) + "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"}) ldb.add({"dn": "@PARTITION", "partition": ["%s:%s" % (s4.basedn, s4.url), diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h index 68dc8197cb..e8fefb5246 100644 --- a/source4/dsdb/schema/schema.h +++ b/source4/dsdb/schema/schema.h @@ -72,8 +72,8 @@ struct dsdb_attribute { struct ldb_val oMObjectClass; bool isSingleValued; - uint32_t rangeLower; - uint32_t rangeUpper; + uint32_t *rangeLower; + uint32_t *rangeUpper; bool extendedCharsAllowed; uint32_t schemaFlagsEx; diff --git a/source4/dsdb/schema/schema_description.c b/source4/dsdb/schema/schema_description.c index c3c37b4653..9443c04bb0 100644 --- a/source4/dsdb/schema/schema_description.c +++ b/source4/dsdb/schema/schema_description.c @@ -20,6 +20,7 @@ */ #include "includes.h" #include "dsdb/samdb/samdb.h" +#include "librpc/ndr/libndr.h" #define IF_NULL_FAIL_RET(x) do { \ if (!x) { \ @@ -36,7 +37,12 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, const char *equality, const char *substring, const char *syntax, - bool single_value, bool operational) + bool single_value, bool operational, + uint32_t *range_lower, + uint32_t *range_upper, + const char *property_guid, + const char *property_set_guid, + bool indexed, bool system_only) { char *schema_entry = talloc_asprintf(mem_ctx, "(%s%s%s", seperator, oid, seperator); @@ -55,11 +61,13 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, "SUBSTR %s%s", substring, seperator); IF_NULL_FAIL_RET(schema_entry); } - - schema_entry = talloc_asprintf_append(schema_entry, - "SYNTAX %s%s", syntax, seperator); - IF_NULL_FAIL_RET(schema_entry); - + + if (syntax) { + schema_entry = talloc_asprintf_append(schema_entry, + "SYNTAX %s%s", syntax, seperator); + IF_NULL_FAIL_RET(schema_entry); + } + if (single_value) { schema_entry = talloc_asprintf_append(schema_entry, "SINGLE-VALUE%s", seperator); @@ -71,7 +79,47 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, "NO-USER-MODIFICATION%s", seperator); IF_NULL_FAIL_RET(schema_entry); } - + + if (range_lower) { + schema_entry = talloc_asprintf_append(schema_entry, + "RANGE-LOWER '%u'%s", + *range_lower, seperator); + IF_NULL_FAIL_RET(schema_entry); + } + + if (range_upper) { + schema_entry = talloc_asprintf_append(schema_entry, + "RANGE-UPPER '%u'%s", + *range_upper, seperator); + IF_NULL_FAIL_RET(schema_entry); + } + + if (property_guid) { + schema_entry = talloc_asprintf_append(schema_entry, + "PROPERTY-GUID '%s'%s", + property_guid, seperator); + IF_NULL_FAIL_RET(schema_entry); + } + + if (property_set_guid) { + schema_entry = talloc_asprintf_append(schema_entry, + "PROPERTY-SET-GUID '%s'%s", + property_set_guid, seperator); + IF_NULL_FAIL_RET(schema_entry); + } + + if (indexed) { + schema_entry = talloc_asprintf_append(schema_entry, + "INDEXED%s", seperator); + IF_NULL_FAIL_RET(schema_entry); + } + + if (system_only) { + schema_entry = talloc_asprintf_append(schema_entry, + "SYSTEM-ONLY%s", seperator); + IF_NULL_FAIL_RET(schema_entry); + } + schema_entry = talloc_asprintf_append(schema_entry, ")"); return schema_entry; @@ -80,14 +128,12 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx, char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute) { char *schema_description; - const struct dsdb_syntax *map = find_syntax_map_by_ad_oid(attribute->attributeSyntax_oid); - const char *syntax = map ? map->ldap_oid : attribute->attributeSyntax_oid; + const char *syntax = attribute->syntax->ldap_oid; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return NULL; } - schema_description = schema_attribute_description(mem_ctx, TARGET_AD_SCHEMA_SUBENTRY, @@ -96,6 +142,34 @@ char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_att attribute->lDAPDisplayName, NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax), attribute->isSingleValued, + attribute->systemOnly,/* TODO: is this correct? */ + NULL, NULL, NULL, NULL, + false, false); + talloc_free(tmp_ctx); + return schema_description; +} + +char *schema_attribute_to_extendedInfo(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute) +{ + char *schema_description; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + return NULL; + } + + schema_description + = schema_attribute_description(mem_ctx, + TARGET_AD_SCHEMA_SUBENTRY, + " ", + attribute->attributeID_oid, + attribute->lDAPDisplayName, + NULL, NULL, NULL, + false, false, + attribute->rangeLower, + attribute->rangeUpper, + GUID_hexstring(tmp_ctx, &attribute->schemaIDGUID), + GUID_hexstring(tmp_ctx, &attribute->attributeSecurityGUID), + (attribute->searchFlags & SEARCH_FLAG_ATTINDEX), attribute->systemOnly); talloc_free(tmp_ctx); return schema_description; @@ -142,7 +216,8 @@ char *schema_class_description(TALLOC_CTX *mem_ctx, const char *subClassOf, int objectClassCategory, char **must, - char **may) + char **may, + const char *schemaHexGUID) { char *schema_entry = talloc_asprintf(mem_ctx, "(%s%s%s", seperator, oid, seperator); @@ -225,7 +300,14 @@ char *schema_class_description(TALLOC_CTX *mem_ctx, ")%s", seperator); IF_NULL_FAIL_RET(schema_entry); } - + + if (schemaHexGUID) { + schema_entry = talloc_asprintf_append(schema_entry, + "CLASS-GUID '%s'%s", + schemaHexGUID, seperator); + IF_NULL_FAIL_RET(schema_entry); + } + schema_entry = talloc_asprintf_append(schema_entry, ")"); return schema_entry; @@ -251,7 +333,8 @@ char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class * dsdb_attribute_list(tmp_ctx, class, DSDB_SCHEMA_ALL_MUST), dsdb_attribute_list(tmp_ctx, - class, DSDB_SCHEMA_ALL_MAY)); + class, DSDB_SCHEMA_ALL_MAY), + NULL); talloc_free(tmp_ctx); return schema_description; } @@ -295,7 +378,38 @@ char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_clas * ditContentRules * per MS-ADTS * 3.1.1.3.1.1.1 */ - -1, must_attr_list, may_attr_list); + -1, must_attr_list, may_attr_list, + NULL); talloc_free(tmp_ctx); return schema_description; } + +char *schema_class_to_extendedInfo(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass) +{ + char *schema_description = NULL; + DATA_BLOB guid_blob; + char *guid_hex; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) { + return NULL; + } + + schema_description + = schema_class_description(mem_ctx, + TARGET_AD_SCHEMA_SUBENTRY, + " ", + sclass->governsID_oid, + sclass->lDAPDisplayName, + NULL, + NULL, /* Must not specify a + * SUP (subclass) in + * ditContentRules + * per MS-ADTS + * 3.1.1.3.1.1.1 */ + -1, NULL, NULL, + GUID_hexstring(tmp_ctx, &sclass->schemaIDGUID)); + talloc_free(tmp_ctx); + return schema_description; +} + + diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 6561e8ed88..763872cf2b 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -643,6 +643,24 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, (p)->elem = samdb_result_uint(msg, attr, 0);\ } while (0) +#define GET_UINT32_PTR_LDB(msg, attr, p, elem) do { \ + uint64_t _v = samdb_result_uint64(msg, attr, UINT64_MAX);\ + if (_v == UINT64_MAX) { \ + (p)->elem = NULL; \ + } else if (_v > UINT32_MAX) { \ + d_printf("%s: %s == 0x%llX\n", __location__, \ + attr, (unsigned long long)_v); \ + return WERR_INVALID_PARAM; \ + } else { \ + (p)->elem = talloc(mem_ctx, uint32_t); \ + if (!(p)->elem) { \ + d_printf("%s: talloc failed for %s\n", __location__, attr); \ + return WERR_NOMEM; \ + } \ + *(p)->elem = (uint32_t)_v; \ + } \ +} while (0) + #define GET_GUID_LDB(msg, attr, p, elem) do { \ (p)->elem = samdb_result_guid(msg, attr);\ } while (0) @@ -707,8 +725,8 @@ WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema, GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass); GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, true); - GET_UINT32_LDB(msg, "rangeLower", attr, rangeLower); - GET_UINT32_LDB(msg, "rangeUpper", attr, rangeUpper); + GET_UINT32_PTR_LDB(msg, "rangeLower", attr, rangeLower); + GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, rangeUpper); GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, false); GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx); @@ -1260,6 +1278,23 @@ static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb } \ } while (0) +#define GET_UINT32_PTR_DS(s, r, attr, p, elem) do { \ + struct drsuapi_DsReplicaAttribute *_a; \ + _a = dsdb_find_object_attr_name(s, r, attr, NULL); \ + if (_a && _a->value_ctr.num_values >= 1 \ + && _a->value_ctr.values[0].blob \ + && _a->value_ctr.values[0].blob->length == 4) { \ + (p)->elem = talloc(mem_ctx, uint32_t); \ + if (!(p)->elem) { \ + d_printf("%s: talloc failed for %s\n", __location__, attr); \ + return WERR_NOMEM; \ + } \ + *(p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\ + } else { \ + (p)->elem = NULL; \ + } \ +} while (0) + #define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \ struct drsuapi_DsReplicaAttribute *_a; \ _a = dsdb_find_object_attr_name(s, r, attr, NULL); \ @@ -1330,8 +1365,8 @@ WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema, GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass); GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, true); - GET_UINT32_DS(schema, r, "rangeLower", attr, rangeLower); - GET_UINT32_DS(schema, r, "rangeUpper", attr, rangeUpper); + GET_UINT32_PTR_DS(schema, r, "rangeLower", attr, rangeLower); + GET_UINT32_PTR_DS(schema, r, "rangeUpper", attr, rangeUpper); GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, false); GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx); diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index d0417107f1..2adff2a1df 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -29,17 +29,13 @@ #include "lib/ldb/include/ldb_errors.h" #include "lib/ldb_wrap.h" -#define VALID_DN_SYNTAX(dn,i) do {\ +#define VALID_DN_SYNTAX(dn) do {\ if (!(dn)) {\ return NT_STATUS_NO_MEMORY;\ } else if ( ! ldb_dn_validate(dn)) {\ result = LDAP_INVALID_DN_SYNTAX;\ errstr = "Invalid DN format";\ goto reply;\ - } else if (ldb_dn_get_comp_num(dn) < (i)) {\ - result = LDAP_INVALID_DN_SYNTAX;\ - errstr = "Invalid DN (" #i " components needed for '" #dn "')";\ - goto reply;\ }\ } while(0) @@ -179,7 +175,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(local_ctx); basedn = ldb_dn_new(local_ctx, samdb, req->basedn); - VALID_DN_SYNTAX(basedn, 0); + VALID_DN_SYNTAX(basedn); DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn)); DEBUG(10, ("SearchRequest: filter: [%s]\n", ldb_filter_from_tree(call, req->tree))); @@ -349,7 +345,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(local_ctx); dn = ldb_dn_new(local_ctx, samdb, req->dn); - VALID_DN_SYNTAX(dn, 0); + VALID_DN_SYNTAX(dn); DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn)); @@ -452,7 +448,7 @@ static NTSTATUS ldapsrv_AddRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(local_ctx); dn = ldb_dn_new(local_ctx, samdb, req->dn); - VALID_DN_SYNTAX(dn,1); + VALID_DN_SYNTAX(dn); DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn)); @@ -542,7 +538,7 @@ static NTSTATUS ldapsrv_DelRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(local_ctx); dn = ldb_dn_new(local_ctx, samdb, req->dn); - VALID_DN_SYNTAX(dn,1); + VALID_DN_SYNTAX(dn); DEBUG(10, ("DelRequest: dn: [%s]\n", req->dn)); @@ -588,10 +584,10 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(local_ctx); olddn = ldb_dn_new(local_ctx, samdb, req->dn); - VALID_DN_SYNTAX(olddn, 2); + VALID_DN_SYNTAX(olddn); newrdn = ldb_dn_new(local_ctx, samdb, req->newrdn); - VALID_DN_SYNTAX(newrdn, 1); + VALID_DN_SYNTAX(newrdn); DEBUG(10, ("ModifyDNRequest: olddn: [%s]\n", req->dn)); DEBUG(10, ("ModifyDNRequest: newrdn: [%s]\n", req->newrdn)); @@ -605,7 +601,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call) if (req->newsuperior) { parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior); - VALID_DN_SYNTAX(parentdn, 0); + VALID_DN_SYNTAX(parentdn); DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior)); if (ldb_dn_get_comp_num(parentdn) < 1) { @@ -672,7 +668,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(local_ctx); dn = ldb_dn_new(local_ctx, samdb, req->dn); - VALID_DN_SYNTAX(dn, 1); + VALID_DN_SYNTAX(dn); DEBUG(10, ("CompareRequest: dn: [%s]\n", req->dn)); filter = talloc_asprintf(local_ctx, "(%s=%*s)", req->attribute, diff --git a/source4/lib/ldb-samba/config.mk b/source4/lib/ldb-samba/config.mk index f84b44dfc7..ceacf277e4 100644 --- a/source4/lib/ldb-samba/config.mk +++ b/source4/lib/ldb-samba/config.mk @@ -2,7 +2,7 @@ # Start SUBSYSTEM LDBSAMBA [SUBSYSTEM::LDBSAMBA] PUBLIC_DEPENDENCIES = LIBLDB -PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_MISC NDR_DRSBLOBS +PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_DRSBLOBS # End SUBSYSTEM LDBSAMBA ################################################ diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index 538ff8feaa..69490e670b 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -328,8 +328,10 @@ int ldb_ldif_write(struct ldb_context *ldb, for (j=0;j<msg->elements[i].num_values;j++) { struct ldb_val v; ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); - CHECK_RET; - if (ldb_should_b64_encode(&v)) { + if (ret != LDB_SUCCESS) { + v = msg->elements[i].values[j]; + } + if (ret != LDB_SUCCESS || ldb_should_b64_encode(&v)) { ret = fprintf_fn(private_data, "%s:: ", msg->elements[i].name); CHECK_RET; diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 6187096ab9..6ecbfbfa08 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -216,7 +216,7 @@ typedef struct ldb_dn { we do it this way... */ talloc_steal(NULL, ret); - if (ret == NULL) + if (ret == NULL || !ldb_dn_validate(ret)) SWIG_exception(SWIG_ValueError, "unable to parse dn string"); fail: diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 34a4e03965..9e3ad80705 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -1076,12 +1076,14 @@ static void ltdb_callback(struct event_context *ev, } if (!ctx->callback_failed) { + /* Once we are done, we do not need timeout events */ + talloc_free(ctx->timeout_event); ltdb_request_done(ctx->req, ret); } } static int ltdb_handle_request(struct ldb_module *module, - struct ldb_request *req) + struct ldb_request *req) { struct event_context *ev; struct ltdb_context *ac; @@ -1115,10 +1117,9 @@ static int ltdb_handle_request(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } - tv.tv_sec = req->starttime + req->timeout; - te = event_add_timed(ev, ac, tv, ltdb_timeout, ac); - if (NULL == te) { + ac->timeout_event = event_add_timed(ev, ac, tv, ltdb_timeout, ac); + if (NULL == ac->timeout_event) { return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 61e90bccc6..c78a8172c7 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -50,6 +50,7 @@ struct ltdb_context { struct ldb_dn *base; enum ldb_scope scope; const char * const *attrs; + struct timed_event *timeout_event; }; /* special record types */ diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk index 2e2b45abe9..9af61f9632 100644 --- a/source4/lib/registry/config.mk +++ b/source4/lib/registry/config.mk @@ -97,7 +97,7 @@ regtree_OBJ_FILES = $(libregistrysrcdir)/tools/regtree.o MANPAGES += $(libregistrysrcdir)/man/regtree.1 [SUBSYSTEM::torture_registry] -PRIVATE_DEPENDENCIES = registry +PRIVATE_DEPENDENCIES = torture registry torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o) diff --git a/source4/lib/wmi/config.mk b/source4/lib/wmi/config.mk index 28f6c73dcd..3bb1690c7b 100644 --- a/source4/lib/wmi/config.mk +++ b/source4/lib/wmi/config.mk @@ -43,7 +43,7 @@ librpc/gen_ndr/dcom_p.c: idl ####################### # Start LIBRARY swig_dcerpc [PYTHON::pywmi] -PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI +PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBNDR LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI $(eval $(call python_py_module_template,wmi.py,$(wmisrcdir)/wmi.py)) diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index a12f7652a5..5e6a5faafa 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -286,7 +286,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, search = &sasl_mechs_msgs[0]->r.SearchResultEntry; if (search->num_attributes != 1) { - DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d\n", + DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n", search->num_attributes)); goto failed; } diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c index 1a695432ee..7d779b0678 100644 --- a/source4/libcli/resolve/host.c +++ b/source4/libcli/resolve/host.c @@ -53,10 +53,15 @@ struct host_state { */ static int host_destructor(struct host_state *state) { + int status; + + kill(state->child, SIGTERM); close(state->child_fd); - if (state->child != (pid_t)-1) { - kill(state->child, SIGTERM); + if (waitpid(state->child, &status, WNOHANG) == 0) { + kill(state->child, SIGKILL); + waitpid(state->child, &status, 0); } + return 0; } @@ -90,16 +95,23 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde, struct host_state *state = talloc_get_type(c->private_data, struct host_state); char address[128]; int ret; + pid_t child = state->child; + int status; /* if we get any event from the child then we know that we won't need to kill it off */ - state->child = (pid_t)-1; + talloc_set_destructor(state, NULL); /* yes, we don't care about EAGAIN or other niceities here. They just can't happen with this parent/child relationship, and even if they did then giving an error is the right thing to do */ ret = read(state->child_fd, address, sizeof(address)-1); + close(state->child_fd); + if (waitpid(state->child, &status, WNOHANG) == 0) { + kill(state->child, SIGKILL); + waitpid(state->child, &status, 0); + } if (ret <= 0) { composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); return; @@ -164,10 +176,6 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx, return c; } - /* signal handling in posix really sucks - doing this in a library - affects the whole app, but what else to do?? */ - signal(SIGCHLD, SIG_IGN); - state->child = fork(); if (state->child == (pid_t)-1) { composite_error(c, map_nt_error_from_unix(errno)); diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index f2883d1ede..30b1f32935 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::LIBSECURITY] -PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR +PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ security_token.o security_descriptor.o \ diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index ba4793cc8e..19c76b26e7 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -8,7 +8,7 @@ dcerpcsrcdir = $(librpcsrcdir)/rpc PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET \ LIBSAMBA-HOSTCONFIG -LIBNDR_OBJ_FILES = $(addprefix $(ndrsrcdir)/, ndr_string.o) ../librpc/ndr/ndr_basic.o ../librpc/ndr/uuid.o ../librpc/ndr/ndr.o +LIBNDR_OBJ_FILES = $(addprefix $(ndrsrcdir)/, ndr_string.o) ../librpc/ndr/ndr_basic.o ../librpc/ndr/uuid.o ../librpc/ndr/ndr.o $(gen_ndrsrcdir)/ndr_misc.o ../librpc/ndr/ndr_misc.o PC_FILES += ../librpc/ndr.pc LIBNDR_VERSION = 0.0.1 @@ -18,6 +18,7 @@ LIBNDR_SOVERSION = 0 ################################################ PUBLIC_HEADERS += ../librpc/ndr/libndr.h +PUBLIC_HEADERS += $(gen_ndrsrcdir)/misc.h $(gen_ndrsrcdir)/ndr_misc.h ################################# # Start BINARY ndrdump @@ -49,7 +50,7 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBNDR NDR_COMPRESSION_OBJ_FILES = ../librpc/ndr/ndr_compression.o [SUBSYSTEM::NDR_SECURITY] -PUBLIC_DEPENDENCIES = NDR_MISC LIBSECURITY +PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o \ ../librpc/ndr/ndr_sec_helper.o \ @@ -108,13 +109,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_EFS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_efs.o -[SUBSYSTEM::NDR_MISC] -PUBLIC_DEPENDENCIES = LIBNDR - -NDR_MISC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_misc.o ../librpc/ndr/ndr_misc.o - -PUBLIC_HEADERS += $(gen_ndrsrcdir)/misc.h $(gen_ndrsrcdir)/ndr_misc.h - [SUBSYSTEM::NDR_ROT] PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC @@ -128,7 +122,7 @@ NDR_LSA_OBJ_FILES = $(gen_ndrsrcdir)/ndr_lsa.o PUBLIC_HEADERS += $(gen_ndrsrcdir)/lsa.h [SUBSYSTEM::NDR_DFS] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_DFS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dfs.o @@ -148,7 +142,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL NDR_DRSUAPI_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o [SUBSYSTEM::NDR_DRSBLOBS] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI +PUBLIC_DEPENDENCIES = LIBNDR NDR_DRSUAPI NDR_DRSBLOBS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsblobs.o ../librpc/ndr/ndr_drsblobs.o @@ -168,14 +162,14 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_UNIXINFO_OBJ_FILES = $(gen_ndrsrcdir)/ndr_unixinfo.o [SUBSYSTEM::NDR_SAMR] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_LSA NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY NDR_SAMR_OBJ_FILES = $(gen_ndrsrcdir)/ndr_samr.o PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/samr.h gen_ndr/ndr_samr.h gen_ndr/ndr_samr_c.h) [SUBSYSTEM::NDR_NFS4ACL] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NFS4ACL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nfs4acl.o @@ -191,7 +185,7 @@ NDR_SPOOLSS_BUF_OBJ_FILES = $(ndrsrcdir)/ndr_spoolss_buf.o $(eval $(call proto_header_template,$(ndrsrcdir)/ndr_spoolss_buf.h,$(NDR_SPOOLSS_BUF_OBJ_FILES:.o=.c))) [SUBSYSTEM::NDR_WKSSVC] -PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_MISC NDR_SECURITY +PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY NDR_WKSSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wkssvc.o @@ -201,7 +195,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY NDR_SRVSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_srvsvc.o [SUBSYSTEM::NDR_SVCCTL] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_svcctl.o @@ -220,7 +214,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_EVENTLOG_OBJ_FILES = $(gen_ndrsrcdir)/ndr_eventlog.o [SUBSYSTEM::NDR_EPMAPPER] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_EPMAPPER_OBJ_FILES = $(gen_ndrsrcdir)/ndr_epmapper.o @@ -230,7 +224,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_DBGIDL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dbgidl.o [SUBSYSTEM::NDR_DSSETUP] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_DSSETUP_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dssetup.o @@ -245,7 +239,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o [SUBSYSTEM::NDR_WINREG] -PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY NDR_WINREG_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winreg.o @@ -270,12 +264,12 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_orpc.o ../librpc/ndr/ndr_orpc.o [SUBSYSTEM::NDR_OXIDRESOLVER] -PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_OXIDRESOLVER_OBJ_FILES = $(gen_ndrsrcdir)/ndr_oxidresolver.o [SUBSYSTEM::NDR_REMACT] -PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_REMACT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_remact.o @@ -347,7 +341,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o [SUBSYSTEM::NDR_NBT] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON +PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON NDR_NBT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nbt.o @@ -385,7 +379,7 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES) [SUBSYSTEM::NDR_TABLE] PUBLIC_DEPENDENCIES = \ NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \ - NDR_DSBACKUP NDR_EFS NDR_MISC NDR_LSA NDR_DFS NDR_DRSUAPI \ + NDR_DSBACKUP NDR_EFS NDR_LSA NDR_DFS NDR_DRSUAPI \ NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \ NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \ NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \ @@ -596,7 +590,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_KEYSVC RPC_NDR_KEYSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_keysvc_c.o [SUBSYSTEM::NDR_DCERPC] -PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC +PUBLIC_DEPENDENCIES = LIBNDR NDR_DCERPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcerpc.o @@ -634,7 +628,7 @@ PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, rpc/dcerpc.h \ [PYTHON::python_dcerpc] LIBRARY_REALNAME = samba/dcerpc/base.$(SHLIBEXT) -PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG dcerpc_samr RPC_NDR_LSA DYNCONFIG swig_credentials param +PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG dcerpc_samr RPC_NDR_LSA DYNCONFIG swig_credentials param python_dcerpc_OBJ_FILES = $(dcerpcsrcdir)/pyrpc.o diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 443cdda936..4b4664f101 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -1,6 +1,6 @@ [SUBSYSTEM::TORTURE_UTIL] PRIVATE_DEPENDENCIES = LIBCLI_RAW -PUBLIC_DEPENDENCIES = POPT_CREDENTIALS +PUBLIC_DEPENDENCIES = torture POPT_CREDENTIALS TORTURE_UTIL_OBJ_FILES = $(addprefix $(torturesrcdir)/, util_smb.o) @@ -89,6 +89,7 @@ mkinclude smb2/config.mk mkinclude winbind/config.mk [SUBSYSTEM::TORTURE_NDR] +PRIVATE_DEPENDENCIES = torture TORTURE_NDR_OBJ_FILES = $(addprefix $(torturesrcdir)/ndr/, ndr.o winreg.o atsvc.o lsa.o epmap.o dfs.o netlogon.o drsuapi.o spoolss.o samr.o) @@ -139,7 +140,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/rap/proto.h,$(TORTURE_RAP_O SUBSYSTEM = smbtorture PRIVATE_DEPENDENCIES = \ LIBCLI_SMB gensec auth KERBEROS \ - POPT_CREDENTIALS SMBPASSWD + POPT_CREDENTIALS SMBPASSWD torture # End SUBSYSTEM TORTURE_AUTH ################################# @@ -181,7 +182,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/unix/proto.h,$(TORTURE_UNIX SUBSYSTEM = smbtorture INIT_FUNCTION = torture_ldap_init PRIVATE_DEPENDENCIES = \ - LIBCLI_LDAP LIBCLI_CLDAP SAMDB POPT_CREDENTIALS + LIBCLI_LDAP LIBCLI_CLDAP SAMDB POPT_CREDENTIALS torture # End SUBSYSTEM TORTURE_LDAP ################################# diff --git a/source4/torture/rpc/ntsvcs.c b/source4/torture/rpc/ntsvcs.c index 3db79ac8bf..5453102039 100644 --- a/source4/torture/rpc/ntsvcs.c +++ b/source4/torture/rpc/ntsvcs.c @@ -108,6 +108,44 @@ static bool test_PNP_GetDeviceList(struct torture_context *tctx, return true; } +static bool test_PNP_GetDeviceRegProp(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + NTSTATUS status; + struct PNP_GetDeviceRegProp r; + + enum winreg_Type reg_data_type = REG_NONE; + uint32_t buffer_size = 0; + uint32_t needed = 0; + uint8_t *buffer; + + buffer = talloc(tctx, uint8_t); + + r.in.devicepath = "ACPI\\ACPI0003\\1"; + r.in.property = DEV_REGPROP_DESC; + r.in.flags = 0; + r.in.reg_data_type = ®_data_type; + r.in.buffer_size = &buffer_size; + r.in.needed = &needed; + r.out.buffer = buffer; + r.out.reg_data_type = ®_data_type; + r.out.buffer_size = &buffer_size; + r.out.needed = &needed; + + status = dcerpc_PNP_GetDeviceRegProp(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceRegProp"); + + if (W_ERROR_EQUAL(r.out.result, WERR_CM_BUFFER_SMALL)) { + + buffer = talloc_array(tctx, uint8_t, needed); + r.in.buffer_size = &needed; + + status = dcerpc_PNP_GetDeviceRegProp(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceRegProp"); + } + + return true; +} struct torture_suite *torture_rpc_ntsvcs(TALLOC_CTX *mem_ctx) { @@ -118,6 +156,8 @@ struct torture_suite *torture_rpc_ntsvcs(TALLOC_CTX *mem_ctx) tcase = torture_suite_add_rpc_iface_tcase(suite, "ntsvcs", &ndr_table_ntsvcs); + test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceRegProp", + test_PNP_GetDeviceRegProp); test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceList", test_PNP_GetDeviceList); test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceListSize", diff --git a/source4/torture/rpc/svcctl.c b/source4/torture/rpc/svcctl.c index c9006baaf5..0e440a3621 100644 --- a/source4/torture/rpc/svcctl.c +++ b/source4/torture/rpc/svcctl.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. test suite for srvsvc rpc operations Copyright (C) Jelmer Vernooij 2004 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -26,28 +26,141 @@ static bool test_OpenSCManager(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h) { struct svcctl_OpenSCManagerW r; - + r.in.MachineName = NULL; r.in.DatabaseName = NULL; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = h; - - torture_assert_ntstatus_ok(tctx, - dcerpc_svcctl_OpenSCManagerW(p, tctx, &r), - "OpenSCManager failed!"); - + + torture_assert_ntstatus_ok(tctx, + dcerpc_svcctl_OpenSCManagerW(p, tctx, &r), + "OpenSCManager failed!"); + return true; } static bool test_CloseServiceHandle(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h) { - struct svcctl_CloseServiceHandle r; + struct svcctl_CloseServiceHandle r; r.in.handle = h; r.out.handle = h; - torture_assert_ntstatus_ok(tctx, - dcerpc_svcctl_CloseServiceHandle(p, tctx, &r), - "CloseServiceHandle failed"); + torture_assert_ntstatus_ok(tctx, + dcerpc_svcctl_CloseServiceHandle(p, tctx, &r), + "CloseServiceHandle failed"); + + return true; +} + +static bool test_OpenService(struct dcerpc_pipe *p, struct torture_context *tctx, + struct policy_handle *h, const char *name, struct policy_handle *s) +{ + struct svcctl_OpenServiceW r; + + r.in.scmanager_handle = h; + r.in.ServiceName = name; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.handle = s; + + torture_assert_ntstatus_ok(tctx, + dcerpc_svcctl_OpenServiceW(p, tctx, &r), + "OpenServiceW failed!"); + torture_assert_werr_ok(tctx, r.out.result, "OpenServiceW failed!"); + + return true; + +} + +static bool test_QueryServiceStatusEx(struct torture_context *tctx, struct dcerpc_pipe *p) +{ + struct svcctl_QueryServiceStatusEx r; + struct policy_handle h, s; + NTSTATUS status; + + uint32_t info_level = 0; + uint8_t *buffer; + uint32_t buf_size = 0; + uint32_t bytes_needed = 0; + + if (!test_OpenSCManager(p, tctx, &h)) + return false; + + if (!test_OpenService(p, tctx, &h, "Netlogon", &s)) + return false; + + buffer = talloc(tctx, uint8_t); + + r.in.handle = &s; + r.in.info_level = 0; + r.in.buf_size = buf_size; + r.out.buffer = buffer; + r.out.bytes_needed = &bytes_needed; + + status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!"); + + if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { + r.in.buf_size = bytes_needed; + buffer = talloc_array(tctx, uint8_t, bytes_needed); + r.out.buffer = buffer; + + status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!"); + torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatusEx failed!"); + } + + if (!test_CloseServiceHandle(p, tctx, &s)) + return false; + + if (!test_CloseServiceHandle(p, tctx, &h)) + return false; + + return true; +} + +static bool test_QueryServiceConfig2W(struct torture_context *tctx, struct dcerpc_pipe *p) +{ + struct svcctl_QueryServiceConfig2W r; + struct policy_handle h, s; + NTSTATUS status; + + uint32_t info_level = 0; + uint8_t *buffer; + uint32_t buf_size = 0; + uint32_t bytes_needed = 0; + + if (!test_OpenSCManager(p, tctx, &h)) + return false; + + if (!test_OpenService(p, tctx, &h, "Netlogon", &s)) + return false; + + buffer = talloc(tctx, uint8_t); + + r.in.handle = &s; + r.in.info_level = 1; + r.in.buf_size = buf_size; + r.out.buffer = buffer; + r.out.bytes_needed = &bytes_needed; + + status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!"); + + if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) { + r.in.buf_size = bytes_needed; + buffer = talloc_array(tctx, uint8_t, bytes_needed); + r.out.buffer = buffer; + + status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!"); + torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!"); + } + + if (!test_CloseServiceHandle(p, tctx, &s)) + return false; + + if (!test_CloseServiceHandle(p, tctx, &h)) + return false; return true; } @@ -59,7 +172,9 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_ int i; NTSTATUS status; uint32_t resume_handle = 0; - struct ENUM_SERVICE_STATUS *service = NULL; + struct ENUM_SERVICE_STATUS *service = NULL; + uint32_t bytes_needed = 0; + uint32_t services_returned = 0; if (!test_OpenSCManager(p, tctx, &h)) return false; @@ -71,17 +186,17 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_ r.in.resume_handle = &resume_handle; r.out.service = NULL; r.out.resume_handle = &resume_handle; - r.out.services_returned = 0; - r.out.bytes_needed = 0; + r.out.services_returned = &services_returned; + r.out.bytes_needed = &bytes_needed; status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!"); if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { - r.in.buf_size = *r.out.bytes_needed; - r.out.service = talloc_array(tctx, uint8_t, *r.out.bytes_needed); - + r.in.buf_size = bytes_needed; + r.out.service = talloc_array(tctx, uint8_t, bytes_needed); + status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!"); @@ -90,17 +205,17 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_ service = (struct ENUM_SERVICE_STATUS *)r.out.service; } - for(i = 0; i < *r.out.services_returned; i++) { + for(i = 0; i < services_returned; i++) { printf("Type: %d, State: %d\n", service[i].status.type, service[i].status.state); } - + if (!test_CloseServiceHandle(p, tctx, &h)) return false; return true; } -static bool test_SCManager(struct torture_context *tctx, +static bool test_SCManager(struct torture_context *tctx, struct dcerpc_pipe *p) { struct policy_handle h; @@ -119,13 +234,16 @@ struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx) struct torture_suite *suite = torture_suite_create(mem_ctx, "SVCCTL"); struct torture_rpc_tcase *tcase; - tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", - &ndr_table_svcctl); - - torture_rpc_tcase_add_test(tcase, "SCManager", - test_SCManager); - torture_rpc_tcase_add_test(tcase, "EnumServicesStatus", - test_EnumServicesStatus); + tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", &ndr_table_svcctl); + + torture_rpc_tcase_add_test(tcase, "SCManager", + test_SCManager); + torture_rpc_tcase_add_test(tcase, "EnumServicesStatus", + test_EnumServicesStatus); + torture_rpc_tcase_add_test(tcase, "QueryServiceStatusEx", + test_QueryServiceStatusEx); + torture_rpc_tcase_add_test(tcase, "QueryServiceConfig2W", + test_QueryServiceConfig2W); return suite; } diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk index 9785303629..3a1ac5e06c 100644 --- a/source4/torture/smb2/config.mk +++ b/source4/torture/smb2/config.mk @@ -5,7 +5,7 @@ SUBSYSTEM = smbtorture INIT_FUNCTION = torture_smb2_init PRIVATE_DEPENDENCIES = \ - LIBCLI_SMB2 POPT_CREDENTIALS + LIBCLI_SMB2 POPT_CREDENTIALS torture # End SUBSYSTEM TORTURE_SMB2 ################################# diff --git a/source4/torture/winbind/config.mk b/source4/torture/winbind/config.mk index 15bc51daba..9648a7472b 100644 --- a/source4/torture/winbind/config.mk +++ b/source4/torture/winbind/config.mk @@ -5,7 +5,7 @@ SUBSYSTEM = smbtorture INIT_FUNCTION = torture_winbind_init PRIVATE_DEPENDENCIES = \ - LIBWINBIND-CLIENT + LIBWINBIND-CLIENT torture # End SUBSYSTEM TORTURE_WINBIND ################################# diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c index c579112b45..e926dd1ccc 100644 --- a/source4/utils/ad2oLschema.c +++ b/source4/utils/ad2oLschema.c @@ -278,7 +278,10 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch substring, syntax, single_value, - false); + false, + NULL, NULL, + NULL, NULL, + false, false); if (schema_entry == NULL) { ret.failures++; @@ -366,7 +369,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch subClassOf, objectClassCategory, must, - may); + may, + NULL); if (schema_entry == NULL) { ret.failures++; return ret; |