From 0016b9cee8d9e640e0b4604a81a900708a944c0d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Feb 2009 10:48:11 +1100 Subject: added a missing linefeed --- source4/utils/net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c index ba5296fd97..d934403ade 100644 --- a/source4/utils/net/net.c +++ b/source4/utils/net/net.c @@ -107,7 +107,7 @@ static const struct net_functable net_functable[] = { {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage}, {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage}, {"user", "manage user accounts\n", net_user, net_user_usage}, - {"machinepw", "Get a machine password out of our SAM", net_machinepw, + {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage}, {NULL, NULL, NULL, NULL} }; -- cgit From 0449d5c285c4f2f64d1aae3654322997e65ceade Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 22:58:33 +0100 Subject: spoolss: generate size functions for printer driver structs. Guenther --- librpc/idl/spoolss.idl | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 17d480261a..4809eef2e8 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -700,7 +700,7 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_StringArray *dependent_files; [value(((ndr_size_spoolss_StringArray(previous_names, ndr->iconv_convenience, ndr->flags)-4)/2))] uint32 _ndr_size_previous_names; spoolss_StringArray *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [string,charset(UTF16)] uint16 *manufacturer_name; [string,charset(UTF16)] uint16 *manufacturer_url; @@ -722,7 +722,7 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_StringArray *dependent_files; [value(((ndr_size_spoolss_StringArray(previous_names, ndr->iconv_convenience, ndr->flags)-4)/2))] uint32 _ndr_size_previous_names; spoolss_StringArray *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [string,charset(UTF16)] uint16 *manufacturer_name; [string,charset(UTF16)] uint16 *manufacturer_url; @@ -759,11 +759,11 @@ import "misc.idl", "security.idl", "winreg.idl"; [in,ref] spoolss_AddDriverInfoCtr *info_ctr ); - typedef struct { + typedef [public,gensize] struct { [relative] nstring *driver_name; } spoolss_DriverInfo1; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -772,7 +772,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *config_file; } spoolss_DriverInfo2; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -785,7 +785,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *default_datatype; } spoolss_DriverInfo3; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -799,7 +799,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring_array *previous_names; } spoolss_DriverInfo4; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -811,7 +811,7 @@ import "misc.idl", "security.idl", "winreg.idl"; uint32 driver_version; } spoolss_DriverInfo5; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -823,7 +823,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *monitor_name; [relative] nstring *default_datatype; [relative] nstring_array *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [relative] nstring *manufacturer_name; [relative] nstring *manufacturer_url; @@ -831,7 +831,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *provider; } spoolss_DriverInfo6; - typedef struct { + typedef [public,gensize] struct { spoolss_DriverOSVersion version; [relative] nstring *driver_name; [relative] nstring *architecture; @@ -843,7 +843,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [relative] nstring *default_datatype; [relative] nstring_array *dependent_files; [relative] nstring_array *previous_names; - NTTIME driver_data; + NTTIME driver_date; hyper driver_version; [relative] nstring *manufacturer_name; [relative] nstring *manufacturer_url; -- cgit From b8b3a6f1fc3dd10820906118264943860a73c1c4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 00:45:25 +0100 Subject: spoolss: add spoolss_DriverInfo101 to IDL. Note that the size_is of the spoolss_DriverFileInfo is not reflected on the ndr. It is just used as pidl cannot handle a relative pointer to a static array of structs. Guenther --- librpc/idl/spoolss.idl | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 4809eef2e8..b8f4c13148 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -628,7 +628,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [string,charset(UTF16)] uint16 *driver_name; } spoolss_AddDriverInfo1; - typedef [v1_enum] enum { + typedef [v1_enum,public] enum { SPOOLSS_DRIVER_VERSION_9X = 0, SPOOLSS_DRIVER_VERSION_NT35 = 1, SPOOLSS_DRIVER_VERSION_NT4 = 2, @@ -859,6 +859,37 @@ import "misc.idl", "security.idl", "winreg.idl"; hyper min_inbox_driver_ver_version; } spoolss_DriverInfo8; + typedef [v1_enum] enum { + SPOOLSS_DRIVER_FILE_TYPE_RENDERING = 0x00000000, + SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION = 0x00000001, + SPOOLSS_DRIVER_FILE_TYPE_DATA = 0x00000002, + SPOOLSS_DRIVER_FILE_TYPE_HELP = 0x00000003, + SPOOLSS_DRIVER_FILE_TYPE_OTHER = 0x00000004 + } spoolss_DriverFileType; + + typedef [public] struct { + [relative] nstring *file_name; + spoolss_DriverFileType file_type; + uint32 file_version; + } spoolss_DriverFileInfo; + + typedef [public,gensize,nopush,nopull] struct { + spoolss_DriverOSVersion version; + [relative] nstring *driver_name; + [relative] nstring *architecture; + [relative] [size_is(file_count)] spoolss_DriverFileInfo *file_info; + uint32 file_count; + [relative] nstring *monitor_name; + [relative] nstring *default_datatype; + [relative] nstring_array *previous_names; + NTTIME driver_date; + hyper driver_version; + [relative] nstring *manufacturer_name; + [relative] nstring *manufacturer_url; + [relative] nstring *hardware_id; + [relative] nstring *provider; + } spoolss_DriverInfo101; + typedef [nodiscriminant,relative_base,public] union { [case(1)] spoolss_DriverInfo1 info1; [case(2)] spoolss_DriverInfo2 info2; @@ -867,6 +898,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [case(5)] spoolss_DriverInfo5 info5; [case(6)] spoolss_DriverInfo6 info6; [case(8)] spoolss_DriverInfo8 info8; + [case(101)] spoolss_DriverInfo101 info101; [default]; } spoolss_DriverInfo; -- cgit From 6532fea2c8469c30a187cc6d4fc36b3b32ec2dd5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 00:47:32 +0100 Subject: spoolss: add push,pull helper for spoolss_DriverInfo101. Guenther --- librpc/ndr/ndr_spoolss_buf.c | 478 +++++++++++++++++++++++++++++++++++++++++++ librpc/ndr/ndr_spoolss_buf.h | 3 + 2 files changed, 481 insertions(+) diff --git a/librpc/ndr/ndr_spoolss_buf.c b/librpc/ndr/ndr_spoolss_buf.c index d7e28ccf0e..afc06be4e0 100644 --- a/librpc/ndr/ndr_spoolss_buf.c +++ b/librpc/ndr/ndr_spoolss_buf.c @@ -544,3 +544,481 @@ _PUBLIC_ size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_StringArray, ic); } +/* hand marshall as pidl cannot (yet) generate a relative pointer to a fixed array of + * structs */ + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r) +{ + uint32_t cntr_file_info_1; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 8)); + NDR_CHECK(ndr_push_spoolss_DriverOSVersion(ndr, NDR_SCALARS, r->version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->driver_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->architecture)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->file_info)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->file_count)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->monitor_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->default_datatype)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous_names)); + ndr->flags = _flags_save_string_array; + } + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); + NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->manufacturer_name)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->manufacturer_url)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->hardware_id)); + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->provider)); + ndr->flags = _flags_save_string; + } + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->driver_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->driver_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->architecture) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->architecture)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->architecture)); + } + ndr->flags = _flags_save_string; + } + if (r->file_info) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->file_info)); +#if 0 + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->file_count)); +#endif + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_push_spoolss_DriverFileInfo(ndr, NDR_SCALARS, &r->file_info[cntr_file_info_1])); + } + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_push_spoolss_DriverFileInfo(ndr, NDR_BUFFERS, &r->file_info[cntr_file_info_1])); + } + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->monitor_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->monitor_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->monitor_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->default_datatype) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->default_datatype)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->default_datatype)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->previous_names) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->previous_names)); + NDR_CHECK(ndr_push_string_array(ndr, NDR_SCALARS, r->previous_names)); + } + ndr->flags = _flags_save_string_array; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->manufacturer_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->manufacturer_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_url) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->manufacturer_url)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->manufacturer_url)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->hardware_id) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->hardware_id)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->hardware_id)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->provider) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->provider)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->provider)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r) +{ + uint32_t _ptr_driver_name; + TALLOC_CTX *_mem_save_driver_name_0; + uint32_t _ptr_architecture; + TALLOC_CTX *_mem_save_architecture_0; + uint32_t _ptr_file_info; + uint32_t cntr_file_info_1; + TALLOC_CTX *_mem_save_file_info_0; + TALLOC_CTX *_mem_save_file_info_1; + uint32_t _ptr_monitor_name; + TALLOC_CTX *_mem_save_monitor_name_0; + uint32_t _ptr_default_datatype; + TALLOC_CTX *_mem_save_default_datatype_0; + uint32_t _ptr_previous_names; + TALLOC_CTX *_mem_save_previous_names_0; + uint32_t _ptr_manufacturer_name; + TALLOC_CTX *_mem_save_manufacturer_name_0; + uint32_t _ptr_manufacturer_url; + TALLOC_CTX *_mem_save_manufacturer_url_0; + uint32_t _ptr_hardware_id; + TALLOC_CTX *_mem_save_hardware_id_0; + uint32_t _ptr_provider; + TALLOC_CTX *_mem_save_provider_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 8)); + NDR_CHECK(ndr_pull_spoolss_DriverOSVersion(ndr, NDR_SCALARS, &r->version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_driver_name)); + if (_ptr_driver_name) { + NDR_PULL_ALLOC(ndr, r->driver_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->driver_name, _ptr_driver_name)); + } else { + r->driver_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_architecture)); + if (_ptr_architecture) { + NDR_PULL_ALLOC(ndr, r->architecture); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->architecture, _ptr_architecture)); + } else { + r->architecture = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_file_info)); + if (_ptr_file_info) { + NDR_PULL_ALLOC(ndr, r->file_info); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->file_info, _ptr_file_info)); + } else { + r->file_info = NULL; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->file_count)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_monitor_name)); + if (_ptr_monitor_name) { + NDR_PULL_ALLOC(ndr, r->monitor_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->monitor_name, _ptr_monitor_name)); + } else { + r->monitor_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_default_datatype)); + if (_ptr_default_datatype) { + NDR_PULL_ALLOC(ndr, r->default_datatype); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->default_datatype, _ptr_default_datatype)); + } else { + r->default_datatype = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous_names)); + if (_ptr_previous_names) { + NDR_PULL_ALLOC(ndr, r->previous_names); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous_names, _ptr_previous_names)); + } else { + r->previous_names = NULL; + } + ndr->flags = _flags_save_string_array; + } + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); + NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_name)); + if (_ptr_manufacturer_name) { + NDR_PULL_ALLOC(ndr, r->manufacturer_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->manufacturer_name, _ptr_manufacturer_name)); + } else { + r->manufacturer_name = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_url)); + if (_ptr_manufacturer_url) { + NDR_PULL_ALLOC(ndr, r->manufacturer_url); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->manufacturer_url, _ptr_manufacturer_url)); + } else { + r->manufacturer_url = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_hardware_id)); + if (_ptr_hardware_id) { + NDR_PULL_ALLOC(ndr, r->hardware_id); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->hardware_id, _ptr_hardware_id)); + } else { + r->hardware_id = NULL; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_provider)); + if (_ptr_provider) { + NDR_PULL_ALLOC(ndr, r->provider); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->provider, _ptr_provider)); + } else { + r->provider = NULL; + } + ndr->flags = _flags_save_string; + } + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->driver_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->driver_name)); + _mem_save_driver_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->driver_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->driver_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_driver_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->architecture) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->architecture)); + _mem_save_architecture_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->architecture, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->architecture)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_architecture_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->file_info) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->file_info)); + _mem_save_file_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->file_info, 0); +#if 0 + NDR_CHECK(ndr_pull_array_size(ndr, &r->file_info)); +#else + NDR_CHECK(ndr_token_store(ndr, &ndr->array_size_list, &r->file_info, r->file_count)); +#endif + NDR_PULL_ALLOC_N(ndr, r->file_info, ndr_get_array_size(ndr, &r->file_info)); + _mem_save_file_info_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->file_info, 0); + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_pull_spoolss_DriverFileInfo(ndr, NDR_SCALARS, &r->file_info[cntr_file_info_1])); + } + for (cntr_file_info_1 = 0; cntr_file_info_1 < r->file_count; cntr_file_info_1++) { + NDR_CHECK(ndr_pull_spoolss_DriverFileInfo(ndr, NDR_BUFFERS, &r->file_info[cntr_file_info_1])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_file_info_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_file_info_0, 0); + ndr->offset = _relative_save_offset; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->monitor_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->monitor_name)); + _mem_save_monitor_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->monitor_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->monitor_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_monitor_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->default_datatype) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->default_datatype)); + _mem_save_default_datatype_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->default_datatype, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->default_datatype)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_default_datatype_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string_array = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->previous_names) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous_names)); + _mem_save_previous_names_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->previous_names, 0); + NDR_CHECK(ndr_pull_string_array(ndr, NDR_SCALARS, &r->previous_names)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_names_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string_array; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->manufacturer_name)); + _mem_save_manufacturer_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->manufacturer_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->manufacturer_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_manufacturer_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->manufacturer_url) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->manufacturer_url)); + _mem_save_manufacturer_url_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->manufacturer_url, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->manufacturer_url)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_manufacturer_url_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->hardware_id) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->hardware_id)); + _mem_save_hardware_id_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->hardware_id, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->hardware_id)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_hardware_id_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->provider) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->provider)); + _mem_save_provider_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->provider, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->provider)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_provider_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + if (r->file_info) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->file_info, r->file_count)); + } + } + return NDR_ERR_SUCCESS; +} diff --git a/librpc/ndr/ndr_spoolss_buf.h b/librpc/ndr/ndr_spoolss_buf.h index 801737610f..5ed848d7e0 100644 --- a/librpc/ndr/ndr_spoolss_buf.h +++ b/librpc/ndr/ndr_spoolss_buf.h @@ -39,6 +39,9 @@ enum ndr_err_code ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flag enum ndr_err_code ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r); uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, struct smb_iconv_convenience *ic, uint32_t flags); size_t ndr_size_spoolss_StringArray(const struct spoolss_StringArray *r, struct smb_iconv_convenience *ic, int flags); +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); + #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) -- cgit From 3e796103b28f1279bdaa481b7d5c4447d62683bb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 01:03:19 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 312 +++++++++++++++++++++++++++++++++++++++---- librpc/gen_ndr/ndr_spoolss.h | 31 +++++ librpc/gen_ndr/spoolss.h | 65 +++++++-- 3 files changed, 369 insertions(+), 39 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 242041fb8d..3e210b2417 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -4796,13 +4796,13 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r) +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r) { uint32_t v; NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); @@ -5704,7 +5704,7 @@ static enum ndr_err_code ndr_push_spoolss_AddDriverInfo6(struct ndr_push *ndr, i NDR_CHECK(ndr_push_unique_ptr(ndr, r->dependent_files)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ((ndr_size_spoolss_StringArray(r->previous_names, ndr->iconv_convenience, ndr->flags) - 4) / 2))); NDR_CHECK(ndr_push_unique_ptr(ndr, r->previous_names)); - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_name)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_url)); @@ -5889,7 +5889,7 @@ static enum ndr_err_code ndr_pull_spoolss_AddDriverInfo6(struct ndr_pull *ndr, i } else { r->previous_names = NULL; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_name)); if (_ptr_manufacturer_name) { @@ -6144,7 +6144,7 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfo6(struct ndr_print *ndr, const char ndr_print_spoolss_StringArray(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -6190,7 +6190,7 @@ static enum ndr_err_code ndr_push_spoolss_AddDriverInfo8(struct ndr_push *ndr, i NDR_CHECK(ndr_push_unique_ptr(ndr, r->dependent_files)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ((ndr_size_spoolss_StringArray(r->previous_names, ndr->iconv_convenience, ndr->flags) - 4) / 2))); NDR_CHECK(ndr_push_unique_ptr(ndr, r->previous_names)); - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_name)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->manufacturer_url)); @@ -6419,7 +6419,7 @@ static enum ndr_err_code ndr_pull_spoolss_AddDriverInfo8(struct ndr_pull *ndr, i } else { r->previous_names = NULL; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_manufacturer_name)); if (_ptr_manufacturer_name) { @@ -6757,7 +6757,7 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfo8(struct ndr_print *ndr, const char ndr_print_spoolss_StringArray(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -7148,7 +7148,7 @@ _PUBLIC_ void ndr_print_spoolss_AddDriverInfoCtr(struct ndr_print *ndr, const ch ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo1 *r) +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo1 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -7173,7 +7173,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo1 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo1 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -7225,7 +7225,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo1(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo2 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo1(const struct spoolss_DriverInfo1 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo1, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo2 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -7311,7 +7316,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo2 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo2 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -7505,7 +7510,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo2(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo3 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo2(const struct spoolss_DriverInfo2 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo2, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo3 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -7651,7 +7661,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo3 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo3 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -7985,7 +7995,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo3(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo4 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo3(const struct spoolss_DriverInfo3 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo3, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo4 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -8146,7 +8161,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo4 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo4 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -8515,7 +8530,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo4(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo5 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo4(const struct spoolss_DriverInfo4 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo4, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo5 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); @@ -8604,7 +8624,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo5 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo5 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -8804,7 +8824,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo5(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo6 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo5(const struct spoolss_DriverInfo5 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo5, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo6 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); @@ -8869,7 +8894,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous_names)); ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -9027,7 +9052,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo6 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo6 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -9180,7 +9205,7 @@ static enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int } ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -9511,7 +9536,7 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo6(struct ndr_print *ndr, const char *n ndr_print_string_array(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -9540,7 +9565,12 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo6(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo8 *r) +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo6(const struct spoolss_DriverInfo6 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo6, ic); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo8 *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); @@ -9605,7 +9635,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous_names)); ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_data)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->driver_date)); NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -9841,7 +9871,7 @@ static enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo8 *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo8 *r) { uint32_t _ptr_driver_name; TALLOC_CTX *_mem_save_driver_name_0; @@ -10004,7 +10034,7 @@ static enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int } ndr->flags = _flags_save_string_array; } - NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_data)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->driver_date)); NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->driver_version)); { uint32_t _flags_save_string = ndr->flags; @@ -10473,7 +10503,7 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo8(struct ndr_print *ndr, const char *n ndr_print_string_array(ndr, "previous_names", r->previous_names); } ndr->depth--; - ndr_print_NTTIME(ndr, "driver_data", r->driver_data); + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); ndr_print_hyper(ndr, "driver_version", r->driver_version); ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); ndr->depth++; @@ -10535,6 +10565,208 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo8(struct ndr_print *ndr, const char *n ndr->depth--; } +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo8(const struct spoolss_DriverInfo8 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo8, ic); +} + +static enum ndr_err_code ndr_push_spoolss_DriverFileType(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverFileType r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_DriverFileType(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverFileType *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_DriverFileType(struct ndr_print *ndr, const char *name, enum spoolss_DriverFileType r) +{ + const char *val = NULL; + + switch (r) { + case SPOOLSS_DRIVER_FILE_TYPE_RENDERING: val = "SPOOLSS_DRIVER_FILE_TYPE_RENDERING"; break; + case SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION: val = "SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION"; break; + case SPOOLSS_DRIVER_FILE_TYPE_DATA: val = "SPOOLSS_DRIVER_FILE_TYPE_DATA"; break; + case SPOOLSS_DRIVER_FILE_TYPE_HELP: val = "SPOOLSS_DRIVER_FILE_TYPE_HELP"; break; + case SPOOLSS_DRIVER_FILE_TYPE_OTHER: val = "SPOOLSS_DRIVER_FILE_TYPE_OTHER"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverFileInfo(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverFileInfo *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->file_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_DriverFileType(ndr, NDR_SCALARS, r->file_type)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->file_version)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->file_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->file_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->file_name)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverFileInfo(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverFileInfo *r) +{ + uint32_t _ptr_file_name; + TALLOC_CTX *_mem_save_file_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_file_name)); + if (_ptr_file_name) { + NDR_PULL_ALLOC(ndr, r->file_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->file_name, _ptr_file_name)); + } else { + r->file_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_DriverFileType(ndr, NDR_SCALARS, &r->file_type)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->file_version)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->file_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->file_name)); + _mem_save_file_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->file_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->file_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_file_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_DriverFileInfo(struct ndr_print *ndr, const char *name, const struct spoolss_DriverFileInfo *r) +{ + ndr_print_struct(ndr, name, "spoolss_DriverFileInfo"); + ndr->depth++; + ndr_print_ptr(ndr, "file_name", r->file_name); + ndr->depth++; + if (r->file_name) { + ndr_print_string(ndr, "file_name", r->file_name); + } + ndr->depth--; + ndr_print_spoolss_DriverFileType(ndr, "file_type", r->file_type); + ndr_print_uint32(ndr, "file_version", r->file_version); + ndr->depth--; +} + +_PUBLIC_ void ndr_print_spoolss_DriverInfo101(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo101 *r) +{ + uint32_t cntr_file_info_1; + ndr_print_struct(ndr, name, "spoolss_DriverInfo101"); + ndr->depth++; + ndr_print_spoolss_DriverOSVersion(ndr, "version", r->version); + ndr_print_ptr(ndr, "driver_name", r->driver_name); + ndr->depth++; + if (r->driver_name) { + ndr_print_string(ndr, "driver_name", r->driver_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "architecture", r->architecture); + ndr->depth++; + if (r->architecture) { + ndr_print_string(ndr, "architecture", r->architecture); + } + ndr->depth--; + ndr_print_ptr(ndr, "file_info", r->file_info); + ndr->depth++; + if (r->file_info) { + ndr->print(ndr, "%s: ARRAY(%d)", "file_info", (int)r->file_count); + ndr->depth++; + for (cntr_file_info_1=0;cntr_file_info_1file_count;cntr_file_info_1++) { + char *idx_1=NULL; + if (asprintf(&idx_1, "[%d]", cntr_file_info_1) != -1) { + ndr_print_spoolss_DriverFileInfo(ndr, "file_info", &r->file_info[cntr_file_info_1]); + free(idx_1); + } + } + ndr->depth--; + } + ndr->depth--; + ndr_print_uint32(ndr, "file_count", r->file_count); + ndr_print_ptr(ndr, "monitor_name", r->monitor_name); + ndr->depth++; + if (r->monitor_name) { + ndr_print_string(ndr, "monitor_name", r->monitor_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "default_datatype", r->default_datatype); + ndr->depth++; + if (r->default_datatype) { + ndr_print_string(ndr, "default_datatype", r->default_datatype); + } + ndr->depth--; + ndr_print_ptr(ndr, "previous_names", r->previous_names); + ndr->depth++; + if (r->previous_names) { + ndr_print_string_array(ndr, "previous_names", r->previous_names); + } + ndr->depth--; + ndr_print_NTTIME(ndr, "driver_date", r->driver_date); + ndr_print_hyper(ndr, "driver_version", r->driver_version); + ndr_print_ptr(ndr, "manufacturer_name", r->manufacturer_name); + ndr->depth++; + if (r->manufacturer_name) { + ndr_print_string(ndr, "manufacturer_name", r->manufacturer_name); + } + ndr->depth--; + ndr_print_ptr(ndr, "manufacturer_url", r->manufacturer_url); + ndr->depth++; + if (r->manufacturer_url) { + ndr_print_string(ndr, "manufacturer_url", r->manufacturer_url); + } + ndr->depth--; + ndr_print_ptr(ndr, "hardware_id", r->hardware_id); + ndr->depth++; + if (r->hardware_id) { + ndr_print_string(ndr, "hardware_id", r->hardware_id); + } + ndr->depth--; + ndr_print_ptr(ndr, "provider", r->provider); + ndr->depth++; + if (r->provider) { + ndr_print_string(ndr, "provider", r->provider); + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ size_t ndr_size_spoolss_DriverInfo101(const struct spoolss_DriverInfo101 *r, struct smb_iconv_convenience *ic, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_spoolss_DriverInfo101, ic); +} + _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_DriverInfo *r) { uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr); @@ -10583,6 +10815,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int NDR_CHECK(ndr_push_spoolss_DriverInfo8(ndr, NDR_SCALARS, &r->info8)); break; } + case 101: { + NDR_CHECK(ndr_push_align(ndr, 8)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_DriverInfo101(ndr, NDR_SCALARS, &r->info101)); + break; } + default: { break; } @@ -10620,6 +10858,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int NDR_CHECK(ndr_push_spoolss_DriverInfo8(ndr, NDR_BUFFERS, &r->info8)); break; + case 101: + NDR_CHECK(ndr_push_spoolss_DriverInfo101(ndr, NDR_BUFFERS, &r->info101)); + break; + default: break; @@ -10678,6 +10920,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_spoolss_DriverInfo8(ndr, NDR_SCALARS, &r->info8)); break; } + case 101: { + NDR_CHECK(ndr_pull_align(ndr, 8)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_DriverInfo101(ndr, NDR_SCALARS, &r->info101)); + break; } + default: { break; } @@ -10714,6 +10962,10 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_spoolss_DriverInfo8(ndr, NDR_BUFFERS, &r->info8)); break; + case 101: + NDR_CHECK(ndr_pull_spoolss_DriverInfo101(ndr, NDR_BUFFERS, &r->info101)); + break; + default: break; @@ -10757,6 +11009,10 @@ _PUBLIC_ void ndr_print_spoolss_DriverInfo(struct ndr_print *ndr, const char *na ndr_print_spoolss_DriverInfo8(ndr, "info8", &r->info8); break; + case 101: + ndr_print_spoolss_DriverInfo101(ndr, "info101", &r->info101); + break; + default: break; diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index b9a533ab38..5b32d510c0 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -256,6 +256,8 @@ enum ndr_err_code ndr_push_spoolss_StringArray(struct ndr_push *ndr, int ndr_fla enum ndr_err_code ndr_pull_spoolss_StringArray(struct ndr_pull *ndr, int ndr_flags, struct spoolss_StringArray *r); void ndr_print_spoolss_StringArray(struct ndr_print *ndr, const char *name, const struct spoolss_StringArray *r); void ndr_print_spoolss_AddDriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo1 *r); +enum ndr_err_code ndr_push_spoolss_DriverOSVersion(struct ndr_push *ndr, int ndr_flags, enum spoolss_DriverOSVersion r); +enum ndr_err_code ndr_pull_spoolss_DriverOSVersion(struct ndr_pull *ndr, int ndr_flags, enum spoolss_DriverOSVersion *r); void ndr_print_spoolss_DriverOSVersion(struct ndr_print *ndr, const char *name, enum spoolss_DriverOSVersion r); void ndr_print_spoolss_AddDriverInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo2 *r); void ndr_print_spoolss_AddDriverInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo3 *r); @@ -264,13 +266,42 @@ void ndr_print_spoolss_AddDriverInfo6(struct ndr_print *ndr, const char *name, c void ndr_print_spoolss_AddDriverInfo8(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfo8 *r); void ndr_print_spoolss_AddDriverInfo(struct ndr_print *ndr, const char *name, const union spoolss_AddDriverInfo *r); void ndr_print_spoolss_AddDriverInfoCtr(struct ndr_print *ndr, const char *name, const struct spoolss_AddDriverInfoCtr *r); +enum ndr_err_code ndr_push_spoolss_DriverInfo1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo1 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo1(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo1 *r); void ndr_print_spoolss_DriverInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo1 *r); +size_t ndr_size_spoolss_DriverInfo1(const struct spoolss_DriverInfo1 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo2 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo2 *r); void ndr_print_spoolss_DriverInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo2 *r); +size_t ndr_size_spoolss_DriverInfo2(const struct spoolss_DriverInfo2 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo3(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo3 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo3 *r); void ndr_print_spoolss_DriverInfo3(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo3 *r); +size_t ndr_size_spoolss_DriverInfo3(const struct spoolss_DriverInfo3 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo4(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo4 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo4(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo4 *r); void ndr_print_spoolss_DriverInfo4(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo4 *r); +size_t ndr_size_spoolss_DriverInfo4(const struct spoolss_DriverInfo4 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo5(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo5 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo5(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo5 *r); void ndr_print_spoolss_DriverInfo5(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo5 *r); +size_t ndr_size_spoolss_DriverInfo5(const struct spoolss_DriverInfo5 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo6(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo6 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo6(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo6 *r); void ndr_print_spoolss_DriverInfo6(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo6 *r); +size_t ndr_size_spoolss_DriverInfo6(const struct spoolss_DriverInfo6 *r, struct smb_iconv_convenience *ic, int flags); +enum ndr_err_code ndr_push_spoolss_DriverInfo8(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo8 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo8(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo8 *r); void ndr_print_spoolss_DriverInfo8(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo8 *r); +size_t ndr_size_spoolss_DriverInfo8(const struct spoolss_DriverInfo8 *r, struct smb_iconv_convenience *ic, int flags); +void ndr_print_spoolss_DriverFileType(struct ndr_print *ndr, const char *name, enum spoolss_DriverFileType r); +enum ndr_err_code ndr_push_spoolss_DriverFileInfo(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverFileInfo *r); +enum ndr_err_code ndr_pull_spoolss_DriverFileInfo(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverFileInfo *r); +void ndr_print_spoolss_DriverFileInfo(struct ndr_print *ndr, const char *name, const struct spoolss_DriverFileInfo *r); +enum ndr_err_code ndr_push_spoolss_DriverInfo101(struct ndr_push *ndr, int ndr_flags, const struct spoolss_DriverInfo101 *r); +enum ndr_err_code ndr_pull_spoolss_DriverInfo101(struct ndr_pull *ndr, int ndr_flags, struct spoolss_DriverInfo101 *r); +void ndr_print_spoolss_DriverInfo101(struct ndr_print *ndr, const char *name, const struct spoolss_DriverInfo101 *r); +size_t ndr_size_spoolss_DriverInfo101(const struct spoolss_DriverInfo101 *r, struct smb_iconv_convenience *ic, int flags); enum ndr_err_code ndr_push_spoolss_DriverInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_DriverInfo *r); enum ndr_err_code ndr_pull_spoolss_DriverInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_DriverInfo *r); void ndr_print_spoolss_DriverInfo(struct ndr_print *ndr, const char *name, const union spoolss_DriverInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 150bf04d6f..0e8ba37cb7 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -635,7 +635,7 @@ struct spoolss_AddDriverInfo6 { struct spoolss_StringArray *dependent_files;/* [unique] */ uint32_t _ndr_size_previous_names;/* [value(((ndr_size_spoolss_StringArray(previous_names,ndr->iconv_convenience,ndr->flags)-4)/2))] */ struct spoolss_StringArray *previous_names;/* [unique] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char *manufacturer_name;/* [unique,charset(UTF16)] */ const char *manufacturer_url;/* [unique,charset(UTF16)] */ @@ -657,7 +657,7 @@ struct spoolss_AddDriverInfo8 { struct spoolss_StringArray *dependent_files;/* [unique] */ uint32_t _ndr_size_previous_names;/* [value(((ndr_size_spoolss_StringArray(previous_names,ndr->iconv_convenience,ndr->flags)-4)/2))] */ struct spoolss_StringArray *previous_names;/* [unique] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char *manufacturer_name;/* [unique,charset(UTF16)] */ const char *manufacturer_url;/* [unique,charset(UTF16)] */ @@ -691,7 +691,7 @@ struct spoolss_AddDriverInfoCtr { struct spoolss_DriverInfo1 { const char * driver_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo2 { enum spoolss_DriverOSVersion version; @@ -700,7 +700,7 @@ struct spoolss_DriverInfo2 { const char * driver_path;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * data_file;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * config_file;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo3 { enum spoolss_DriverOSVersion version; @@ -713,7 +713,7 @@ struct spoolss_DriverInfo3 { const char ** dependent_files;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo4 { enum spoolss_DriverOSVersion version; @@ -727,7 +727,7 @@ struct spoolss_DriverInfo4 { const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo5 { enum spoolss_DriverOSVersion version; @@ -739,7 +739,7 @@ struct spoolss_DriverInfo5 { uint32_t driver_attributes; uint32_t config_version; uint32_t driver_version; -}; +}/* [gensize,public] */; struct spoolss_DriverInfo6 { enum spoolss_DriverOSVersion version; @@ -753,13 +753,13 @@ struct spoolss_DriverInfo6 { const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char * manufacturer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * manufacturer_url;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * hardware_id;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * provider;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ -}; +}/* [gensize,public] */; struct spoolss_DriverInfo8 { enum spoolss_DriverOSVersion version; @@ -773,7 +773,7 @@ struct spoolss_DriverInfo8 { const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** dependent_files;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ - NTTIME driver_data; + NTTIME driver_date; uint64_t driver_version; const char * manufacturer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ const char * manufacturer_url;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ @@ -787,7 +787,49 @@ struct spoolss_DriverInfo8 { const char ** core_driver_dependencies;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ NTTIME min_inbox_driver_ver_date; uint64_t min_inbox_driver_ver_version; -}; +}/* [gensize,public] */; + +enum spoolss_DriverFileType +#ifndef USE_UINT_ENUMS + { + SPOOLSS_DRIVER_FILE_TYPE_RENDERING=0x00000000, + SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION=0x00000001, + SPOOLSS_DRIVER_FILE_TYPE_DATA=0x00000002, + SPOOLSS_DRIVER_FILE_TYPE_HELP=0x00000003, + SPOOLSS_DRIVER_FILE_TYPE_OTHER=0x00000004 +} +#else + { __donnot_use_enum_spoolss_DriverFileType=0x7FFFFFFF} +#define SPOOLSS_DRIVER_FILE_TYPE_RENDERING ( 0x00000000 ) +#define SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION ( 0x00000001 ) +#define SPOOLSS_DRIVER_FILE_TYPE_DATA ( 0x00000002 ) +#define SPOOLSS_DRIVER_FILE_TYPE_HELP ( 0x00000003 ) +#define SPOOLSS_DRIVER_FILE_TYPE_OTHER ( 0x00000004 ) +#endif +; + +struct spoolss_DriverFileInfo { + const char * file_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + enum spoolss_DriverFileType file_type; + uint32_t file_version; +}/* [public] */; + +struct spoolss_DriverInfo101 { + enum spoolss_DriverOSVersion version; + const char * driver_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * architecture;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct spoolss_DriverFileInfo *file_info;/* [relative,size_is(file_count)] */ + uint32_t file_count; + const char * monitor_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * default_datatype;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char ** previous_names;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + NTTIME driver_date; + uint64_t driver_version; + const char * manufacturer_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * manufacturer_url;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * hardware_id;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + const char * provider;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ +}/* [gensize,nopush,public,nopull] */; union spoolss_DriverInfo { struct spoolss_DriverInfo1 info1;/* [case] */ @@ -797,6 +839,7 @@ union spoolss_DriverInfo { struct spoolss_DriverInfo5 info5;/* [case(5)] */ struct spoolss_DriverInfo6 info6;/* [case(6)] */ struct spoolss_DriverInfo8 info8;/* [case(8)] */ + struct spoolss_DriverInfo101 info101;/* [case(101)] */ }/* [relative_base,nodiscriminant,public] */; struct spoolss_DriverDirectoryInfo1 { -- cgit From bcd6e5ec3315b14cedf7437a70c34d233ded082e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Feb 2009 11:43:32 +0100 Subject: s3-spoolss: fix notify_printer_status_byname. This took me almost a week to find, so here a little longer explanation: When a windows client registers printer *status* change notifies using spoolss_RemoteFindFirstChangeNotify, it registers them to a print server handle, not a printer handle. We were then correctly monitoring the printer status changes but were sending out the spoolss_RouterReplyPrinterEx via the back-channel connection with job_id set to 0 (which we only may do for monitored printer change status notifies on printer handlers, not print server handles). Windows was then showing a new empty dummy printer icon in the explorer as it cannot route the notify event to the approriate local handle. It also discarded the content of the notify event message of course. With this, printer change notify for pausing, resuming and purging printers nicely works again here. Jerry, Tim and all other printing gurus, please check. Guenther --- source3/printing/notify.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/printing/notify.c b/source3/printing/notify.c index d478b86f91..e19212eea8 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -397,8 +397,10 @@ void notify_printer_status_byname(const char *sharename, uint32 status) { /* Printer status stored in value1 */ + int snum = print_queue_snum(sharename); + send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE, - PRINTER_NOTIFY_STATUS, 0, + PRINTER_NOTIFY_STATUS, snum, status, 0, 0); } -- cgit From faa1100d229aef56da5d48f5c19ec901e520f8ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Feb 2009 16:22:43 -0800 Subject: More warning fixes for Solaris. Jeremy. --- lib/replace/getifaddrs.c | 9 ------- source3/client/client.c | 6 ++--- source3/lib/ldap_debug_handler.c | 4 +-- source3/lib/smbldap.c | 2 ++ source3/lib/system.c | 3 +-- source3/lib/tdb_validate.c | 5 ++-- source3/libsmb/libsmb_dir.c | 2 +- source3/modules/vfs_extd_audit.c | 8 +++--- source3/nmbd/nmbd.c | 14 +++++------ source3/smbd/open.c | 2 +- source3/smbd/posix_acls.c | 52 +++++++++++++++++++-------------------- source3/smbd/server.c | 2 +- source3/smbd/sesssetup.c | 4 +-- source3/utils/smbget.c | 6 +++-- source3/winbindd/winbindd.c | 2 +- source3/winbindd/winbindd_cache.c | 18 +++++++------- source3/winbindd/winbindd_dual.c | 2 +- 17 files changed, 67 insertions(+), 74 deletions(-) diff --git a/lib/replace/getifaddrs.c b/lib/replace/getifaddrs.c index f6f0ec080c..3a91bb40d2 100644 --- a/lib/replace/getifaddrs.c +++ b/lib/replace/getifaddrs.c @@ -84,9 +84,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; @@ -164,9 +161,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) char buff[8192]; int fd, i, n; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; @@ -265,9 +259,6 @@ int rep_getifaddrs(struct ifaddrs **ifap) int fd, i; struct ifconf ifc; struct ifreq *ifr=NULL; - struct in_addr ipaddr; - struct in_addr nmask; - char *iname; struct ifaddrs *curif; struct ifaddrs *lastif = NULL; diff --git a/source3/client/client.c b/source3/client/client.c index 2f9e3c0d49..aaa9e35d96 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1784,13 +1784,13 @@ static struct file_list { Free a file_list structure. ****************************************************************************/ -static void free_file_list (struct file_list *list_head) +static void free_file_list (struct file_list *l_head) { struct file_list *list, *next; - for (list = list_head; list; list = next) { + for (list = l_head; list; list = next) { next = list->next; - DLIST_REMOVE(list_head, list); + DLIST_REMOVE(l_head, list); SAFE_FREE(list->file_path); SAFE_FREE(list); } diff --git a/source3/lib/ldap_debug_handler.c b/source3/lib/ldap_debug_handler.c index 2181ff014d..98623d1985 100644 --- a/source3/lib/ldap_debug_handler.c +++ b/source3/lib/ldap_debug_handler.c @@ -19,13 +19,11 @@ #include "includes.h" -#if HAVE_LDAP - +#if defined(HAVE_LDAP) && defined(HAVE_LBER_LOG_PRINT_FN) static void samba_ldap_log_print_fn(LDAP_CONST char *data) { DEBUG(lp_ldap_debug_threshold(), ("[LDAP] %s", data)); } - #endif void init_ldap_debugging(void) diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index f0561a5081..e24d35818c 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -581,7 +581,9 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) int smb_ldap_start_tls(LDAP *ldap_struct, int version) { +#ifdef LDAP_OPT_X_TLS int rc; +#endif if (lp_ldap_ssl() != LDAP_SSL_START_TLS) { return LDAP_SUCCESS; diff --git a/source3/lib/system.c b/source3/lib/system.c index ed66666ddb..8bdc9fa92b 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -2008,7 +2008,6 @@ static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size) static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) { ssize_t len = 0; - int stop = 0; DIR *dirp; struct dirent *de; int newfd = dup(attrdirfd); @@ -2080,7 +2079,7 @@ static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) { int filedes = openat(fildes, path, oflag, mode); if (filedes == -1) { - DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno))); + DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes,path,strerror(errno))); if (errno == EINVAL) { errno = ENOTSUP; } else { diff --git a/source3/lib/tdb_validate.c b/source3/lib/tdb_validate.c index 1f5dfe4d25..092546e3eb 100644 --- a/source3/lib/tdb_validate.c +++ b/source3/lib/tdb_validate.c @@ -118,7 +118,8 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn) /* parent */ - DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n",child_pid)); + DEBUG(10, ("tdb_validate: fork succeeded, child PID = %u\n", + (unsigned int)child_pid)); DEBUG(10, ("tdb_validate: waiting for child to finish...\n")); while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) { @@ -134,7 +135,7 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn) } if (wait_pid != child_pid) { DEBUG(1, ("tdb_validate: waitpid returned pid %d, " - "but %d was expected\n", wait_pid, child_pid)); + "but %u was expected\n", wait_pid, (unsigned int)child_pid)); goto done; } diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 1843fe262f..56661af70b 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1519,7 +1519,7 @@ SMBC_chmod_ctx(SMBCCTX *context, return -1; } - DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, (unsigned int)newmode)); if (SMBC_parse_path(frame, context, diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index d7c9d39c5e..b59a780f52 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -310,7 +310,7 @@ static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: chmod %s mode 0x%x %s %s\n", - path, mode, + path, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -330,7 +330,7 @@ static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t m (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: chmod_acl %s mode 0x%x %s %s\n", - path, mode, + path, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -350,7 +350,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s", - fsp->fsp_name, mode, + fsp->fsp_name, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); @@ -370,7 +370,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t (result < 0) ? strerror(errno) : ""); } DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s", - fsp->fsp_name, mode, + fsp->fsp_name, (unsigned int)mode, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index adefb7d94f..3279466602 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -412,18 +412,18 @@ static void msg_nmbd_send_packet(struct messaging_context *msg, const struct sockaddr_storage *pss; const struct in_addr *local_ip; - DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src))); + DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src))); if (data->length != sizeof(struct packet_struct)) { - DEBUG(2, ("Discarding invalid packet length from %d\n", - procid_to_pid(&src))); + DEBUG(2, ("Discarding invalid packet length from %u\n", + (unsigned int)procid_to_pid(&src))); return; } if ((p->packet_type != NMB_PACKET) && (p->packet_type != DGRAM_PACKET)) { - DEBUG(2, ("Discarding invalid packet type from %d: %d\n", - procid_to_pid(&src), p->packet_type)); + DEBUG(2, ("Discarding invalid packet type from %u: %d\n", + (unsigned int)procid_to_pid(&src), p->packet_type)); return; } @@ -431,8 +431,8 @@ static void msg_nmbd_send_packet(struct messaging_context *msg, pss = iface_ip((struct sockaddr *)&ss); if (pss == NULL) { - DEBUG(2, ("Could not find ip for packet from %d\n", - procid_to_pid(&src))); + DEBUG(2, ("Could not find ip for packet from %u\n", + (unsigned int)procid_to_pid(&src))); return; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ac7c35c240..a42705adb6 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1440,7 +1440,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, "create_disposition = 0x%x create_options=0x%x " "unix mode=0%o oplock_request=%d\n", fname, new_dos_attributes, access_mask, share_access, - create_disposition, create_options, unx_mode, + create_disposition, create_options, (unsigned int)unx_mode, oplock_request)); if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) { diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index e9b581efe8..2f84a831c6 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -719,12 +719,12 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn, Count a linked list of canonical ACE entries. ****************************************************************************/ -static size_t count_canon_ace_list( canon_ace *list_head ) +static size_t count_canon_ace_list( canon_ace *l_head ) { size_t count = 0; canon_ace *ace; - for (ace = list_head; ace; ace = ace->next) + for (ace = l_head; ace; ace = ace->next) count++; return count; @@ -734,13 +734,13 @@ static size_t count_canon_ace_list( canon_ace *list_head ) Free a linked list of canonical ACE entries. ****************************************************************************/ -static void free_canon_ace_list( canon_ace *list_head ) +static void free_canon_ace_list( canon_ace *l_head ) { canon_ace *list, *next; - for (list = list_head; list; list = next) { + for (list = l_head; list; list = next) { next = list->next; - DLIST_REMOVE(list_head, list); + DLIST_REMOVE(l_head, list); SAFE_FREE(list); } } @@ -916,7 +916,7 @@ static bool identity_in_ace_equal(canon_ace *ace1, canon_ace *ace2) static void merge_aces( canon_ace **pp_list_head ) { - canon_ace *list_head = *pp_list_head; + canon_ace *l_head = *pp_list_head; canon_ace *curr_ace_outer; canon_ace *curr_ace_outer_next; @@ -925,7 +925,7 @@ static void merge_aces( canon_ace **pp_list_head ) * with identical SIDs. */ - for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { + for (curr_ace_outer = l_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { canon_ace *curr_ace; canon_ace *curr_ace_next; @@ -947,7 +947,7 @@ static void merge_aces( canon_ace **pp_list_head ) /* Merge two allow or two deny ACE's. */ curr_ace_outer->perms |= curr_ace->perms; - DLIST_REMOVE(list_head, curr_ace); + DLIST_REMOVE(l_head, curr_ace); SAFE_FREE(curr_ace); curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */ } @@ -960,7 +960,7 @@ static void merge_aces( canon_ace **pp_list_head ) * appears only once in the list. */ - for (curr_ace_outer = list_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { + for (curr_ace_outer = l_head; curr_ace_outer; curr_ace_outer = curr_ace_outer_next) { canon_ace *curr_ace; canon_ace *curr_ace_next; @@ -992,7 +992,7 @@ static void merge_aces( canon_ace **pp_list_head ) * The deny overrides the allow. Remove the allow. */ - DLIST_REMOVE(list_head, curr_ace); + DLIST_REMOVE(l_head, curr_ace); SAFE_FREE(curr_ace); curr_ace_outer_next = curr_ace_outer->next; /* We may have deleted the link. */ @@ -1008,7 +1008,7 @@ static void merge_aces( canon_ace **pp_list_head ) * before we can get to an allow ace. */ - DLIST_REMOVE(list_head, curr_ace_outer); + DLIST_REMOVE(l_head, curr_ace_outer); SAFE_FREE(curr_ace_outer); break; } @@ -1019,7 +1019,7 @@ static void merge_aces( canon_ace **pp_list_head ) /* We may have modified the list. */ - *pp_list_head = list_head; + *pp_list_head = l_head; } /**************************************************************************** @@ -2305,12 +2305,12 @@ static bool unpack_canon_ace(files_struct *fsp, static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head) { - canon_ace *list_head = *pp_list_head; + canon_ace *l_head = *pp_list_head; canon_ace *owner_ace = NULL; canon_ace *other_ace = NULL; canon_ace *ace = NULL; - for (ace = list_head; ace; ace = ace->next) { + for (ace = l_head; ace; ace = ace->next) { if (ace->type == SMB_ACL_USER_OBJ) owner_ace = ace; else if (ace->type == SMB_ACL_OTHER) { @@ -2331,16 +2331,16 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head) */ if (owner_ace) { - DLIST_PROMOTE(list_head, owner_ace); + DLIST_PROMOTE(l_head, owner_ace); } if (other_ace) { - DLIST_DEMOTE(list_head, other_ace, canon_ace *); + DLIST_DEMOTE(l_head, other_ace, canon_ace *); } /* We have probably changed the head of the list. */ - *pp_list_head = list_head; + *pp_list_head = l_head; } /**************************************************************************** @@ -2353,7 +2353,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type) { mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR); - canon_ace *list_head = NULL; + canon_ace *l_head = NULL; canon_ace *ace = NULL; canon_ace *next_ace = NULL; int entry_id = SMB_ACL_FIRST_ENTRY; @@ -2457,14 +2457,14 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, ace->owner_type = owner_type; ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT)); - DLIST_ADD(list_head, ace); + DLIST_ADD(l_head, ace); } /* * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(&list_head, conn->params, + if (!ensure_canon_entry_valid(&l_head, conn->params, S_ISDIR(psbuf->st_mode), powner, pgroup, psbuf, False)) goto fail; @@ -2476,7 +2476,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" )); - for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) { + for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) { next_ace = ace->next; /* Masks are only applied to entries other than USER_OBJ and OTHER. */ @@ -2484,7 +2484,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, ace->perms &= acl_mask; if (ace->perms == 0) { - DLIST_PROMOTE(list_head, ace); + DLIST_PROMOTE(l_head, ace); } if( DEBUGLVL( 10 ) ) { @@ -2492,15 +2492,15 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, } } - arrange_posix_perms(fname,&list_head ); + arrange_posix_perms(fname,&l_head ); - print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head ); + print_canon_ace_list( "canonicalise_acl: ace entries after arrange", l_head ); - return list_head; + return l_head; fail: - free_canon_ace_list(list_head); + free_canon_ace_list(l_head); return NULL; } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 49995d8901..346e8973de 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -212,7 +212,7 @@ static void remove_child_pid(pid_t pid, bool unclean_shutdown) /* a child terminated uncleanly so tickle all processes to see if they can grab any of the pending locks */ - DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", pid)); + DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", (unsigned int)pid)); messaging_send_buf(smbd_messaging_context(), procid_self(), MSG_SMB_BRL_VALIDATE, NULL, 0); message_send_all(smbd_messaging_context(), diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8a09ed39a9..2c29192220 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1352,8 +1352,8 @@ static int shutdown_other_smbds(struct db_record *rec, return 0; } - DEBUG(0,("shutdown_other_smbds: shutting down pid %d " - "(IP %s)\n", procid_to_pid(&crec->pid), ip)); + DEBUG(0,("shutdown_other_smbds: shutting down pid %u " + "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid), ip)); messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN, &data_blob_null); diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index 7c01f5db3a..042f3a98f7 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -194,7 +194,8 @@ static int smb_download_dir(const char *base, const char *name, int resume) } if(chmod(relname, remotestat.st_mode) < 0) { - fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, remotestat.st_mode); + fprintf(stderr, "Unable to change mode of local dir %s to %o\n", relname, + (unsigned int)remotestat.st_mode); smbc_closedir(dirhandle); return 0; } @@ -471,7 +472,8 @@ static int smb_download_file(const char *base, const char *name, int recursive, if(keep_permissions && !send_stdout) { if(fchmod(localhandle, remotestat.st_mode) < 0) { - fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode); + fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, + (unsigned int)remotestat.st_mode); smbc_close(remotehandle); close(localhandle); return 0; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index be91611bfb..dbe83152dd 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -386,7 +386,7 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx, if (child_pid != 0) { /* parent */ DEBUG(5, ("winbind_msg_validate_cache: child created with " - "pid %d.\n", child_pid)); + "pid %d.\n", (int)child_pid)); return; } diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 8326aba40a..02d0b5bc4e 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -2625,9 +2625,9 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) return; DEBUG(10, ("Storing response for pid %d, len %d\n", - pid, response->length)); + (int)pid, response->length)); - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); if (tdb_store(wcache->tdb, string_tdb_data(key_str), make_tdb_data((uint8 *)response, sizeof(*response)), TDB_REPLACE) == -1) @@ -2641,7 +2641,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) DEBUG(10, ("Storing extra data: len=%d\n", (int)(response->length - sizeof(*response)))); - fstr_sprintf(key_str, "DE/%d", pid); + fstr_sprintf(key_str, "DE/%d", (int)pid); if (tdb_store(wcache->tdb, string_tdb_data(key_str), make_tdb_data((uint8 *)response->extra_data.data, response->length - sizeof(*response)), @@ -2651,7 +2651,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response) /* We could not store the extra data, make sure the tdb does not * contain a main record with wrong dangling extra data */ - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); tdb_delete(wcache->tdb, string_tdb_data(key_str)); return; @@ -2665,9 +2665,9 @@ bool cache_retrieve_response(pid_t pid, struct winbindd_response * response) if (!init_wcache()) return false; - DEBUG(10, ("Retrieving response for pid %d\n", pid)); + DEBUG(10, ("Retrieving response for pid %d\n", (int)pid)); - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); data = tdb_fetch(wcache->tdb, string_tdb_data(key_str)); if (data.dptr == NULL) @@ -2689,7 +2689,7 @@ bool cache_retrieve_response(pid_t pid, struct winbindd_response * response) DEBUG(10, ("Retrieving extra data length=%d\n", (int)(response->length - sizeof(*response)))); - fstr_sprintf(key_str, "DE/%d", pid); + fstr_sprintf(key_str, "DE/%d", (int)pid); data = tdb_fetch(wcache->tdb, string_tdb_data(key_str)); if (data.dptr == NULL) { @@ -2716,10 +2716,10 @@ void cache_cleanup_response(pid_t pid) if (!init_wcache()) return; - fstr_sprintf(key_str, "DR/%d", pid); + fstr_sprintf(key_str, "DR/%d", (int)pid); tdb_delete(wcache->tdb, string_tdb_data(key_str)); - fstr_sprintf(key_str, "DE/%d", pid); + fstr_sprintf(key_str, "DE/%d", (int)pid); tdb_delete(wcache->tdb, string_tdb_data(key_str)); return; diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index d40bab94ef..f56a63faa0 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -183,7 +183,7 @@ static void async_request_timeout_handler(struct event_context *ctx, DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. " "Closing connection to it.\n", - state->child_pid )); + (unsigned int)state->child_pid )); /* Deal with the reply - set to error. */ async_reply_recv(private_data, False); -- cgit From b9860043dc092df25d4a39074e106d7367ebbe8f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Feb 2009 11:39:44 +1100 Subject: fixed the event context for net vampire --- source4/utils/net/net_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/utils/net/net_join.c b/source4/utils/net/net_join.c index ad63340089..b0a25bb7c0 100644 --- a/source4/utils/net/net_join.c +++ b/source4/utils/net/net_join.c @@ -126,7 +126,7 @@ int net_vampire(struct net_context *ctx, int argc, const char **argv) domain_name = tmp; - libnetctx = libnet_context_init(NULL, ctx->lp_ctx); + libnetctx = libnet_context_init(ctx->event_ctx, ctx->lp_ctx); if (!libnetctx) { return -1; } -- cgit From 8d63c596a0f512c96f5663c0a9bd49d3c98c6df9 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Mon, 23 Feb 2009 20:46:11 -0800 Subject: Refactored sys_fork() and sys_pid() into shared util library This fixes a bug in 116ce19b, where we didn't clear the pid cache in become_daemon() and thus the /var/run/smbd.pid didn't match the actual pid of the parent process. Currently S4 will clear the pid cache on fork but doesn't yet take advantage of the pid cache by using sys_pid() instead of the direct get_pid(). --- lib/util/become_daemon.c | 6 +++--- lib/util/system.c | 29 +++++++++++++++++++++++++++++ lib/util/util.h | 10 ++++++++++ source3/Makefile.in | 2 +- source3/include/proto.h | 2 -- source3/lib/system.c | 29 ----------------------------- 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c index 5a97b65407..3d06a4363d 100644 --- a/lib/util/become_daemon.c +++ b/lib/util/become_daemon.c @@ -66,10 +66,10 @@ _PUBLIC_ void close_low_fds(bool stderr_too) Become a daemon, discarding the controlling terminal. ****************************************************************************/ -_PUBLIC_ void become_daemon(bool Fork, bool no_process_group) +_PUBLIC_ void become_daemon(bool do_fork, bool no_process_group) { - if (Fork) { - if (fork()) { + if (do_fork) { + if (sys_fork()) { _exit(0); } } diff --git a/lib/util/system.c b/lib/util/system.c index 9bd1800233..9bf5de1a83 100644 --- a/lib/util/system.c +++ b/lib/util/system.c @@ -88,3 +88,32 @@ _PUBLIC_ struct in_addr sys_inet_makeaddr(int net, int host) return in2; } +/************************************************************************** + Wrapper for fork. Ensures we clear our pid cache. +****************************************************************************/ + +static pid_t mypid = (pid_t)-1; + +_PUBLIC_ pid_t sys_fork(void) +{ + pid_t forkret = fork(); + + if (forkret == (pid_t)0) { + /* Child - reset mypid so sys_getpid does a system call. */ + mypid = (pid_t) -1; + } + + return forkret; +} + +/************************************************************************** + Wrapper for getpid. Ensures we only do a system call *once*. +****************************************************************************/ + +_PUBLIC_ pid_t sys_getpid(void) +{ + if (mypid == (pid_t)-1) + mypid = getpid(); + + return mypid; +} diff --git a/lib/util/util.h b/lib/util/util.h index d3e446f488..27f94cd685 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -134,6 +134,16 @@ apparent reason. _PUBLIC_ struct hostent *sys_gethostbyname(const char *name); _PUBLIC_ struct in_addr sys_inet_makeaddr(int net, int host); +/** + * Wrapper for fork used to invalid pid cache. + **/ +_PUBLIC_ pid_t sys_fork(void); + +/** + * Wrapper for getpid. Ensures we only do a system call *once*. + **/ +_PUBLIC_ pid_t sys_getpid(void); + /* The following definitions come from lib/util/genrand.c */ /** diff --git a/source3/Makefile.in b/source3/Makefile.in index 7564659dd3..a403f143bb 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -339,7 +339,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/util.o ../lib/util/fsusage.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ - ../lib/util/become_daemon.o + ../lib/util/become_daemon.o ../lib/util/system.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index faf47d3844..14241d5ce3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -972,8 +972,6 @@ struct passwd *sys_getpwnam(const char *name); struct passwd *sys_getpwuid(uid_t uid); struct group *sys_getgrnam(const char *name); struct group *sys_getgrgid(gid_t gid); -pid_t sys_fork(void); -pid_t sys_getpid(void); int sys_popen(const char *command); int sys_pclose(int fd); ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size); diff --git a/source3/lib/system.c b/source3/lib/system.c index 8bdc9fa92b..10b55f662d 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1042,35 +1042,6 @@ static char **extract_args(TALLOC_CTX *mem_ctx, const char *command) return NULL; } -/************************************************************************** - Wrapper for fork. Ensures that mypid is reset. Used so we can write - a sys_getpid() that only does a system call *once*. -****************************************************************************/ - -static pid_t mypid = (pid_t)-1; - -pid_t sys_fork(void) -{ - pid_t forkret = fork(); - - if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */ - mypid = (pid_t) -1; - - return forkret; -} - -/************************************************************************** - Wrapper for getpid. Ensures we only do a system call *once*. -****************************************************************************/ - -pid_t sys_getpid(void) -{ - if (mypid == (pid_t)-1) - mypid = getpid(); - - return mypid; -} - /************************************************************************** Wrapper for popen. Safer as it doesn't search a path. Modified from the glibc sources. -- cgit From 7bcaaf14fbf22805d88b945256b6bd31121c7c66 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Sun, 22 Feb 2009 20:50:30 -0800 Subject: s3 OneFS: Add a parameter that unconditionally allows execute access --- source3/modules/onefs.h | 2 ++ source3/modules/onefs_system.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index a70664bbf3..418e13d9d2 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -41,6 +41,8 @@ enum onefs_acl_wire_format #define PARM_ONEFS_TYPE "onefs" #define PARM_ACL_WIRE_FORMAT "acl wire format" #define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD +#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always" +#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false #define PARM_ATIME_NOW "atime now files" #define PARM_ATIME_NOW_DEFAULT NULL #define PARM_ATIME_STATIC "atime static files" diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 10802895cd..76df006d82 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -132,6 +132,30 @@ int onefs_sys_create_file(connection_struct *conn, if (lp_nt_acl_support(SNUM(conn)) && !lp_inherit_perms(SNUM(conn))) cf_flags = cf_flags_or(cf_flags, CF_FLAGS_DEFAULT_ACL); + /* + * Some customer workflows require the execute bit to be ignored. + */ + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_ALLOW_EXECUTE_ALWAYS, + PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT) && + (open_access_mask & FILE_EXECUTE)) { + + DEBUG(3, ("Stripping execute bit from %s: (0x%x)\n", path, + open_access_mask)); + + /* Strip execute. */ + open_access_mask &= ~FILE_EXECUTE; + + /* + * Add READ_DATA, so we're not left with desired_access=0. An + * execute call should imply the client will read the data. + */ + open_access_mask |= FILE_READ_DATA; + + DEBUGADD(3, ("New stripped access mask: 0x%x\n", + open_access_mask)); + } + DEBUG(10,("onefs_sys_create_file: base_fd = %d, " "open_access_mask = 0x%x, flags = 0x%x, mode = 0%o, " "desired_oplock = %s, id = 0x%x, secinfo = 0x%x, sd = %p, " -- cgit From 997dfbbf5409a9df3b3c87025fa80fb6bdafcac2 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 23 Feb 2009 17:43:47 -0800 Subject: s3 OneFS: Fix a double free in an error path --- source3/smbd/oplock_onefs.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c index 0908ce4386..d4f181fc47 100644 --- a/source3/smbd/oplock_onefs.c +++ b/source3/smbd/oplock_onefs.c @@ -744,13 +744,13 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx) po.po_flags_on |= P_NON_BLOCKING_SEMLOCK; if (setprocoptions(&po) != 0) { DEBUG(0, ("setprocoptions failed: %s.\n", strerror(errno))); - goto err_out; + return NULL; } /* Setup the oplock contexts */ _ctx = talloc_zero(mem_ctx, struct kernel_oplocks); if (!_ctx) { - goto err_out; + return NULL; } ctx = talloc_zero(_ctx, struct onefs_oplocks_context); @@ -788,7 +788,6 @@ struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx) err_out: talloc_free(_ctx); - talloc_free(ctx); return NULL; } -- cgit From 022946d1961ddca40a9ac1fc00cf79ae32797669 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 24 Feb 2009 20:41:50 +1100 Subject: Make the 'modules.conf' generation in the LDAP selftest simpler The versions of OpenLDAP that we require don't need us to specify the location any more - slaptest knows this from it's build time. Andrew Bartlett --- selftest/target/Samba4.pm | 59 ++++++----------------------------------------- 1 file changed, 7 insertions(+), 52 deletions(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 09138cf0aa..71dddf6939 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -242,77 +242,32 @@ sub mk_openldap($$$) $ENV{PATH} = "$olpath/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}"; unlink($modconf); - open(CONF, ">$modconf"); close(CONF); - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules - print CONF " -modulepath $olroot/libexec/openldap -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules - print CONF " -modulepath $olroot/libexec/openldap -moduleload back_hdb -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } + #This code tries to guess what modules we need to load (if any) by trying different combinations in the modules.conf - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules - print CONF " -moduleload back_hdb -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } + # Try without any slapd modules + open(CONF, ">$modconf"); close(CONF); if (system("slaptest -u -f $slapd_conf >&2") != 0) { open(CONF, ">$modconf"); # enable slapd modules print CONF " -modulepath /usr/lib/ldap -moduleload back_hdb moduleload syncprov moduleload memberof moduleload refint +moduleload deref "; close(CONF); } - if (system("slaptest -u -f $slapd_conf >&2") != 0) { open(CONF, ">$modconf"); - # enable slapd modules (Fedora layout) + # enable slapd modules, and the module for back_hdb print CONF " -modulepath /usr/lib/openldap -moduleload syncprov -moduleload memberof -moduleload refint -"; - close(CONF); - } - - if (system("slaptest -u -f $slapd_conf >&2") != 0) { - open(CONF, ">$modconf"); - # enable slapd modules (Fedora x86_64 layout) - print CONF " -modulepath /usr/lib64/openldap +moduleload back_hdb moduleload syncprov moduleload memberof moduleload refint +moduleload deref "; close(CONF); } -- cgit From 0ca5b72ad951df5f1cc3be30ca5be87399714dcc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:40:21 +0100 Subject: spoolss: add SPOOLSS_DEFAULT_SERVER_PATH. Guenther --- librpc/idl/spoolss.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index b8f4c13148..4765dd0b1e 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1118,6 +1118,7 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x1a */ const string SPOOLSS_ARCHITECTURE_NT_X86 = "Windows NT x86"; + const string SPOOLSS_DEFAULT_SERVER_PATH = "C:\\WINDOWS\\system32\\spool"; typedef [public,gensize] struct { [value(ndr_size_spoolss_OSVersion(r,ndr->iconv_convenience,ndr->flags))] uint32 _ndr_size; -- cgit From aa576c292f6b16ee95e539c921f54f9b07313f17 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:41:05 +0100 Subject: spoolss: return subcontext spoolss_DriverInfo in spoolss_GetPrinterDriver2. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 4765dd0b1e..510ad3e8b2 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1505,7 +1505,7 @@ import "misc.idl", "security.idl", "winreg.idl"; [in] uint32 offered, [in] uint32 client_major_version, [in] uint32 client_minor_version, - [out,unique] DATA_BLOB *info, + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_DriverInfo *info, [out,ref] uint32 *needed, [out,ref] uint32 *server_major_version, [out,ref] uint32 *server_minor_version -- cgit From 13995f5212bf1f5db4d246e8de3f63b761788d71 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:43:53 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/cli_spoolss.c | 2 +- librpc/gen_ndr/cli_spoolss.h | 2 +- librpc/gen_ndr/ndr_spoolss.c | 19 ++++++++++++++++--- librpc/gen_ndr/spoolss.h | 3 ++- librpc/gen_ndr/srv_spoolss.c | 4 ++-- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c index 02a05b94ff..2aa42b93bf 100644 --- a/librpc/gen_ndr/cli_spoolss.c +++ b/librpc/gen_ndr/cli_spoolss.c @@ -2540,7 +2540,7 @@ NTSTATUS rpccli_spoolss_GetPrinterDriver2(struct rpc_pipe_client *cli, uint32_t offered /* [in] */, uint32_t client_major_version /* [in] */, uint32_t client_minor_version /* [in] */, - DATA_BLOB *info /* [out] [unique] */, + union spoolss_DriverInfo *info /* [out] [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */, uint32_t *needed /* [out] [ref] */, uint32_t *server_major_version /* [out] [ref] */, uint32_t *server_minor_version /* [out] [ref] */, diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h index bb38d59cfb..83b2e28729 100644 --- a/librpc/gen_ndr/cli_spoolss.h +++ b/librpc/gen_ndr/cli_spoolss.h @@ -331,7 +331,7 @@ NTSTATUS rpccli_spoolss_GetPrinterDriver2(struct rpc_pipe_client *cli, uint32_t offered /* [in] */, uint32_t client_major_version /* [in] */, uint32_t client_minor_version /* [in] */, - DATA_BLOB *info /* [out] [unique] */, + union spoolss_DriverInfo *info /* [out] [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */, uint32_t *needed /* [out] [ref] */, uint32_t *server_major_version /* [out] [ref] */, uint32_t *server_minor_version /* [out] [ref] */, diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 3e210b2417..642ac0b71b 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -20096,7 +20096,13 @@ static enum ndr_err_code ndr_push_spoolss_GetPrinterDriver2(struct ndr_push *ndr if (flags & NDR_OUT) { NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info)); if (r->out.info) { - NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, *r->out.info)); + { + struct ndr_push *_ndr_info; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); + NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->out.info, r->in.level)); + NDR_CHECK(ndr_push_spoolss_DriverInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); + } } if (r->out.needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -20188,7 +20194,13 @@ static enum ndr_err_code ndr_pull_spoolss_GetPrinterDriver2(struct ndr_pull *ndr if (r->out.info) { _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0); - NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, r->out.info)); + { + struct ndr_pull *_ndr_info; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 4, r->in.offered)); + NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->out.info, r->in.level)); + NDR_CHECK(ndr_pull_spoolss_DriverInfo(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 4, r->in.offered)); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { @@ -20255,7 +20267,8 @@ _PUBLIC_ void ndr_print_spoolss_GetPrinterDriver2(struct ndr_print *ndr, const c ndr_print_ptr(ndr, "info", r->out.info); ndr->depth++; if (r->out.info) { - ndr_print_DATA_BLOB(ndr, "info", *r->out.info); + ndr_print_set_switch_value(ndr, r->out.info, r->in.level); + ndr_print_spoolss_DriverInfo(ndr, "info", r->out.info); } ndr->depth--; ndr_print_ptr(ndr, "needed", r->out.needed); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 0e8ba37cb7..0b77997ee4 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -10,6 +10,7 @@ #define PRINTER_ENUM_ICONMASK ( (PRINTER_ENUM_ICON1|PRINTER_ENUM_ICON2|PRINTER_ENUM_ICON3|PRINTER_ENUM_ICON4|PRINTER_ENUM_ICON5|PRINTER_ENUM_ICON6|PRINTER_ENUM_ICON7|PRINTER_ENUM_ICON8) ) #define SPOOLSS_ARCHITECTURE_NT_X86 ( "Windows NT x86" ) +#define SPOOLSS_DEFAULT_SERVER_PATH ( "C:\\WINDOWS\\system32\\spool" ) #define PRINTER_CHANGE_PRINTER ( 0x000000FF ) #define PRINTER_CHANGE_JOB ( 0x0000FF00 ) #define PRINTER_CHANGE_FORM ( (PRINTER_CHANGE_ADD_FORM|PRINTER_CHANGE_SET_FORM|PRINTER_CHANGE_DELETE_FORM) ) @@ -2282,7 +2283,7 @@ struct spoolss_GetPrinterDriver2 { } in; struct { - DATA_BLOB *info;/* [unique] */ + union spoolss_DriverInfo *info;/* [unique,subcontext_size(offered),subcontext(4),switch_is(level)] */ uint32_t *needed;/* [ref] */ uint32_t *server_major_version;/* [ref] */ uint32_t *server_minor_version;/* [ref] */ diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c index f6c17cb1fa..891be85376 100644 --- a/librpc/gen_ndr/srv_spoolss.c +++ b/librpc/gen_ndr/srv_spoolss.c @@ -4169,7 +4169,7 @@ static bool api_spoolss_GetPrinterDriver2(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.info = talloc_zero(r, DATA_BLOB); + r->out.info = talloc_zero(r, union spoolss_DriverInfo); if (r->out.info == NULL) { talloc_free(r); return false; @@ -8080,7 +8080,7 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_SPOOLSS_GETPRINTERDRIVER2: { struct spoolss_GetPrinterDriver2 *r = (struct spoolss_GetPrinterDriver2 *)_r; ZERO_STRUCT(r->out); - r->out.info = talloc_zero(mem_ctx, DATA_BLOB); + r->out.info = talloc_zero(mem_ctx, union spoolss_DriverInfo); if (r->out.info == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From 00173c6ce6e6aa394acc0685827b0b9fb1faf45c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 10:34:40 +0100 Subject: s3-spoolss: merge path handling in _spoolss_PrintProcessorDirectory and _spoolss_PrinterDriverDirectory. Guenther --- source3/rpc_server/srv_spoolss_nt.c | 127 ++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 36 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index a4679eb717..62301c001b 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -8059,45 +8059,106 @@ WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p, /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx, +struct _spoolss_paths { + int type; + const char *share; + const char *dir; +}; + +enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH }; + +static const struct _spoolss_paths spoolss_paths[]= { + { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" }, + { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" } +}; + +static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx, const char *servername, const char *environment, - struct spoolss_DriverDirectoryInfo1 *info1, - uint32_t offered, - uint32_t *needed) + int component, + char **path) { - char *path = NULL; const char *pservername = NULL; const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86; const char *short_archi; - if (environment) { + *path = NULL; + + /* environment may be empty */ + if (environment && strlen(environment)) { long_archi = environment; } - pservername = canon_servername(servername); + /* servername may be empty */ + if (servername && strlen(servername)) { + pservername = canon_servername(servername); - if ( !is_myname_or_ipaddr(pservername)) - return WERR_INVALID_PARAM; + if (!is_myname_or_ipaddr(pservername)) { + return WERR_INVALID_PARAM; + } + } - if (!(short_archi = get_short_archi(long_archi))) + if (!(short_archi = get_short_archi(long_archi))) { return WERR_INVALID_ENVIRONMENT; + } - path = talloc_asprintf(mem_ctx, - "\\\\%s\\print$\\%s", pservername, short_archi); - if (!path) { + switch (component) { + case SPOOLSS_PRTPROCS_PATH: + case SPOOLSS_DRIVER_PATH: + if (pservername) { + *path = talloc_asprintf(mem_ctx, + "\\\\%s\\%s\\%s", + pservername, + spoolss_paths[component].share, + short_archi); + } else { + *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s", + SPOOLSS_DEFAULT_SERVER_PATH, + spoolss_paths[component].dir, + short_archi); + } + break; + default: + return WERR_INVALID_PARAM; + } + + if (!*path) { return WERR_NOMEM; } + return WERR_OK; +} + +/**************************************************************************** +****************************************************************************/ + +static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx, + const char *servername, + const char *environment, + struct spoolss_DriverDirectoryInfo1 *r, + uint32_t offered, + uint32_t *needed) +{ + WERROR werr; + char *path = NULL; + + werr = compose_spoolss_server_path(mem_ctx, + servername, + environment, + SPOOLSS_DRIVER_PATH, + &path); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + DEBUG(4,("printer driver directory: [%s]\n", path)); - info1->directory_name = path; + r->directory_name = path; - *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0); + *needed += ndr_size_spoolss_DriverDirectoryInfo1(r, NULL, 0); if (*needed > offered) { talloc_free(path); - ZERO_STRUCTP(info1); return WERR_INSUFFICIENT_BUFFER; } @@ -9728,36 +9789,30 @@ done: static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx, const char *servername, const char *environment, - struct spoolss_PrintProcessorDirectoryInfo1 *info1, + struct spoolss_PrintProcessorDirectoryInfo1 *r, uint32_t offered, uint32_t *needed) { - const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86; - const char *short_archi; - - if (environment) { - long_archi = environment; - } + WERROR werr; + char *path = NULL; - short_archi = get_short_archi(long_archi); - if (!short_archi) { - return WERR_INVALID_ENVIRONMENT; + werr = compose_spoolss_server_path(mem_ctx, + servername, + environment, + SPOOLSS_PRTPROCS_PATH, + &path); + if (!W_ERROR_IS_OK(werr)) { + return werr; } - /* I think this should look like this - gd - info1->directory_name = talloc_asprintf(mem_ctx, - "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi); - */ - info1->directory_name = talloc_strdup(mem_ctx, - "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86"); + DEBUG(4,("print processor directory: [%s]\n", path)); - if (!info1->directory_name) { - return WERR_NOMEM; - } + r->directory_name = path; - *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0); + *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(r, NULL, 0); if (*needed > offered) { + talloc_free(path); return WERR_INSUFFICIENT_BUFFER; } -- cgit From 31f2cddcf5886b0a78290fdfa609a2ee63bda5ad Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Tue, 24 Feb 2009 11:37:58 +1100 Subject: Added mmr and olc to the OpenLDAP backend provisioning-scripts These extensions add mmr (multi-master-replication) and olc (openldap-online-configuration) capabilities to the provisioning-scripts (provision-backend and provision.py), for use with the openldap-backend (only versions >=2.4.15!). Changes / additions made to the provision-backend -script: added new command-line-options: --ol-mmr-urls= for use with mmr (can be combined with --ol-olc=yes), --ol-olc=[yes/no] (activate automatic conversion from static slapd.conf to olc), --ol-slaptest= (needed in conjunction with --ol-olc=yes) Changes / additions made to the provision.py -script: added extensions, that will automatically generate the chosen mmr and/or olc setup for the openldap backend, according to the to chosen parameters set in the provision-backend script Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision.py | 187 ++++++++++++++++++++++------ source4/setup/DB_CONFIG | 11 -- source4/setup/mmr_serverids.conf | 1 - source4/setup/olcOverlay={0}syncprov.ldif | 11 ++ source4/setup/olc_acl.conf | 4 + source4/setup/olc_mmr.conf | 3 + source4/setup/olc_pass.conf | 3 + source4/setup/olc_seed.ldif | 16 +++ source4/setup/olc_serverid.conf | 1 + source4/setup/olc_syncrepl.conf | 13 ++ source4/setup/olc_syncrepl_seed.conf | 5 + source4/setup/provision-backend | 12 +- source4/setup/slapd.conf | 20 +-- 13 files changed, 224 insertions(+), 63 deletions(-) create mode 100644 source4/setup/olcOverlay={0}syncprov.ldif create mode 100644 source4/setup/olc_acl.conf create mode 100644 source4/setup/olc_mmr.conf create mode 100644 source4/setup/olc_pass.conf create mode 100644 source4/setup/olc_seed.ldif create mode 100644 source4/setup/olc_serverid.conf create mode 100644 source4/setup/olc_syncrepl.conf create mode 100644 source4/setup/olc_syncrepl_seed.conf diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a5b3e8322f..8442c24d71 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -26,6 +26,7 @@ from base64 import b64encode import os +import sys import pwd import grp import time @@ -93,9 +94,14 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - self.olmmron = None - self.olmmrserveridsconf = None - self.olmmrsyncreplconf = None + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None + self.olcdir = None + self.olslaptest = None + self.olcseedldif = None + self.olcsyncprovdir = None + self.olcsyncprovfile = None class ProvisionNames(object): @@ -268,6 +274,14 @@ def provision_paths_from_lp(lp, dnsdomain): "mmr_serverids.conf") paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, "mmr_syncrepl.conf") + paths.olcdir = os.path.join(paths.ldapdir, + "slapd.d") + paths.olcseedldif = os.path.join(paths.ldapdir, + "olc_seed.ldif") + paths.olcsyncprovdir = os.path.join(paths.olcdir, + "cn=config/olcDatabase={0}config") + paths.olcsyncprovfile = os.path.join(paths.olcsyncprovdir, + "olcOverlay={0}syncprov.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1178,7 +1192,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None): + ol_mmr_urls=None,ol_olc=None,ol_slaptest=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1205,6 +1219,19 @@ def provision_backend(setup_dir=None, message=None, make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + # openldap-online-configuration: validation of olc and slaptest + if ol_olc == "yes" and ol_slaptest is None: + sys.exit("Warning: OpenLDAP-Online-Configuration cant be setup without path to slaptest-Binary!") + + if ol_olc == "yes" and ol_slaptest is not None: + ol_slaptest = ol_slaptest + "/slaptest" + if not os.path.exists(ol_slaptest): + message (ol_slaptest) + sys.exit("Warning: Given Path to slaptest-Binary does not exist!") + ### + + + lp = param.LoadParm() lp.load(smbconf) @@ -1300,52 +1327,95 @@ def provision_backend(setup_dir=None, message=None, { "LINK_ATTRS" : refint_attributes}) # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts - mmr_on_config = "" - mmr_replicator_acl = "" - mmr_serverids_config = "" + mmr_on_config = "" + mmr_replicator_acl = "" + mmr_serverids_config = "" mmr_syncrepl_schema_config = "" - mmr_syncrepl_config_config = "" - mmr_syncrepl_user_config = "" - - if ol_mmr_urls is not None: + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + + + if ol_mmr_urls is not None: # For now, make these equal mmr_pass = adminpass - url_list=filter(None,ol_mmr_urls.split(' ')) + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) - mmr_on_config = "MirrorMode On" - mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" - serverid=0 - for url in url_list: - serverid=serverid+1 - mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(serverid), - "LDAPSERVER" : url }) + mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" + serverid=0 + for url in url_list: + serverid=serverid+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) rid=serverid*10 - rid=rid+1 - mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.schemadn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.schemadn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.configdn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.configdn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.domaindn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.domaindn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass }) + # olc = yes? + olc_config_pass = "" + olc_config_acl = "" + olc_syncrepl_config = "" + olc_mmr_config = "" + if ol_olc == "yes": + olc_config_pass += read_and_sub_file(setup_path("olc_pass.conf"), + { "OLC_PW": adminpass }) + olc_config_acl += read_and_sub_file(setup_path("olc_acl.conf"),{}) + + # if olc = yes + mmr = yes, generate cn=config-replication directives + # and olc_seed.lif for the other mmr-servers + if ol_olc == "yes" and ol_mmr_urls is not None: + serverid=0 + olc_serverids_config = "" + olc_syncrepl_config = "" + olc_syncrepl_seed_config = "" + olc_mmr_config = "" + olc_mmr_config += read_and_sub_file(setup_path("olc_mmr.conf"),{}) + rid=1000 + for url in url_list: + serverid=serverid+1 + olc_serverids_config += read_and_sub_file(setup_path("olc_serverid.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) + + rid=rid+1 + olc_syncrepl_config += read_and_sub_file(setup_path("olc_syncrepl.conf"), + { "RID" : str(rid), + "LDAPSERVER" : url, + "MMR_PASSWORD": adminpass}) + + olc_syncrepl_seed_config += read_and_sub_file(setup_path("olc_syncrepl_seed.conf"), + { "RID" : str(rid), + "LDAPSERVER" : url}) + + setup_file(setup_path("olc_seed.ldif"), paths.olcseedldif, + {"OLC_SERVER_ID_CONF": olc_serverids_config, + "OLC_PW": adminpass, + "OLC_SYNCREPL_CONF": olc_syncrepl_seed_config}) + + # end olc setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1360,8 +1430,12 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, + "OLC_CONFIG_PASS": olc_config_pass, + "OLC_SYNCREPL_CONFIG": olc_syncrepl_config, + "OLC_CONFIG_ACL": olc_config_acl, + "OLC_MMR_CONFIG": olc_mmr_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) @@ -1380,16 +1454,15 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - - if ol_mmr_urls is not None: - setup_file(setup_path("cn=replicator.ldif"), + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" @@ -1399,7 +1472,18 @@ def provision_backend(setup_dir=None, message=None, else: server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + if ol_olc != "yes" and ol_mmr_urls is None: + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + if ol_olc == "yes" and ol_mmr_urls is None: + slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" + + if ol_olc != "yes" and ol_mmr_urls is not None: + slapdcommand="Start slapd with: slapd -F " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" + + if ol_olc == "yes" and ol_mmr_urls is not None: + slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" + ldapuser = "--username=samba-admin" @@ -1437,6 +1521,27 @@ def provision_backend(setup_dir=None, message=None, message("Run provision with: " + " ".join(args)) + # if --ol-olc=yes, generate online-configuration in ../private/ldap/slapd.d + if ol_olc == "yes": + if not os.path.isdir(paths.olcdir): + os.makedirs(paths.olcdir, 0770) + paths.olslaptest = str(ol_slaptest) + olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir + " >/dev/null 2>&1" + os.system(olc_command) + #os.remove(paths.slapdconf) + # use line below for debugging during olc-conversion with slaptest + #olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir" + + # workaround, if overlay syncprov is was not created properly during conversion to cn=config. + # otherwise, cn=config won't be replicated + if ol_olc == "yes" and ol_mmr_urls is not None: + if not os.path.exists(paths.olcsyncprovdir): + os.makedirs(paths.olcsyncprovdir, 0770) + setup_file(setup_path("olcOverlay={0}syncprov.ldif"), + os.path.join(paths.olcsyncprovdir, "olcOverlay={0}syncprov.ldif"), {}) + + + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. diff --git a/source4/setup/DB_CONFIG b/source4/setup/DB_CONFIG index b4d2bfa868..74bb09d800 100644 --- a/source4/setup/DB_CONFIG +++ b/source4/setup/DB_CONFIG @@ -1,17 +1,6 @@ -# -# Set the database in memory cache size. -# set_cachesize 0 524288 0 - -# -# Set log values. -# set_lg_regionmax 104857 set_lg_max 1048576 set_lg_bsize 209715 set_lg_dir ${LDAPDBDIR}/bdb-logs - -# -# Set temporary file creation directory. -# set_tmp_dir ${LDAPDBDIR}/tmp diff --git a/source4/setup/mmr_serverids.conf b/source4/setup/mmr_serverids.conf index c6d14010b4..e4daf2028a 100644 --- a/source4/setup/mmr_serverids.conf +++ b/source4/setup/mmr_serverids.conf @@ -1,2 +1 @@ -# Generated from template mmr_serverids.conf ServerID ${SERVERID} "${LDAPSERVER}" diff --git a/source4/setup/olcOverlay={0}syncprov.ldif b/source4/setup/olcOverlay={0}syncprov.ldif new file mode 100644 index 0000000000..4f5b513c67 --- /dev/null +++ b/source4/setup/olcOverlay={0}syncprov.ldif @@ -0,0 +1,11 @@ +dn: olcOverlay={0}syncprov +objectClass: olcOverlayConfig +objectClass: olcSyncProvConfig +olcOverlay: {0}syncprov +structuralObjectClass: olcSyncProvConfig +entryUUID: 41df5aca-785a-102d-9077-999999999999 +creatorsName: cn=config +createTimestamp: 20090116201111Z +entryCSN: 20090116201111.111111Z#000000#000#000000 +modifiersName: cn=config +modifyTimestamp: 20090116201111Z diff --git a/source4/setup/olc_acl.conf b/source4/setup/olc_acl.conf new file mode 100644 index 0000000000..c248b30fb5 --- /dev/null +++ b/source4/setup/olc_acl.conf @@ -0,0 +1,4 @@ +access to dn.sub="cn=config" + by dn="cn=samba-admin,cn=samba" write + by dn="cn=replicator,cn=samba" read + diff --git a/source4/setup/olc_mmr.conf b/source4/setup/olc_mmr.conf new file mode 100644 index 0000000000..2f60df1421 --- /dev/null +++ b/source4/setup/olc_mmr.conf @@ -0,0 +1,3 @@ +overlay syncprov +MirrorMode on + diff --git a/source4/setup/olc_pass.conf b/source4/setup/olc_pass.conf new file mode 100644 index 0000000000..4c66c1c43f --- /dev/null +++ b/source4/setup/olc_pass.conf @@ -0,0 +1,3 @@ +database config +rootdn cn=config + diff --git a/source4/setup/olc_seed.ldif b/source4/setup/olc_seed.ldif new file mode 100644 index 0000000000..afc3abe5a0 --- /dev/null +++ b/source4/setup/olc_seed.ldif @@ -0,0 +1,16 @@ +dn: cn=config +objectClass: olcGlobal +cn: config +${OLC_SERVER_ID_CONF} + +dn: olcDatabase={0}config,cn=config +objectClass: olcDatabaseConfig +olcDatabase: {0}config +olcRootDN: cn=config +olcRootPW: ${OLC_PW} +${OLC_SYNCREPL_CONF}olcMirrorMode: TRUE + +dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config +objectClass: olcSyncProvConfig +olcOverlay: syncprov + diff --git a/source4/setup/olc_serverid.conf b/source4/setup/olc_serverid.conf new file mode 100644 index 0000000000..3d28acbfb4 --- /dev/null +++ b/source4/setup/olc_serverid.conf @@ -0,0 +1 @@ +olcServerID: ${SERVERID} "${LDAPSERVER}" diff --git a/source4/setup/olc_syncrepl.conf b/source4/setup/olc_syncrepl.conf new file mode 100644 index 0000000000..fd7a58d03b --- /dev/null +++ b/source4/setup/olc_syncrepl.conf @@ -0,0 +1,13 @@ +# Generated from template olc_syncrepl.conf + +syncrepl rid=${RID} + provider="${LDAPSERVER}" + searchbase="cn=config" + filter="(!(olcDatabase={0}config))" + type=refreshAndPersist + retry="10 +" + bindmethod=sasl + saslmech=DIGEST-MD5 + authcid="replicator" + credentials="${MMR_PASSWORD}" + diff --git a/source4/setup/olc_syncrepl_seed.conf b/source4/setup/olc_syncrepl_seed.conf new file mode 100644 index 0000000000..1833fb9228 --- /dev/null +++ b/source4/setup/olc_syncrepl_seed.conf @@ -0,0 +1,5 @@ +olcSyncRepl: rid=${RID} provider="${LDAPSERVER}" + binddn="cn=config" bindmethod=sasl saslmech=DIGEST-MD5 + authcid="replicator" credentials="linux" + searchbase="cn=config" filter="(!(olcDatabase={0}config))" + type=refreshAndPersist retry="10 +" diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend index eca209cb18..20e4420414 100755 --- a/source4/setup/provision-backend +++ b/source4/setup/provision-backend @@ -65,8 +65,12 @@ parser.add_option("--server-role", type="choice", metavar="ROLE", parser.add_option("--targetdir", type="string", metavar="DIR", help="Set target directory") parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", - help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR") - + help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") +parser.add_option("--ol-olc", type="choice", metavar="OPENLDAP-OLC", + help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'", + choices=["yes", "no"]) +parser.add_option("--ol-slaptest", type="string", metavar="SLAPTEST-PATH", + help="Path to slaptest-binary [e.g.:'/usr/local/sbin']. Only for use with --ol-olc='yes'") opts = parser.parse_args()[0] @@ -103,5 +107,7 @@ provision_backend(setup_dir=setup_dir, message=message, smbconf=smbconf, targetd root=opts.root, serverrole=server_role, ldap_backend_type=opts.ldap_backend_type, ldap_backend_port=opts.ldap_backend_port, - ol_mmr_urls=opts.ol_mmr_urls) + ol_mmr_urls=opts.ol_mmr_urls, + ol_olc=opts.ol_olc, + ol_slaptest=opts.ol_slaptest) diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf index 506dc504b4..09dffbbfa3 100644 --- a/source4/setup/slapd.conf +++ b/source4/setup/slapd.conf @@ -7,7 +7,6 @@ sizelimit unlimited ${MMR_SERVERIDS_CONFIG} - include ${LDAPDIR}/backend-schema.schema pidfile ${LDAPDIR}/slapd.pid @@ -62,6 +61,13 @@ suffix cn=Samba directory ${LDAPDIR}/db/samba rootdn cn=Manager,cn=Samba +######################################## +## olc - configuration ### +${OLC_CONFIG_PASS} +${OLC_SYNCREPL_CONFIG} +${OLC_MMR_CONFIG} +${OLC_CONFIG_ACL} + ######################################## ### cn=schema ### database hdb @@ -78,10 +84,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=schema Subcontext ### @@ -107,10 +113,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=config Subcontext ### ${MMR_SYNCREPL_CONFIG_CONFIG} @@ -139,10 +145,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=user/base-dn context ### ${MMR_SYNCREPL_USER_CONFIG} -- cgit From f21ae452a008370a4846c8955ac1a8fe1a0acb3c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 11:34:57 +0100 Subject: s3-lib: add marshall_sec_desc_buf and unmarshall_sec_desc_buf helpers. Guenther --- source3/include/proto.h | 5 ++++ source3/lib/secdesc.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 14241d5ce3..3ca94b9192 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -695,8 +695,13 @@ SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src); NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, struct security_descriptor *secdesc, uint8 **data, size_t *len); +NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx, + struct sec_desc_buf *secdesc_buf, + uint8_t **data, size_t *len); NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, struct security_descriptor **psecdesc); +NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len, + struct sec_desc_buf **psecdesc_buf); SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid, SEC_ACL *dacl, size_t *sd_size); SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc); diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 232bbca43c..a81c4ae82a 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -290,6 +290,32 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/******************************************************************* + Convert a secdesc_buf into a byte stream +********************************************************************/ + +NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx, + struct sec_desc_buf *secdesc_buf, + uint8_t **data, size_t *len) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + ndr_err = ndr_push_struct_blob( + &blob, mem_ctx, NULL, secdesc_buf, + (ndr_push_flags_fn_t)ndr_push_sec_desc_buf); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n", + ndr_errstr(ndr_err))); + return ndr_map_error2ntstatus(ndr_err);; + } + + *data = blob.data; + *len = blob.length; + return NT_STATUS_OK; +} + /******************************************************************* Parse a byte stream into a secdesc ********************************************************************/ @@ -326,6 +352,43 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, return NT_STATUS_OK; } +/******************************************************************* + Parse a byte stream into a sec_desc_buf +********************************************************************/ + +NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len, + struct sec_desc_buf **psecdesc_buf) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct sec_desc_buf *result; + + if ((data == NULL) || (len == 0)) { + return NT_STATUS_INVALID_PARAMETER; + } + + result = TALLOC_ZERO_P(mem_ctx, struct sec_desc_buf); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + blob = data_blob_const(data, len); + + ndr_err = ndr_pull_struct_blob( + &blob, result, NULL, result, + (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n", + ndr_errstr(ndr_err))); + TALLOC_FREE(result); + return ndr_map_error2ntstatus(ndr_err);; + } + + *psecdesc_buf = result; + return NT_STATUS_OK; +} + /******************************************************************* Creates a SEC_DESC structure with typical defaults. ********************************************************************/ -- cgit From e1749a1f7815dae4f0721a62a0ea5d3a88aaf320 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 12:19:01 +0100 Subject: s3-spoolss: use marshall/unmarshall_sec_desc_buf in nt_printing_setsec/getsec. Guenther --- source3/printing/nt_printing.c | 80 ++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index ad3a95826a..bbe8ebc2bc 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -5408,11 +5408,12 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) { SEC_DESC_BUF *new_secdesc_ctr = NULL; SEC_DESC_BUF *old_secdesc_ctr = NULL; - prs_struct ps; - bool prs_init_done = false; TALLOC_CTX *mem_ctx = NULL; TDB_DATA kbuf; + TDB_DATA dbuf; + DATA_BLOB blob; WERROR status; + NTSTATUS nt_status; mem_ctx = talloc_init("nt_printing_setsec"); if (mem_ctx == NULL) @@ -5474,26 +5475,19 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) /* Store the security descriptor in a tdb */ - if (!prs_init(&ps, - (uint32_t)ndr_size_security_descriptor(new_secdesc_ctr->sd, - NULL, 0) - + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL) ) { - status = WERR_NOMEM; - goto out; - } - - - prs_init_done = true; - - if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr, - &ps, 1)) { - status = WERR_BADFUNC; + nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr, + &blob.data, &blob.length); + if (!NT_STATUS_IS_OK(nt_status)) { + status = ntstatus_to_werror(nt_status); goto out; } kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename ); - if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) { + dbuf.dptr = (unsigned char *)blob.data; + dbuf.dsize = blob.length; + + if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) { status = WERR_OK; } else { DEBUG(1,("Failed to store secdesc for %s\n", sharename)); @@ -5501,12 +5495,10 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) } /* Free malloc'ed memory */ + talloc_free(blob.data); out: - if (prs_init_done) { - prs_mem_free(&ps); - } if (mem_ctx) talloc_destroy(mem_ctx); return status; @@ -5602,47 +5594,45 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx) bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr) { - prs_struct ps; TDB_DATA kbuf; + TDB_DATA dbuf; + DATA_BLOB blob; char *temp; + NTSTATUS status; if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) { sharename = temp + 1; } - ZERO_STRUCT(ps); - /* Fetch security descriptor from tdb */ - kbuf = make_printers_secdesc_tdbkey(ctx, sharename ); - - if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 || - !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) { - - prs_mem_free(&ps); - - DEBUG(4,("using default secdesc for %s\n", sharename)); + kbuf = make_printers_secdesc_tdbkey(ctx, sharename); - if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) { - return False; - } - - /* Save default security descriptor for later */ + dbuf = tdb_fetch(tdb_printers, kbuf); + if (dbuf.dptr) { - if (!prs_init(&ps, (uint32_t)ndr_size_security_descriptor((*secdesc_ctr)->sd, NULL, 0) + - sizeof(SEC_DESC_BUF), ctx, MARSHALL)) - return False; + status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize, + secdesc_ctr); + SAFE_FREE(dbuf.dptr); - if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) { - tdb_prs_store(tdb_printers, kbuf, &ps); + if (NT_STATUS_IS_OK(status)) { + return true; } + } - prs_mem_free(&ps); - - return True; + *secdesc_ctr = construct_default_printer_sdb(ctx); + if (!*secdesc_ctr) { + return false; } - prs_mem_free(&ps); + status = marshall_sec_desc_buf(ctx, *secdesc_ctr, + &blob.data, &blob.length); + if (NT_STATUS_IS_OK(status)) { + dbuf.dptr = (unsigned char *)blob.data; + dbuf.dsize = blob.length; + tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE); + talloc_free(blob.data); + } /* If security descriptor is owned by S-1-1-0 and winbindd is up, this security descriptor has been created when winbindd was -- cgit From 5c5ce2bee68c4f90a0de3f1833d37cf6f71aa867 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 12:37:04 +0100 Subject: spoolss: fix _spoolss_SetPrinter level 3. Guenther --- librpc/idl/spoolss.idl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 510ad3e8b2..3e35399f8d 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -552,7 +552,7 @@ import "misc.idl", "security.idl", "winreg.idl"; } spoolss_SetPrinterInfo2; typedef struct { - security_descriptor *secdesc; + uint32 sec_desc_ptr; } spoolss_SetPrinterInfo3; typedef struct { -- cgit From 89c682c4185acbf5de16cb4132e33ea825527f41 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 12:38:53 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 31 +++++-------------------------- librpc/gen_ndr/spoolss.h | 2 +- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 642ac0b71b..fdafa2582b 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -3867,36 +3867,20 @@ static enum ndr_err_code ndr_push_spoolss_SetPrinterInfo3(struct ndr_push *ndr, { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_unique_ptr(ndr, r->secdesc)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sec_desc_ptr)); } if (ndr_flags & NDR_BUFFERS) { - if (r->secdesc) { - NDR_CHECK(ndr_push_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); - } } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_spoolss_SetPrinterInfo3(struct ndr_pull *ndr, int ndr_flags, struct spoolss_SetPrinterInfo3 *r) { - uint32_t _ptr_secdesc; - TALLOC_CTX *_mem_save_secdesc_0; if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_secdesc)); - if (_ptr_secdesc) { - NDR_PULL_ALLOC(ndr, r->secdesc); - } else { - r->secdesc = NULL; - } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sec_desc_ptr)); } if (ndr_flags & NDR_BUFFERS) { - if (r->secdesc) { - _mem_save_secdesc_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->secdesc, 0); - NDR_CHECK(ndr_pull_security_descriptor(ndr, NDR_SCALARS|NDR_BUFFERS, r->secdesc)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_secdesc_0, 0); - } } return NDR_ERR_SUCCESS; } @@ -3905,12 +3889,7 @@ _PUBLIC_ void ndr_print_spoolss_SetPrinterInfo3(struct ndr_print *ndr, const cha { ndr_print_struct(ndr, name, "spoolss_SetPrinterInfo3"); ndr->depth++; - ndr_print_ptr(ndr, "secdesc", r->secdesc); - ndr->depth++; - if (r->secdesc) { - ndr_print_security_descriptor(ndr, "secdesc", r->secdesc); - } - ndr->depth--; + ndr_print_uint32(ndr, "sec_desc_ptr", r->sec_desc_ptr); ndr->depth--; } @@ -4279,7 +4258,7 @@ static enum ndr_err_code ndr_push_spoolss_SetPrinterInfo(struct ndr_push *ndr, i case 3: if (r->info3) { - NDR_CHECK(ndr_push_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS|NDR_BUFFERS, r->info3)); + NDR_CHECK(ndr_push_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS, r->info3)); } break; @@ -4486,7 +4465,7 @@ static enum ndr_err_code ndr_pull_spoolss_SetPrinterInfo(struct ndr_pull *ndr, i if (r->info3) { _mem_save_info3_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->info3, 0); - NDR_CHECK(ndr_pull_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS|NDR_BUFFERS, r->info3)); + NDR_CHECK(ndr_pull_spoolss_SetPrinterInfo3(ndr, NDR_SCALARS, r->info3)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info3_0, 0); } break; diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 0b77997ee4..ad4554dbe5 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -501,7 +501,7 @@ struct spoolss_SetPrinterInfo2 { }; struct spoolss_SetPrinterInfo3 { - struct security_descriptor *secdesc;/* [unique] */ + uint32_t sec_desc_ptr; }; struct spoolss_SetPrinterInfo4 { -- cgit From 6e16c5eed59bb3539af365d30e9ec35012b8c8ac Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 16:57:30 +0100 Subject: s3:mount.cifs: don't error exit on explicitly requested help... Michael --- source3/client/mount.cifs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index a736609580..641584947f 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -179,7 +179,6 @@ static void mount_cifs_usage(void) printf("\n\t%s -V\n",thisprogram); SAFE_FREE(mountpassword); - exit(EX_USAGE); } /* caller frees username if necessary */ @@ -1102,7 +1101,7 @@ int main(int argc, char ** argv) case '?': case 'h': /* help */ mount_cifs_usage (); - exit(EX_USAGE); + exit(0); case 'n': ++nomtab; break; -- cgit From d7ca4997017e86b6f23ced64f1f1672bfb15716b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 24 Feb 2009 16:58:33 +0100 Subject: s3:mount.cifs: make "mount.cifs -V" print the version, not usage. Also make "mount.cifs -h" not exit with error exit code but with return code 0. Michael --- source3/client/mount.cifs.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 641584947f..ae8a7fd186 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -1016,6 +1016,14 @@ uppercase_string(char *string) return 1; } +static void print_cifs_mount_version(void) +{ + printf("mount.cifs version: %s.%s%s\n", + MOUNT_CIFS_VERSION_MAJOR, + MOUNT_CIFS_VERSION_MINOR, + MOUNT_CIFS_VENDOR_SUFFIX); +} + int main(int argc, char ** argv) { int c; @@ -1077,6 +1085,24 @@ int main(int argc, char ** argv) exit(EX_SYSERR); } mountpoint = argv[2]; + } else if (argc == 2) { + if ((strcmp(argv[1], "-V") == 0) || + (strcmp(argv[1], "--version") == 0)) + { + print_cifs_mount_version(); + exit(0); + } + + if ((strcmp(argv[1], "-h") == 0) || + (strcmp(argv[1], "-?") == 0) || + (strcmp(argv[1], "--help") == 0)) + { + mount_cifs_usage(); + exit(0); + } + + mount_cifs_usage(); + exit(EX_USAGE); } else { mount_cifs_usage(); exit(EX_USAGE); @@ -1133,11 +1159,8 @@ int main(int argc, char ** argv) case 'v': ++verboseflag; break; - case 'V': - printf ("mount.cifs version: %s.%s%s\n", - MOUNT_CIFS_VERSION_MAJOR, - MOUNT_CIFS_VERSION_MINOR, - MOUNT_CIFS_VENDOR_SUFFIX); + case 'V': + print_cifs_mount_version(); exit (0); case 'w': flags &= ~MS_RDONLY; -- cgit From dc03a328d8ff55df30a5b996b4a17e82db29708b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 15:28:54 +0100 Subject: s3:example/VFS: fix the build metze --- examples/VFS/skel_opaque.c | 6 ++++-- examples/VFS/skel_transparent.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 5845f62e34..118a5b9da7 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -85,9 +85,11 @@ static SMB_STRUCT_DIR *skel_opendir(vfs_handle_struct *handle, const char *fnam return vfswrap_opendir(NULL, fname, mask, attr); } -static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { - return vfswrap_readdir(NULL, dirp); + return vfswrap_readdir(NULL, dirp, sbuf); } static void skel_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 7036c730dd..a95b5ae6cd 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -79,9 +79,11 @@ static SMB_STRUCT_DIR *skel_opendir(vfs_handle_struct *handle, const char *fnam return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr); } -static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp, + SMB_STRUCT_STAT *sbuf) { - return SMB_VFS_NEXT_READDIR(handle, dirp); + return SMB_VFS_NEXT_READDIR(handle, dirp, sbuf); } static void skel_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset) -- cgit From d1922725c66c9f4de25c1d664ae03c90e6c098fb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:06:27 +0100 Subject: s3: remove unused smb_ldap.h metze --- source3/include/includes.h | 2 - source3/include/smb_ldap.h | 255 --------------------------------------------- 2 files changed, 257 deletions(-) delete mode 100644 source3/include/smb_ldap.h diff --git a/source3/include/includes.h b/source3/include/includes.h index 5ab5564e47..80d7bfc6cf 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -677,8 +677,6 @@ struct printjob; #include "smbldap.h" -#include "smb_ldap.h" - /* * Reasons for cache flush. */ diff --git a/source3/include/smb_ldap.h b/source3/include/smb_ldap.h deleted file mode 100644 index a3c270d95c..0000000000 --- a/source3/include/smb_ldap.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 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 . - -*/ - -#ifndef _SMB_LDAP_H -#define _SMB_LDAP_H - -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -#ifndef LDAP_SUCCESS -enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_SASL_BIND_IN_PROGRESS = 0x0e, - LDAP_INVALID_CREDENTIALS = 0x31, - LDAP_OTHER = 0x50 -}; -#endif /* LDAP_SUCCESS */ - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_attribute { - const char *name; - int num_values; - DATA_BLOB *values; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB secblob; - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB secblob; - } SASL; -}; - -struct ldap_UnbindRequest { - uint8 __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32 timelimit; - uint32 sizelimit; - bool attributesonly; - char *filter; - int num_attributes; - const char **attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldap_attribute *attributes; -}; - -struct ldap_SearchResRef { - int num_referrals; - const char **referrals; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldap_attribute attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldap_attribute *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior; -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - const char *value; -}; - -struct ldap_AbandonRequest { - uint32 messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB value; -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *name; - DATA_BLOB value; -}; - -union ldap_Request { - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - -struct ldap_Control { - const char *oid; - bool critical; - DATA_BLOB value; -}; - -struct ldap_message { - TALLOC_CTX *mem_ctx; - uint32 messageid; - uint8 type; - union ldap_Request r; - int num_controls; - struct ldap_Control *controls; -}; - -struct ldap_queue_entry { - struct ldap_queue_entry *next, *prev; - int msgid; - struct ldap_message *msg; -}; - -struct ldap_connection { - TALLOC_CTX *mem_ctx; - int sock; - int next_msgid; - char *host; - uint16 port; - bool ldaps; - - const char *auth_dn; - const char *simple_pw; - - /* Current outstanding search entry */ - int searchid; - - /* List for incoming search entries */ - struct ldap_queue_entry *search_entries; - - /* Outstanding LDAP requests that have not yet been replied to */ - struct ldap_queue_entry *outstanding; -}; - -#endif -- cgit From 12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 11:40:18 +0100 Subject: s4:libcli: split out LIBCLI_LDAP_MESSAGE subsystem metze --- source4/headermap.txt | 1 + source4/libcli/ldap/config.mk | 21 +- source4/libcli/ldap/ldap.c | 1411 ---------------------------------- source4/libcli/ldap/ldap.h | 191 +---- source4/libcli/ldap/ldap_message.c | 1468 ++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_message.h | 225 ++++++ source4/libcli/ldap/ldap_msg.c | 87 --- 7 files changed, 1709 insertions(+), 1695 deletions(-) delete mode 100644 source4/libcli/ldap/ldap.c create mode 100644 source4/libcli/ldap/ldap_message.c create mode 100644 source4/libcli/ldap/ldap_message.h delete mode 100644 source4/libcli/ldap/ldap_msg.c diff --git a/source4/headermap.txt b/source4/headermap.txt index 8f3749a3b5..8a968315bf 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -49,6 +49,7 @@ param/share.h: share.h ../lib/util/util_tdb.h: util_tdb.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h +libcli/ldap/ldap_message.h: ldap_message.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 2708c66b68..a0e178ac40 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,14 +1,20 @@ +[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB +PRIVATE_DEPENDENCIES = ASN1_UTIL + +LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ + ldap_message.o) +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h + [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR LP_RESOLVE gensec +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ + LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ - ldap.o ldap_client.o ldap_bind.o \ - ldap_msg.o ldap_ildap.o ldap_controls.o) - - -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h + ldap_client.o ldap_bind.o \ + ldap_ildap.o ldap_controls.o) +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) @@ -16,3 +22,4 @@ $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_L PRIVATE_DEPENDENCIES = LIBLDB LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c deleted file mode 100644 index 7a65cc5c27..0000000000 --- a/source4/libcli/ldap/ldap.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 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 . - -*/ - -#include "includes.h" -#include "../lib/util/asn1.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_proto.h" - - -static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) -{ - int i; - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return false; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return false; - } - asn1_pop_tag(data); - break; - - case LDB_OP_EQUALITY: - /* equality test */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.equality.attr, - strlen(tree->u.equality.attr)); - asn1_write_OctetString(data, tree->u.equality.value.data, - tree->u.equality.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_SUBSTRING: - /* - SubstringFilter ::= SEQUENCE { - type AttributeDescription, - -- at least one must be present - substrings SEQUENCE OF CHOICE { - initial [0] LDAPString, - any [1] LDAPString, - final [2] LDAPString } } - */ - asn1_push_tag(data, ASN1_CONTEXT(4)); - asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - i = 0; - if ( ! tree->u.substring.start_with_wildcard) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - while (tree->u.substring.chunks[i]) { - int ctx; - - if (( ! tree->u.substring.chunks[i + 1]) && - (tree->u.substring.end_with_wildcard == 0)) { - ctx = 2; - } else { - ctx = 1; - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - case LDB_OP_GREATER: - /* greaterOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(5)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_LESS: - /* lessOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(6)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_PRESENT: - /* present test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write_LDAPString(data, tree->u.present.attr); - asn1_pop_tag(data); - return !data->has_error; - - case LDB_OP_APPROX: - /* approx test */ - asn1_push_tag(data, ASN1_CONTEXT(8)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_EXTENDED: - /* - MatchingRuleAssertion ::= SEQUENCE { - matchingRule [1] MatchingRuleID OPTIONAL, - type [2] AttributeDescription OPTIONAL, - matchValue [3] AssertionValue, - dnAttributes [4] BOOLEAN DEFAULT FALSE - } - */ - asn1_push_tag(data, ASN1_CONTEXT(9)); - if (tree->u.extended.rule_id) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write_LDAPString(data, tree->u.extended.rule_id); - asn1_pop_tag(data); - } - if (tree->u.extended.attr) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_write_LDAPString(data, tree->u.extended.attr); - asn1_pop_tag(data); - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); - asn1_pop_tag(data); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_write_uint8(data, tree->u.extended.dnAttributes); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - default: - return false; - } - return !data->has_error; -} - -static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) -{ - asn1_write_enumerated(data, result->resultcode); - asn1_write_OctetString(data, result->dn, - (result->dn) ? strlen(result->dn) : 0); - asn1_write_OctetString(data, result->errormessage, - (result->errormessage) ? - strlen(result->errormessage) : 0); - if (result->referral) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, result->referral, - strlen(result->referral)); - asn1_pop_tag(data); - } -} - -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) -{ - struct asn1_data *data = asn1_init(mem_ctx); - int i, j; - - if (!data) return false; - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_Integer(data, msg->messageid); - - switch (msg->type) { - case LDAP_TAG_BindRequest: { - struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(data, r->version); - asn1_write_OctetString(data, r->dn, - (r->dn != NULL) ? strlen(r->dn) : 0); - - switch (r->mechanism) { - case LDAP_AUTH_MECH_SIMPLE: - /* context, primitive */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->creds.password, - strlen(r->creds.password)); - asn1_pop_tag(data); - break; - case LDAP_AUTH_MECH_SASL: - /* context, constructed */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, r->creds.SASL.mechanism, - strlen(r->creds.SASL.mechanism)); - if (r->creds.SASL.secblob) { - asn1_write_OctetString(data, r->creds.SASL.secblob->data, - r->creds.SASL.secblob->length); - } - asn1_pop_tag(data); - break; - default: - return false; - } - - asn1_pop_tag(data); - break; - } - case LDAP_TAG_BindResponse: { - struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->SASL.secblob) { - asn1_write_ContextSimple(data, 7, r->SASL.secblob); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_UnbindRequest: { -/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ - break; - } - case LDAP_TAG_SearchRequest: { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(data, r->scope); - asn1_write_enumerated(data, r->deref); - asn1_write_Integer(data, r->sizelimit); - asn1_write_Integer(data, r->timelimit); - asn1_write_BOOLEAN(data, r->attributesonly); - - if (!ldap_push_filter(data, r->tree)) { - return false; - } - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - asn1_write_OctetString(data, r->attributes[i], - strlen(r->attributes[i])); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultEntry: { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attr->name, - strlen(attr->name)); - asn1_push_tag(data, ASN1_SEQUENCE(1)); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attr->values[j].data, - attr->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultDone: { - struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyRequest: { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_mods; i++) { - struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(data, r->mods[i].type); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - - } - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyResponse: { - struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddRequest: { - struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddResponse: { - struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(data, r->dn, strlen(r->dn)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNRequest: { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(data, r->deleteolddn); - if (r->newsuperior) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->newsuperior, - strlen(r->newsuperior)); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareRequest: { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, r->attribute, - strlen(r->attribute)); - asn1_write_OctetString(data, r->value.data, - r->value.length); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AbandonRequest: { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(data, r->messageid); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultReference: { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->referral, strlen(r->referral)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedRequest: { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedResponse: { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->oid) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - } - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - default: - return false; - } - - if (msg->controls != NULL) { - asn1_push_tag(data, ASN1_CONTEXT(0)); - - for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return false; - } - } - - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - - if (data->has_error) { - asn1_free(data); - return false; - } - - *result = data_blob_talloc(mem_ctx, data->data, data->length); - asn1_free(data); - return true; -} - -static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, - DATA_BLOB blob) -{ - char *result = talloc_array(mem_ctx, char, blob.length+1); - memcpy(result, blob.data, blob.length); - result[blob.length] = '\0'; - return result; -} - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) -{ - DATA_BLOB string; - if (!asn1_read_OctetString(data, mem_ctx, &string)) - return false; - *result = blob2string_talloc(mem_ctx, string); - data_blob_free(&string); - return true; -} - -static void ldap_decode_response(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - struct ldap_Result *result) -{ - asn1_read_enumerated(data, &result->resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); - asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - asn1_end_tag(data); - } else { - result->referral = NULL; - } -} - -static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) -{ - - chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); - if (chunks == NULL) { - return NULL; - } - - chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); - if (chunks[chunk_num] == NULL) { - return NULL; - } - - chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); - if (chunks[chunk_num]->data == NULL) { - return NULL; - } - chunks[chunk_num]->length = strlen(value); - - chunks[chunk_num + 1] = '\0'; - - return chunks; -} - - -/* - parse the ASN.1 formatted search string into a ldb_parse_tree -*/ -static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, - struct asn1_data *data) -{ - uint8_t filter_tag; - struct ldb_parse_tree *ret; - - if (!asn1_peek_uint8(data, &filter_tag)) { - return NULL; - } - - filter_tag &= 0x1f; /* strip off the asn1 stuff */ - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (ret == NULL) return NULL; - - switch(filter_tag) { - case 0: - case 1: - /* AND or OR of one or more filters */ - ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; - ret->u.list.num_elements = 0; - ret->u.list.elements = NULL; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - while (asn1_tag_remaining(data) > 0) { - struct ldb_parse_tree *subtree; - subtree = ldap_decode_filter_tree(ret, data); - if (subtree == NULL) { - goto failed; - } - ret->u.list.elements = - talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); - if (ret->u.list.elements == NULL) { - goto failed; - } - talloc_steal(ret->u.list.elements, subtree); - ret->u.list.elements[ret->u.list.num_elements] = subtree; - ret->u.list.num_elements++; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 2: - /* 'not' operation */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldap_decode_filter_tree(ret, data); - if (ret->u.isnot.child == NULL) { - goto failed; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attrib); - ret->u.equality.value.data = talloc_steal(ret, value.data); - ret->u.equality.value.length = value.length; - break; - } - case 4: { - /* substrings */ - DATA_BLOB attr; - uint8_t subs_tag; - char *value; - int chunk_num = 0; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); - ret->u.substring.chunks = NULL; - ret->u.substring.start_with_wildcard = 1; - ret->u.substring.end_with_wildcard = 1; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - goto failed; - } - - while (asn1_tag_remaining(data)) { - asn1_peek_uint8(data, &subs_tag); - subs_tag &= 0x1f; /* strip off the asn1 stuff */ - if (subs_tag > 2) goto failed; - - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, mem_ctx, &value); - asn1_end_tag(data); - - switch (subs_tag) { - case 0: - if (ret->u.substring.chunks != NULL) { - /* initial value found in the middle */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.start_with_wildcard = 0; - chunk_num = 1; - break; - - case 1: - if (ret->u.substring.end_with_wildcard == 0) { - /* "any" value found after a "final" value */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - chunk_num++; - break; - - case 2: - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.end_with_wildcard = 0; - break; - - default: - goto failed; - } - - } - - if (!asn1_end_tag(data)) { /* SEQUENCE */ - goto failed; - } - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 5: { - /* greaterOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 6: { - /* lessOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 7: { - /* Normal presence, "attribute=*" */ - char *attr; - - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { - goto failed; - } - if (!asn1_read_LDAPString(data, ret, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = talloc_steal(ret, attr); - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 8: { - /* approx */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 9: { - char *oid = NULL, *attr = NULL, *value; - uint8_t dnAttributes; - /* an extended search */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's - we need to check we properly implement --SSS */ - /* either oid or type must be defined */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, ret, &oid); - asn1_end_tag(data); - } - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, ret, &attr); - asn1_end_tag(data); - } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, ret, &value); - asn1_end_tag(data); - /* dnAttributes is marked as BOOLEAN DEFAULT FALSE - it is not marked as OPTIONAL but openldap tools - do not set this unless it is to be set as TRUE - NOTE: openldap tools do not work with AD as it - seems that AD always requires the dnAttributes - boolean value to be set */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - } else { - dnAttributes = 0; - } - if ((oid == NULL && attr == NULL) || (value == NULL)) { - goto failed; - } - - if (oid) { - ret->operation = LDB_OP_EXTENDED; - - /* From the RFC2251: If the type field is - absent and matchingRule is present, the matchValue is compared - against all attributes in an entry which support that matchingRule - */ - if (attr) { - ret->u.extended.attr = talloc_steal(ret, attr); - } else { - ret->u.extended.attr = talloc_strdup(ret, "*"); - } - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; - } else { - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); - ret->u.equality.value.length = strlen(value); - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - - default: - DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -/* Decode a single LDAP attribute, possibly containing multiple values */ -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element *attrib) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); - asn1_start_tag(data, ASN1_SET); - while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - DATA_BLOB blob; - asn1_read_OctetString(data, mem_ctx, &blob); - add_value_to_attrib(mem_ctx, &blob, attrib); - } - asn1_end_tag(data); - asn1_end_tag(data); - -} - -/* Decode a set of LDAP attributes, as found in the dereference control */ -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldb_message_element attrib; - ZERO_STRUCT(attrib); - ldap_decode_attrib(mem_ctx, data, &attrib); - add_attrib_to_array_talloc(mem_ctx, &attrib, - attributes, num_attributes); - } -} - -/* Decode a set of LDAP attributes, as found in a search entry */ -void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - ldap_decode_attribs_bare(mem_ctx, data, - attributes, num_attributes); - asn1_end_tag(data); -} - -/* This routine returns LDAP status codes */ - -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) -{ - uint8_t tag; - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &msg->messageid); - - if (!asn1_peek_uint8(data, &tag)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - - switch(tag) { - - case ASN1_APPLICATION(LDAP_TAG_BindRequest): { - struct ldap_BindRequest *r = &msg->r.BindRequest; - msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, tag); - asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg, data, &r->dn); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { - int pwlen; - r->creds.password = ""; - r->mechanism = LDAP_AUTH_MECH_SIMPLE; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - pwlen = asn1_tag_remaining(data); - if (pwlen == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - if (pwlen != 0) { - char *pw = talloc_array(msg, char, pwlen+1); - if (!pw) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, pw, pwlen); - pw[pwlen] = '\0'; - r->creds.password = pw; - } - asn1_end_tag(data); - } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ - asn1_start_tag(data, ASN1_CONTEXT(3)); - r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, msg, &tmp_blob); - r->creds.SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->creds.SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->creds.SASL.secblob = NULL; - } - asn1_end_tag(data); - } else { - /* Neither Simple nor SASL bind */ - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_BindResponse): { - struct ldap_BindResponse *r = &msg->r.BindResponse; - msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->SASL.secblob = NULL; - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { - msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, tag); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->basedn); - asn1_read_enumerated(data, (int *)&(r->scope)); - asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN(data, &r->attributesonly); - - r->tree = ldap_decode_filter_tree(msg, data); - if (r->tree == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_attributes = 0; - r->attributes = NULL; - - while (asn1_tag_remaining(data) > 0) { - - const char *attr; - if (!asn1_read_OctetString_talloc(msg, data, - &attr)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - if (!add_string_to_array(msg, attr, - &r->attributes, - &r->num_attributes)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - msg->type = LDAP_TAG_SearchResultEntry; - r->attributes = NULL; - r->num_attributes = 0; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_Result *r = &msg->r.SearchResultDone; - msg->type = LDAP_TAG_SearchResultDone; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - msg->type = LDAP_TAG_SearchResultReference; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->referral); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - msg->type = LDAP_TAG_ModifyRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_mods = 0; - r->mods = NULL; - - while (asn1_tag_remaining(data) > 0) { - struct ldap_mod mod; - int v; - ZERO_STRUCT(mod); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &v); - mod.type = v; - ldap_decode_attrib(msg, data, &mod.attrib); - asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_Result *r = &msg->r.ModifyResponse; - msg->type = LDAP_TAG_ModifyResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddRequest): { - struct ldap_AddRequest *r = &msg->r.AddRequest; - msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - - r->attributes = NULL; - r->num_attributes = 0; - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_Result *r = &msg->r.AddResponse; - msg->type = LDAP_TAG_AddResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; - int len; - char *dn; - msg->type = LDAP_TAG_DelRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - dn = talloc_array(msg, char, len+1); - if (dn == NULL) - break; - asn1_read(data, dn, len); - dn[len] = '\0'; - r->dn = dn; - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - msg->type = LDAP_TAG_ModifyDNRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_read_OctetString_talloc(msg, data, &r->newrdn); - asn1_read_BOOLEAN(data, &r->deleteolddn); - r->newsuperior = NULL; - if (asn1_tag_remaining(data) > 0) { - int len; - char *newsup; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - newsup = talloc_array(msg, char, len+1); - if (newsup == NULL) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, newsup, len); - newsup[len] = '\0'; - r->newsuperior = newsup; - asn1_end_tag(data); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - msg->type = LDAP_TAG_ModifyDNResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - msg->type = LDAP_TAG_CompareRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, msg, &r->value); - if (r->value.data) { - talloc_steal(msg, r->value.data); - } - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_Result *r = &msg->r.CompareResponse; - msg->type = LDAP_TAG_CompareResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, tag); - asn1_read_implicit_Integer(data, &r->messageid); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,tag); - if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } else { - r->oid = NULL; - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - default: - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - msg->controls = NULL; - msg->controls_decoded = NULL; - - if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i = 0; - struct ldb_control **ctrl = NULL; - bool *decoded = NULL; - - asn1_start_tag(data, ASN1_CONTEXT(0)); - - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - DATA_BLOB value; - /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - - ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); - if (!ctrl) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - decoded = talloc_realloc(msg, decoded, bool, i+1); - if (!decoded) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - if (!ctrl[i]) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { - if (ctrl[i]->critical) { - ctrl[i]->data = NULL; - decoded[i] = false; - i++; - } else { - talloc_free(ctrl[i]); - ctrl[i] = NULL; - } - } else { - decoded[i] = true; - i++; - } - } - - if (ctrl != NULL) { - ctrl[i] = NULL; - } - - msg->controls = ctrl; - msg->controls_decoded = decoded; - - asn1_end_tag(data); - } - - asn1_end_tag(data); - if ((data->has_error) || (data->nesting != NULL)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - return NT_STATUS_OK; -} - - -/* - return NT_STATUS_OK if a blob has enough bytes in it to be a full - ldap packet. Set packet_size if true. -*/ -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) -{ - return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); -} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 3d99d6f47d..a642e671e6 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -21,200 +21,11 @@ #ifndef _SMB_LDAP_H_ #define _SMB_LDAP_H_ -#include "libcli/ldap/ldap_errors.h" -#include "lib/ldb/include/ldb.h" +#include "libcli/ldap/ldap_message.h" #include "librpc/gen_ndr/misc.h" -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB *secblob;/* optional */ - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB *secblob;/* optional */ - } SASL; -}; - -struct ldap_UnbindRequest { - uint8_t __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32_t timelimit; - uint32_t sizelimit; - bool attributesonly; - struct ldb_parse_tree *tree; - int num_attributes; - const char * const *attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_SearchResRef { - const char *referral; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldb_message_element attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior;/* optional */ -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - DATA_BLOB value; -}; - -struct ldap_AbandonRequest { - uint32_t messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB *value;/* optional */ -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *oid;/* optional */ - DATA_BLOB *value;/* optional */ -}; - -union ldap_Request { - struct ldap_Result GeneralResult; - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - - -struct ldap_message { - int messageid; - enum ldap_request_tag type; - union ldap_Request r; - struct ldb_control **controls; - bool *controls_decoded; -}; - struct tevent_context; struct cli_credentials; struct dom_sid; -struct asn1_data; - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); #endif diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c new file mode 100644 index 0000000000..07362fa685 --- /dev/null +++ b/source4/libcli/ldap/ldap_message.c @@ -0,0 +1,1468 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 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 . + +*/ + +#include "includes.h" +#include "../lib/util/asn1.h" +#include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" + +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldap_message); +} + + +static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return false; + + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; + attrib->num_values += 1; + return true; +} + +static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return false; + + (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); + *num_attribs += 1; + return true; +} + +static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return false; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return true; +} + +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +{ + int i; + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return false; + } + } + asn1_pop_tag(data); + break; + + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return false; + } + asn1_pop_tag(data); + break; + + case LDB_OP_EQUALITY: + /* equality test */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, ASN1_CONTEXT(9)); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); + asn1_pop_tag(data); + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + default: + return false; + } + return !data->has_error; +} + +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) +{ + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); + } +} + +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +{ + struct asn1_data *data = asn1_init(mem_ctx); + int i, j; + + if (!data) return false; + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); + } + asn1_pop_tag(data); + break; + default: + return false; + } + + asn1_pop_tag(data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->SASL.secblob) { + asn1_write_ContextSimple(data, 7, r->SASL.secblob); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { + return false; + } + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attr = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, + strlen(attr->name)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_Result *r = &msg->r.SearchResultDone; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldb_message_element *attrib = &r->mods[i].attrib; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attrib = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); + if (r->newsuperior) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(data, r->value.data, + r->value.length); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultReference: { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->oid) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + } + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + default: + return false; + } + + if (msg->controls != NULL) { + asn1_push_tag(data, ASN1_CONTEXT(0)); + + for (i = 0; msg->controls[i] != NULL; i++) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + return false; + } + } + + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + + if (data->has_error) { + asn1_free(data); + return false; + } + + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); + return true; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc_array(mem_ctx, char, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, mem_ctx, &string)) + return false; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return true; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + struct ldap_Result *result) +{ + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + asn1_end_tag(data); + } else { + result->referral = NULL; + } +} + +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value); + + chunks[chunk_num + 1] = '\0'; + + return chunks; +} + + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) +{ + uint8_t filter_tag; + struct ldb_parse_tree *ret; + + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } + + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; + + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + while (asn1_tag_remaining(data) > 0) { + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { + goto failed; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; + break; + } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, mem_ctx, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { + goto failed; + } + if (!asn1_read_LDAPString(data, ret, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 9: { + char *oid = NULL, *attr = NULL, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, ret, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, ret, &attr); + asn1_end_tag(data); + } + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, ret, &value); + asn1_end_tag(data); + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { + goto failed; + } + + if (oid) { + ret->operation = LDB_OP_EXTENDED; + + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + + default: + DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +/* Decode a single LDAP attribute, possibly containing multiple values */ +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + asn1_read_OctetString(data, mem_ctx, &blob); + add_value_to_attrib(mem_ctx, &blob, attrib); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +/* Decode a set of LDAP attributes, as found in the dereference control */ +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldb_message_element attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } +} + +/* Decode a set of LDAP attributes, as found in a search entry */ +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + ldap_decode_attribs_bare(mem_ctx, data, + attributes, num_attributes); + asn1_end_tag(data); +} + +/* This routine returns LDAP status codes */ + +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +{ + uint8_t tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, tag); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg, data, &r->dn); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { + int pwlen; + r->creds.password = ""; + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + if (pwlen != 0) { + char *pw = talloc_array(msg, char, pwlen+1); + if (!pw) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, msg, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->creds.SASL.secblob = NULL; + } + asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = NULL; + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, tag); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN(data, &r->attributesonly); + + r->tree = ldap_decode_filter_tree(msg, data); + if (r->tree == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + + const char *attr; + if (!asn1_read_OctetString_talloc(msg, data, + &attr)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + if (!add_string_to_array(msg, attr, + &r->attributes, + &r->num_attributes)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_Result *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->referral); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + int v; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &v); + mod.type = v; + ldap_decode_attrib(msg, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg, &mod, + &r->mods, &r->num_mods)) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_Result *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_Result *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + dn = talloc_array(msg, char, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); + asn1_read_BOOLEAN(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + newsup = talloc_array(msg, char, len+1); + if (newsup == NULL) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg, data, &r->attribute); + asn1_read_OctetString(data, msg, &r->value); + if (r->value.data) { + talloc_steal(msg, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_Result *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, tag); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,tag); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + default: + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + msg->controls = NULL; + msg->controls_decoded = NULL; + + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + int i = 0; + struct ldb_control **ctrl = NULL; + bool *decoded = NULL; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ + + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); + if (!ctrl) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + ctrl[i] = talloc(ctrl, struct ldb_control); + if (!ctrl[i]) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + ctrl[i]->data = NULL; + decoded[i] = false; + i++; + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + decoded[i] = true; + i++; + } + } + + if (ctrl != NULL) { + ctrl[i] = NULL; + } + + msg->controls = ctrl; + msg->controls_decoded = decoded; + + asn1_end_tag(data); + } + + asn1_end_tag(data); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; +} + + +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h new file mode 100644 index 0000000000..47ee724e97 --- /dev/null +++ b/source4/libcli/ldap/ldap_message.h @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 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 . + +*/ + +#ifndef _LIBCLI_LDAP_MESSAGE_H_ +#define _LIBCLI_LDAP_MESSAGE_H_ + +#include "libcli/ldap/ldap_errors.h" +#include "lib/ldb/include/ldb.h" + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB *secblob;/* optional */ + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB *secblob;/* optional */ + } SASL; +}; + +struct ldap_UnbindRequest { + uint8_t __dummy; +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32_t timelimit; + uint32_t sizelimit; + bool attributesonly; + struct ldb_parse_tree *tree; + int num_attributes; + const char * const *attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_SearchResRef { + const char *referral; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldb_message_element attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + bool deleteolddn; + const char *newsuperior;/* optional */ +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + DATA_BLOB value; +}; + +struct ldap_AbandonRequest { + uint32_t messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB *value;/* optional */ +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ +}; + +union ldap_Request { + struct ldap_Result GeneralResult; + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + + +struct ldap_message { + int messageid; + enum ldap_request_tag type; + union ldap_Request r; + struct ldb_control **controls; + bool *controls_decoded; +}; + +struct asn1_data; + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result); + +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes); + +#endif diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c deleted file mode 100644 index e45213c004..0000000000 --- a/source4/libcli/ldap/ldap_msg.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Volker Lendecke 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 . - -*/ - -#include "includes.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_client.h" -#include "libcli/ldap/ldap_proto.h" - - -_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldap_message); -} - - -bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return false; - - attrib->values[attrib->num_values].data = talloc_steal(attrib->values, - value->data); - attrib->values[attrib->num_values].length = value->length; - attrib->num_values += 1; - return true; -} - -bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return false; - - (*attribs)[*num_attribs] = *attrib; - talloc_steal(*attribs, attrib->values); - talloc_steal(*attribs, attrib->name); - *num_attribs += 1; - return true; -} - -bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return false; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return true; -} - -- cgit From 1ab9c1a40290fbecf8b7090492363eab0443c7c6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:09:11 +0100 Subject: s4:libcli/ldap: remove reference to DEBUG() This prepares using ldap_message.c in source3/ later metze --- source4/libcli/ldap/ldap_message.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c index 07362fa685..d8bbf42634 100644 --- a/source4/libcli/ldap/ldap_message.c +++ b/source4/libcli/ldap/ldap_message.c @@ -940,7 +940,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } default: - DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); goto failed; } -- cgit From 536318549fba35a4d9eb60fbb2d0e91b88c44a7b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:13:41 +0100 Subject: libcli/ldap: move ldap_message.[ch] from source4/ to the toplevel metze --- libcli/ldap/config.mk | 7 + libcli/ldap/ldap_message.c | 1466 +++++++++++++++++++++++++++++++++++ libcli/ldap/ldap_message.h | 225 ++++++ source4/headermap.txt | 2 +- source4/libcli/ldap/config.mk | 8 - source4/libcli/ldap/ldap.h | 2 +- source4/libcli/ldap/ldap_message.c | 1467 ------------------------------------ source4/libcli/ldap/ldap_message.h | 225 ------ source4/main.mk | 2 + 9 files changed, 1702 insertions(+), 1702 deletions(-) create mode 100644 libcli/ldap/config.mk create mode 100644 libcli/ldap/ldap_message.c create mode 100644 libcli/ldap/ldap_message.h delete mode 100644 source4/libcli/ldap/ldap_message.c delete mode 100644 source4/libcli/ldap/ldap_message.h diff --git a/libcli/ldap/config.mk b/libcli/ldap/config.mk new file mode 100644 index 0000000000..067b6778b7 --- /dev/null +++ b/libcli/ldap/config.mk @@ -0,0 +1,7 @@ +[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB +PRIVATE_DEPENDENCIES = ASN1_UTIL + +LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix ../libcli/ldap/, \ + ldap_message.o) +PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c new file mode 100644 index 0000000000..e8ec716e64 --- /dev/null +++ b/libcli/ldap/ldap_message.c @@ -0,0 +1,1466 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 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 . + +*/ + +#include "includes.h" +#include "../lib/util/asn1.h" +#include "../libcli/ldap/ldap_message.h" + +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldap_message); +} + + +static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return false; + + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; + attrib->num_values += 1; + return true; +} + +static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return false; + + (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); + *num_attribs += 1; + return true; +} + +static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return false; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return true; +} + +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +{ + int i; + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return false; + } + } + asn1_pop_tag(data); + break; + + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return false; + } + asn1_pop_tag(data); + break; + + case LDB_OP_EQUALITY: + /* equality test */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, ASN1_CONTEXT(9)); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); + asn1_pop_tag(data); + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + default: + return false; + } + return !data->has_error; +} + +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) +{ + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); + } +} + +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +{ + struct asn1_data *data = asn1_init(mem_ctx); + int i, j; + + if (!data) return false; + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); + } + asn1_pop_tag(data); + break; + default: + return false; + } + + asn1_pop_tag(data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->SASL.secblob) { + asn1_write_ContextSimple(data, 7, r->SASL.secblob); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { + return false; + } + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attr = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, + strlen(attr->name)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_Result *r = &msg->r.SearchResultDone; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldb_message_element *attrib = &r->mods[i].attrib; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attrib = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); + if (r->newsuperior) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(data, r->value.data, + r->value.length); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultReference: { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->oid) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + } + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + default: + return false; + } + + if (msg->controls != NULL) { + asn1_push_tag(data, ASN1_CONTEXT(0)); + + for (i = 0; msg->controls[i] != NULL; i++) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + return false; + } + } + + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + + if (data->has_error) { + asn1_free(data); + return false; + } + + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); + return true; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc_array(mem_ctx, char, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, mem_ctx, &string)) + return false; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return true; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + struct ldap_Result *result) +{ + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + asn1_end_tag(data); + } else { + result->referral = NULL; + } +} + +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value); + + chunks[chunk_num + 1] = '\0'; + + return chunks; +} + + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) +{ + uint8_t filter_tag; + struct ldb_parse_tree *ret; + + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } + + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; + + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + while (asn1_tag_remaining(data) > 0) { + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { + goto failed; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; + break; + } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, mem_ctx, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { + goto failed; + } + if (!asn1_read_LDAPString(data, ret, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 9: { + char *oid = NULL, *attr = NULL, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, ret, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, ret, &attr); + asn1_end_tag(data); + } + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, ret, &value); + asn1_end_tag(data); + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { + goto failed; + } + + if (oid) { + ret->operation = LDB_OP_EXTENDED; + + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + + default: + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +/* Decode a single LDAP attribute, possibly containing multiple values */ +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + asn1_read_OctetString(data, mem_ctx, &blob); + add_value_to_attrib(mem_ctx, &blob, attrib); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +/* Decode a set of LDAP attributes, as found in the dereference control */ +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldb_message_element attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } +} + +/* Decode a set of LDAP attributes, as found in a search entry */ +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + ldap_decode_attribs_bare(mem_ctx, data, + attributes, num_attributes); + asn1_end_tag(data); +} + +/* This routine returns LDAP status codes */ + +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +{ + uint8_t tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, tag); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg, data, &r->dn); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { + int pwlen; + r->creds.password = ""; + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + if (pwlen != 0) { + char *pw = talloc_array(msg, char, pwlen+1); + if (!pw) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, msg, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->creds.SASL.secblob = NULL; + } + asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = NULL; + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, tag); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN(data, &r->attributesonly); + + r->tree = ldap_decode_filter_tree(msg, data); + if (r->tree == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + + const char *attr; + if (!asn1_read_OctetString_talloc(msg, data, + &attr)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + if (!add_string_to_array(msg, attr, + &r->attributes, + &r->num_attributes)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_Result *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->referral); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + int v; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &v); + mod.type = v; + ldap_decode_attrib(msg, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg, &mod, + &r->mods, &r->num_mods)) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_Result *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_Result *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + dn = talloc_array(msg, char, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); + asn1_read_BOOLEAN(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + newsup = talloc_array(msg, char, len+1); + if (newsup == NULL) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg, data, &r->attribute); + asn1_read_OctetString(data, msg, &r->value); + if (r->value.data) { + talloc_steal(msg, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_Result *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, tag); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,tag); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + default: + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + msg->controls = NULL; + msg->controls_decoded = NULL; + + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + int i = 0; + struct ldb_control **ctrl = NULL; + bool *decoded = NULL; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ + + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); + if (!ctrl) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + ctrl[i] = talloc(ctrl, struct ldb_control); + if (!ctrl[i]) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + ctrl[i]->data = NULL; + decoded[i] = false; + i++; + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + decoded[i] = true; + i++; + } + } + + if (ctrl != NULL) { + ctrl[i] = NULL; + } + + msg->controls = ctrl; + msg->controls_decoded = decoded; + + asn1_end_tag(data); + } + + asn1_end_tag(data); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; +} + + +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h new file mode 100644 index 0000000000..47ee724e97 --- /dev/null +++ b/libcli/ldap/ldap_message.h @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 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 . + +*/ + +#ifndef _LIBCLI_LDAP_MESSAGE_H_ +#define _LIBCLI_LDAP_MESSAGE_H_ + +#include "libcli/ldap/ldap_errors.h" +#include "lib/ldb/include/ldb.h" + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB *secblob;/* optional */ + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB *secblob;/* optional */ + } SASL; +}; + +struct ldap_UnbindRequest { + uint8_t __dummy; +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32_t timelimit; + uint32_t sizelimit; + bool attributesonly; + struct ldb_parse_tree *tree; + int num_attributes; + const char * const *attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_SearchResRef { + const char *referral; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldb_message_element attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + bool deleteolddn; + const char *newsuperior;/* optional */ +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + DATA_BLOB value; +}; + +struct ldap_AbandonRequest { + uint32_t messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB *value;/* optional */ +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ +}; + +union ldap_Request { + struct ldap_Result GeneralResult; + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + + +struct ldap_message { + int messageid; + enum ldap_request_tag type; + union ldap_Request r; + struct ldb_control **controls; + bool *controls_decoded; +}; + +struct asn1_data; + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result); + +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes); + +#endif diff --git a/source4/headermap.txt b/source4/headermap.txt index 8a968315bf..9d8e698f5c 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -49,7 +49,7 @@ param/share.h: share.h ../lib/util/util_tdb.h: util_tdb.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h -libcli/ldap/ldap_message.h: ldap_message.h +../libcli/ldap/ldap_message.h: ldap_message.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a0e178ac40..a1f34a6513 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,11 +1,3 @@ -[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB -PRIVATE_DEPENDENCIES = ASN1_UTIL - -LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ - ldap_message.o) -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h - [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index a642e671e6..79cfef2128 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -21,7 +21,7 @@ #ifndef _SMB_LDAP_H_ #define _SMB_LDAP_H_ -#include "libcli/ldap/ldap_message.h" +#include "../libcli/ldap/ldap_message.h" #include "librpc/gen_ndr/misc.h" struct tevent_context; diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c deleted file mode 100644 index d8bbf42634..0000000000 --- a/source4/libcli/ldap/ldap_message.c +++ /dev/null @@ -1,1467 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 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 . - -*/ - -#include "includes.h" -#include "../lib/util/asn1.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_proto.h" - -_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldap_message); -} - - -static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return false; - - attrib->values[attrib->num_values].data = talloc_steal(attrib->values, - value->data); - attrib->values[attrib->num_values].length = value->length; - attrib->num_values += 1; - return true; -} - -static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return false; - - (*attribs)[*num_attribs] = *attrib; - talloc_steal(*attribs, attrib->values); - talloc_steal(*attribs, attrib->name); - *num_attribs += 1; - return true; -} - -static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return false; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return true; -} - -static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) -{ - int i; - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return false; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return false; - } - asn1_pop_tag(data); - break; - - case LDB_OP_EQUALITY: - /* equality test */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.equality.attr, - strlen(tree->u.equality.attr)); - asn1_write_OctetString(data, tree->u.equality.value.data, - tree->u.equality.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_SUBSTRING: - /* - SubstringFilter ::= SEQUENCE { - type AttributeDescription, - -- at least one must be present - substrings SEQUENCE OF CHOICE { - initial [0] LDAPString, - any [1] LDAPString, - final [2] LDAPString } } - */ - asn1_push_tag(data, ASN1_CONTEXT(4)); - asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - i = 0; - if ( ! tree->u.substring.start_with_wildcard) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - while (tree->u.substring.chunks[i]) { - int ctx; - - if (( ! tree->u.substring.chunks[i + 1]) && - (tree->u.substring.end_with_wildcard == 0)) { - ctx = 2; - } else { - ctx = 1; - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - case LDB_OP_GREATER: - /* greaterOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(5)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_LESS: - /* lessOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(6)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_PRESENT: - /* present test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write_LDAPString(data, tree->u.present.attr); - asn1_pop_tag(data); - return !data->has_error; - - case LDB_OP_APPROX: - /* approx test */ - asn1_push_tag(data, ASN1_CONTEXT(8)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_EXTENDED: - /* - MatchingRuleAssertion ::= SEQUENCE { - matchingRule [1] MatchingRuleID OPTIONAL, - type [2] AttributeDescription OPTIONAL, - matchValue [3] AssertionValue, - dnAttributes [4] BOOLEAN DEFAULT FALSE - } - */ - asn1_push_tag(data, ASN1_CONTEXT(9)); - if (tree->u.extended.rule_id) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write_LDAPString(data, tree->u.extended.rule_id); - asn1_pop_tag(data); - } - if (tree->u.extended.attr) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_write_LDAPString(data, tree->u.extended.attr); - asn1_pop_tag(data); - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); - asn1_pop_tag(data); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_write_uint8(data, tree->u.extended.dnAttributes); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - default: - return false; - } - return !data->has_error; -} - -static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) -{ - asn1_write_enumerated(data, result->resultcode); - asn1_write_OctetString(data, result->dn, - (result->dn) ? strlen(result->dn) : 0); - asn1_write_OctetString(data, result->errormessage, - (result->errormessage) ? - strlen(result->errormessage) : 0); - if (result->referral) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, result->referral, - strlen(result->referral)); - asn1_pop_tag(data); - } -} - -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) -{ - struct asn1_data *data = asn1_init(mem_ctx); - int i, j; - - if (!data) return false; - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_Integer(data, msg->messageid); - - switch (msg->type) { - case LDAP_TAG_BindRequest: { - struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(data, r->version); - asn1_write_OctetString(data, r->dn, - (r->dn != NULL) ? strlen(r->dn) : 0); - - switch (r->mechanism) { - case LDAP_AUTH_MECH_SIMPLE: - /* context, primitive */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->creds.password, - strlen(r->creds.password)); - asn1_pop_tag(data); - break; - case LDAP_AUTH_MECH_SASL: - /* context, constructed */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, r->creds.SASL.mechanism, - strlen(r->creds.SASL.mechanism)); - if (r->creds.SASL.secblob) { - asn1_write_OctetString(data, r->creds.SASL.secblob->data, - r->creds.SASL.secblob->length); - } - asn1_pop_tag(data); - break; - default: - return false; - } - - asn1_pop_tag(data); - break; - } - case LDAP_TAG_BindResponse: { - struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->SASL.secblob) { - asn1_write_ContextSimple(data, 7, r->SASL.secblob); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_UnbindRequest: { -/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ - break; - } - case LDAP_TAG_SearchRequest: { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(data, r->scope); - asn1_write_enumerated(data, r->deref); - asn1_write_Integer(data, r->sizelimit); - asn1_write_Integer(data, r->timelimit); - asn1_write_BOOLEAN(data, r->attributesonly); - - if (!ldap_push_filter(data, r->tree)) { - return false; - } - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - asn1_write_OctetString(data, r->attributes[i], - strlen(r->attributes[i])); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultEntry: { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attr->name, - strlen(attr->name)); - asn1_push_tag(data, ASN1_SEQUENCE(1)); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attr->values[j].data, - attr->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultDone: { - struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyRequest: { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_mods; i++) { - struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(data, r->mods[i].type); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - - } - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyResponse: { - struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddRequest: { - struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddResponse: { - struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(data, r->dn, strlen(r->dn)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNRequest: { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(data, r->deleteolddn); - if (r->newsuperior) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->newsuperior, - strlen(r->newsuperior)); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareRequest: { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, r->attribute, - strlen(r->attribute)); - asn1_write_OctetString(data, r->value.data, - r->value.length); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AbandonRequest: { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(data, r->messageid); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultReference: { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->referral, strlen(r->referral)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedRequest: { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedResponse: { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->oid) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - } - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - default: - return false; - } - - if (msg->controls != NULL) { - asn1_push_tag(data, ASN1_CONTEXT(0)); - - for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return false; - } - } - - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - - if (data->has_error) { - asn1_free(data); - return false; - } - - *result = data_blob_talloc(mem_ctx, data->data, data->length); - asn1_free(data); - return true; -} - -static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, - DATA_BLOB blob) -{ - char *result = talloc_array(mem_ctx, char, blob.length+1); - memcpy(result, blob.data, blob.length); - result[blob.length] = '\0'; - return result; -} - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) -{ - DATA_BLOB string; - if (!asn1_read_OctetString(data, mem_ctx, &string)) - return false; - *result = blob2string_talloc(mem_ctx, string); - data_blob_free(&string); - return true; -} - -static void ldap_decode_response(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - struct ldap_Result *result) -{ - asn1_read_enumerated(data, &result->resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); - asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - asn1_end_tag(data); - } else { - result->referral = NULL; - } -} - -static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) -{ - - chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); - if (chunks == NULL) { - return NULL; - } - - chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); - if (chunks[chunk_num] == NULL) { - return NULL; - } - - chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); - if (chunks[chunk_num]->data == NULL) { - return NULL; - } - chunks[chunk_num]->length = strlen(value); - - chunks[chunk_num + 1] = '\0'; - - return chunks; -} - - -/* - parse the ASN.1 formatted search string into a ldb_parse_tree -*/ -static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, - struct asn1_data *data) -{ - uint8_t filter_tag; - struct ldb_parse_tree *ret; - - if (!asn1_peek_uint8(data, &filter_tag)) { - return NULL; - } - - filter_tag &= 0x1f; /* strip off the asn1 stuff */ - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (ret == NULL) return NULL; - - switch(filter_tag) { - case 0: - case 1: - /* AND or OR of one or more filters */ - ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; - ret->u.list.num_elements = 0; - ret->u.list.elements = NULL; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - while (asn1_tag_remaining(data) > 0) { - struct ldb_parse_tree *subtree; - subtree = ldap_decode_filter_tree(ret, data); - if (subtree == NULL) { - goto failed; - } - ret->u.list.elements = - talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); - if (ret->u.list.elements == NULL) { - goto failed; - } - talloc_steal(ret->u.list.elements, subtree); - ret->u.list.elements[ret->u.list.num_elements] = subtree; - ret->u.list.num_elements++; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 2: - /* 'not' operation */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldap_decode_filter_tree(ret, data); - if (ret->u.isnot.child == NULL) { - goto failed; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attrib); - ret->u.equality.value.data = talloc_steal(ret, value.data); - ret->u.equality.value.length = value.length; - break; - } - case 4: { - /* substrings */ - DATA_BLOB attr; - uint8_t subs_tag; - char *value; - int chunk_num = 0; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); - ret->u.substring.chunks = NULL; - ret->u.substring.start_with_wildcard = 1; - ret->u.substring.end_with_wildcard = 1; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - goto failed; - } - - while (asn1_tag_remaining(data)) { - asn1_peek_uint8(data, &subs_tag); - subs_tag &= 0x1f; /* strip off the asn1 stuff */ - if (subs_tag > 2) goto failed; - - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, mem_ctx, &value); - asn1_end_tag(data); - - switch (subs_tag) { - case 0: - if (ret->u.substring.chunks != NULL) { - /* initial value found in the middle */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.start_with_wildcard = 0; - chunk_num = 1; - break; - - case 1: - if (ret->u.substring.end_with_wildcard == 0) { - /* "any" value found after a "final" value */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - chunk_num++; - break; - - case 2: - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.end_with_wildcard = 0; - break; - - default: - goto failed; - } - - } - - if (!asn1_end_tag(data)) { /* SEQUENCE */ - goto failed; - } - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 5: { - /* greaterOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 6: { - /* lessOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 7: { - /* Normal presence, "attribute=*" */ - char *attr; - - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { - goto failed; - } - if (!asn1_read_LDAPString(data, ret, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = talloc_steal(ret, attr); - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 8: { - /* approx */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 9: { - char *oid = NULL, *attr = NULL, *value; - uint8_t dnAttributes; - /* an extended search */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's - we need to check we properly implement --SSS */ - /* either oid or type must be defined */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, ret, &oid); - asn1_end_tag(data); - } - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, ret, &attr); - asn1_end_tag(data); - } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, ret, &value); - asn1_end_tag(data); - /* dnAttributes is marked as BOOLEAN DEFAULT FALSE - it is not marked as OPTIONAL but openldap tools - do not set this unless it is to be set as TRUE - NOTE: openldap tools do not work with AD as it - seems that AD always requires the dnAttributes - boolean value to be set */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - } else { - dnAttributes = 0; - } - if ((oid == NULL && attr == NULL) || (value == NULL)) { - goto failed; - } - - if (oid) { - ret->operation = LDB_OP_EXTENDED; - - /* From the RFC2251: If the type field is - absent and matchingRule is present, the matchValue is compared - against all attributes in an entry which support that matchingRule - */ - if (attr) { - ret->u.extended.attr = talloc_steal(ret, attr); - } else { - ret->u.extended.attr = talloc_strdup(ret, "*"); - } - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; - } else { - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); - ret->u.equality.value.length = strlen(value); - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - - default: - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -/* Decode a single LDAP attribute, possibly containing multiple values */ -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element *attrib) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); - asn1_start_tag(data, ASN1_SET); - while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - DATA_BLOB blob; - asn1_read_OctetString(data, mem_ctx, &blob); - add_value_to_attrib(mem_ctx, &blob, attrib); - } - asn1_end_tag(data); - asn1_end_tag(data); - -} - -/* Decode a set of LDAP attributes, as found in the dereference control */ -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldb_message_element attrib; - ZERO_STRUCT(attrib); - ldap_decode_attrib(mem_ctx, data, &attrib); - add_attrib_to_array_talloc(mem_ctx, &attrib, - attributes, num_attributes); - } -} - -/* Decode a set of LDAP attributes, as found in a search entry */ -static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - ldap_decode_attribs_bare(mem_ctx, data, - attributes, num_attributes); - asn1_end_tag(data); -} - -/* This routine returns LDAP status codes */ - -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) -{ - uint8_t tag; - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &msg->messageid); - - if (!asn1_peek_uint8(data, &tag)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - - switch(tag) { - - case ASN1_APPLICATION(LDAP_TAG_BindRequest): { - struct ldap_BindRequest *r = &msg->r.BindRequest; - msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, tag); - asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg, data, &r->dn); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { - int pwlen; - r->creds.password = ""; - r->mechanism = LDAP_AUTH_MECH_SIMPLE; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - pwlen = asn1_tag_remaining(data); - if (pwlen == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - if (pwlen != 0) { - char *pw = talloc_array(msg, char, pwlen+1); - if (!pw) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, pw, pwlen); - pw[pwlen] = '\0'; - r->creds.password = pw; - } - asn1_end_tag(data); - } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ - asn1_start_tag(data, ASN1_CONTEXT(3)); - r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, msg, &tmp_blob); - r->creds.SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->creds.SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->creds.SASL.secblob = NULL; - } - asn1_end_tag(data); - } else { - /* Neither Simple nor SASL bind */ - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_BindResponse): { - struct ldap_BindResponse *r = &msg->r.BindResponse; - msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->SASL.secblob = NULL; - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { - msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, tag); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->basedn); - asn1_read_enumerated(data, (int *)&(r->scope)); - asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN(data, &r->attributesonly); - - r->tree = ldap_decode_filter_tree(msg, data); - if (r->tree == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_attributes = 0; - r->attributes = NULL; - - while (asn1_tag_remaining(data) > 0) { - - const char *attr; - if (!asn1_read_OctetString_talloc(msg, data, - &attr)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - if (!add_string_to_array(msg, attr, - &r->attributes, - &r->num_attributes)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - msg->type = LDAP_TAG_SearchResultEntry; - r->attributes = NULL; - r->num_attributes = 0; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_Result *r = &msg->r.SearchResultDone; - msg->type = LDAP_TAG_SearchResultDone; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - msg->type = LDAP_TAG_SearchResultReference; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->referral); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - msg->type = LDAP_TAG_ModifyRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_mods = 0; - r->mods = NULL; - - while (asn1_tag_remaining(data) > 0) { - struct ldap_mod mod; - int v; - ZERO_STRUCT(mod); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &v); - mod.type = v; - ldap_decode_attrib(msg, data, &mod.attrib); - asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_Result *r = &msg->r.ModifyResponse; - msg->type = LDAP_TAG_ModifyResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddRequest): { - struct ldap_AddRequest *r = &msg->r.AddRequest; - msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - - r->attributes = NULL; - r->num_attributes = 0; - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_Result *r = &msg->r.AddResponse; - msg->type = LDAP_TAG_AddResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; - int len; - char *dn; - msg->type = LDAP_TAG_DelRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - dn = talloc_array(msg, char, len+1); - if (dn == NULL) - break; - asn1_read(data, dn, len); - dn[len] = '\0'; - r->dn = dn; - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - msg->type = LDAP_TAG_ModifyDNRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_read_OctetString_talloc(msg, data, &r->newrdn); - asn1_read_BOOLEAN(data, &r->deleteolddn); - r->newsuperior = NULL; - if (asn1_tag_remaining(data) > 0) { - int len; - char *newsup; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - newsup = talloc_array(msg, char, len+1); - if (newsup == NULL) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, newsup, len); - newsup[len] = '\0'; - r->newsuperior = newsup; - asn1_end_tag(data); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - msg->type = LDAP_TAG_ModifyDNResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - msg->type = LDAP_TAG_CompareRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, msg, &r->value); - if (r->value.data) { - talloc_steal(msg, r->value.data); - } - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_Result *r = &msg->r.CompareResponse; - msg->type = LDAP_TAG_CompareResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, tag); - asn1_read_implicit_Integer(data, &r->messageid); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,tag); - if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } else { - r->oid = NULL; - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - default: - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - msg->controls = NULL; - msg->controls_decoded = NULL; - - if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i = 0; - struct ldb_control **ctrl = NULL; - bool *decoded = NULL; - - asn1_start_tag(data, ASN1_CONTEXT(0)); - - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - DATA_BLOB value; - /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - - ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); - if (!ctrl) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - decoded = talloc_realloc(msg, decoded, bool, i+1); - if (!decoded) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - if (!ctrl[i]) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { - if (ctrl[i]->critical) { - ctrl[i]->data = NULL; - decoded[i] = false; - i++; - } else { - talloc_free(ctrl[i]); - ctrl[i] = NULL; - } - } else { - decoded[i] = true; - i++; - } - } - - if (ctrl != NULL) { - ctrl[i] = NULL; - } - - msg->controls = ctrl; - msg->controls_decoded = decoded; - - asn1_end_tag(data); - } - - asn1_end_tag(data); - if ((data->has_error) || (data->nesting != NULL)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - return NT_STATUS_OK; -} - - -/* - return NT_STATUS_OK if a blob has enough bytes in it to be a full - ldap packet. Set packet_size if true. -*/ -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) -{ - return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); -} diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h deleted file mode 100644 index 47ee724e97..0000000000 --- a/source4/libcli/ldap/ldap_message.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 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 . - -*/ - -#ifndef _LIBCLI_LDAP_MESSAGE_H_ -#define _LIBCLI_LDAP_MESSAGE_H_ - -#include "libcli/ldap/ldap_errors.h" -#include "lib/ldb/include/ldb.h" - -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB *secblob;/* optional */ - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB *secblob;/* optional */ - } SASL; -}; - -struct ldap_UnbindRequest { - uint8_t __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32_t timelimit; - uint32_t sizelimit; - bool attributesonly; - struct ldb_parse_tree *tree; - int num_attributes; - const char * const *attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_SearchResRef { - const char *referral; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldb_message_element attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior;/* optional */ -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - DATA_BLOB value; -}; - -struct ldap_AbandonRequest { - uint32_t messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB *value;/* optional */ -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *oid;/* optional */ - DATA_BLOB *value;/* optional */ -}; - -union ldap_Request { - struct ldap_Result GeneralResult; - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - - -struct ldap_message { - int messageid; - enum ldap_request_tag type; - union ldap_Request r; - struct ldb_control **controls; - bool *controls_decoded; -}; - -struct asn1_data; - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result); - -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes); - -#endif diff --git a/source4/main.mk b/source4/main.mk index 04f7a36a5f..ee2018fb69 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -50,3 +50,5 @@ mkinclude kdc/config.mk mkinclude ../lib/smbconf/config.mk mkinclude ../lib/async_req/config.mk mkinclude ../libcli/security/config.mk +mkinclude ../libcli/ldap/config.mk + -- cgit From ef0fa403f1c5d670b7991770e7fbb8394879de4b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 16:52:37 +0100 Subject: libcli/ldap: move ldap_errors.h to the toplevel and install it metze --- libcli/ldap/config.mk | 2 +- libcli/ldap/ldap_errors.h | 68 +++++++++++++++++++++++++++++++++++++++ libcli/ldap/ldap_message.h | 2 +- source4/headermap.txt | 1 + source4/libcli/ldap/ldap_errors.h | 66 ------------------------------------- source4/libcli/util/nterr.c | 2 +- 6 files changed, 72 insertions(+), 69 deletions(-) create mode 100644 libcli/ldap/ldap_errors.h delete mode 100644 source4/libcli/ldap/ldap_errors.h diff --git a/libcli/ldap/config.mk b/libcli/ldap/config.mk index 067b6778b7..02397cb43a 100644 --- a/libcli/ldap/config.mk +++ b/libcli/ldap/config.mk @@ -4,4 +4,4 @@ PRIVATE_DEPENDENCIES = ASN1_UTIL LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix ../libcli/ldap/, \ ldap_message.o) -PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h +PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h ../libcli/ldap/ldap_errors.h diff --git a/libcli/ldap/ldap_errors.h b/libcli/ldap/ldap_errors.h new file mode 100644 index 0000000000..fa929c6936 --- /dev/null +++ b/libcli/ldap/ldap_errors.h @@ -0,0 +1,68 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 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 . + +*/ + +#ifndef _SMB_LDAP_ERRORS_H_ +#define _SMB_LDAP_ERRORS_H_ + +#ifndef LDAP_SUCCESS +enum ldap_result_code { + LDAP_SUCCESS = 0, + LDAP_OPERATIONS_ERROR = 1, + LDAP_PROTOCOL_ERROR = 2, + LDAP_TIME_LIMIT_EXCEEDED = 3, + LDAP_SIZE_LIMIT_EXCEEDED = 4, + LDAP_COMPARE_FALSE = 5, + LDAP_COMPARE_TRUE = 6, + LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, + LDAP_STRONG_AUTH_REQUIRED = 8, + LDAP_REFERRAL = 10, + LDAP_ADMIN_LIMIT_EXCEEDED = 11, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, + LDAP_CONFIDENTIALITY_REQUIRED = 13, + LDAP_SASL_BIND_IN_PROGRESS = 14, + LDAP_NO_SUCH_ATTRIBUTE = 16, + LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, + LDAP_INAPPROPRIATE_MATCHING = 18, + LDAP_CONSTRAINT_VIOLATION = 19, + LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, + LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, + LDAP_NO_SUCH_OBJECT = 32, + LDAP_ALIAS_PROBLEM = 33, + LDAP_INVALID_DN_SYNTAX = 34, + LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, + LDAP_INAPPROPRIATE_AUTHENTICATION = 48, + LDAP_INVALID_CREDENTIALS = 49, + LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, + LDAP_BUSY = 51, + LDAP_UNAVAILABLE = 52, + LDAP_UNWILLING_TO_PERFORM = 53, + LDAP_LOOP_DETECT = 54, + LDAP_NAMING_VIOLATION = 64, + LDAP_OBJECT_CLASS_VIOLATION = 65, + LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, + LDAP_NOT_ALLOWED_ON_RDN = 67, + LDAP_ENTRY_ALREADY_EXISTS = 68, + LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, + LDAP_AFFECTS_MULTIPLE_DSAS = 71, + LDAP_OTHER = 80 +}; +#endif + +#endif /* _SMB_LDAP_ERRORS_H_ */ diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h index 47ee724e97..672de0d925 100644 --- a/libcli/ldap/ldap_message.h +++ b/libcli/ldap/ldap_message.h @@ -21,7 +21,7 @@ #ifndef _LIBCLI_LDAP_MESSAGE_H_ #define _LIBCLI_LDAP_MESSAGE_H_ -#include "libcli/ldap/ldap_errors.h" +#include "../libcli/ldap/ldap_errors.h" #include "lib/ldb/include/ldb.h" enum ldap_request_tag { diff --git a/source4/headermap.txt b/source4/headermap.txt index 9d8e698f5c..6417603d1d 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -50,6 +50,7 @@ param/share.h: share.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h ../libcli/ldap/ldap_message.h: ldap_message.h +../libcli/ldap/ldap_errors.h: ldap_errors.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/ldap_errors.h b/source4/libcli/ldap/ldap_errors.h deleted file mode 100644 index 17ac43814c..0000000000 --- a/source4/libcli/ldap/ldap_errors.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 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 . - -*/ - -#ifndef _SMB_LDAP_ERRORS_H_ -#define _SMB_LDAP_ERRORS_H_ - -enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_OPERATIONS_ERROR = 1, - LDAP_PROTOCOL_ERROR = 2, - LDAP_TIME_LIMIT_EXCEEDED = 3, - LDAP_SIZE_LIMIT_EXCEEDED = 4, - LDAP_COMPARE_FALSE = 5, - LDAP_COMPARE_TRUE = 6, - LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, - LDAP_STRONG_AUTH_REQUIRED = 8, - LDAP_REFERRAL = 10, - LDAP_ADMIN_LIMIT_EXCEEDED = 11, - LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, - LDAP_CONFIDENTIALITY_REQUIRED = 13, - LDAP_SASL_BIND_IN_PROGRESS = 14, - LDAP_NO_SUCH_ATTRIBUTE = 16, - LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, - LDAP_INAPPROPRIATE_MATCHING = 18, - LDAP_CONSTRAINT_VIOLATION = 19, - LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, - LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, - LDAP_NO_SUCH_OBJECT = 32, - LDAP_ALIAS_PROBLEM = 33, - LDAP_INVALID_DN_SYNTAX = 34, - LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, - LDAP_INAPPROPRIATE_AUTHENTICATION = 48, - LDAP_INVALID_CREDENTIALS = 49, - LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, - LDAP_BUSY = 51, - LDAP_UNAVAILABLE = 52, - LDAP_UNWILLING_TO_PERFORM = 53, - LDAP_LOOP_DETECT = 54, - LDAP_NAMING_VIOLATION = 64, - LDAP_OBJECT_CLASS_VIOLATION = 65, - LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, - LDAP_NOT_ALLOWED_ON_RDN = 67, - LDAP_ENTRY_ALREADY_EXISTS = 68, - LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, - LDAP_AFFECTS_MULTIPLE_DSAS = 71, - LDAP_OTHER = 80 -}; - -#endif /* _SMB_LDAP_ERRORS_H_ */ diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 8371837dcb..4e7cdf5c3a 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -20,7 +20,7 @@ /* NT error codes. please read nterr.h */ #include "includes.h" -#include "libcli/ldap/ldap_errors.h" +#include "../libcli/ldap/ldap_errors.h" #undef strcasecmp typedef struct -- cgit From 7aaec963c1764869b042240fb5b5d6a339ee052b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:29:59 +0100 Subject: libcli/ldap: fix compiler warnings metze --- libcli/ldap/ldap_message.c | 15 ++++++++++----- libcli/ldap/ldap_message.h | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index e8ec716e64..06052a936a 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -923,13 +923,13 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, ret->u.extended.attr = talloc_strdup(ret, "*"); } ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.data = (uint8_t *)talloc_steal(ret, value); ret->u.extended.value.length = strlen(value); ret->u.extended.dnAttributes = dnAttributes; } else { ret->operation = LDB_OP_EQUALITY; ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.data = (uint8_t *)talloc_steal(ret, value); ret->u.equality.value.length = strlen(value); } if (!asn1_end_tag(data)) { @@ -1087,13 +1087,17 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { struct ldap_SearchRequest *r = &msg->r.SearchRequest; + int sizelimit, timelimit; + const char **attrs = NULL; msg->type = LDAP_TAG_SearchRequest; asn1_start_tag(data, tag); asn1_read_OctetString_talloc(msg, data, &r->basedn); asn1_read_enumerated(data, (int *)&(r->scope)); asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); + asn1_read_Integer(data, &sizelimit); + r->sizelimit = sizelimit; + asn1_read_Integer(data, &timelimit); + r->timelimit = timelimit; asn1_read_BOOLEAN(data, &r->attributesonly); r->tree = ldap_decode_filter_tree(msg, data); @@ -1113,10 +1117,11 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) &attr)) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); if (!add_string_to_array(msg, attr, - &r->attributes, + &attrs, &r->num_attributes)) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } + r->attributes = attrs; asn1_end_tag(data); asn1_end_tag(data); diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h index 672de0d925..d2ce14445d 100644 --- a/libcli/ldap/ldap_message.h +++ b/libcli/ldap/ldap_message.h @@ -160,7 +160,7 @@ struct ldap_CompareRequest { }; struct ldap_AbandonRequest { - uint32_t messageid; + int messageid; }; struct ldap_ExtendedRequest { -- cgit From 18b30e5646d7a484c1714eac9b9ce1f8c1a8241a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:50:43 +0100 Subject: libcli/ldap: move ldap_ndr from source4/ to toplevel metze --- libcli/ldap/config.mk | 10 ++++- libcli/ldap/ldap_ndr.c | 96 ++++++++++++++++++++++++++++++++++++++++++ libcli/ldap/ldap_ndr.h | 12 ++++++ source4/headermap.txt | 2 +- source4/libcli/ldap/config.mk | 7 +-- source4/libcli/ldap/ldap_ndr.c | 96 ------------------------------------------ source4/libcli/ldap/ldap_ndr.h | 12 ------ 7 files changed, 119 insertions(+), 116 deletions(-) create mode 100644 libcli/ldap/ldap_ndr.c create mode 100644 libcli/ldap/ldap_ndr.h delete mode 100644 source4/libcli/ldap/ldap_ndr.c delete mode 100644 source4/libcli/ldap/ldap_ndr.h diff --git a/libcli/ldap/config.mk b/libcli/ldap/config.mk index 02397cb43a..22cad8cfbc 100644 --- a/libcli/ldap/config.mk +++ b/libcli/ldap/config.mk @@ -1,7 +1,15 @@ [SUBSYSTEM::LIBCLI_LDAP_MESSAGE] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB -PRIVATE_DEPENDENCIES = ASN1_UTIL +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL ASN1_UTIL LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix ../libcli/ldap/, \ ldap_message.o) PUBLIC_HEADERS += ../libcli/ldap/ldap_message.h ../libcli/ldap/ldap_errors.h + +[SUBSYSTEM::LIBCLI_LDAP_NDR] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB NDR_MISC NDR_SECURITY + +LIBCLI_LDAP_NDR_OBJ_FILES = ../libcli/ldap/ldap_ndr.o +PUBLIC_HEADERS += ../libcli/ldap/ldap_ndr.h + diff --git a/libcli/ldap/ldap_ndr.c b/libcli/ldap/ldap_ndr.c new file mode 100644 index 0000000000..dd820ff8d5 --- /dev/null +++ b/libcli/ldap/ldap_ndr.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS mplementation. + + wrap/unwrap NDR encoded elements for ldap calls + + Copyright (C) Andrew Tridgell 2005 + + 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 . + +*/ + +#include "includes.h" +#include "lib/ldb/include/ldb.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_misc.h" +#include "libcli/ldap/ldap_ndr.h" + +/* + encode a NDR uint32 as a ldap filter element +*/ +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) +{ + uint8_t buf[4]; + struct ldb_val val; + SIVAL(buf, 0, value); + val.data = buf; + val.length = 4; + return ldb_binary_encode(mem_ctx, val); +} + +/* + encode a NDR dom_sid as a ldap filter element +*/ +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + char *ret; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, + (ndr_push_flags_fn_t)ndr_push_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return NULL; + } + ret = ldb_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} + + +/* + encode a NDR GUID as a ldap filter element +*/ +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + char *ret; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, + (ndr_push_flags_fn_t)ndr_push_GUID); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return NULL; + } + ret = ldb_binary_encode(mem_ctx, blob); + data_blob_free(&blob); + return ret; +} + +/* + decode a NDR GUID from a ldap filter element +*/ +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + blob.data = val.data; + blob.length = val.length; + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, + (ndr_pull_flags_fn_t)ndr_pull_GUID); + talloc_free(val.data); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + return NT_STATUS_OK; +} diff --git a/libcli/ldap/ldap_ndr.h b/libcli/ldap/ldap_ndr.h new file mode 100644 index 0000000000..ee1f702c78 --- /dev/null +++ b/libcli/ldap/ldap_ndr.h @@ -0,0 +1,12 @@ +#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ +#define __LIBCLI_LDAP_LDAP_NDR_H__ + +#include "librpc/gen_ndr/ndr_misc.h" + +char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); +char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); + +#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ + diff --git a/source4/headermap.txt b/source4/headermap.txt index 6417603d1d..8287044622 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -51,7 +51,7 @@ param/share.h: share.h ../lib/util/wrap_xattr.h: wrap_xattr.h ../libcli/ldap/ldap_message.h: ldap_message.h ../libcli/ldap/ldap_errors.h: ldap_errors.h -libcli/ldap/ldap_ndr.h: ldap_ndr.h +../libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h auth/session.h: samba/session.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a1f34a6513..f0c0f5295d 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,7 @@ [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ - LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE + LIBCLI_LDAP_NDR LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ ldap_client.o ldap_bind.o \ @@ -10,8 +10,3 @@ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) -[SUBSYSTEM::LDAP_ENCODE] -PRIVATE_DEPENDENCIES = LIBLDB - -LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c deleted file mode 100644 index f0a11ba41f..0000000000 --- a/source4/libcli/ldap/ldap_ndr.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - - wrap/unwrap NDR encoded elements for ldap calls - - Copyright (C) Andrew Tridgell 2005 - - 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 . - -*/ - -#include "includes.h" -#include "libcli/ldap/ldap.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "libcli/ldap/ldap_ndr.h" - -/* - encode a NDR uint32 as a ldap filter element -*/ -char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) -{ - uint8_t buf[4]; - struct ldb_val val; - SIVAL(buf, 0, value); - val.data = buf; - val.length = 4; - return ldb_binary_encode(mem_ctx, val); -} - -/* - encode a NDR dom_sid as a ldap filter element -*/ -char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NULL; - } - ret = ldb_binary_encode(mem_ctx, blob); - data_blob_free(&blob); - return ret; -} - - -/* - encode a NDR GUID as a ldap filter element -*/ -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NULL; - } - ret = ldb_binary_encode(mem_ctx, blob); - data_blob_free(&blob); - return ret; -} - -/* - decode a NDR GUID from a ldap filter element -*/ -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - - blob.data = val.data; - blob.length = val.length; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - talloc_free(val.data); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - return NT_STATUS_OK; -} diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h deleted file mode 100644 index ee1f702c78..0000000000 --- a/source4/libcli/ldap/ldap_ndr.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ -#define __LIBCLI_LDAP_LDAP_NDR_H__ - -#include "librpc/gen_ndr/ndr_misc.h" - -char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); -char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); - -#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ - -- cgit From 7b1c5c94f6a08108d90a73ba78a91df661d68064 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:45:01 +0100 Subject: s4:libcli/ldap: don't use 'void **out' as arguments as the behavior is not defined in C. metze --- source4/libcli/ldap/ldap_controls.c | 49 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 109837c2bf..487ea61222 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -28,12 +28,13 @@ struct control_handler { const char *oid; - bool (*decode)(void *mem_ctx, DATA_BLOB in, void **out); + bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); }; -static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB attr; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; @@ -77,8 +78,9 @@ static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB attr; DATA_BLOB rule; struct asn1_data *data = asn1_init(mem_ctx); @@ -156,8 +158,9 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data; struct ldb_extended_dn_control *ledc; @@ -196,8 +199,9 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; @@ -229,8 +233,9 @@ static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; @@ -262,8 +267,9 @@ static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou return true; } -static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; @@ -310,8 +316,9 @@ static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return true; } -static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; @@ -365,8 +372,9 @@ static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB source_attribute; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; @@ -425,8 +433,9 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -434,8 +443,9 @@ static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -443,8 +453,9 @@ static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -452,8 +463,9 @@ static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -461,8 +473,9 @@ static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void * return true; } -static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -470,8 +483,9 @@ static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB assertion_value, context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; @@ -582,8 +596,9 @@ static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; @@ -1132,7 +1147,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) return true; } -static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) { struct asn1_data *data = asn1_init(mem_ctx); struct dsdb_openldap_dereference_result_control *control; -- cgit From f6b0a99cefaedfa7642af31f8fcc4457bacb07a3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 16:49:26 +0100 Subject: libcli/ldap: move generic ldap control encoding code to ldap_message.c As they can we static there, we pass the specific handlers as parameter where we need to support controls. metze --- libcli/ldap/ldap_message.c | 148 +++++++++++++++++++++++++++++++++++- libcli/ldap/ldap_message.h | 14 +++- source4/ldap_server/ldap_server.c | 4 +- source4/libcli/cldap/cldap.c | 12 +-- source4/libcli/ldap/ldap_client.c | 4 +- source4/libcli/ldap/ldap_controls.c | 131 +------------------------------ 6 files changed, 170 insertions(+), 143 deletions(-) diff --git a/libcli/ldap/ldap_message.c b/libcli/ldap/ldap_message.c index 06052a936a..9b00d0188d 100644 --- a/libcli/ldap/ldap_message.c +++ b/libcli/ldap/ldap_message.c @@ -84,6 +84,138 @@ static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, return true; } +static bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, + const struct ldap_control_handler *handlers, + struct ldb_control *ctrl) +{ + int i; + + if (!handlers) { + return true; + } + + for (i = 0; handlers[i].oid != NULL; i++) { + if (strcmp(handlers[i].oid, ctrl->oid) == 0) { + if (!handlers[i].decode || !handlers[i].decode(mem_ctx, value, &ctrl->data)) { + return false; + } + break; + } + } + if (handlers[i].oid == NULL) { + return false; + } + + return true; +} + +static bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, + struct ldb_control *ctrl, DATA_BLOB *value) +{ + DATA_BLOB oid; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + if (!asn1_read_OctetString(data, mem_ctx, &oid)) { + return false; + } + ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); + if (!ctrl->oid) { + return false; + } + + if (asn1_peek_tag(data, ASN1_BOOLEAN)) { + bool critical; + if (!asn1_read_BOOLEAN(data, &critical)) { + return false; + } + ctrl->critical = critical; + } else { + ctrl->critical = false; + } + + ctrl->data = NULL; + + if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { + *value = data_blob(NULL, 0); + goto end_tag; + } + + if (!asn1_read_OctetString(data, mem_ctx, value)) { + return false; + } + +end_tag: + if (!asn1_end_tag(data)) { + return false; + } + + return true; +} + +static bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, + const struct ldap_control_handler *handlers, + struct ldb_control *ctrl) +{ + DATA_BLOB value; + int i; + + if (!handlers) { + return false; + } + + for (i = 0; handlers[i].oid != NULL; i++) { + if (strcmp(handlers[i].oid, ctrl->oid) == 0) { + if (!handlers[i].encode) { + if (ctrl->critical) { + return false; + } else { + /* not encoding this control */ + return true; + } + } + if (!handlers[i].encode(mem_ctx, ctrl->data, &value)) { + return false; + } + break; + } + } + if (handlers[i].oid == NULL) { + return false; + } + + if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { + return false; + } + + if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { + return false; + } + + if (ctrl->critical) { + if (!asn1_write_BOOLEAN(data, ctrl->critical)) { + return false; + } + } + + if (!ctrl->data) { + goto pop_tag; + } + + if (!asn1_write_OctetString(data, value.data, value.length)) { + return false; + } + +pop_tag: + if (!asn1_pop_tag(data)) { + return false; + } + + return true; +} + static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) { int i; @@ -244,7 +376,9 @@ static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *res } } -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, + const struct ldap_control_handler *control_handlers, + DATA_BLOB *result, TALLOC_CTX *mem_ctx) { struct asn1_data *data = asn1_init(mem_ctx); int i, j; @@ -531,7 +665,9 @@ _PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CT asn1_push_tag(data, ASN1_CONTEXT(0)); for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + if (!ldap_encode_control(mem_ctx, data, + control_handlers, + msg->controls[i])) { return false; } } @@ -993,7 +1129,9 @@ static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, /* This routine returns LDAP status codes */ -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, + const struct ldap_control_handler *control_handlers, + struct ldap_message *msg) { uint8_t tag; @@ -1428,7 +1566,9 @@ _PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (!ldap_decode_control_value(ctrl, value, + control_handlers, + ctrl[i])) { if (ctrl[i]->critical) { ctrl[i]->data = NULL; decoded[i] = false; diff --git a/libcli/ldap/ldap_message.h b/libcli/ldap/ldap_message.h index d2ce14445d..c50018465c 100644 --- a/libcli/ldap/ldap_message.h +++ b/libcli/ldap/ldap_message.h @@ -207,11 +207,21 @@ struct ldap_message { bool *controls_decoded; }; +struct ldap_control_handler { + const char *oid; + bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); + bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); +}; + struct asn1_data; struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, + const struct ldap_control_handler *control_handlers, + struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, + const struct ldap_control_handler *control_handlers, + DATA_BLOB *result, TALLOC_CTX *mem_ctx); NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index da44c02aa8..a924024160 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -104,7 +104,7 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, bool ret; msg = call->replies->msg; - if (!ldap_encode(msg, &b, call)) { + if (!ldap_encode(msg, samba_ldap_control_handlers(), &b, call)) { DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type)); talloc_free(call); return; @@ -150,7 +150,7 @@ static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob) return NT_STATUS_NO_MEMORY; } - status = ldap_decode(asn1, msg); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); if (!NT_STATUS_IS_OK(status)) { asn1_free(asn1); return status; diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 8d2e2e374c..b18ba12b1f 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -108,7 +108,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } /* this initial decode is used to find the message id */ - status = ldap_decode(asn1, ldap_msg); + status = ldap_decode(asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); @@ -343,7 +343,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, goto failed; } - if (!ldap_encode(msg, &req->encoded, req)) { + if (!ldap_encode(msg, NULL, &req->encoded, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); goto failed; @@ -396,7 +396,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultEntry; msg->r.SearchResultEntry = *io->response; - if (!ldap_encode(msg, &blob1, req)) { + if (!ldap_encode(msg, NULL, &blob1, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; @@ -409,7 +409,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultDone; msg->r.SearchResultDone = *io->result; - if (!ldap_encode(msg, &blob2, req)) { + if (!ldap_encode(msg, NULL, &blob2, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; @@ -463,7 +463,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, ldap_msg = talloc(mem_ctx, struct ldap_message); NT_STATUS_HAVE_NO_MEMORY(ldap_msg); - status = ldap_decode(req->asn1, ldap_msg); + status = ldap_decode(req->asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status))); talloc_free(req); @@ -479,7 +479,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, *io->out.response = ldap_msg->r.SearchResultEntry; /* decode the 2nd part */ - status = ldap_decode(req->asn1, ldap_msg); + status = ldap_decode(req->asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status))); talloc_free(req); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 3e54d7fff0..304a2e1253 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -200,7 +200,7 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - status = ldap_decode(asn1, msg); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); if (!NT_STATUS_IS_OK(status)) { asn1_free(asn1); return status; @@ -608,7 +608,7 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; - if (!ldap_encode(msg, &req->data, req)) { + if (!ldap_encode(msg, samba_ldap_control_handlers(), &req->data, req)) { status = NT_STATUS_INTERNAL_ERROR; goto failed; } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 487ea61222..7949758a80 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -26,12 +26,6 @@ #include "libcli/ldap/ldap_proto.h" #include "dsdb/samdb/samdb.h" -struct control_handler { - const char *oid; - bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); - bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); -}; - static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) { void **out = (void **)_out; @@ -435,7 +429,6 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -445,7 +438,6 @@ static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -455,7 +447,6 @@ static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -465,7 +456,6 @@ static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -475,7 +465,6 @@ static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void * static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -1149,6 +1138,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct dsdb_openldap_dereference_result_control *control; struct dsdb_openldap_dereference_result **r = NULL; @@ -1216,7 +1206,7 @@ static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) return true; } -struct control_handler ldap_known_controls[] = { +static const struct ldap_control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, @@ -1240,121 +1230,8 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) +const struct ldap_control_handler *samba_ldap_control_handlers(void) { - int i; - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { - return false; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return false; - } - - return true; + return ldap_known_controls; } -bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) -{ - DATA_BLOB oid; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return false; - } - - if (!asn1_read_OctetString(data, mem_ctx, &oid)) { - return false; - } - ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); - if (!ctrl->oid) { - return false; - } - - if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - bool critical; - if (!asn1_read_BOOLEAN(data, &critical)) { - return false; - } - ctrl->critical = critical; - } else { - ctrl->critical = false; - } - - ctrl->data = NULL; - - if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { - *value = data_blob(NULL, 0); - goto end_tag; - } - - if (!asn1_read_OctetString(data, mem_ctx, value)) { - return false; - } - -end_tag: - if (!asn1_end_tag(data)) { - return false; - } - - return true; -} - -bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) -{ - DATA_BLOB value; - int i; - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].encode) { - if (ctrl->critical) { - return false; - } else { - /* not encoding this control */ - return true; - } - } - if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { - return false; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return false; - } - - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return false; - } - - if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { - return false; - } - - if (ctrl->critical) { - if (!asn1_write_BOOLEAN(data, ctrl->critical)) { - return false; - } - } - - if (!ctrl->data) { - goto pop_tag; - } - - if (!asn1_write_OctetString(data, value.data, value.length)) { - return false; - } - -pop_tag: - if (!asn1_pop_tag(data)) { - return false; - } - - return true; -} -- cgit From 023164f77e36694f4dc7435119f28f42ea0fb0ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:23:12 +0100 Subject: s3:Makefile: build libcli/ldap files metze --- source3/Makefile.in | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index a403f143bb..4cd25c8cee 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -444,7 +444,10 @@ LIBSMB_OBJ0 = \ LIBSAMBA_OBJ = $(LIBSMB_OBJ0) \ $(LIBSMB_ERR_OBJ) -CLDAP_OBJ = libads/cldap.o +LIBCLI_LDAP_MESSAGE_OBJ = ../libcli/ldap/ldap_message.o +LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o + +CLDAP_OBJ = libads/cldap.o $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ) LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o ../lib/util/asn1.o \ @@ -756,7 +759,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \ nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \ nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o smbd/connection.o -NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -935,7 +938,7 @@ NET_OBJ = $(NET_OBJ1) \ $(PRIVILEGES_BASIC_OBJ) @LIBLUA_STATIC@ \ $(LIB_EVENTLOG_OBJ) -CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ +CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -952,24 +955,24 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta torture/denytest.o torture/mangle_test.o SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \ - $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ + $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ lib/wb_reqtrans.o lib/wbclient.o \ @LIBWBCLIENT_STATIC@ \ $(LIBNDR_GEN_OBJ0) -MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) -MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \ - $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \ + $(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) -NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ +NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \ $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -984,7 +987,7 @@ SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ LOG2PCAP_OBJ = utils/log2pcaphex.o -LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \ +LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBNDR_GEN_OBJ0) @@ -1024,7 +1027,7 @@ REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \ DEBUG2HTML_OBJ = utils/debug2html.o utils/debugparse.o -SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ +SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(LIBNDR_GEN_OBJ0) -- cgit From 365925eea308673f15e03d81b69f04b8908468e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 11:37:57 -0800 Subject: Start fixing Solaris build failures. Jeremy. --- source4/heimdal/kuser/kuser_locl.h | 2 +- source4/heimdal/lib/krb5/krb5_locl.h | 2 +- source4/heimdal_build/internal.m4 | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source4/heimdal/kuser/kuser_locl.h b/source4/heimdal/kuser/kuser_locl.h index 21e9776975..eed9e00af6 100644 --- a/source4/heimdal/kuser/kuser_locl.h +++ b/source4/heimdal/kuser/kuser_locl.h @@ -88,7 +88,7 @@ #include #endif -#ifdef LIBINTL +#ifdef HAVE_LIBINTL_H #include #define N_(x,y) gettext(x) #define NP_(x,y) (x) diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 1a490392a9..ced722f2d9 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -118,7 +118,7 @@ struct sockaddr_dl; #define HEIMDAL_TEXTDOMAIN "heimdal_krb5" -#ifdef LIBINTL +#ifdef HAVE_LIBINTL_H #include #define N_(x,y) dgettext(HEIMDAL_TEXTDOMAIN, x) #else diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index b2f64a6825..50a3c8adda 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -69,7 +69,8 @@ AC_CHECK_HEADERS([ \ ttyname.h \ netinet/in.h \ netinet/in6.h \ - netinet6/in6.h + netinet6/in6.h \ + libintl.h ]) AC_CHECK_FUNCS([ \ -- cgit From dbc79381a87269e8ca0631e001aebb064ab4851b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 11:53:50 +0100 Subject: Convert name_mangle() to use talloc --- source3/include/proto.h | 2 +- source3/libsmb/cliconnect.c | 25 +++++++++++++++++++++---- source3/libsmb/nmblib.c | 15 +++++++++++---- source3/utils/smbfilter.c | 11 +++++++++-- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 3ca94b9192..87dac3e496 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3117,7 +3117,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name); int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len); void sort_query_replies(char *data, int n, struct in_addr ip); -int name_mangle( char *In, char *Out, char name_type ); +char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type); int name_extract(char *buf,int ofs, fstring name); int name_len(char *s1); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index dabfc398ce..ad11ee0ed4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1642,6 +1642,7 @@ bool cli_session_request(struct cli_state *cli, { char *p; int len = 4; + char *tmp; /* 445 doesn't have session request */ if (cli->port == 445) @@ -1651,14 +1652,30 @@ bool cli_session_request(struct cli_state *cli, memcpy(&(cli->called ), called , sizeof(*called )); /* put in the destination name */ + + tmp = name_mangle(talloc_tos(), cli->called.name, + cli->called.name_type); + if (tmp == NULL) { + return false; + } + p = cli->outbuf+len; - name_mangle(cli->called .name, p, cli->called .name_type); - len += name_len(p); + memcpy(p, tmp, name_len(tmp)); + len += name_len(tmp); + TALLOC_FREE(tmp); /* and my name */ + + tmp = name_mangle(talloc_tos(), cli->calling.name, + cli->calling.name_type); + if (tmp == NULL) { + return false; + } + p = cli->outbuf+len; - name_mangle(cli->calling.name, p, cli->calling.name_type); - len += name_len(p); + memcpy(p, tmp, name_len(tmp)); + len += name_len(tmp); + TALLOC_FREE(tmp); /* send a session request (RFC 1002) */ /* setup the packet length diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 02b13ae63e..5f3eda44fe 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1279,12 +1279,19 @@ static int name_interpret(char *in, fstring name) Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. ****************************************************************************/ -int name_mangle( char *In, char *Out, char name_type ) +char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type) { int i; int len; nstring buf; - char *p = Out; + char *result; + char *p; + + result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2); + if (result == NULL) { + return NULL; + } + p = result; /* Safely copy the input string, In, into buf[]. */ if (strcmp(In,"*") == 0) @@ -1321,7 +1328,7 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = len; if( len > 0 ) p[len+1] = 0; - return( name_len(Out) ); + return result; case '.': p[0] = len; p += (len + 1); @@ -1333,7 +1340,7 @@ int name_mangle( char *In, char *Out, char name_type ) } } - return( name_len(Out) ); + return result; } /**************************************************************************** diff --git a/source3/utils/smbfilter.c b/source3/utils/smbfilter.c index 1fdea818d6..39a264011e 100644 --- a/source3/utils/smbfilter.c +++ b/source3/utils/smbfilter.c @@ -91,8 +91,15 @@ static void filter_request(char *buf) d_printf("sesion_request: %s -> %s\n", name1, name2); if (netbiosname) { - /* replace the destination netbios name */ - name_mangle(netbiosname, buf+4, 0x20); + char *mangled = name_mangle( + talloc_tos(), netbiosname, 0x20); + if (mangled != NULL) { + /* replace the destination netbios + * name */ + memcpy(buf+4, mangled, + name_len(mangled)); + TALLOC_FREE(mangled); + } } } return; -- cgit From c50233695e002d9f7c872821f7b90cdea632dd30 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:47:54 +0100 Subject: Add tevent_req_is_unix_error --- lib/util/tevent_unix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ lib/util/tevent_unix.h | 27 +++++++++++++++++++++++++++ source3/Makefile.in | 3 ++- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 lib/util/tevent_unix.c create mode 100644 lib/util/tevent_unix.h diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c new file mode 100644 index 0000000000..b89d5cd4d4 --- /dev/null +++ b/lib/util/tevent_unix.c @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 2009 + + 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 . +*/ + +#include "tevent_unix.h" +#include "../replace/replace.h" + +bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) +{ + enum tevent_req_state state; + uint64_t err; + + if (!tevent_req_is_error(req, &state, &err)) { + return false; + } + switch (state) { + case TEVENT_REQ_TIMED_OUT: + *perrno = ETIMEDOUT; + break; + case TEVENT_REQ_NO_MEMORY: + *perrno = ENOMEM; + break; + case TEVENT_REQ_USER_ERROR: + *perrno = err; + break; + default: + *perrno = EINVAL; + break; + } + return true; +} diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h new file mode 100644 index 0000000000..dc3ffaef33 --- /dev/null +++ b/lib/util/tevent_unix.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + Wrap unix errno around tevent_req + Copyright (C) Volker Lendecke 2009 + + 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 . +*/ + +#ifndef _TEVENT_UNIX_H +#define _TEVENT_UNIX_H + +#include "../tevent/tevent.h" + +bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno); + +#endif diff --git a/source3/Makefile.in b/source3/Makefile.in index 4cd25c8cee..73b2989421 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -339,7 +339,8 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/util.o ../lib/util/fsusage.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ - ../lib/util/become_daemon.o ../lib/util/system.o + ../lib/util/become_daemon.o ../lib/util/system.o \ + ../lib/util/tevent_unix.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ -- cgit From 70814474f55befc1617e1162a23d14838ba451a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:48:46 +0100 Subject: tevent.h requires bool and uint[16|32|64]_t --- lib/tevent/tevent.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 16fac7327f..33747f0986 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -31,6 +31,7 @@ #include #include #include +#include <../lib/replace/replace.h> struct tevent_context; struct tevent_ops; -- cgit From 39976035ebd669d168afa91274d7e368305bf69d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 19:49:18 +0100 Subject: Convert async_connect to tevent_req --- lib/async_req/async_sock.c | 54 ++++++++++++++++++++-------------------- lib/async_req/async_sock.h | 11 ++++---- source3/lib/util_sock.c | 29 ++++++++++++---------- source3/lib/wbclient.c | 62 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 93 insertions(+), 63 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 02ae880683..f5e3e5ba33 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -22,6 +22,7 @@ #include "lib/tevent/tevent.h" #include "lib/async_req/async_req.h" #include "lib/async_req/async_sock.h" +#include "lib/util/tevent_unix.h" #include #ifndef TALLOC_FREE @@ -633,17 +634,18 @@ static void async_connect_connected(struct tevent_context *ev, * connect in an async state. This will be reset when the request is finished. */ -struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len) +struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len) { - struct async_req *result; + struct tevent_req *result; struct async_connect_state *state; struct tevent_fd *fde; - if (!async_req_setup(mem_ctx, &result, &state, - struct async_connect_state)) { + result = tevent_req_create( + mem_ctx, &state, struct async_connect_state); + if (result == NULL) { return NULL; } @@ -664,8 +666,8 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, state->result = connect(fd, address, address_len); if (state->result == 0) { - state->sys_errno = 0; - goto post_status; + errno = 0; + goto post_errno; } /** @@ -686,22 +688,20 @@ struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, async_connect_connected, result); if (fde == NULL) { - state->sys_errno = ENOMEM; - goto post_status; + errno = ENOMEM; + goto post_errno; } return result; post_errno: state->sys_errno = errno; - post_status: fcntl(fd, F_SETFL, state->old_sockflags); - if (!async_post_error(result, ev, state->sys_errno)) { - goto fail; + if (state->sys_errno == 0) { + tevent_req_done(result); + } else { + tevent_req_error(result, state->sys_errno); } - return result; - fail: - TALLOC_FREE(result); - return NULL; + return tevent_req_post(result, ev); } /** @@ -716,10 +716,10 @@ static void async_connect_connected(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *priv) { - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); + struct tevent_req *req = talloc_get_type_abort( + priv, struct tevent_req); struct async_connect_state *state = talloc_get_type_abort( - req->private_data, struct async_connect_state); + req->private_state, struct async_connect_state); TALLOC_FREE(fde); @@ -743,27 +743,27 @@ static void async_connect_connected(struct tevent_context *ev, DEBUG(10, ("connect returned %s\n", strerror(errno))); fcntl(state->fd, F_SETFL, state->old_sockflags); - async_req_error(req, state->sys_errno); + tevent_req_error(req, state->sys_errno); return; } state->sys_errno = 0; - async_req_done(req); + tevent_req_done(req); } -int async_connect_recv(struct async_req *req, int *perrno) +int async_connect_recv(struct tevent_req *req, int *perrno) { struct async_connect_state *state = talloc_get_type_abort( - req->private_data, struct async_connect_state); + req->private_state, struct async_connect_state); int err; fcntl(state->fd, F_SETFL, state->old_sockflags); - - if (async_req_is_errno(req, &err)) { + if (tevent_req_is_unix_error(req, &err)) { *perrno = err; return -1; } + if (state->sys_errno == 0) { return 0; } diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index c8739e9ed6..784571ed5a 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -35,11 +35,12 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); -struct async_req *async_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const struct sockaddr *address, - socklen_t address_len); -int async_connect_recv(struct async_req *req, int *perrno); + +struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const struct sockaddr *address, + socklen_t address_len); +int async_connect_recv(struct tevent_req *req, int *perrno); struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buffer, size_t length, diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index c46aa2ac49..83e8a9d355 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -953,7 +953,7 @@ struct open_socket_out_state { int wait_nsec; }; -static void open_socket_out_connected(struct async_req *subreq); +static void open_socket_out_connected(struct tevent_req *subreq); static int open_socket_out_state_destructor(struct open_socket_out_state *s) { @@ -974,7 +974,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, int timeout) { char addr[INET6_ADDRSTRLEN]; - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct open_socket_out_state *state; NTSTATUS status; @@ -1026,13 +1027,14 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, (struct sockaddr *)&state->ss, state->salen); if ((subreq == NULL) - || !async_req_set_timeout(subreq, state->ev, - timeval_set(0, state->wait_nsec))) { + || !tevent_req_set_endtime( + subreq, state->ev, + timeval_current_ofs(0, state->wait_nsec))) { status = NT_STATUS_NO_MEMORY; goto post_status; } subreq->async.fn = open_socket_out_connected; - subreq->async.priv = result; + subreq->async.private_data = result; return result; post_status: @@ -1045,18 +1047,18 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, return NULL; } -static void open_socket_out_connected(struct async_req *subreq) +static void open_socket_out_connected(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct open_socket_out_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_state); - int err; + int ret; int sys_errno; - err = async_connect_recv(subreq, &sys_errno); + ret = async_connect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); - if (err == 0) { + if (ret == 0) { async_req_done(req); return; } @@ -1083,13 +1085,14 @@ static void open_socket_out_connected(struct async_req *subreq) if (async_req_nomem(subreq, req)) { return; } - if (!async_req_set_timeout(subreq, state->ev, - timeval_set(0, state->wait_nsec))) { + if (!tevent_req_set_endtime( + subreq, state->ev, + timeval_current_ofs(0, state->wait_nsec))) { async_req_error(req, ENOMEM); return; } subreq->async.fn = open_socket_out_connected; - subreq->async.priv = req; + subreq->async.private_data = req; return; } diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index 4d3a609530..b8d55a944a 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -147,17 +147,30 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) return result; } +struct wb_connect_state { + int dummy; +}; + +static void wbc_connect_connected(struct tevent_req *subreq); + static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct wb_context *wb_ctx, - const char *dir) + struct tevent_context *ev, + struct wb_context *wb_ctx, + const char *dir) { - struct async_req *req; + struct async_req *result; + struct tevent_req *subreq; + struct wb_connect_state *state; struct sockaddr_un sunaddr; struct stat st; char *path = NULL; wbcErr wbc_err; + if (!async_req_setup(mem_ctx, &result, &state, + struct wb_connect_state)) { + return NULL; + } + if (wb_ctx->fd != -1) { close(wb_ctx->fd); wb_ctx->fd = -1; @@ -205,33 +218,46 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, goto post_status; } - req = async_connect_send(mem_ctx, ev, wb_ctx->fd, - (struct sockaddr *)&sunaddr, - sizeof(sunaddr)); - if (req == NULL) { + subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd, + (struct sockaddr *)&sunaddr, + sizeof(sunaddr)); + if (subreq == NULL) { goto nomem; } - if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) { - TALLOC_FREE(req); + subreq->async.fn = wbc_connect_connected; + subreq->async.private_data = result; + + if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) { goto nomem; } - return req; + return result; nomem: wbc_err = WBC_ERR_NO_MEMORY; post_status: - req = async_req_new(mem_ctx); - if (req == NULL) { - return NULL; - } - if (async_post_error(req, ev, wbc_err)) { - return req; + if (async_post_error(result, ev, wbc_err)) { + return result; } - TALLOC_FREE(req); + TALLOC_FREE(result); return NULL; } +static void wbc_connect_connected(struct tevent_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.private_data, struct async_req); + int res, err; + + res = async_connect_recv(subreq, &err); + TALLOC_FREE(subreq); + if (res == -1) { + async_req_error(req, map_wbc_err_from_errno(err)); + return; + } + async_req_done(req); +} + static wbcErr wb_connect_recv(struct async_req *req) { return async_req_simple_recv_wbcerr(req); -- cgit From 76c6330dfb78e536bc7620719d12859ff7418c36 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 20:16:32 +0100 Subject: Add async writev --- lib/async_req/async_sock.c | 105 +++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 4 ++ 2 files changed, 109 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index f5e3e5ba33..380fea5908 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -771,3 +771,108 @@ int async_connect_recv(struct tevent_req *req, int *perrno) *perrno = state->sys_errno; return -1; } + +struct writev_state { + struct tevent_context *ev; + int fd; + struct iovec *iov; + int count; + size_t total_size; +}; + +static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, struct iovec *iov, int count) +{ + struct tevent_req *result; + struct writev_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct writev_state); + if (result == NULL) { + return NULL; + } + state->ev = ev; + state->fd = fd; + state->total_size = 0; + state->count = count; + state->iov = (struct iovec *)talloc_memdup( + state, iov, sizeof(struct iovec) * count); + if (state->iov == NULL) { + goto fail; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, writev_handler, + result); + if (fde == NULL) { + goto fail; + } + return result; + + fail: + TALLOC_FREE(result); + return NULL; +} + +static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct writev_state *state = talloc_get_type_abort( + req->private_state, struct writev_state); + size_t to_write, written; + int i; + + to_write = 0; + + for (i=0; icount; i++) { + to_write += state->iov[i].iov_len; + } + + written = sys_writev(state->fd, state->iov, state->count); + if (written == -1) { + tevent_req_error(req, errno); + return; + } + if (written == 0) { + tevent_req_error(req, EOF); + return; + } + state->total_size += written; + + if (written == to_write) { + tevent_req_done(req); + return; + } + + /* + * We've written less than we were asked to, drop stuff from + * state->iov. + */ + + while (written > 0) { + if (written < state->iov[0].iov_len) { + state->iov[0].iov_base = + (char *)state->iov[0].iov_base + written; + state->iov[0].iov_len -= written; + break; + } + written = state->iov[0].iov_len; + state->iov += 1; + state->count -= 1; + } +} + +ssize_t writev_recv(struct tevent_req *req, int *perrno) +{ + struct writev_state *state = talloc_get_type_abort( + req->private_state, struct writev_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->total_size; +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 784571ed5a..3d70673c17 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -52,4 +52,8 @@ struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int flags); ssize_t recvall_recv(struct async_req *req, int *perr); +struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + int fd, struct iovec *iov, int count); +ssize_t writev_recv(struct tevent_req *req, int *perrno); + #endif -- cgit From 53b059fc52c0908d4f8cbc98510b10d96850dcc6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 21:41:57 +0100 Subject: Use async writev in wb_req_write --- source3/lib/wb_reqtrans.c | 74 ++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 52 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 9bf6f29105..1c2d09318d 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -237,90 +237,60 @@ wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, } struct req_write_state { - struct winbindd_request *wb_req; - struct tevent_context *ev; - int fd; + struct iovec iov[2]; }; -static void wb_req_write_main(struct async_req *subreq); -static void wb_req_write_extra(struct async_req *subreq); +static void wb_req_write_done(struct tevent_req *subreq); struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct winbindd_request *wb_req) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct req_write_state *state; + int count = 1; if (!async_req_setup(mem_ctx, &result, &state, struct req_write_state)) { return NULL; } - state->fd = fd; - state->ev = ev; - state->wb_req = wb_req; - subreq = sendall_send(state, state->ev, state->fd, state->wb_req, - sizeof(struct winbindd_request), 0); - if (subreq == NULL) { - goto nomem; + state->iov[0].iov_base = wb_req; + state->iov[0].iov_len = sizeof(struct winbindd_request); + + if (wb_req->extra_len != 0) { + state->iov[1].iov_base = wb_req->extra_data.data; + state->iov[1].iov_len = wb_req->extra_len; + count = 2; } - subreq->async.fn = wb_req_write_main; - subreq->async.priv = result; + subreq = writev_send(state, ev, fd, state->iov, count); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = wb_req_write_done; + subreq->async.private_data = result; return result; - nomem: + fail: TALLOC_FREE(result); return NULL; } -static void wb_req_write_main(struct async_req *subreq) +static void wb_req_write_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct req_write_state *state = talloc_get_type_abort( - req->private_data, struct req_write_state); + subreq->async.private_data, struct async_req); int err; ssize_t ret; - ret = sendall_recv(subreq, &err); + ret = writev_recv(subreq, &err); TALLOC_FREE(subreq); if (ret < 0) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - - if (state->wb_req->extra_len == 0) { - async_req_done(req); - return; - } - - subreq = sendall_send(state, state->ev, state->fd, - state->wb_req->extra_data.data, - state->wb_req->extra_len, 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_req_write_extra; - subreq->async.priv = req; -} - -static void wb_req_write_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; - - ret = sendall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; - } - async_req_done(req); } -- cgit From ae1a0b553414dafbe7a0aa38581a352b202e1411 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 21:55:03 +0100 Subject: Use async writev for wb_resp_write --- source3/lib/wb_reqtrans.c | 76 ++++++++++++++--------------------------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 1c2d09318d..1be7239092 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -451,91 +451,61 @@ wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, } struct resp_write_state { - struct winbindd_response *wb_resp; - struct tevent_context *ev; - int fd; + struct iovec iov[2]; }; -static void wb_resp_write_main(struct async_req *subreq); -static void wb_resp_write_extra(struct async_req *subreq); +static void wb_resp_write_done(struct tevent_req *subreq); struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct winbindd_response *wb_resp) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct resp_write_state *state; + int count = 1; if (!async_req_setup(mem_ctx, &result, &state, struct resp_write_state)) { return NULL; } - state->fd = fd; - state->ev = ev; - state->wb_resp = wb_resp; - subreq = sendall_send(state, state->ev, state->fd, state->wb_resp, - sizeof(struct winbindd_response), 0); - if (subreq == NULL) { - goto nomem; + state->iov[0].iov_base = wb_resp; + state->iov[0].iov_len = sizeof(struct winbindd_response); + + if (wb_resp->length > sizeof(struct winbindd_response)) { + state->iov[1].iov_base = wb_resp->extra_data.data; + state->iov[1].iov_len = + wb_resp->length - sizeof(struct winbindd_response); + count = 2; } - subreq->async.fn = wb_resp_write_main; - subreq->async.priv = result; + subreq = writev_send(state, ev, fd, state->iov, count); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = wb_resp_write_done; + subreq->async.private_data = result; return result; - nomem: + fail: TALLOC_FREE(result); return NULL; } -static void wb_resp_write_main(struct async_req *subreq) +static void wb_resp_write_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct resp_write_state *state = talloc_get_type_abort( - req->private_data, struct resp_write_state); + subreq->async.private_data, struct async_req); int err; ssize_t ret; - ret = sendall_recv(subreq, &err); + ret = writev_recv(subreq, &err); TALLOC_FREE(subreq); if (ret < 0) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - - if (state->wb_resp->length == sizeof(struct winbindd_response)) { - async_req_done(req); - return; - } - - subreq = sendall_send( - state, state->ev, state->fd, - state->wb_resp->extra_data.data, - state->wb_resp->length - sizeof(struct winbindd_response), 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_resp_write_extra; - subreq->async.priv = req; -} - -static void wb_resp_write_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; - - ret = sendall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (err < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; - } - async_req_done(req); } -- cgit From 70f788ba7ea7ffa4d0808d0a299d98ee894a89a2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 22:01:35 +0100 Subject: Use async_writev in np_write --- source3/rpc_server/srv_pipe_hnd.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 6dead2d264..d33d7f64b2 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1171,13 +1171,12 @@ NTSTATUS np_open(TALLOC_CTX *mem_ctx, const char *name, struct np_write_state { struct event_context *ev; struct np_proxy_state *p; - const uint8_t *data; - size_t len; + struct iovec iov; ssize_t nwritten; }; static void np_write_trigger(struct async_req *req); -static void np_write_done(struct async_req *subreq); +static void np_write_done(struct tevent_req *subreq); struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct fake_file_handle *handle, @@ -1218,8 +1217,8 @@ struct async_req *np_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->ev = ev; state->p = p; - state->data = data; - state->len = len; + state->iov.iov_base = CONST_DISCARD(void *, data); + state->iov.iov_len = len; if (!async_req_enqueue(p->write_queue, ev, result, np_write_trigger)) { @@ -1242,27 +1241,26 @@ static void np_write_trigger(struct async_req *req) { struct np_write_state *state = talloc_get_type_abort( req->private_data, struct np_write_state); - struct async_req *subreq; + struct tevent_req *subreq; - subreq = sendall_send(state, state->ev, state->p->fd, state->data, - state->len, 0); + subreq = writev_send(state, state->ev, state->p->fd, &state->iov, 1); if (async_req_nomem(subreq, req)) { return; } subreq->async.fn = np_write_done; - subreq->async.priv = req; + subreq->async.private_data = req; } -static void np_write_done(struct async_req *subreq) +static void np_write_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct np_write_state *state = talloc_get_type_abort( req->private_data, struct np_write_state); ssize_t received; int err; - received = sendall_recv(subreq, &err); + received = writev_recv(subreq, &err); if (received < 0) { async_req_nterror(req, map_nt_error_from_unix(err)); return; -- cgit From e50075a5804204068f07cb82337d3a251b368245 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 22:03:06 +0100 Subject: Remove async sendall --- lib/async_req/async_sock.c | 111 --------------------------------------------- lib/async_req/async_sock.h | 5 -- 2 files changed, 116 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 380fea5908..33f8ebe192 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -34,7 +34,6 @@ */ enum async_syscall_type { ASYNC_SYSCALL_SEND, - ASYNC_SYSCALL_SENDALL, ASYNC_SYSCALL_RECV, ASYNC_SYSCALL_RECVALL, ASYNC_SYSCALL_CONNECT @@ -55,13 +54,6 @@ struct async_syscall_state { size_t length; int flags; } param_send; - struct param_sendall { - int fd; - const void *buffer; - size_t length; - int flags; - size_t sent; - } param_sendall; struct param_recv { int fd; void *buffer; @@ -337,109 +329,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "sendall" syscall group - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the send - * @param[in] flags Can only be TEVENT_FD_WRITE here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_sendall_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_sendall *p = &state->param.param_sendall; - - if (state->syscall_type != ASYNC_SYSCALL_SENDALL) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = send(p->fd, - (const char *)p->buffer + p->sent, - p->length - p->sent, p->flags); - state->sys_errno = errno; - - if (state->result.result_ssize_t == -1) { - async_req_error(req, state->sys_errno); - return; - } - - if (state->result.result_ssize_t == 0) { - async_req_error(req, EOF); - return; - } - - p->sent += state->result.result_ssize_t; - if (p->sent > p->length) { - async_req_error(req, EIO); - return; - } - - if (p->sent == p->length) { - TALLOC_FREE(state->fde); - async_req_done(req); - } -} - -/** - * @brief Send all bytes to a socket - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to send to - * @param[in] buffer The buffer to send - * @param[in] length How many bytes to send - * @param[in] flags flags passed to send(2) - * - * async_sendall calls send(2) as long as it is necessary to send all of the - * "length" bytes - */ - -struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_SENDALL, - fd, TEVENT_FD_WRITE, async_sendall_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_sendall.fd = fd; - state->param.param_sendall.buffer = buffer; - state->param.param_sendall.length = length; - state->param.param_sendall.flags = flags; - state->param.param_sendall.sent = 0; - - return result; -} - -ssize_t sendall_recv(struct async_req *req, int *perr) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - int err; - - err = async_req_simple_recv_errno(req); - - if (err != 0) { - *perr = err; - return -1; - } - - return state->result.result_ssize_t; -} - /** * fde event handler for the "recv" syscall * @param[in] ev The event context that sent us here diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 3d70673c17..6a862c45c6 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,11 +42,6 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, socklen_t address_len); int async_connect_recv(struct tevent_req *req, int *perrno); -struct async_req *sendall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags); -ssize_t sendall_recv(struct async_req *req, int *perr); - struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); -- cgit From f9df355befdef7c424ebc70abfeb696de095235e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:12:56 +0100 Subject: Fix async writev --- lib/async_req/async_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 33f8ebe192..67776ff67f 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -727,7 +727,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, return; } if (written == 0) { - tevent_req_error(req, EOF); + tevent_req_error(req, EPIPE); return; } state->total_size += written; -- cgit From 4021029cddddcb23c41cd7f8b711f3a8d83c3931 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:13:34 +0100 Subject: Add async read_packet --- lib/async_req/async_sock.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 10 ++++ 2 files changed, 128 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 67776ff67f..02e4c9eb4b 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -765,3 +765,121 @@ ssize_t writev_recv(struct tevent_req *req, int *perrno) } return state->total_size; } + +struct read_packet_state { + int fd; + uint8_t *buf; + size_t nread; + ssize_t (*more)(uint8_t *buf, size_t buflen, void *private_data); + void *private_data; +}; + +static void read_packet_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t initial, + ssize_t (*more)(uint8_t *buf, + size_t buflen, + void *private_data), + void *private_data) +{ + struct tevent_req *result; + struct read_packet_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct read_packet_state); + if (result == NULL) { + return NULL; + } + state->fd = fd; + state->nread = 0; + state->more = more; + state->private_data = private_data; + + state->buf = talloc_array(state, uint8_t, initial); + if (state->buf == NULL) { + goto fail; + } + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_packet_handler, + result); + if (fde == NULL) { + goto fail; + } + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void read_packet_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct read_packet_state *state = talloc_get_type_abort( + req->private_state, struct read_packet_state); + size_t total = talloc_get_size(state->buf); + ssize_t nread, more; + uint8_t *tmp; + + nread = read(state->fd, state->buf+state->nread, total-state->nread); + if (nread == -1) { + tevent_req_error(req, errno); + return; + } + if (nread == 0) { + tevent_req_error(req, EPIPE); + return; + } + + state->nread += nread; + if (state->nread < total) { + /* Come back later */ + return; + } + + /* + * We got what was initially requested. See if "more" asks for -- more. + */ + if (state->more == NULL) { + /* Nobody to ask, this is a async read_data */ + tevent_req_done(req); + return; + } + + more = state->more(state->buf, total, state->private_data); + if (more == -1) { + /* We got an invalid packet, tell the caller */ + tevent_req_error(req, EIO); + return; + } + if (more == 0) { + /* We're done, full packet received */ + tevent_req_done(req); + return; + } + + tmp = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, total+more); + if (tevent_req_nomem(tmp, req)) { + return; + } + state->buf = tmp; +} + +ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno) +{ + struct read_packet_state *state = talloc_get_type_abort( + req->private_state, struct read_packet_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + *pbuf = talloc_move(mem_ctx, &state->buf); + return talloc_get_size(*pbuf); +} diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 6a862c45c6..0cf4e4ecf5 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -51,4 +51,14 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct iovec *iov, int count); ssize_t writev_recv(struct tevent_req *req, int *perrno); +struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t initial, + ssize_t (*more)(uint8_t *buf, + size_t buflen, + void *private_data), + void *private_data); +ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno); + #endif -- cgit From 5d653f69de27ee22137333bc319ae2d7e60e56b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:17:15 +0100 Subject: Replace read_pkt by read_packet in np_read --- source3/rpc_server/srv_pipe_hnd.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index d33d7f64b2..33e89c8acb 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1314,7 +1314,7 @@ struct np_read_state { }; static void np_read_trigger(struct async_req *req); -static void np_read_done(struct async_req *subreq); +static void np_read_done(struct tevent_req *subreq); struct async_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct fake_file_handle *handle, @@ -1391,28 +1391,28 @@ static void np_read_trigger(struct async_req *req) { struct np_read_state *state = talloc_get_type_abort( req->private_data, struct np_read_state); - struct async_req *subreq; + struct tevent_req *subreq; - subreq = read_pkt_send(state, state->ev, state->p->fd, RPC_HEADER_LEN, - rpc_frag_more_fn, NULL); + subreq = read_packet_send(state, state->ev, state->p->fd, + RPC_HEADER_LEN, rpc_frag_more_fn, NULL); if (async_req_nomem(subreq, req)) { return; } subreq->async.fn = np_read_done; - subreq->async.priv = req; + subreq->async.private_data = req; } -static void np_read_done(struct async_req *subreq) +static void np_read_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct np_read_state *state = talloc_get_type_abort( req->private_data, struct np_read_state); ssize_t received; size_t thistime; int err; - received = read_pkt_recv(subreq, state->p, &state->p->msg, &err); + received = read_packet_recv(subreq, state->p, &state->p->msg, &err); TALLOC_FREE(subreq); if (received == -1) { async_req_nterror(req, map_nt_error_from_unix(err)); -- cgit From 202a31d96d9abaf09716bad4c57caf38ef03cc81 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Feb 2009 23:18:04 +0100 Subject: Remove read_pkt --- source3/include/proto.h | 9 ----- source3/lib/util.c | 99 ------------------------------------------------- 2 files changed, 108 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 87dac3e496..daeef637ca 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1243,15 +1243,6 @@ bool is_valid_policy_hnd(const POLICY_HND *hnd); bool policy_hnd_equal(const struct policy_handle *hnd1, const struct policy_handle *hnd2); const char *strip_hostname(const char *s); -struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - int fd, size_t initial, - ssize_t (*more)(uint8_t *buf, size_t buflen, - void *priv), - void *priv); -ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx, - uint8_t **pbuf, int *perr); - /* The following definitions come from lib/util_file.c */ diff --git a/source3/lib/util.c b/source3/lib/util.c index cda1fb474d..89f7be8e6c 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -3145,102 +3145,3 @@ const char *strip_hostname(const char *s) return s; } - -struct read_pkt_state { - struct event_context *ev; - int fd; - uint8_t *buf; - ssize_t (*more)(uint8_t *buf, size_t buflen, void *priv); - void *priv; -}; - -static void read_pkt_done(struct async_req *subreq); - -struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - int fd, size_t initial, - ssize_t (*more)(uint8_t *buf, size_t buflen, - void *priv), - void *priv) -{ - struct async_req *result, *subreq; - struct read_pkt_state *state; - - if (!async_req_setup(mem_ctx, &result, &state, - struct read_pkt_state)) { - return NULL; - } - state->ev = ev; - state->fd = fd; - state->more = more; - - state->buf = talloc_array(state, uint8_t, initial); - if (state->buf == NULL) { - goto fail; - } - subreq = recvall_send(state, ev, fd, state->buf, initial, 0); - if (subreq == NULL) { - goto fail; - } - subreq->async.fn = read_pkt_done; - subreq->async.priv = result; - return result; - fail: - TALLOC_FREE(result); - return NULL; -} - -static void read_pkt_done(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct read_pkt_state *state = talloc_get_type_abort( - req->private_data, struct read_pkt_state); - size_t current_size; - ssize_t received; - ssize_t more; - int err; - - received = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (received == -1) { - async_req_error(req, err); - return; - } - current_size = talloc_get_size(state->buf); - - more = state->more(state->buf, current_size, state->priv); - if (more < 0) { - async_req_error(req, EIO); - return; - } - if (more == 0) { - async_req_done(req); - return; - } - state->buf = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, - current_size + more); - if (async_req_nomem(state->buf, req)) { - return; - } - subreq = recvall_send(state, state->ev, state->fd, - state->buf + current_size, more, 0); - if (async_req_nomem(subreq, req)) { - return; - } - subreq->async.fn = read_pkt_done; - subreq->async.priv = req; -} - -ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx, - uint8_t **pbuf, int *perr) -{ - struct read_pkt_state *state = talloc_get_type_abort( - req->private_data, struct read_pkt_state); - - if (async_req_is_errno(req, perr)) { - return -1; - } - *pbuf = talloc_move(mem_ctx, &state->buf); - return talloc_get_size(*pbuf); -} -- cgit From 008901827058251a31de99426858f87c77bcf23b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:06:56 +0100 Subject: Use read_packet for wb_req_read --- source3/lib/wb_reqtrans.c | 128 +++++++++++++--------------------------------- 1 file changed, 36 insertions(+), 92 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 1be7239092..76b0f53717 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -27,9 +27,7 @@ struct req_read_state { struct winbindd_request *wb_req; - struct tevent_context *ev; size_t max_extra_data; - int fd; }; bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err) @@ -83,145 +81,91 @@ wbcErr async_req_simple_recv_wbcerr(struct async_req *req) return WBC_ERR_SUCCESS; } -static void wb_req_read_len(struct async_req *subreq); -static void wb_req_read_main(struct async_req *subreq); -static void wb_req_read_extra(struct async_req *subreq); +static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data); +static void wb_req_read_done(struct tevent_req *subreq); struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, size_t max_extra_data) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct req_read_state *state; if (!async_req_setup(mem_ctx, &result, &state, struct req_read_state)) { return NULL; } - state->fd = fd; - state->ev = ev; state->max_extra_data = max_extra_data; - state->wb_req = talloc(state, struct winbindd_request); - if (state->wb_req == NULL) { - goto nomem; - } - subreq = recvall_send(state, ev, state->fd, &(state->wb_req->length), - sizeof(state->wb_req->length), 0); + subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state); if (subreq == NULL) { goto nomem; } - subreq->async.fn = wb_req_read_len; - subreq->async.priv = result; + subreq->async.fn = wb_req_read_done; + subreq->async.private_data = result; return result; - nomem: TALLOC_FREE(result); return NULL; } -static void wb_req_read_len(struct async_req *subreq) +static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); struct req_read_state *state = talloc_get_type_abort( - req->private_data, struct req_read_state); - int err; - ssize_t ret; + private_data, struct req_read_state); + struct winbindd_request *req = (struct winbindd_request *)buf; - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; + if (buflen == 4) { + if (req->length != sizeof(struct winbindd_request)) { + DEBUG(0, ("wb_req_read_len: Invalid request size " + "received: %d (expected %d)\n", + (int)req->length, + (int)sizeof(struct winbindd_request))); + return -1; + } + return sizeof(struct winbindd_request) - 4; } - if (state->wb_req->length != sizeof(struct winbindd_request)) { - DEBUG(0, ("wb_req_read_len: Invalid request size received: " - "%d (expected %d)\n", (int)state->wb_req->length, - (int)sizeof(struct winbindd_request))); - async_req_error(req, WBC_ERR_INVALID_RESPONSE); - return; - } - - subreq = recvall_send( - req, state->ev, state->fd, (uint32 *)(state->wb_req)+1, - sizeof(struct winbindd_request) - sizeof(uint32), 0); - if (async_req_nomem(subreq, req)) { - return; + if ((state->max_extra_data != 0) + && (req->extra_len > state->max_extra_data)) { + DEBUG(3, ("Got request with %d bytes extra data on " + "unprivileged socket\n", (int)req->extra_len)); + return -1; } - subreq->async.fn = wb_req_read_main; - subreq->async.priv = req; + return req->extra_len; } -static void wb_req_read_main(struct async_req *subreq) +static void wb_req_read_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct req_read_state *state = talloc_get_type_abort( req->private_data, struct req_read_state); int err; ssize_t ret; + uint8_t *buf; - ret = recvall_recv(subreq, &err); + ret = read_packet_recv(subreq, state, &buf, &err); TALLOC_FREE(subreq); - if (ret < 0) { + if (ret == -1) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - if ((state->max_extra_data != 0) - && (state->wb_req->extra_len > state->max_extra_data)) { - DEBUG(3, ("Got request with %d bytes extra data on " - "unprivileged socket\n", - (int)state->wb_req->extra_len)); - async_req_error(req, WBC_ERR_INVALID_RESPONSE); - return; - } - - if (state->wb_req->extra_len == 0) { - async_req_done(req); - return; - } - - state->wb_req->extra_data.data = TALLOC_ARRAY( - state->wb_req, char, state->wb_req->extra_len + 1); - if (async_req_nomem(state->wb_req->extra_data.data, req)) { - return; - } - - state->wb_req->extra_data.data[state->wb_req->extra_len] = 0; - - subreq = recvall_send( - req, state->ev, state->fd, state->wb_req->extra_data.data, - state->wb_req->extra_len, 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_req_read_extra; - subreq->async.priv = req; -} + state->wb_req = (struct winbindd_request *)buf; -static void wb_req_read_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; - - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; + if (state->wb_req->extra_len != 0) { + state->wb_req->extra_data.data = + (char *)buf + sizeof(struct winbindd_request); + } else { + state->wb_req->extra_data.data = NULL; } async_req_done(req); } - wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, struct winbindd_request **preq) { -- cgit From 5766bf896cf85d17023410addb540ebbbef366dd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:18:29 +0100 Subject: Use read_packet for wb_resp_read --- source3/lib/wb_reqtrans.c | 119 +++++++++++----------------------------------- 1 file changed, 29 insertions(+), 90 deletions(-) diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index 76b0f53717..a5adf8f108 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -245,40 +245,29 @@ wbcErr wb_req_write_recv(struct async_req *req) struct resp_read_state { struct winbindd_response *wb_resp; - struct tevent_context *ev; - size_t max_extra_data; - int fd; }; -static void wb_resp_read_len(struct async_req *subreq); -static void wb_resp_read_main(struct async_req *subreq); -static void wb_resp_read_extra(struct async_req *subreq); +static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data); +static void wb_resp_read_done(struct tevent_req *subreq); struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd) { - struct async_req *result, *subreq; + struct async_req *result; + struct tevent_req *subreq; struct resp_read_state *state; if (!async_req_setup(mem_ctx, &result, &state, struct resp_read_state)) { return NULL; } - state->fd = fd; - state->ev = ev; - state->wb_resp = talloc(state, struct winbindd_response); - if (state->wb_resp == NULL) { - goto nomem; - } - subreq = recvall_send(state, ev, state->fd, &(state->wb_resp->length), - sizeof(state->wb_resp->length), 0); + subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state); if (subreq == NULL) { goto nomem; } - - subreq->async.fn = wb_resp_read_len; - subreq->async.priv = result; + subreq->async.fn = wb_resp_read_done; + subreq->async.private_data = result; return result; nomem: @@ -286,100 +275,50 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, return NULL; } -static void wb_resp_read_len(struct async_req *subreq) +static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct resp_read_state *state = talloc_get_type_abort( - req->private_data, struct resp_read_state); - int err; - ssize_t ret; - - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; - } + struct winbindd_response *resp = (struct winbindd_response *)buf; - if (state->wb_resp->length < sizeof(struct winbindd_response)) { - DEBUG(0, ("wb_resp_read_len: Invalid response size received: " - "%d (expected at least%d)\n", - (int)state->wb_resp->length, - (int)sizeof(struct winbindd_response))); - async_req_error(req, WBC_ERR_INVALID_RESPONSE); - return; - } - - subreq = recvall_send( - req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1, - sizeof(struct winbindd_response) - sizeof(uint32), 0); - if (async_req_nomem(subreq, req)) { - return; + if (buflen == 4) { + if (resp->length < sizeof(struct winbindd_response)) { + DEBUG(0, ("wb_resp_read_len: Invalid response size " + "received: %d (expected at least%d)\n", + (int)resp->length, + (int)sizeof(struct winbindd_response))); + return -1; + } } - - subreq->async.fn = wb_resp_read_main; - subreq->async.priv = req; + return resp->length - 4; } -static void wb_resp_read_main(struct async_req *subreq) +static void wb_resp_read_done(struct tevent_req *subreq) { struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + subreq->async.private_data, struct async_req); struct resp_read_state *state = talloc_get_type_abort( req->private_data, struct resp_read_state); + uint8_t *buf; int err; ssize_t ret; - size_t extra_len; - ret = recvall_recv(subreq, &err); + ret = read_packet_recv(subreq, state, &buf, &err); TALLOC_FREE(subreq); - if (ret < 0) { + if (ret == -1) { async_req_error(req, map_wbc_err_from_errno(err)); return; } - extra_len = state->wb_resp->length - sizeof(struct winbindd_response); - if (extra_len == 0) { - async_req_done(req); - return; - } - - state->wb_resp->extra_data.data = TALLOC_ARRAY( - state->wb_resp, char, extra_len+1); - if (async_req_nomem(state->wb_resp->extra_data.data, req)) { - return; - } - ((char *)state->wb_resp->extra_data.data)[extra_len] = 0; - - subreq = recvall_send( - req, state->ev, state->fd, state->wb_resp->extra_data.data, - extra_len, 0); - if (async_req_nomem(subreq, req)) { - return; - } - - subreq->async.fn = wb_resp_read_extra; - subreq->async.priv = req; -} - -static void wb_resp_read_extra(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - int err; - ssize_t ret; + state->wb_resp = (struct winbindd_response *)buf; - ret = recvall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (ret < 0) { - async_req_error(req, map_wbc_err_from_errno(err)); - return; + if (state->wb_resp->length > sizeof(struct winbindd_response)) { + state->wb_resp->extra_data.data = + (char *)buf + sizeof(struct winbindd_response); + } else { + state->wb_resp->extra_data.data = NULL; } async_req_done(req); } - wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx, struct winbindd_response **presp) { -- cgit From bbbdfa20566a607e0fdfdd190bb12bc3130e8bee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:20:24 +0100 Subject: Remove unused recvall --- lib/async_req/async_sock.c | 110 --------------------------------------------- lib/async_req/async_sock.h | 5 --- 2 files changed, 115 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 02e4c9eb4b..86f89c159a 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -35,7 +35,6 @@ enum async_syscall_type { ASYNC_SYSCALL_SEND, ASYNC_SYSCALL_RECV, - ASYNC_SYSCALL_RECVALL, ASYNC_SYSCALL_CONNECT }; @@ -60,13 +59,6 @@ struct async_syscall_state { size_t length; int flags; } param_recv; - struct param_recvall { - int fd; - void *buffer; - size_t length; - int flags; - size_t received; - } param_recvall; struct param_connect { /** * connect needs to be done on a nonblocking @@ -397,108 +389,6 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "recvall" syscall group - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the recv - * @param[in] flags Can only be TEVENT_FD_READ here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_recvall_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_recvall *p = &state->param.param_recvall; - - if (state->syscall_type != ASYNC_SYSCALL_RECVALL) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = recv(p->fd, - (char *)p->buffer + p->received, - p->length - p->received, p->flags); - state->sys_errno = errno; - - if (state->result.result_ssize_t == -1) { - async_req_error(req, state->sys_errno); - return; - } - - if (state->result.result_ssize_t == 0) { - async_req_error(req, EIO); - return; - } - - p->received += state->result.result_ssize_t; - if (p->received > p->length) { - async_req_error(req, EIO); - return; - } - - if (p->received == p->length) { - TALLOC_FREE(state->fde); - async_req_done(req); - } -} - -/** - * Receive a specified number of bytes from a socket - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to recv from - * @param[in] buffer The buffer to recv into - * @param[in] length How many bytes to recv - * @param[in] flags flags passed to recv(2) - * - * async_recvall will call recv(2) until "length" bytes are received - */ - -struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_RECVALL, - fd, TEVENT_FD_READ, async_recvall_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_recvall.fd = fd; - state->param.param_recvall.buffer = buffer; - state->param.param_recvall.length = length; - state->param.param_recvall.flags = flags; - state->param.param_recvall.received = 0; - - return result; -} - -ssize_t recvall_recv(struct async_req *req, int *perr) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - int err; - - err = async_req_simple_recv_errno(req); - - if (err != 0) { - *perr = err; - return -1; - } - - return state->result.result_ssize_t; -} - struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 0cf4e4ecf5..bfa23d7836 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,11 +42,6 @@ struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, socklen_t address_len); int async_connect_recv(struct tevent_req *req, int *perrno); -struct async_req *recvall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags); -ssize_t recvall_recv(struct async_req *req, int *perr); - struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, struct iovec *iov, int count); ssize_t writev_recv(struct tevent_req *req, int *perrno); -- cgit From 08f028f179f474f83d46b1a23d1cfbd8848b68b0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 00:21:27 +0100 Subject: Remove unused param_connect struct --- lib/async_req/async_sock.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 86f89c159a..7bb52767af 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -35,7 +35,6 @@ enum async_syscall_type { ASYNC_SYSCALL_SEND, ASYNC_SYSCALL_RECV, - ASYNC_SYSCALL_CONNECT }; /** @@ -59,16 +58,6 @@ struct async_syscall_state { size_t length; int flags; } param_recv; - struct param_connect { - /** - * connect needs to be done on a nonblocking - * socket. Keep the old flags around - */ - long old_sockflags; - int fd; - const struct sockaddr *address; - socklen_t address_len; - } param_connect; } param; union { -- cgit From a60480b71ad7cdaa495b7624f04bc477a3330cbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 08:53:01 +0100 Subject: Add more conventional async_send --- lib/async_req/async_sock.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 6 +++++ 2 files changed, 73 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 7bb52767af..323d285729 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -378,6 +378,73 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } +struct async_send_state { + int fd; + const void *buf; + size_t len; + int flags; + ssize_t sent; +}; + +static void async_send_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t len, + int flags) +{ + struct tevent_req *result; + struct async_send_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct async_send_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, async_send_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void async_send_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct async_send_state *state = talloc_get_type_abort( + req->private_state, struct async_send_state); + + state->sent = send(state->fd, state->buf, state->len, state->flags); + if (state->sent == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t async_send_recv(struct tevent_req *req, int *perrno) +{ + struct async_send_state *state = talloc_get_type_abort( + req->private_state, struct async_send_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->sent; +} + struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index bfa23d7836..89dabdac4c 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -36,6 +36,12 @@ struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, void *buffer, size_t length, int flags); +struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t len, + int flags); +ssize_t async_send_recv(struct tevent_req *req, int *perrno); + struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, -- cgit From 25df6d74131b8b9bd8924ca70eb891ff97d3ddfd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Feb 2009 08:56:35 +0100 Subject: Add more conventional async_recv --- lib/async_req/async_sock.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_sock.h | 5 ++++ 2 files changed, 72 insertions(+) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 323d285729..3563421e0e 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -445,6 +445,73 @@ ssize_t async_send_recv(struct tevent_req *req, int *perrno) return state->sent; } +struct async_recv_state { + int fd; + void *buf; + size_t len; + int flags; + ssize_t received; +}; + +static void async_recv_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data); + +struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags) +{ + struct tevent_req *result; + struct async_recv_state *state; + struct tevent_fd *fde; + + result = tevent_req_create(mem_ctx, &state, struct async_recv_state); + if (result == NULL) { + return result; + } + state->fd = fd; + state->buf = buf; + state->len = len; + state->flags = flags; + + fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, async_recv_handler, + result); + if (fde == NULL) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +static void async_recv_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct async_recv_state *state = talloc_get_type_abort( + req->private_state, struct async_recv_state); + + state->received = recv(state->fd, state->buf, state->len, + state->flags); + if (state->received == -1) { + tevent_req_error(req, errno); + return; + } + tevent_req_done(req); +} + +ssize_t async_recv_recv(struct tevent_req *req, int *perrno) +{ + struct async_recv_state *state = talloc_get_type_abort( + req->private_state, struct async_recv_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + return state->received; +} + struct async_connect_state { int fd; int result; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 89dabdac4c..bfc4346d39 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -42,6 +42,11 @@ struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, int flags); ssize_t async_send_recv(struct tevent_req *req, int *perrno); +struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t len, int flags); +ssize_t async_recv_recv(struct tevent_req *req, int *perrno); + struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *address, -- cgit From e3746ac922c29f90d0dbb23a76f5387daf21c8c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Feb 2009 21:08:07 +0100 Subject: Fix some C++ warnings --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 0fa638e863..f1c063ed90 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -47,7 +47,8 @@ struct server_pipe_state { static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerReqChallenge *r) { - struct server_pipe_state *pipe_state = dce_call->context->private_data; + struct server_pipe_state *pipe_state = + (struct server_pipe_state *)dce_call->context->private_data; ZERO_STRUCTP(r->out.return_credentials); @@ -76,7 +77,8 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate3 *r) { - struct server_pipe_state *pipe_state = dce_call->context->private_data; + struct server_pipe_state *pipe_state = + (struct server_pipe_state *)dce_call->context->private_data; struct creds_CredentialState *creds; void *sam_ctx; struct samr_Password *mach_pwd; @@ -148,7 +150,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs, + num_records = gendb_search((struct ldb_context *)sam_ctx, + mem_ctx, NULL, &msgs, + trust_dom_attrs, "(&(trustPartner=%s)(objectclass=trustedDomain))", encoded_account); @@ -179,7 +183,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, + num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, + NULL, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", ldb_binary_encode_string(mem_ctx, account_name)); @@ -848,13 +853,14 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C return WERR_DS_SERVICE_UNAVAILABLE; } - domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx, + domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx, r->in.domainname); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; } @@ -1218,13 +1224,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); } - domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx, + domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx, + mem_ctx, r->in.domain_name); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; } @@ -1377,9 +1385,11 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); + partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx, + mem_ctx); - ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL, + &dom_res, dom_attrs); if (ret == -1) { return WERR_GENERAL_FAILURE; } @@ -1387,7 +1397,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs, + ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, + partitions_basedn, &ref_res, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", ldb_dn_get_linearized(dom_res[0]->dn)); if (ret == -1) { -- cgit From 3a88316e233079199117731756d35d0aea4670e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 12:19:06 -0800 Subject: Fix the build. Looks like no one ever compiled this on a system with a libintl.h before. Jeremy. --- source4/client/mount.cifs.c | 2 ++ source4/heimdal/kuser/kinit.c | 2 ++ source4/heimdal/lib/krb5/context.c | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/source4/client/mount.cifs.c b/source4/client/mount.cifs.c index 7167859d7b..899c90cefd 100644 --- a/source4/client/mount.cifs.c +++ b/source4/client/mount.cifs.c @@ -313,8 +313,10 @@ int main(int argc, char ** argv) FILE * pmntfile; /* setlocale(LC_ALL, ""); +#if defined(LOCALEDIR) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); */ +#endif if(argc && argv) { thisprogram = argv[0]; diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index d1ef776716..fbb2d2287b 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -726,8 +726,10 @@ main (int argc, char **argv) setprogname (argv[0]); setlocale (LC_ALL, ""); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); textdomain("heimdal_kuser"); +#endif ret = krb5_init_context (&context); if (ret == KRB5_CONFIG_BADFORMAT) diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index aa35a184c0..127dfa117d 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -295,7 +295,9 @@ krb5_init_context(krb5_context *context) *context = NULL; /* should have a run_once */ +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR); +#endif p = calloc(1, sizeof(*p)); if(!p) @@ -836,20 +838,30 @@ krb5_init_ets(krb5_context context) { if(context->et_list == NULL){ krb5_add_et_list(context, initialize_krb5_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_asn1_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_heim_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_k524_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR); +#endif #ifdef PKINIT krb5_add_et_list(context, initialize_hx_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR); +#endif #endif } } -- cgit From e4e1b1a0bb2ed333ed42e8cfab0349589a420029 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:18:22 +0100 Subject: s3-spoolss: add rpccli_spoolss_getprinterdriver2 convenience wrapper. Guenther --- source3/include/proto.h | 11 +++++++ source3/rpc_client/cli_spoolss.c | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index daeef637ca..b41a405655 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5465,6 +5465,17 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, const char *printername, uint32_t access_desired, struct policy_handle *handle); +WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *architecture, + uint32_t level, + uint32_t offered, + uint32_t client_major_version, + uint32_t client_minor_version, + union spoolss_DriverInfo *info, + uint32_t *server_major_version, + uint32_t *server_minor_version); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 6ad3af1f4e..b8f17416cc 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -75,6 +75,68 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli, return WERR_OK; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetPrinterDriver2 +**********************************************************************/ + +WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + const char *architecture, + uint32_t level, + uint32_t offered, + uint32_t client_major_version, + uint32_t client_minor_version, + union spoolss_DriverInfo *info, + uint32_t *server_major_version, + uint32_t *server_minor_version) +{ + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx, + handle, + architecture, + level, + (offered > 0) ? &buffer : NULL, + offered, + client_major_version, + client_minor_version, + info, + &needed, + server_major_version, + server_minor_version, + &werror); + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx, + handle, + architecture, + level, + &buffer, + offered, + client_major_version, + client_minor_version, + info, + &needed, + server_major_version, + server_minor_version, + &werror); + } + + return werror; +} + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ -- cgit From e4c1841d1a0b9daa32901f1eb21a3dd504a7677c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:20:30 +0100 Subject: s3-rpcclient: use rpccli_spoolss_getprinterdriver2 wrapper. Guenther --- source3/rpcclient/cmd_spoolss.c | 86 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index bb9d0e6d6c..99838f6396 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -986,6 +986,68 @@ static void display_print_driver_3(DRIVER_INFO_3 *i1) return; } +/**************************************************************************** +****************************************************************************/ + +static void display_print_driver1(struct spoolss_DriverInfo1 *r) +{ + if (!r) { + return; + } + + printf("Printer Driver Info 1:\n"); + printf("\tDriver Name: [%s]\n\n", r->driver_name); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_print_driver2(struct spoolss_DriverInfo2 *r) +{ + if (!r) { + return; + } + + printf("Printer Driver Info 2:\n"); + printf("\tVersion: [%x]\n", r->version); + printf("\tDriver Name: [%s]\n", r->driver_name); + printf("\tArchitecture: [%s]\n", r->architecture); + printf("\tDriver Path: [%s]\n", r->driver_path); + printf("\tDatafile: [%s]\n", r->data_file); + printf("\tConfigfile: [%s]\n\n", r->config_file); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_print_driver3(struct spoolss_DriverInfo3 *r) +{ + int i; + + if (!r) { + return; + } + + printf("Printer Driver Info 3:\n"); + printf("\tVersion: [%x]\n", r->version); + printf("\tDriver Name: [%s]\n", r->driver_name); + printf("\tArchitecture: [%s]\n", r->architecture); + printf("\tDriver Path: [%s]\n", r->driver_path); + printf("\tDatafile: [%s]\n", r->data_file); + printf("\tConfigfile: [%s]\n\n", r->config_file); + printf("\tHelpfile: [%s]\n\n", r->help_file); + + for (i=0; r->dependent_files[i] != NULL; i++) { + printf("\tDependentfiles: [%s]\n", r->dependent_files[i]); + } + + printf("\n"); + + printf("\tMonitorname: [%s]\n", r->monitor_name); + printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype); +} + + /**************************************************************************** ****************************************************************************/ @@ -997,10 +1059,12 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, WERROR werror; uint32 info_level = 3; bool opened_hnd = False; - PRINTER_DRIVER_CTR ctr; const char *printername; uint32 i; bool success = False; + union spoolss_DriverInfo info; + uint32_t server_major_version; + uint32_t server_minor_version; if ((argc == 1) || (argc > 3)) { @@ -1032,10 +1096,16 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, for (i=0; archi_table[i].long_archi!=NULL; i++) { - werror = rpccli_spoolss_getprinterdriver( cli, mem_ctx, &pol, info_level, - archi_table[i].long_archi, archi_table[i].version, - &ctr); - + werror = rpccli_spoolss_getprinterdriver2(cli, mem_ctx, + &pol, + archi_table[i].long_archi, + info_level, + 0, /* offered */ + archi_table[i].version, + 2, + &info, + &server_major_version, + &server_minor_version); if (!W_ERROR_IS_OK(werror)) continue; @@ -1047,13 +1117,13 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, switch (info_level) { case 1: - display_print_driver_1 (ctr.info1); + display_print_driver1(&info.info1); break; case 2: - display_print_driver_2 (ctr.info2); + display_print_driver2(&info.info2); break; case 3: - display_print_driver_3 (ctr.info3); + display_print_driver3(&info.info3); break; default: printf("unknown info level %d\n", info_level); -- cgit From 3ceffcaa467d72890d6148f600ce7c2ddadb63d5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:23:56 +0100 Subject: s3-net: use rpccli_spoolss_AddPrinterDriver and rpccli_spoolss_getprinterdriver2 wrapper. Guenther --- source3/utils/net_rpc_printer.c | 145 ++++++++++++++++++++++++---------------- 1 file changed, 89 insertions(+), 56 deletions(-) diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index bb8747ede3..17df69597f 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -50,6 +50,33 @@ static const struct table_node archi_table[]= { Printer info level 3 display function. ****************************************************************************/ +static void display_print_driver3(struct spoolss_DriverInfo3 *r) +{ + int i; + + if (!r) { + return; + } + + printf("Printer Driver Info 3:\n"); + printf("\tVersion: [%x]\n", r->version); + printf("\tDriver Name: [%s]\n", r->driver_name); + printf("\tArchitecture: [%s]\n", r->architecture); + printf("\tDriver Path: [%s]\n", r->driver_path); + printf("\tDatafile: [%s]\n", r->data_file); + printf("\tConfigfile: [%s]\n\n", r->config_file); + printf("\tHelpfile: [%s]\n\n", r->help_file); + + for (i=0; r->dependent_files[i] != NULL; i++) { + printf("\tDependentfiles: [%s]\n", r->dependent_files[i]); + } + + printf("\n"); + + printf("\tMonitorname: [%s]\n", r->monitor_name); + printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype); +} + static void display_print_driver_3(DRIVER_INFO_3 *i1) { fstring name = ""; @@ -513,7 +540,7 @@ static NTSTATUS net_copy_driverfile(struct net_context *c, TALLOC_CTX *mem_ctx, struct cli_state *cli_share_src, struct cli_state *cli_share_dst, - char *file, const char *short_archi) { + const char *file, const char *short_archi) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; const char *p; @@ -523,6 +550,10 @@ static NTSTATUS net_copy_driverfile(struct net_context *c, char *filename; char *tok; + if (!file) { + return NT_STATUS_OK; + } + /* scroll through the file until we have the part beyond archi_table.short_archi */ p = file; @@ -617,67 +648,47 @@ static NTSTATUS copy_print_driver_3(struct net_context *c, TALLOC_CTX *mem_ctx, struct cli_state *cli_share_src, struct cli_state *cli_share_dst, - const char *short_archi, DRIVER_INFO_3 *i1) + const char *short_archi, + struct spoolss_DriverInfo3 *r) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - int length = 0; - bool valid = true; + int i; - fstring name = ""; - fstring driverpath = ""; - fstring datafile = ""; - fstring configfile = ""; - fstring helpfile = ""; - fstring dependentfiles = ""; - - if (i1 == NULL) + if (r == NULL) { return nt_status; - - rpcstr_pull(name, i1->name.buffer, sizeof(name), -1, STR_TERMINATE); - rpcstr_pull(driverpath, i1->driverpath.buffer, sizeof(driverpath), -1, STR_TERMINATE); - rpcstr_pull(datafile, i1->datafile.buffer, sizeof(datafile), -1, STR_TERMINATE); - rpcstr_pull(configfile, i1->configfile.buffer, sizeof(configfile), -1, STR_TERMINATE); - rpcstr_pull(helpfile, i1->helpfile.buffer, sizeof(helpfile), -1, STR_TERMINATE); - + } if (c->opt_verbose) d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n", - name, short_archi, i1->version); + r->driver_name, short_archi, r->version); nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - driverpath, short_archi); + r->driver_path, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - datafile, short_archi); + r->data_file, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - configfile, short_archi); + r->config_file, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst, - helpfile, short_archi); + r->help_file, short_archi); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; - while (valid) { + for (i=0; r->dependent_files[i] != NULL; i++) { - rpcstr_pull(dependentfiles, i1->dependentfiles+length, sizeof(dependentfiles), -1, STR_TERMINATE); - length += strlen(dependentfiles)+1; - - if (strlen(dependentfiles) > 0) { - - nt_status = net_copy_driverfile(c, mem_ctx, - cli_share_src, cli_share_dst, - dependentfiles, short_archi); - if (!NT_STATUS_IS_OK(nt_status)) - return nt_status; - } else { - valid = false; + nt_status = net_copy_driverfile(c, mem_ctx, + cli_share_src, cli_share_dst, + r->dependent_files[i], short_archi); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; } } @@ -930,15 +941,23 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, const char *env, int version, - PRINTER_DRIVER_CTR *ctr) + union spoolss_DriverInfo *info) { WERROR result; + uint32_t server_major_version; + uint32_t server_minor_version; /* getprinterdriver call */ - result = rpccli_spoolss_getprinterdriver( - pipe_hnd, mem_ctx, hnd, level, - env, version, ctr); - + result = rpccli_spoolss_getprinterdriver2(pipe_hnd, mem_ctx, + hnd, + env, + level, + 0, + version, + 2, + info, + &server_major_version, + &server_minor_version); if (!W_ERROR_IS_OK(result)) { DEBUG(1,("cannot get driver (for architecture: %s): %s\n", env, win_errstr(result))); @@ -955,13 +974,31 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) + union spoolss_DriverInfo *info) { WERROR result; + NTSTATUS status; + struct spoolss_AddDriverInfoCtr info_ctr; - /* addprinterdriver call */ - result = rpccli_spoolss_addprinterdriver(pipe_hnd, mem_ctx, level, ctr); + info_ctr.level = level; + + switch (level) { + case 2: + info_ctr.info.info2 = (struct spoolss_AddDriverInfo2 *)&info->info2; + break; + case 3: + info_ctr.info.info3 = (struct spoolss_AddDriverInfo3 *)&info->info3; + break; + default: + printf("unsupported info level: %d\n", level); + return false; + } + /* addprinterdriver call */ + status = rpccli_spoolss_AddPrinterDriver(pipe_hnd, mem_ctx, + pipe_hnd->srv_name_slash, + &info_ctr, + &result); /* be more verbose */ if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) { printf("You are not allowed to add drivers\n"); @@ -1785,15 +1822,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_DRIVER_CTR drv_ctr_src, drv_ctr_dst; + union spoolss_DriverInfo drv_info_src; PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst; struct cli_state *cli_dst = NULL; struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; - fstring drivername = ""; + const char *drivername = NULL; - ZERO_STRUCT(drv_ctr_src); - ZERO_STRUCT(drv_ctr_dst); ZERO_STRUCT(info_ctr_enum); ZERO_STRUCT(info_ctr_dst); @@ -1890,15 +1925,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* getdriver src */ if (!net_spoolss_getprinterdriver(pipe_hnd, mem_ctx, &hnd_src, level, archi_table[i].long_archi, - archi_table[i].version, &drv_ctr_src)) + archi_table[i].version, &drv_info_src)) continue; - rpcstr_pull(drivername, drv_ctr_src.info3->name.buffer, - sizeof(drivername), -1, STR_TERMINATE); + drivername = drv_info_src.info3.driver_name; if (c->opt_verbose) - display_print_driver_3(drv_ctr_src.info3); - + display_print_driver3(&drv_info_src.info3); /* check arch dir */ nt_status = check_arch_dir(cli_share_dst, archi_table[i].short_archi); @@ -1909,13 +1942,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, /* copy driver-files */ nt_status = copy_print_driver_3(c, mem_ctx, cli_share_src, cli_share_dst, archi_table[i].short_archi, - drv_ctr_src.info3); + &drv_info_src.info3); if (!NT_STATUS_IS_OK(nt_status)) goto done; /* adddriver dst */ - if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_ctr_src)) { + if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_info_src)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } -- cgit From 5ffa03dcd879e59f3e810fbb8833cb9a3e9afcca Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:26:09 +0100 Subject: s3-spoolss: remove old rpccli_spoolss_getprinterdriver wrapper. Guenther --- source3/include/proto.h | 4 -- source3/rpc_client/cli_spoolss.c | 79 --------------------------------------- source3/rpc_parse/parse_spoolss.c | 27 ------------- 3 files changed, 110 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index b41a405655..08840bd7cc 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5487,10 +5487,6 @@ WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr, uint32 command); -WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - const char *env, int version, PRINTER_DRIVER_CTR *ctr); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index b8f17416cc..8a8dabeba4 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -801,85 +801,6 @@ WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getprinterdriver(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - const char *env, int version, PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVER2 in; - SPOOL_R_GETPRINTERDRIVER2 out; - RPC_BUFFER buffer; - fstring server; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - fstrcpy(server, cli->desthost); - strupper_m(server); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinterdriver2( &in, pol, env, level, - version, 2, &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinterdriver2, - spoolss_io_r_getprinterdriver2, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinterdriver2( &in, pol, env, level, - version, 2, &buffer, offered); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTERDRIVER2, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinterdriver2, - spoolss_io_r_getprinterdriver2, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 1: - if (!decode_printer_driver_1(mem_ctx, out.buffer, 1, &ctr->info1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_driver_2(mem_ctx, out.buffer, 1, &ctr->info2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_driver_3(mem_ctx, out.buffer, 1, &ctr->info3)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 435bb1bd80..4ffa121e1c 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -2050,33 +2050,6 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) return size; } -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, - const POLICY_HND *hnd, - const fstring architecture, - uint32 level, uint32 clientmajor, uint32 clientminor, - RPC_BUFFER *buffer, uint32 offered) -{ - if (q_u == NULL) - return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture); - - q_u->level=level; - q_u->clientmajorversion=clientmajor; - q_u->clientminorversion=clientminor; - - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - /******************************************************************* * read a structure. * called from spoolss_getprinterdriver2 (srv_spoolss.c) -- cgit From 9bb1bea53709dd32b8c3bf6032b38d9f95c8c379 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 14:07:29 -0800 Subject: s3: Fix a bug that prevent core files from being created Removed an erroneous free() that was causing the corepath to be NULL during dump_core(). This prevented dump_core() from actually calling abort() to create a core file. The bug was introduced in December by: 07e0094365e8dc360a83eec2e7cf9b1d5d8d6d00 --- source3/lib/fault.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source3/lib/fault.c b/source3/lib/fault.c index a1530987f3..8c4a45bbc9 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -157,7 +157,6 @@ void dump_core_setup(const char *progname) return; } - SAFE_FREE(corepath); SAFE_FREE(logbase); #ifdef HAVE_GETRLIMIT -- cgit From 3777978eb466bf0e5268851f2820f8f91ff1bf85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Feb 2009 00:43:23 +0100 Subject: s3-rpcclient: use rpccli_spoolss_AddPrinterDriver. Guenther --- source3/include/proto.h | 1 - source3/rpcclient/cmd_spoolss.c | 119 +++++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 51 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 08840bd7cc..95c4c1659b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6239,7 +6239,6 @@ bool init_service_op_table( void ); /* The following definitions come from rpcclient/cmd_spoolss.c */ -void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch); /* The following definitions come from rpcclient/cmd_srvsvc.c */ diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 99838f6396..17ff818de6 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1289,7 +1289,9 @@ static WERROR cmd_spoolss_getdriverdir(struct rpc_pipe_client *cli, /**************************************************************************** ****************************************************************************/ -void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) +static void set_drv_info_3_env(TALLOC_CTX *mem_ctx, + struct spoolss_AddDriverInfo3 *info, + const char *arch) { int i; @@ -1299,7 +1301,7 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) if (strcmp(arch, archi_table[i].short_archi) == 0) { info->version = archi_table[i].version; - init_unistr (&info->architecture, archi_table[i].long_archi); + info->architecture = talloc_strdup(mem_ctx, archi_table[i].long_archi); break; } } @@ -1318,8 +1320,9 @@ void set_drv_info_3_env (DRIVER_INFO_3 *info, const char *arch) Needed to handle the empty parameter string denoted by "NULL" *************************************************************************/ -static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest, - char **saveptr) +static char *get_driver_3_param(TALLOC_CTX *mem_ctx, char *str, + const char *delim, const char **dest, + char **saveptr) { char *ptr; @@ -1330,70 +1333,80 @@ static char* get_driver_3_param (char* str, const char* delim, UNISTR* dest, parameter because two consecutive delimiters will not return an empty string. See man strtok(3) for details */ - if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) + if (ptr && (StrCaseCmp(ptr, "NULL") == 0)) { ptr = NULL; + } - if (dest != NULL) - init_unistr(dest, ptr); + if (dest != NULL) { + *dest = talloc_strdup(mem_ctx, ptr); + } return ptr; } /******************************************************************************** - fill in the members of a DRIVER_INFO_3 struct using a character + fill in the members of a spoolss_AddDriverInfo3 struct using a character string in the form of :::\ :::\ : *******************************************************************************/ -static bool init_drv_info_3_members ( TALLOC_CTX *mem_ctx, DRIVER_INFO_3 *info, - char *args ) + +static bool init_drv_info_3_members(TALLOC_CTX *mem_ctx, struct spoolss_AddDriverInfo3 *r, + char *args) { char *str, *str2; - uint32 len, i; + int count = 0; char *saveptr = NULL; + struct spoolss_StringArray *deps; + const char **file_array = NULL; + int i; /* fill in the UNISTR fields */ - str = get_driver_3_param (args, ":", &info->name, &saveptr); - str = get_driver_3_param (NULL, ":", &info->driverpath, &saveptr); - str = get_driver_3_param (NULL, ":", &info->datafile, &saveptr); - str = get_driver_3_param (NULL, ":", &info->configfile, &saveptr); - str = get_driver_3_param (NULL, ":", &info->helpfile, &saveptr); - str = get_driver_3_param (NULL, ":", &info->monitorname, &saveptr); - str = get_driver_3_param (NULL, ":", &info->defaultdatatype, &saveptr); + str = get_driver_3_param(mem_ctx, args, ":", &r->driver_name, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->driver_path, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->data_file, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->config_file, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->help_file, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->monitor_name, &saveptr); + str = get_driver_3_param(mem_ctx, NULL, ":", &r->default_datatype, &saveptr); /* */ /* save the beginning of the string */ - str2 = get_driver_3_param (NULL, ":", NULL, &saveptr); + str2 = get_driver_3_param(mem_ctx, NULL, ":", NULL, &saveptr); str = str2; /* begin to strip out each filename */ str = strtok_r(str, ",", &saveptr); - len = 0; - while (str != NULL) - { - /* keep a cumlative count of the str lengths */ - len += strlen(str)+1; + + /* no dependent files, we are done */ + if (!str) { + return true; + } + + deps = talloc_zero(mem_ctx, struct spoolss_StringArray); + if (!deps) { + return false; + } + + while (str != NULL) { + add_string_to_array(deps, str, &file_array, &count); str = strtok_r(NULL, ",", &saveptr); } - /* allocate the space; add one extra slot for a terminating NULL. - Each filename is NULL terminated and the end contains a double - NULL */ - if ((info->dependentfiles=TALLOC_ARRAY(mem_ctx, uint16, len+1)) == NULL) - { - DEBUG(0,("init_drv_info_3_members: Unable to malloc memory for dependenfiles\n")); - return False; + deps->string = talloc_zero_array(deps, const char *, count + 1); + if (!deps->string) { + return false; } - for (i=0; idependentfiles[i], 0, str2[i]); + + for (i=0; i < count; i++) { + deps->string[i] = file_array[i]; } - info->dependentfiles[len] = '\0'; - return True; -} + r->dependent_files = deps; + return true; +} /**************************************************************************** ****************************************************************************/ @@ -1403,11 +1416,11 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR result; + NTSTATUS status; uint32 level = 3; - PRINTER_DRIVER_CTR ctr; - DRIVER_INFO_3 info3; + struct spoolss_AddDriverInfoCtr info_ctr; + struct spoolss_AddDriverInfo3 info3; const char *arch; - fstring driver_name; char *driver_args; /* parse the command arguments */ @@ -1422,15 +1435,16 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, return WERR_OK; } - /* Fill in the DRIVER_INFO_3 struct */ + /* Fill in the spoolss_AddDriverInfo3 struct */ ZERO_STRUCT(info3); - if (!(arch = cmd_spoolss_get_short_archi(argv[1]))) - { + + arch = cmd_spoolss_get_short_archi(argv[1]); + if (!arch) { printf ("Error Unknown architechture [%s]\n", argv[1]); return WERR_INVALID_PARAM; } - else - set_drv_info_3_env(&info3, arch); + + set_drv_info_3_env(mem_ctx, &info3, arch); driver_args = talloc_strdup( mem_ctx, argv[2] ); if (!init_drv_info_3_members(mem_ctx, &info3, driver_args )) @@ -1448,14 +1462,19 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, } - ctr.info3 = &info3; - result = rpccli_spoolss_addprinterdriver (cli, mem_ctx, level, &ctr); + info_ctr.level = level; + info_ctr.info.info3 = &info3; + status = rpccli_spoolss_AddPrinterDriver(cli, mem_ctx, + cli->srv_name_slash, + &info_ctr, + &result); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } if (W_ERROR_IS_OK(result)) { - rpcstr_pull(driver_name, info3.name.buffer, - sizeof(driver_name), -1, STR_TERMINATE); printf ("Printer Driver %s successfully installed.\n", - driver_name); + info3.driver_name); } return result; -- cgit From b2e038ef8bd78e9ca847bbd0aaaf593cea059b18 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 22:53:05 +0100 Subject: s3-spoolss: remove rpccli_spoolss_addprinterdriver. Guenther --- source3/include/proto.h | 6 --- source3/rpc_client/cli_spoolss.c | 30 ----------- source3/rpc_parse/parse_spoolss.c | 103 -------------------------------------- 3 files changed, 139 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 95c4c1659b..6edad71a99 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5492,9 +5492,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, uint32 level, const char *env, uint32 *num_drivers, PRINTER_DRIVER_CTR *ctr); -WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr); WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR*ctr); WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, @@ -5941,9 +5938,6 @@ bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_I bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, uint32 level, PRINTER_DRIVER_CTR *info); -bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info, - DRIVER_INFO_3 *info3); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 8a8dabeba4..19e9aae0f8 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -886,36 +886,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_addprinterdriver (struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTERDRIVER in; - SPOOL_R_ADDPRINTERDRIVER out; - fstring server; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper_m(server); - - make_spoolss_q_addprinterdriver( mem_ctx, &in, server, level, ctr ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTERDRIVER, - in, out, - qbuf, rbuf, - spoolss_io_q_addprinterdriver, - spoolss_io_r_addprinterdriver, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR*ctr) { diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 4ffa121e1c..9c69dd2659 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -3382,109 +3382,6 @@ bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_I return True; } -/******************************************************************* - init a SPOOL_Q_ADDPRINTERDRIVER struct - ******************************************************************/ - -bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx, - SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, - uint32 level, PRINTER_DRIVER_CTR *info) -{ - DEBUG(5,("make_spoolss_q_addprinterdriver\n")); - - if (!srv_name || !info) { - return False; - } - - q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */ - init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE); - - q_u->level = level; - - q_u->info.level = level; - q_u->info.ptr = 1; /* Info is != NULL, see above */ - switch (level) - { - /* info level 3 is supported by Windows 95/98, WinNT and Win2k */ - case 3 : - make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3); - break; - - default: - DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level)); - break; - } - - return True; -} - -bool make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info, - DRIVER_INFO_3 *info3) -{ - uint32 len = 0; - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf; - - if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3))) - return False; - - inf->cversion = info3->version; - inf->name_ptr = (info3->name.buffer!=NULL)?1:0; - inf->environment_ptr = (info3->architecture.buffer!=NULL)?1:0; - inf->driverpath_ptr = (info3->driverpath.buffer!=NULL)?1:0; - inf->datafile_ptr = (info3->datafile.buffer!=NULL)?1:0; - inf->configfile_ptr = (info3->configfile.buffer!=NULL)?1:0; - inf->helpfile_ptr = (info3->helpfile.buffer!=NULL)?1:0; - inf->monitorname_ptr = (info3->monitorname.buffer!=NULL)?1:0; - inf->defaultdatatype_ptr = (info3->defaultdatatype.buffer!=NULL)?1:0; - - init_unistr2_from_unistr(inf, &inf->name, &info3->name); - init_unistr2_from_unistr(inf, &inf->environment, &info3->architecture); - init_unistr2_from_unistr(inf, &inf->driverpath, &info3->driverpath); - init_unistr2_from_unistr(inf, &inf->datafile, &info3->datafile); - init_unistr2_from_unistr(inf, &inf->configfile, &info3->configfile); - init_unistr2_from_unistr(inf, &inf->helpfile, &info3->helpfile); - init_unistr2_from_unistr(inf, &inf->monitorname, &info3->monitorname); - init_unistr2_from_unistr(inf, &inf->defaultdatatype, &info3->defaultdatatype); - - if (info3->dependentfiles) { - bool done = False; - bool null_char = False; - uint16 *ptr = info3->dependentfiles; - - while (!done) { - switch (*ptr) { - case 0: - /* the null_char bool is used to help locate - two '\0's back to back */ - if (null_char) { - done = True; - } else { - null_char = True; - } - break; - - default: - null_char = False; - break; - } - len++; - ptr++; - } - } - - inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0; - inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0; - if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) { - SAFE_FREE(inf); - return False; - } - - *spool_drv_info = inf; - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ -- cgit From 28fb708ba0bf3c81e54b1f99a8f56d671e62a047 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 24 Feb 2009 23:45:14 +0100 Subject: error-codes: print out WERR_UNKNOWN_PRINT_MONITOR. Guenther --- libcli/util/doserr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c index 226c2f950d..1044ab351a 100644 --- a/libcli/util/doserr.c +++ b/libcli/util/doserr.c @@ -169,6 +169,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_SERVICE_NEVER_STARTED", WERR_SERVICE_NEVER_STARTED }, { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, { "WERR_ACCOUNT_LOCKED_OUT", WERR_ACCOUNT_LOCKED_OUT }, + { "WERR_UNKNOWN_PRINT_MONITOR", WERR_UNKNOWN_PRINT_MONITOR }, { NULL, W_ERROR(0) } }; -- cgit From a028e9640b54554f4ae036f46cc16ae73f00884e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 15:27:47 -0800 Subject: Make S4 build on OpenSolaris. Jeremy. --- source4/lib/tls/config.m4 | 2 ++ source4/lib/tls/config.mk | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/lib/tls/config.m4 b/source4/lib/tls/config.m4 index 0bafc5ddf1..c46a009e3d 100644 --- a/source4/lib/tls/config.m4 +++ b/source4/lib/tls/config.m4 @@ -40,4 +40,6 @@ if test x$use_gnutls = xyes; then AC_CHECK_TYPES([gnutls_datum_t],,,[#include "gnutls/gnutls.h"]) AC_DEFINE(ENABLE_GNUTLS,1,[Whether we have gnutls support (SSL)]) AC_CHECK_HEADERS(gcrypt.h) + AC_CHECK_LIB_EXT(gcrypt, GCRYPT_LIBS, gcry_control) + SMB_EXT_LIB(GCRYPT, $GCRYPT_LIBS) fi diff --git a/source4/lib/tls/config.mk b/source4/lib/tls/config.mk index ff1eedfd5d..0e1978cc1b 100644 --- a/source4/lib/tls/config.mk +++ b/source4/lib/tls/config.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::LIBTLS] PUBLIC_DEPENDENCIES = \ - LIBTALLOC GNUTLS LIBSAMBA-HOSTCONFIG samba_socket + LIBTALLOC GNUTLS GCRYPT LIBSAMBA-HOSTCONFIG samba_socket LIBTLS_OBJ_FILES = $(addprefix $(libtlssrcdir)/, tls.o tlscert.o) -- cgit From b3d53e2ce6da661c3b41f03fdb0ecbe44579b593 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 00:30:14 +0100 Subject: s3-spoolss: remove some left-over hand marshalling code and structs. Guenther --- source3/include/proto.h | 16 -- source3/include/rpc_spoolss.h | 93 ----------- source3/rpc_parse/parse_spoolss.c | 324 -------------------------------------- 3 files changed, 433 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 6edad71a99..9366607995 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5867,11 +5867,6 @@ uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info); uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p); uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); -bool make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, - const POLICY_HND *hnd, - const fstring architecture, - uint32 level, uint32 clientmajor, uint32 clientminor, - RPC_BUFFER *buffer, uint32 offered); bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumprinters( @@ -5929,18 +5924,7 @@ bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth); bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth); -bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, - prs_struct *ps, int depth); -bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, - prs_struct *ps, int depth); -bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth); -bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth); -bool make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx, - SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, - uint32 level, PRINTER_DRIVER_CTR *info); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); -bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, NT_PRINTER_INFO_LEVEL_2 *d); bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 504cfea70b..48609a3cd6 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -945,82 +945,6 @@ typedef struct spool_printer_info_level } SPOOL_PRINTER_INFO_LEVEL; -typedef struct spool_printer_driver_info_level_3 -{ - uint32 cversion; - uint32 name_ptr; - uint32 environment_ptr; - uint32 driverpath_ptr; - uint32 datafile_ptr; - uint32 configfile_ptr; - uint32 helpfile_ptr; - uint32 monitorname_ptr; - uint32 defaultdatatype_ptr; - uint32 dependentfilessize; - uint32 dependentfiles_ptr; - - UNISTR2 name; - UNISTR2 environment; - UNISTR2 driverpath; - UNISTR2 datafile; - UNISTR2 configfile; - UNISTR2 helpfile; - UNISTR2 monitorname; - UNISTR2 defaultdatatype; - BUFFER5 dependentfiles; - -} -SPOOL_PRINTER_DRIVER_INFO_LEVEL_3; - -/* SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure */ -typedef struct { - uint32 version; - uint32 name_ptr; - uint32 environment_ptr; - uint32 driverpath_ptr; - uint32 datafile_ptr; - uint32 configfile_ptr; - uint32 helpfile_ptr; - uint32 monitorname_ptr; - uint32 defaultdatatype_ptr; - uint32 dependentfiles_len; - uint32 dependentfiles_ptr; - uint32 previousnames_len; - uint32 previousnames_ptr; - NTTIME driverdate; - uint64 driverversion; - uint32 dummy4; - uint32 mfgname_ptr; - uint32 oemurl_ptr; - uint32 hardwareid_ptr; - uint32 provider_ptr; - UNISTR2 name; - UNISTR2 environment; - UNISTR2 driverpath; - UNISTR2 datafile; - UNISTR2 configfile; - UNISTR2 helpfile; - UNISTR2 monitorname; - UNISTR2 defaultdatatype; - BUFFER5 dependentfiles; - BUFFER5 previousnames; - UNISTR2 mfgname; - UNISTR2 oemurl; - UNISTR2 hardwareid; - UNISTR2 provider; -} SPOOL_PRINTER_DRIVER_INFO_LEVEL_6; - - -typedef struct spool_printer_driver_info_level -{ - uint32 level; - uint32 ptr; - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3; - SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *info_6; -} -SPOOL_PRINTER_DRIVER_INFO_LEVEL; - - typedef struct spool_q_setprinter { POLICY_HND handle; @@ -1057,23 +981,6 @@ typedef struct { WERROR status; } SPOOL_R_ADDPRINTEREX; -/********************************************/ - -typedef struct spool_q_addprinterdriver -{ - uint32 server_name_ptr; - UNISTR2 server_name; - uint32 level; - SPOOL_PRINTER_DRIVER_INFO_LEVEL info; -} -SPOOL_Q_ADDPRINTERDRIVER; - -typedef struct spool_r_addprinterdriver -{ - WERROR status; -} -SPOOL_R_ADDPRINTERDRIVER; - typedef struct spool_q_enumprintprocessors { uint32 name_ptr; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 9c69dd2659..12c7af49cf 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -3100,288 +3100,6 @@ bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, return True; } -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, - prs_struct *ps, int depth) -{ - SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il; - - prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3"); - depth++; - - /* reading */ - if (UNMARSHALLING(ps)) { - il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1); - if(il == NULL) - return False; - *q_u=il; - } - else { - il=*q_u; - } - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("cversion", ps, depth, &il->cversion)) - return False; - if(!prs_uint32("name", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("environment", ps, depth, &il->environment_ptr)) - return False; - if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr)) - return False; - if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr)) - return False; - if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr)) - return False; - if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr)) - return False; - if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr)) - return False; - if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr)) - return False; - if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize)) - return False; - if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr)) - return False; - - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if (il->dependentfiles_ptr) - smb_io_buffer5("", &il->dependentfiles, ps, depth); - - return True; -} - -/******************************************************************* -parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure -********************************************************************/ - -bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, - prs_struct *ps, int depth) -{ - SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il; - - prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6"); - depth++; - - /* reading */ - if (UNMARSHALLING(ps)) { - il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1); - if(il == NULL) - return False; - *q_u=il; - } - else { - il=*q_u; - } - - if(!prs_align(ps)) - return False; - - /* - * I know this seems weird, but I have no other explanation. - * This is observed behavior on both NT4 and 2K servers. - * --jerry - */ - - if (!prs_align_uint64(ps)) - return False; - - /* parse the main elements the packet */ - - if(!prs_uint32("cversion ", ps, depth, &il->version)) - return False; - if(!prs_uint32("name ", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("environment ", ps, depth, &il->environment_ptr)) - return False; - if(!prs_uint32("driverpath ", ps, depth, &il->driverpath_ptr)) - return False; - if(!prs_uint32("datafile ", ps, depth, &il->datafile_ptr)) - return False; - if(!prs_uint32("configfile ", ps, depth, &il->configfile_ptr)) - return False; - if(!prs_uint32("helpfile ", ps, depth, &il->helpfile_ptr)) - return False; - if(!prs_uint32("monitorname ", ps, depth, &il->monitorname_ptr)) - return False; - if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr)) - return False; - if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len)) - return False; - if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr)) - return False; - if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_len)) - return False; - if(!prs_uint32("previousnames ", ps, depth, &il->previousnames_ptr)) - return False; - if(!smb_io_time("driverdate ", &il->driverdate, ps, depth)) - return False; - if(!prs_uint32("dummy4 ", ps, depth, &il->dummy4)) - return False; - if(!prs_uint64("driverversion ", ps, depth, &il->driverversion)) - return False; - if(!prs_uint32("mfgname ", ps, depth, &il->mfgname_ptr)) - return False; - if(!prs_uint32("oemurl ", ps, depth, &il->oemurl_ptr)) - return False; - if(!prs_uint32("hardwareid ", ps, depth, &il->hardwareid_ptr)) - return False; - if(!prs_uint32("provider ", ps, depth, &il->provider_ptr)) - return False; - - /* parse the structures in the packet */ - - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if (il->dependentfiles_ptr) { - if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - } - if (il->previousnames_ptr) { - if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - } - if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - read a UNICODE array with null terminated strings - and null terminated array - and size of array at beginning -********************************************************************/ - -bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth) -{ - if (buffer==NULL) return False; - - buffer->offset=0; - buffer->uni_str_len=buffer->uni_max_len; - - if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len)) - return False; - - if(!prs_unistr2(True, "buffer ", ps, depth, buffer)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("level", ps, depth, &il->level)) - return False; - if(!prs_uint32("ptr", ps, depth, &il->ptr)) - return False; - - if (il->ptr==0) - return True; - - switch (il->level) { - case 3: - if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth)) - return False; - break; - case 6: - if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth)) - return False; - break; - default: - return False; - } - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ @@ -3406,48 +3124,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 return True; } -/******************************************************************* - fill in the prs_struct for a ADDPRINTERDRIVER request PDU - ********************************************************************/ - -bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr)) - return False; - if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("info_level", ps, depth, &q_u->level)) - return False; - - if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver"); - depth++; - - if(!prs_werror("status", ps, depth, &q_u->status)) - return False; - - return True; -} - /******************************************************************* ********************************************************************/ -- cgit From 503d15e8df9075ea9cf8b2d260487e68fc68f559 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Wed, 25 Feb 2009 10:27:19 +1100 Subject: Updates to the recent cn=config support for the OpenLDAP backend - removed workaround for olcSyncprovConfig - creation (works perfect now with 2.4.15, release was today) - added 1 message-helpline, which is displayed when running provision-backend with olc and/or mmr setup - corrected 1 wrong slapcommand-helpline - slapd.conf is removed now in case of olc-setup - added 1 copyright-line to provision.py and provision-backend Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision.py | 24 ++++++------------------ source4/setup/olcOverlay={0}syncprov.ldif | 11 ----------- source4/setup/provision-backend | 5 +++-- 3 files changed, 9 insertions(+), 31 deletions(-) delete mode 100644 source4/setup/olcOverlay={0}syncprov.ldif diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8442c24d71..c817bffbdd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -4,6 +4,7 @@ # Copyright (C) Jelmer Vernooij 2007-2008 # Copyright (C) Andrew Bartlett 2008 +# Copyright (C) Oliver Liebel 2008-2009 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -100,8 +101,6 @@ class ProvisionPaths(object): self.olcdir = None self.olslaptest = None self.olcseedldif = None - self.olcsyncprovdir = None - self.olcsyncprovfile = None class ProvisionNames(object): @@ -278,10 +277,6 @@ def provision_paths_from_lp(lp, dnsdomain): "slapd.d") paths.olcseedldif = os.path.join(paths.ldapdir, "olc_seed.ldif") - paths.olcsyncprovdir = os.path.join(paths.olcdir, - "cn=config/olcDatabase={0}config") - paths.olcsyncprovfile = os.path.join(paths.olcsyncprovdir, - "olcOverlay={0}syncprov.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1479,7 +1474,7 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" if ol_olc != "yes" and ol_mmr_urls is not None: - slapdcommand="Start slapd with: slapd -F " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" if ol_olc == "yes" and ol_mmr_urls is not None: slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" @@ -1505,6 +1500,8 @@ def provision_backend(setup_dir=None, message=None, message("LDAP admin password: %s" % adminpass) message(slapdcommand) + if ol_olc == "yes" or ol_mmr_urls is not None: + message("Attention to slapd-Port: must be different than 389!") assert isinstance(ldap_backend_type, str) assert isinstance(ldapuser, str) assert isinstance(adminpass, str) @@ -1528,19 +1525,10 @@ def provision_backend(setup_dir=None, message=None, paths.olslaptest = str(ol_slaptest) olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir + " >/dev/null 2>&1" os.system(olc_command) - #os.remove(paths.slapdconf) - # use line below for debugging during olc-conversion with slaptest + os.remove(paths.slapdconf) + # use line below for debugging during olc-conversion with slaptest, instead of olc_command above #olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir" - # workaround, if overlay syncprov is was not created properly during conversion to cn=config. - # otherwise, cn=config won't be replicated - if ol_olc == "yes" and ol_mmr_urls is not None: - if not os.path.exists(paths.olcsyncprovdir): - os.makedirs(paths.olcsyncprovdir, 0770) - setup_file(setup_path("olcOverlay={0}syncprov.ldif"), - os.path.join(paths.olcsyncprovdir, "olcOverlay={0}syncprov.ldif"), {}) - - def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. diff --git a/source4/setup/olcOverlay={0}syncprov.ldif b/source4/setup/olcOverlay={0}syncprov.ldif deleted file mode 100644 index 4f5b513c67..0000000000 --- a/source4/setup/olcOverlay={0}syncprov.ldif +++ /dev/null @@ -1,11 +0,0 @@ -dn: olcOverlay={0}syncprov -objectClass: olcOverlayConfig -objectClass: olcSyncProvConfig -olcOverlay: {0}syncprov -structuralObjectClass: olcSyncProvConfig -entryUUID: 41df5aca-785a-102d-9077-999999999999 -creatorsName: cn=config -createTimestamp: 20090116201111Z -entryCSN: 20090116201111.111111Z#000000#000#000000 -modifiersName: cn=config -modifyTimestamp: 20090116201111Z diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend index 20e4420414..28e73ae302 100755 --- a/source4/setup/provision-backend +++ b/source4/setup/provision-backend @@ -4,6 +4,7 @@ # provision a Samba4 server # Copyright (C) Jelmer Vernooij 2007-2008 # Copyright (C) Andrew Bartlett 2008 +# Copyright (C) Oliver Liebel 2008-2009 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -65,9 +66,9 @@ parser.add_option("--server-role", type="choice", metavar="ROLE", parser.add_option("--targetdir", type="string", metavar="DIR", help="Set target directory") parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", - help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") + help="List of LDAP-URLS [ ldap://:/ (where has to be different from 389!) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") parser.add_option("--ol-olc", type="choice", metavar="OPENLDAP-OLC", - help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'", + help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'. Note: Only OpenLDAP-Versions greater or equal 2.4.15 should be used!", choices=["yes", "no"]) parser.add_option("--ol-slaptest", type="string", metavar="SLAPTEST-PATH", help="Path to slaptest-binary [e.g.:'/usr/local/sbin']. Only for use with --ol-olc='yes'") -- cgit From 95bf60b39d003bea6f9f5ad2bc63d5f2a8b8b2af Mon Sep 17 00:00:00 2001 From: todd stecher Date: Mon, 23 Feb 2009 10:24:33 -0800 Subject: S3: Add in profile counters for new vfs and syscall entries. --- source3/include/smbprofile.h | 28 ++++++++++++++++++++++++++++ source3/modules/onefs_acl.c | 11 ++++++++++- source3/modules/onefs_cbrl.c | 26 ++++++++++++++++++++++++-- source3/modules/onefs_streams.c | 16 +++++++++++++--- source3/modules/onefs_system.c | 18 ++++++++++++++++++ source3/profile/profile.c | 7 +++++++ 6 files changed, 100 insertions(+), 6 deletions(-) diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 131416b685..f9a0436546 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -75,6 +75,10 @@ enum profile_stats_values #define syscall_open_count __profile_stats_value(PR_VALUE_SYSCALL_OPEN, count) #define syscall_open_time __profile_stats_value(PR_VALUE_SYSCALL_OPEN, time) + PR_VALUE_SYSCALL_CREATEFILE, +#define syscall_createfile_count __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, count) +#define syscall_createfile_time __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, time) + PR_VALUE_SYSCALL_CLOSE, #define syscall_close_count __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, count) #define syscall_close_time __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, time) @@ -111,6 +115,10 @@ enum profile_stats_values #define syscall_rename_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME, count) #define syscall_rename_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME, time) + PR_VALUE_SYSCALL_RENAME_AT, +#define syscall_rename_at_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, count) +#define syscall_rename_at_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, time) + PR_VALUE_SYSCALL_FSYNC, #define syscall_fsync_count __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, count) #define syscall_fsync_time __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, time) @@ -215,6 +223,26 @@ enum profile_stats_values #define syscall_set_quota_count __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, count) #define syscall_set_quota_time __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, time) + PR_VALUE_SYSCALL_GET_SD, +#define syscall_get_sd_count __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, count) +#define syscall_get_sd_time __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, time) + + PR_VALUE_SYSCALL_SET_SD, +#define syscall_set_sd_count __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, count) +#define syscall_set_sd_time __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, time) + + PR_VALUE_SYSCALL_BRL_LOCK, +#define syscall_brl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, count) +#define syscall_brl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, time) + + PR_VALUE_SYSCALL_BRL_UNLOCK, +#define syscall_brl_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, count) +#define syscall_brl_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, time) + + PR_VALUE_SYSCALL_BRL_CANCEL, +#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count) +#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time) + /* counters for individual SMB types */ PR_VALUE_SMBMKDIR, #define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 7bc4a1728f..b463722e61 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -614,6 +614,8 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status = NT_STATUS_OK; + START_PROFILE(syscall_get_sd); + *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", @@ -753,6 +755,9 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5, ("Finished retrieving/canonicalizing SD!\n")); /* FALLTHROUGH */ out: + + END_PROFILE(syscall_get_sd); + if (alloced && sd) { if (new_aces_alloced && sd->dacl->aces) SAFE_FREE(sd->dacl->aces); @@ -892,6 +897,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status; + START_PROFILE(syscall_set_sd); + DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd, @@ -899,7 +906,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); - return status; + goto out; } fd = fsp->fh->fd; @@ -938,6 +945,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* FALLTHROUGH */ out: + END_PROFILE(syscall_set_sd); + if (fopened) close(fd); diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index a860023764..2c5e39c359 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -255,6 +255,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, struct onefs_cbrl_blr_state *bs; NTSTATUS status; + START_PROFILE(syscall_brl_lock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); @@ -301,10 +303,13 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, /* ASYNC still in progress: The process_* calls will keep * calling even if we haven't gotten the lock. Keep erroring * without calling ifs_cbrl, or getting/setting an id. */ - if (bs->state == ONEFS_CBRL_ASYNC) + if (bs->state == ONEFS_CBRL_ASYNC) { goto failure; - else if (bs->state == ONEFS_CBRL_ERROR) + } + else if (bs->state == ONEFS_CBRL_ERROR) { + END_PROFILE(syscall_brl_lock); return NT_STATUS_NO_MEMORY; + } SMB_ASSERT(bs->state == ONEFS_CBRL_NONE); async = true; @@ -343,6 +348,9 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, } failure: + + END_PROFILE(syscall_brl_lock); + /* Failure - error or async. */ plock->context.smbpid = (uint32) ONEFS_BLOCKING_PID; @@ -355,6 +363,9 @@ failure: return status; success: + + END_PROFILE(syscall_brl_lock); + /* Success. */ onefs_cbrl_enumerate_blq("onefs_brl_unlock_windows"); DEBUG(10, ("returning NT_STATUS_OK.\n")); @@ -371,6 +382,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, int error; int fd = br_lck->fsp->fh->fd; + START_PROFILE(syscall_brl_unlock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); @@ -378,6 +391,9 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_unlock); + if (error) { DEBUG(10, ("returning false.\n")); return false; @@ -404,6 +420,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, int fd = br_lck->fsp->fh->fd; struct onefs_cbrl_blr_state *bs; + START_PROFILE(syscall_brl_cancel); + SMB_ASSERT(plock); SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(blr); @@ -416,6 +434,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, if (bs->state == ONEFS_CBRL_DONE) { /* No-op. */ DEBUG(10, ("State=DONE, returning true\n")); + END_PROFILE(syscall_brl_cancel); return true; } @@ -427,6 +446,9 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_cancel); + if (error) { DEBUG(10, ("returning false\n")); bs->state = ONEFS_CBRL_ERROR; diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 9616ca48d5..2dcd8891eb 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -160,18 +160,26 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, char *nbase = NULL; char *nsname = NULL; + START_PROFILE(syscall_rename_at); + frame = talloc_stackframe(); ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } if (!old_is_stream && !new_is_stream) { - return SMB_VFS_NEXT_RENAME(handle, oldname, newname); + ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname); + END_PROFILE(syscall_rename_at); + return ret; } dir_fd = get_stream_dir_fd(handle->conn, obase, NULL); @@ -192,6 +200,8 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, } done: + END_PROFILE(syscall_rename_at); + saved_errno = errno; if (dir_fd >= 0) { close(dir_fd); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 76df006d82..518a398154 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -95,6 +95,8 @@ int onefs_sys_create_file(connection_struct *conn, uint32_t onefs_dos_attributes; struct ifs_createfile_flags cf_flags = CF_FLAGS_NONE; + START_PROFILE(syscall_createfile); + /* Setup security descriptor and get secinfo. */ if (sd != NULL) { NTSTATUS status; @@ -196,6 +198,7 @@ int onefs_sys_create_file(connection_struct *conn, } out: + END_PROFILE(syscall_createfile); aclu_free_sd(pifs_sd, false); return ret_fd; @@ -307,6 +310,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, bool atomic = false; ssize_t ret = 0; + START_PROFILE_BYTES(syscall_sendfile, count); + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_ATOMIC_SENDFILE, PARM_ATOMIC_SENDFILE_DEFAULT)) { @@ -320,6 +325,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* If the sendfile wasn't atomic, we're done. */ if (!atomic) { DEBUG(10, ("non-atomic sendfile read %ul bytes", ret)); + END_PROFILE(syscall_sendfile); return ret; } @@ -391,6 +397,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* Handle case 1: short read -> truncated file. */ if (ret == 0) { + END_PROFILE(syscall_sendfile); return ret; } @@ -402,6 +409,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, PARM_SENDFILE_LARGE_READS_DEFAULT)) { DEBUG(3, ("Not attempting non-atomic large sendfile: " "%lu bytes\n", count)); + END_PROFILE(syscall_sendfile); return 0; } @@ -421,6 +429,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, DEBUG(1, ("error on non-atomic large sendfile " "(%lu bytes): %s\n", count, strerror(errno))); + END_PROFILE(syscall_sendfile); return ret; } @@ -439,9 +448,11 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_SENDFILE_SAFE, PARM_SENDFILE_SAFE_DEFAULT)) { + END_PROFILE(syscall_sendfile); return -1; } + END_PROFILE(syscall_sendfile); return ret; } @@ -455,6 +466,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, count, strerror(errno))); } + END_PROFILE(syscall_sendfile); return ret; } @@ -509,10 +521,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, off_t rbytes; off_t wbytes; + START_PROFILE_BYTES(syscall_recvfile, count); + DEBUG(10,("onefs_recvfile: from = %d, to = %d, offset=%llu, count = " "%lu\n", fromfd, tofd, offset, count)); if (count == 0) { + END_PROFILE(syscall_recvfile); return 0; } @@ -624,6 +639,9 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, ret = total_wbytes; out: + + END_PROFILE(syscall_recvfile); + /* Make sure we always try to drain the socket. */ if (!socket_drained && count - total_rbytes) { int saved_errno = errno; diff --git a/source3/profile/profile.c b/source3/profile/profile.c index bdbd805718..6d2d5ae06d 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -290,6 +290,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_rmdir", /* PR_VALUE_SYSCALL_RMDIR */ "syscall_closedir", /* PR_VALUE_SYSCALL_CLOSEDIR */ "syscall_open", /* PR_VALUE_SYSCALL_OPEN */ + "syscall_createfile", /* PR_VALUE_SYSCALL_CREATEFILE */ "syscall_close", /* PR_VALUE_SYSCALL_CLOSE */ "syscall_read", /* PR_VALUE_SYSCALL_READ */ "syscall_pread", /* PR_VALUE_SYSCALL_PREAD */ @@ -299,6 +300,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_sendfile", /* PR_VALUE_SYSCALL_SENDFILE */ "syscall_recvfile", /* PR_VALUE_SYSCALL_RECVFILE */ "syscall_rename", /* PR_VALUE_SYSCALL_RENAME */ + "syscall_rename_at", /* PR_VALUE_SYSCALL_RENAME_AT */ "syscall_fsync", /* PR_VALUE_SYSCALL_FSYNC */ "syscall_stat", /* PR_VALUE_SYSCALL_STAT */ "syscall_fstat", /* PR_VALUE_SYSCALL_FSTAT */ @@ -323,6 +325,11 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_realpath", /* PR_VALUE_SYSCALL_REALPATH */ "syscall_get_quota", /* PR_VALUE_SYSCALL_GET_QUOTA */ "syscall_set_quota", /* PR_VALUE_SYSCALL_SET_QUOTA */ + "syscall_get_sd", /* PR_VALUE_SYSCALL_GET_SD */ + "syscall_set_sd", /* PR_VALUE_SYSCALL_SET_SD */ + "syscall_brl_lock", /* PR_VALUE_SYSCALL_BRL_LOCK */ + "syscall_brl_unlock", /* PR_VALUE_SYSCALL_BRL_UNLOCK */ + "syscall_brl_cancel", /* PR_VALUE_SYSCALL_BRL_CANCEL */ "SMBmkdir", /* PR_VALUE_SMBMKDIR */ "SMBrmdir", /* PR_VALUE_SMBRMDIR */ "SMBopen", /* PR_VALUE_SMBOPEN */ -- cgit From 4e024b3f87ee1ccb0d7c83dfc6a4b5a6b2c47c13 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Tue, 24 Feb 2009 14:12:48 -0800 Subject: s3: onefs_acl.c cleanup Remove some duplicate code. Add a \n to a debugging statement --- source3/modules/onefs_acl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index b463722e61..b8097b6455 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -273,9 +273,6 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl, if (aclu_initialize_acl(acl, aces, num_aces)) goto err_free; - if (aclu_initialize_acl(acl, aces, num_aces)) - goto err_free; - /* Currently aclu_initialize_acl should copy the aces over, allowing * us to immediately free */ free(aces); @@ -905,7 +902,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, SNUM(handle->conn)); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); + DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status))); goto out; } -- cgit From aeab22b55cb1484ff6da7242bd525e30b69e5752 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Mon, 23 Feb 2009 23:21:13 -0800 Subject: s3: Rename auth_onefs_wb and pdb_onefs_sam auth_onefs_wb.c -> auth_wbc.c pdb_onefs_sam.c -> pdb_wbc_sam.c No changes to functionality --- source3/Makefile.in | 10 +- source3/auth/auth_onefs_wb.c | 134 ------------ source3/auth/auth_wbc.c | 150 ++++++++++++++ source3/configure.in | 8 +- source3/passdb/pdb_onefs_sam.c | 433 --------------------------------------- source3/passdb/pdb_wbc_sam.c | 448 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 607 insertions(+), 576 deletions(-) delete mode 100644 source3/auth/auth_onefs_wb.c create mode 100644 source3/auth/auth_wbc.c delete mode 100644 source3/passdb/pdb_onefs_sam.c create mode 100644 source3/passdb/pdb_wbc_sam.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 73b2989421..8f1d1a5b77 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -689,7 +689,7 @@ AUTH_SAM_OBJ = auth/auth_sam.o AUTH_SERVER_OBJ = auth/auth_server.o AUTH_UNIX_OBJ = auth/auth_unix.o AUTH_WINBIND_OBJ = auth/auth_winbind.o -AUTH_ONEFS_WB_OBJ = auth/auth_onefs_wb.o +AUTH_WBC_OBJ = auth/auth_wbc.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o @@ -2355,9 +2355,9 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_WINBIND_OBJ) -bin/onefs_wb.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_ONEFS_WB_OBJ) +bin/wbc.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WBC_OBJ) @echo "Building plugin $@" - @$(SHLD_MODULE) $(AUTH_ONEFS_WB_OBJ) + @$(SHLD_MODULE) $(AUTH_WBC_OBJ) bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ) @echo "Building plugin $@" @@ -2375,9 +2375,9 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o @echo "Building plugin $@" @$(SHLD_MODULE) passdb/pdb_tdb.o -bin/onefs_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_onefs_sam.o +bin/wbc_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_wbc_sam.o @echo "Building plugin $@" - @$(SHLD_MODULE) passdb/pdb_onefs_sam.o + @$(SHLD_MODULE) passdb/pdb_wbc_sam.o bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o @echo "Building plugin $@" diff --git a/source3/auth/auth_onefs_wb.c b/source3/auth/auth_onefs_wb.c deleted file mode 100644 index 49de6966b0..0000000000 --- a/source3/auth/auth_onefs_wb.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind authentication mechnism, customized for onefs - - Copyright (C) Tim Potter 2000 - Copyright (C) Andrew Bartlett 2001 - 2002 - Copyright (C) Dan Sledz 2009 - - 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 . -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -/* Authenticate a user with a challenge/response */ - -static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const auth_usersupplied_info *user_info, - auth_serversupplied_info **server_info) -{ - NTSTATUS nt_status; - wbcErr wbc_status; - struct wbcAuthUserParams params; - struct wbcAuthUserInfo *info = NULL; - struct wbcAuthErrorInfo *err = NULL; - - if (!user_info || !auth_context || !server_info) { - return NT_STATUS_INVALID_PARAMETER; - } - /* Send off request */ - - params.account_name = user_info->smb_name; - params.domain_name = user_info->domain; - params.workstation_name = user_info->wksta_name; - - params.flags = 0; - params.parameter_control= user_info->logon_parameters; - - /* Handle plaintext */ - if (!user_info->encrypted) { - DEBUG(3,("Checking plaintext password for %s.\n", - user_info->internal_username)); - params.level = WBC_AUTH_USER_LEVEL_PLAIN; - - params.password.plaintext = user_info->plaintext_password.data; - } else { - DEBUG(3,("Checking encrypted password for %s.\n", - user_info->internal_username)); - params.level = WBC_AUTH_USER_LEVEL_RESPONSE; - - memcpy(params.password.response.challenge, - auth_context->challenge.data, - sizeof(params.password.response.challenge)); - - params.password.response.nt_length = user_info->nt_resp.length; - params.password.response.nt_data = user_info->nt_resp.data; - params.password.response.lm_length = user_info->lm_resp.length; - params.password.response.lm_data = user_info->lm_resp.data; - - } - - /* we are contacting the privileged pipe */ - become_root(); - wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); - unbecome_root(); - - if (!WBC_ERROR_IS_OK(wbc_status)) { - DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", - wbc_status, wbcErrorString(wbc_status))); - } - - if (wbc_status == WBC_ERR_NO_MEMORY) { - return NT_STATUS_NO_MEMORY; - } - - if (wbc_status == WBC_ERR_AUTH_ERROR) { - nt_status = NT_STATUS(err->nt_status); - wbcFreeMemory(err); - return nt_status; - } - - if (!WBC_ERROR_IS_OK(wbc_status)) { - return NT_STATUS_LOGON_FAILURE; - } - - DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); - - nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, - user_info->smb_name, - user_info->domain, - info, server_info); - wbcFreeMemory(info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - (*server_info)->nss_token |= user_info->was_mapped; - - return nt_status; -} - -/* module initialisation */ -static NTSTATUS auth_init_onefs_wb(struct auth_context *auth_context, const char *param, auth_methods **auth_method) -{ - if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; - } - - (*auth_method)->name = "onefs_wb"; - (*auth_method)->auth = check_onefs_wb_security; - - return NT_STATUS_OK; -} - -NTSTATUS auth_onefs_wb_init(void) -{ - return smb_register_auth(AUTH_INTERFACE_VERSION, "onefs_wb", auth_init_onefs_wb); -} diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c new file mode 100644 index 0000000000..b0af9ffb1d --- /dev/null +++ b/source3/auth/auth_wbc.c @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client authentication mechanism designed to defer all + authentication to the winbind daemon. + + Copyright (C) Tim Potter 2000 + Copyright (C) Andrew Bartlett 2001 - 2002 + Copyright (C) Dan Sledz 2009 + + 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 . +*/ + +/* This auth module is very similar to auth_winbind with 3 distinct + * differences. + * + * 1) Does not fallback to another auth module if winbindd is unavailable + * 2) Does not validate the domain of the user + * 3) Handles unencrypted passwords + * + * The purpose of this module is to defer all authentication decisions (ie: + * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc + * compatible daemon. This centeralizes all authentication decisions to a + * single provider. + * + * This auth backend is most useful when used in conjunction with pdb_wbc_sam. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/* Authenticate a user with a challenge/response */ + +static NTSTATUS check_wbc_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status; + wbcErr wbc_status; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + + if (!user_info || !auth_context || !server_info) { + return NT_STATUS_INVALID_PARAMETER; + } + /* Send off request */ + + params.account_name = user_info->smb_name; + params.domain_name = user_info->domain; + params.workstation_name = user_info->wksta_name; + + params.flags = 0; + params.parameter_control= user_info->logon_parameters; + + /* Handle plaintext */ + if (!user_info->encrypted) { + DEBUG(3,("Checking plaintext password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_PLAIN; + + params.password.plaintext = user_info->plaintext_password.data; + } else { + DEBUG(3,("Checking encrypted password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; + + memcpy(params.password.response.challenge, + auth_context->challenge.data, + sizeof(params.password.response.challenge)); + + params.password.response.nt_length = user_info->nt_resp.length; + params.password.response.nt_data = user_info->nt_resp.data; + params.password.response.lm_length = user_info->lm_resp.length; + params.password.response.lm_data = user_info->lm_resp.data; + + } + + /* we are contacting the privileged pipe */ + become_root(); + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); + unbecome_root(); + + if (!WBC_ERROR_IS_OK(wbc_status)) { + DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", + wbc_status, wbcErrorString(wbc_status))); + } + + if (wbc_status == WBC_ERR_NO_MEMORY) { + return NT_STATUS_NO_MEMORY; + } + + if (wbc_status == WBC_ERR_AUTH_ERROR) { + nt_status = NT_STATUS(err->nt_status); + wbcFreeMemory(err); + return nt_status; + } + + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_LOGON_FAILURE; + } + + DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); + + nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, + user_info->smb_name, + user_info->domain, + info, server_info); + wbcFreeMemory(info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + (*server_info)->nss_token |= user_info->was_mapped; + + return nt_status; +} + +/* module initialisation */ +static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return NT_STATUS_NO_MEMORY; + } + + (*auth_method)->name = "wbc"; + (*auth_method)->auth = check_wbc_security; + + return NT_STATUS_OK; +} + +NTSTATUS auth_wbc_init(void) +{ + return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc); +} diff --git a/source3/configure.in b/source3/configure.in index bd3d4af40b..d67feccb9b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -414,7 +414,7 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" +default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer" @@ -1088,7 +1088,7 @@ echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" - default_static_modules="$default_static_modules auth_onefs_wb pdb_onefs_sam" + default_static_modules="$default_static_modules" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -6130,7 +6130,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT" [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] ) SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB) SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) -SMB_MODULE(pdb_onefs_sam, passdb/pdb_onefs_sam.o, "bin/onefs_sam.$SHLIBEXT", PDB) +SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) @@ -6173,7 +6173,7 @@ SMB_SUBSYSTEM(CHARSET,lib/iconv.o) SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH) SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH) SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH) -SMB_MODULE(auth_onefs_wb, \$(AUTH_ONEFS_WB_OBJ), "bin/onefs_wb.$SHLIBEXT", AUTH) +SMB_MODULE(auth_wbc, \$(AUTH_WBC_OBJ), "bin/wbc.$SHLIBEXT", AUTH) SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH) SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH) SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH) diff --git a/source3/passdb/pdb_onefs_sam.c b/source3/passdb/pdb_onefs_sam.c deleted file mode 100644 index 51b8618aad..0000000000 --- a/source3/passdb/pdb_onefs_sam.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling for wbclient - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Jelmer Vernooij 2002 - Copyright (C) Simo Sorce 2003 - Copyright (C) Volker Lendecke 2006 - Copyright (C) Dan Sledz 2009 - - 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 . -*/ - -#include "includes.h" - -/*************************************************************************** - Default implementations of some functions. - ****************************************************************************/ -static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods, - struct samu *user, - const struct passwd *pwd) -{ - NTSTATUS result = NT_STATUS_OK; - - if (pwd == NULL) - return NT_STATUS_NO_SUCH_USER; - - memset(user, 0, sizeof(user)); - - /* Can we really get away with this little of information */ - user->methods = methods; - result = samu_set_unix(user, pwd); - - return result; -} - -static NTSTATUS pdb_onefs_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) -{ - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwnam(sname)); -} - -static NTSTATUS pdb_onefs_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) -{ - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwsid(sid)); -} - -static bool pdb_onefs_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, - DOM_SID *sid) -{ - return winbind_uid_to_sid(sid, uid); -} - -static bool pdb_onefs_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, - DOM_SID *sid) -{ - return winbind_gid_to_sid(sid, gid); -} - -static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods, - const DOM_SID *sid, - union unid_t *id, enum lsa_SidType *type) -{ - if (winbind_sid_to_uid(&id->uid, sid)) { - *type = SID_NAME_USER; - } else if (winbind_sid_to_gid(&id->gid, sid)) { - /* We assume all gids are groups, not aliases */ - *type = SID_NAME_DOM_GRP; - } else { - return false; - } - - return true; -} - -static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - const DOM_SID *group, - uint32 **pp_member_rids, - size_t *p_num_members) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - struct samu *user, - DOM_SID **pp_sids, - gid_t **pp_gids, - size_t *p_num_groups) -{ - size_t i; - const char *username = pdb_get_username(user); - - if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { - return NT_STATUS_NO_SUCH_USER; - } - - if (*p_num_groups == 0) { - smb_panic("primary group missing"); - } - - *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); - - if (*pp_sids == NULL) { - TALLOC_FREE(*pp_gids); - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i < *p_num_groups; i++) { - gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_onefs_sam_lookup_rids(struct pdb_methods *methods, - const DOM_SID *domain_sid, - int num_rids, - uint32 *rids, - const char **names, - enum lsa_SidType *attrs) -{ - NTSTATUS result = NT_STATUS_OK; - char *domain = NULL; - char **account_names = NULL; - char name[256]; - enum lsa_SidType *attr_list = NULL; - int i; - - if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, - (const char **)&domain, - (const char ***)&account_names, &attr_list)) - { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); - - for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", - domain, *lp_winbind_separator(), name); - map->sid_name_use = name_type; - map->sid = *sid; - map->gid = gid; - return true; -} - -static NTSTATUS pdb_onefs_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, - DOM_SID sid) -{ - NTSTATUS result = NT_STATUS_OK; - char *name = NULL; - char *domain = NULL; - enum lsa_SidType name_type; - gid_t gid; - - if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, - (const char **) &name, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_sid_to_gid(&gid, &sid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - TALLOC_FREE(name); - TALLOC_FREE(domain); - return result; -} - -static NTSTATUS pdb_onefs_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, - gid_t gid) -{ - NTSTATUS result = NT_STATUS_OK; - char *name = NULL; - char *domain = NULL; - DOM_SID sid; - enum lsa_SidType name_type; - - if (!winbind_gid_to_sid(&sid, gid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, - (const char **)&name, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - TALLOC_FREE(name); - TALLOC_FREE(domain); - - return result; -} - -static NTSTATUS pdb_onefs_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, - const char *name) -{ - NTSTATUS result = NT_STATUS_OK; - char *user_name = NULL; - char *domain = NULL; - DOM_SID sid; - gid_t gid; - enum lsa_SidType name_type; - - if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_sid_to_gid(&gid, &sid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - - return result; -} - -static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods, - const DOM_SID *sid, enum lsa_SidType sid_name_use, - GROUP_MAP **pp_rmap, size_t *p_num_entries, - bool unix_only) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_get_aliasinfo(struct pdb_methods *methods, - const DOM_SID *sid, - struct acct_info *info) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_enum_aliasmem(struct pdb_methods *methods, - const DOM_SID *alias, DOM_SID **pp_members, - size_t *p_num_members) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - const DOM_SID *domain_sid, - const DOM_SID *members, - size_t num_members, - uint32 **pp_alias_rids, - size_t *p_num_alias_rids) -{ - if (!winbind_get_sid_aliases(mem_ctx, domain_sid, - members, num_members, pp_alias_rids, p_num_alias_rids)) - return NT_STATUS_UNSUCCESSFUL; - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *location) -{ - NTSTATUS result; - - if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { - return result; - } - - (*pdb_method)->name = "onefs_sam"; - - (*pdb_method)->getsampwnam = pdb_onefs_sam_getsampwnam; - (*pdb_method)->getsampwsid = pdb_onefs_sam_getsampwsid; - - (*pdb_method)->getgrsid = pdb_onefs_sam_getgrsid; - (*pdb_method)->getgrgid = pdb_onefs_sam_getgrgid; - (*pdb_method)->getgrnam = pdb_onefs_sam_getgrnam; - (*pdb_method)->enum_group_mapping = pdb_onefs_sam_enum_group_mapping; - (*pdb_method)->enum_group_members = pdb_onefs_sam_enum_group_members; - (*pdb_method)->enum_group_memberships = pdb_onefs_sam_enum_group_memberships; - (*pdb_method)->get_aliasinfo = pdb_onefs_sam_get_aliasinfo; - (*pdb_method)->enum_aliasmem = pdb_onefs_sam_enum_aliasmem; - (*pdb_method)->enum_alias_memberships = pdb_onefs_sam_alias_memberships; - (*pdb_method)->lookup_rids = pdb_onefs_sam_lookup_rids; - (*pdb_method)->get_account_policy = pdb_onefs_sam_get_account_policy; - (*pdb_method)->set_account_policy = pdb_onefs_sam_set_account_policy; - (*pdb_method)->uid_to_sid = pdb_onefs_sam_uid_to_sid; - (*pdb_method)->gid_to_sid = pdb_onefs_sam_gid_to_sid; - (*pdb_method)->sid_to_id = pdb_onefs_sam_sid_to_id; - - (*pdb_method)->search_groups = pdb_onefs_sam_search_groups; - (*pdb_method)->search_aliases = pdb_onefs_sam_search_aliases; - - (*pdb_method)->get_trusteddom_pw = pdb_onefs_sam_get_trusteddom_pw; - (*pdb_method)->set_trusteddom_pw = pdb_onefs_sam_set_trusteddom_pw; - (*pdb_method)->del_trusteddom_pw = pdb_onefs_sam_del_trusteddom_pw; - (*pdb_method)->enum_trusteddoms = pdb_onefs_sam_enum_trusteddoms; - - (*pdb_method)->private_data = NULL; - (*pdb_method)->free_private_data = NULL; - - return NT_STATUS_OK; -} - -NTSTATUS pdb_onefs_sam_init(void) -{ - return smb_register_passdb(PASSDB_INTERFACE_VERSION, "onefs_sam", pdb_init_onefs_sam); -} diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c new file mode 100644 index 0000000000..33dc03fe4c --- /dev/null +++ b/source3/passdb/pdb_wbc_sam.c @@ -0,0 +1,448 @@ +/* + Unix SMB/CIFS implementation. + + Password and authentication handling by wbclient + + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Simo Sorce 2003 + Copyright (C) Volker Lendecke 2006 + Copyright (C) Dan Sledz 2009 + + 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 . +*/ + +/* This passdb module retrieves full passdb information for local users and + * groups from a wbclient compatible daemon. + * + * The purpose of this module is to defer all SAM authorization information + * storage and retrieval to a wbc compatible daemon. + * + * This passdb backend is most useful when used in conjunction with auth_wbc. + * + * A few current limitations of this module are: + * - read only interface + * - no privileges + */ + +#include "includes.h" + +/*************************************************************************** + Default implementations of some functions. + ****************************************************************************/ +static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods, + struct samu *user, + const struct passwd *pwd) +{ + NTSTATUS result = NT_STATUS_OK; + + if (pwd == NULL) + return NT_STATUS_NO_SUCH_USER; + + memset(user, 0, sizeof(user)); + + /* Can we really get away with this little of information */ + user->methods = methods; + result = samu_set_unix(user, pwd); + + return result; +} + +static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) +{ + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname)); +} + +static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) +{ + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid)); +} + +static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, + DOM_SID *sid) +{ + return winbind_uid_to_sid(sid, uid); +} + +static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, + DOM_SID *sid) +{ + return winbind_gid_to_sid(sid, gid); +} + +static bool pdb_wbc_sam_sid_to_id(struct pdb_methods *methods, + const DOM_SID *sid, + union unid_t *id, enum lsa_SidType *type) +{ + if (winbind_sid_to_uid(&id->uid, sid)) { + *type = SID_NAME_USER; + } else if (winbind_sid_to_gid(&id->gid, sid)) { + /* We assume all gids are groups, not aliases */ + *type = SID_NAME_DOM_GRP; + } else { + return false; + } + + return true; +} + +static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *group, + uint32 **pp_member_rids, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + struct samu *user, + DOM_SID **pp_sids, + gid_t **pp_gids, + size_t *p_num_groups) +{ + size_t i; + const char *username = pdb_get_username(user); + + if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + return NT_STATUS_NO_SUCH_USER; + } + + if (*p_num_groups == 0) { + smb_panic("primary group missing"); + } + + *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); + + if (*pp_sids == NULL) { + TALLOC_FREE(*pp_gids); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < *p_num_groups; i++) { + gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); + } + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, + const DOM_SID *domain_sid, + int num_rids, + uint32 *rids, + const char **names, + enum lsa_SidType *attrs) +{ + NTSTATUS result = NT_STATUS_OK; + char *domain = NULL; + char **account_names = NULL; + char name[256]; + enum lsa_SidType *attr_list = NULL; + int i; + + if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, + (const char **)&domain, + (const char ***)&account_names, &attr_list)) + { + result = NT_STATUS_NONE_MAPPED; + goto done; + } + + memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); + + for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", + domain, *lp_winbind_separator(), name); + map->sid_name_use = name_type; + map->sid = *sid; + map->gid = gid; + return true; +} + +static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, + DOM_SID sid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + enum lsa_SidType name_type; + gid_t gid; + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **) &name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + return result; +} + +static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, + gid_t gid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + DOM_SID sid; + enum lsa_SidType name_type; + + if (!winbind_gid_to_sid(&sid, gid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **)&name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + + return result; +} + +static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, + const char *name) +{ + NTSTATUS result = NT_STATUS_OK; + char *user_name = NULL; + char *domain = NULL; + DOM_SID sid; + gid_t gid; + enum lsa_SidType name_type; + + if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + + return result; +} + +static NTSTATUS pdb_wbc_sam_enum_group_mapping(struct pdb_methods *methods, + const DOM_SID *sid, enum lsa_SidType sid_name_use, + GROUP_MAP **pp_rmap, size_t *p_num_entries, + bool unix_only) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods, + const DOM_SID *alias, DOM_SID **pp_members, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + const DOM_SID *members, + size_t num_members, + uint32 **pp_alias_rids, + size_t *p_num_alias_rids) +{ + if (!winbind_get_sid_aliases(mem_ctx, domain_sid, + members, num_members, pp_alias_rids, p_num_alias_rids)) + return NT_STATUS_UNSUCCESSFUL; + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location) +{ + NTSTATUS result; + + if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { + return result; + } + + (*pdb_method)->name = "wbc_sam"; + + (*pdb_method)->getsampwnam = pdb_wbc_sam_getsampwnam; + (*pdb_method)->getsampwsid = pdb_wbc_sam_getsampwsid; + + (*pdb_method)->getgrsid = pdb_wbc_sam_getgrsid; + (*pdb_method)->getgrgid = pdb_wbc_sam_getgrgid; + (*pdb_method)->getgrnam = pdb_wbc_sam_getgrnam; + (*pdb_method)->enum_group_mapping = pdb_wbc_sam_enum_group_mapping; + (*pdb_method)->enum_group_members = pdb_wbc_sam_enum_group_members; + (*pdb_method)->enum_group_memberships = pdb_wbc_sam_enum_group_memberships; + (*pdb_method)->get_aliasinfo = pdb_wbc_sam_get_aliasinfo; + (*pdb_method)->enum_aliasmem = pdb_wbc_sam_enum_aliasmem; + (*pdb_method)->enum_alias_memberships = pdb_wbc_sam_alias_memberships; + (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids; + (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy; + (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy; + (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid; + (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid; + (*pdb_method)->sid_to_id = pdb_wbc_sam_sid_to_id; + + (*pdb_method)->search_groups = pdb_wbc_sam_search_groups; + (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases; + + (*pdb_method)->get_trusteddom_pw = pdb_wbc_sam_get_trusteddom_pw; + (*pdb_method)->set_trusteddom_pw = pdb_wbc_sam_set_trusteddom_pw; + (*pdb_method)->del_trusteddom_pw = pdb_wbc_sam_del_trusteddom_pw; + (*pdb_method)->enum_trusteddoms = pdb_wbc_sam_enum_trusteddoms; + + (*pdb_method)->private_data = NULL; + (*pdb_method)->free_private_data = NULL; + + return NT_STATUS_OK; +} + +NTSTATUS pdb_wbc_sam_init(void) +{ + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam); +} -- cgit From cde5724780c0e52705e0f6e7cd41e0c884afbb40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 17:32:22 -0800 Subject: Added torture test from a usage case from the Apple OS/X client. Setting an attribute on a stream fnum must change the attribute on the base file. Jeremy. --- source4/torture/raw/streams.c | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index 0622e0809d..bf87bd224f 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1535,6 +1535,121 @@ static bool test_stream_large_streaminfo(struct torture_context *tctx, return ret; } +/* Test the effect of setting attributes on a stream. */ +static bool test_stream_attributes(struct torture_context *tctx, + struct smbcli_state *cli, + TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_open io; + const char *fname = BASEDIR "\\stream_attr.txt"; + const char *stream = "Stream One:$DATA"; + const char *fname_stream; + int fnum = -1; + union smb_fileinfo finfo; + union smb_setfileinfo sfinfo; + time_t basetime = (time(NULL) - 86400) & ~1; + + printf ("(%s) testing attribute setting on stream\n", __location__); + + fname_stream = talloc_asprintf(mem_ctx, "%s:%s", fname, stream); + + /* Create a file with a stream with attribute FILE_ATTRIBUTE_ARCHIVE. */ + ret = create_file_with_stream(tctx, cli, mem_ctx, fname, + fname_stream); + if (!ret) { + goto done; + } + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_BASIC_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + CHECK_STATUS(status, NT_STATUS_OK); + + if (finfo.basic_info.out.attrib != FILE_ATTRIBUTE_ARCHIVE) { + printf("(%s) Incorrect attrib %x - should be %x\n", \ + __location__, (unsigned int)finfo.basic_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_ARCHIVE); + ret = false; + goto done; + } + + /* Now open the stream name. */ + + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA| + SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL|SEC_FILE_WRITE_ATTRIBUTE); + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.file_attr = 0; + io.ntcreatex.in.share_access = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname_stream; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + fnum = io.ntcreatex.out.file.fnum; + + /* Change the attributes + time on the stream fnum. */ + ZERO_STRUCT(sfinfo); + sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY; + unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime); + + sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION; + sfinfo.generic.in.file.fnum = fnum; + status = smb_raw_setfileinfo(cli->tree, &sfinfo); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + printf("(%s) %s - %s (should be %s)\n", __location__, "SETATTR", + nt_errstr(status), nt_errstr(NT_STATUS_OK)); + ret = false; + goto done; + } + + smbcli_close(cli->tree, fnum); + fnum = -1; + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_ALL_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (!NT_STATUS_IS_OK(status)) { + printf("(%s) %s pathinfo - %s\n", __location__, "SETATTRE", nt_errstr(status)); + ret = false; + goto done; + } + + if (finfo.all_info.out.attrib != FILE_ATTRIBUTE_READONLY) { + printf("(%s) attrib incorrect. Was 0x%x, should be 0x%x\n", + __location__, + (unsigned int)finfo.all_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_READONLY); + ret = false; + goto done; + } + + if (nt_time_to_unix(finfo.all_info.out.write_time) != basetime) { + printf("(%s) time incorrect.\n", + __location__); + ret = false; + goto done; + } + + done: + + if (fnum != -1) { + smbcli_close(cli->tree, fnum); + } + smbcli_unlink(cli->tree, fname); + return ret; +} + /* basic testing of streams calls */ @@ -1566,6 +1681,10 @@ bool torture_raw_streams(struct torture_context *torture, smb_raw_exit(cli->session); ret &= test_stream_create_disposition(torture, cli, torture); smb_raw_exit(cli->session); + + ret &= test_stream_attributes(torture, cli, torture); + smb_raw_exit(cli->session); + /* ret &= test_stream_large_streaminfo(torture, cli, torture); */ /* smb_raw_exit(cli->session); */ -- cgit From ebe1aa9340d190b2ebcfd2c96f68c7771cccdf01 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 18:03:49 -0800 Subject: Allow set attributes on a stream fnum to be redirected to the base filename. Fixes the new RAW-STREAMS torture test. Jeremy. --- source3/smbd/trans2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 759e520866..433b8a008d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4972,6 +4972,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, ****************************************************************************/ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, + files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 dosmode) @@ -4980,6 +4981,14 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (fsp) { + if (fsp->base_fsp) { + fname = fsp->base_fsp->fsp_name; + } else { + fname = fsp->fsp_name; + } + } + if (dosmode) { if (S_ISDIR(psbuf->st_mode)) { dosmode |= aDIR; @@ -5723,12 +5732,11 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, fname, psbuf, dosmode); + status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } - /* access time */ ft.atime = interpret_long_date(pdata+8); -- cgit From 7040d94149d8538c0b731b9e62b9b4c7807841b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2009 13:14:36 +1100 Subject: Prepare for a quick alpha7 release to help simo meet Fedora deadlines While there isn't much in this release, there is enough to be worth cutting the tarball, and not much cost in doing so. Andrew Bartlett --- WHATSNEW4.txt | 101 ++++++++++++---------------------------------------------- 1 file changed, 21 insertions(+), 80 deletions(-) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index 03cd72c518..2093a4ee1f 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -1,4 +1,4 @@ -What's new in Samba 4 alpha6 +What's new in Samba 4 alpha7 ============================ Samba 4 is the ambitious next version of the Samba suite that is being @@ -6,13 +6,13 @@ developed in parallel to the stable 3.0 series. The main emphasis in this branch is support for the Active Directory logon protocols used by Windows 2000 and above. -Samba4 alpha6 follows on from the alpha release series we have been +Samba4 alpha7 follows on from the alpha release series we have been publishing since September 2007 WARNINGS ======== -Samba4 alpha6 is not a final Samba release. That is more a reference +Samba4 alpha7 is not a final Samba release. That is more a reference to Samba4's lack of the features we expect you will need than a statement of code quality, but clearly it hasn't seen a broad deployment yet. If you were to upgrade Samba3 (or indeed Windows) to @@ -62,85 +62,30 @@ working on modules to map between AD-like behaviours and this backend. We are aiming for Samba 4 to be powerful frontend to large directories. -CHANGES SINCE Alpha5 +CHANGES SINCE alpha6 ===================== -In the time since Samba4 Alpha5 was released in June 2008, Samba has +In the time since Samba4 alpha6 was released in Janurary 2009, Samba has continued to evolve, but you may particularly notice these areas (in no particular order): - The source code for various libraries that are used by both Samba 3 and - Samba 4 are now shared between the two rather than duplicated - (and being slightly diverged). + OpenLDAP Multi Master Replication can now also replicate the OpenLDAP + configuration itself. - The tevent library has been split out and is now usable on its own. + Support for Windows 7 beta as a member of the Samba4 domain - Several crash bugs and memory leaks in the registry library have been fixed. + Issues with the nesting of LDB transactions have been fixed - The Python modules have been extended and are no longer generated using SWIG. + A number of internal libraries (tevent, auth in particular has been + updated for easier use outside Samba4 - Stream renames are now supported. - - The provision script now has an interactive mode. - - The (broken) copy of CTDB has been removed. - - More work towards supporting an OpenLDAP backend. - - Initial work on using the Microsoft LDAP schema. - - The storage of schemas in LDB is now much more efficient. - - Support for extended DNs in LDB has been added. - - Incoming trusts are now supported. - - Compatibility of the registry server with several Windows versions has been - improved. - - Improvements to LSA.idl for better functionality in the usrmgr.exe. - - Improved handling of non-standard characters in passwords. - - The embedded JavaScript library has been removed in favor of Python. - - The WMI implementation has been re-added, but does not completely work yet. - - xpress compression is now supported in the NDR layer. - - The main binary is now named "samba" rather than "smbd". - - A simple script for setting the expiration of a user was added. - - The LDB library is now completely asynchronous internally. - - Various unknowns and correctness issues in the drsblobs and drsuapi RPC - interface implementations have been fixed. - - It is now possible to connect to an LDAP backend using SASL credentials. - - Multi-fragment NTtrans request support has been added. - - The DCE/RPC server can now listen on a separate pipe to allow DCE/RPC - connections forwarded from Samba 3. The user credentials are provided - by the client. - - A large number of bugs in the SMB2 implementation have been fixed. - - Auxiliary classes in LDAP schema conversion are now collapsed. - - Several tests have been added to the SMB testsuite. - - Object GUIDs in DCE/RPC connections are now dealt with properly. - - The correctness of the LSA and NETLOGON implementations has been - improved. - - Multi Master Replication configuration can now be generated - for OpenLDAP. - -These are just some of the highlights of the work done in the past few -months. More details can be found in our GIT history. + spoolss IDL updates to bring Samba3 to use PIDL code, and to merge + the corrected IDL back into Samba4 + + Fixes to allow use of C++ compilers and to increase portability + +These are just some of the highlights of the work done in the past +month. More details can be found in our GIT history. CHANGES @@ -163,17 +108,13 @@ KNOWN ISSUES - Clock Synchronisation is critical. Many 'wrong password' errors are actually due to Kerberos objecting to a clock skew between client - and server. (The NTP work in the previous alpha is partly to assist + and server. (The NTP work in the previous alphas are partly to assist with this problem). -- Samba4 alpha6 is currently only portable to recent Linux +- Samba4 alpha7 is currently only portable to recent Linux distributions. Work to return support for other Unix varients is - expected during the next alpha cycle + expected during the next alpha cycles -- Samba4 alpha6 is incompatible with GnuTLS 2.0, found in Fedora 9 and - recent Ubuntu releases. GnuTLS use may be disabled using the - --disable-gnutls argument to ./configure. (otherwise 'make test' and - LDAPS operations will hang). RUNNING Samba4 ============== -- cgit From d75df717336e063f52af1415f99b6e16ccbf918c Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 24 Feb 2009 20:53:46 -0600 Subject: Fix guest mounts guest session setup, login (user id) as anonymous. This patch is for samba bugzilla bug 4640. Signed-off-by: Shirish Pargaonkar Acked-by: Jeff Layton Signed-off-by: Steve French --- source3/client/mount.cifs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index ae8a7fd186..8623d3c04b 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -649,7 +649,9 @@ static int parse_options(char ** optionsp, int * filesys_flags) } else if (strncmp(data, "exec", 4) == 0) { *filesys_flags &= ~MS_NOEXEC; } else if (strncmp(data, "guest", 5) == 0) { - got_password=1; + user_name = (char *)calloc(1, 1); + got_user = 1; + got_password = 1; } else if (strncmp(data, "ro", 2) == 0) { *filesys_flags |= MS_RDONLY; } else if (strncmp(data, "rw", 2) == 0) { -- cgit From afc7e45a4ccf8505e4c598334e339e79ba036057 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 21:53:30 -0800 Subject: s3 OneFS: Fix uninitialized variable --- source3/modules/onefs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index b8097b6455..a1bfa6e121 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -890,7 +890,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { struct ifs_security_descriptor sd = {}; - int fd; + int fd = -1; bool fopened = false; NTSTATUS status; -- cgit From c2cdb4ad5c9398ef0d3310613107999f8d33c7ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2009 17:43:07 +1100 Subject: Work around ndr_unpack failing on structures with relative pointers. This disgusting hack works around the fact that ndr_pull_struct_blob_all will always fail on structures with relative pointers. So, map ndr_unpack to ndr_pull_struct_blob_all only if we don't have any relative pointers in this structure. Andrew Bartlett --- pidl/lib/Parse/Pidl/Samba4/Python.pm | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 48785f5b0a..6099fe5cae 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -275,7 +275,24 @@ sub PythonStruct($$$$$$) $self->pidl("if (!PyArg_ParseTuple(args, \"s#:__ndr_unpack__\", &blob.data, &blob.length))"); $self->pidl("\treturn NULL;"); $self->pidl(""); - $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); + + # This disgusting hack works around the fact that ndr_pull_struct_blob_all will always fail on structures with relative pointers. + # So, map ndr_unpack to ndr_pull_struct_blob_all only if we don't have any relative pointers in this + my $got_relative = 0; + if ($#{$d->{ELEMENTS}} > -1) { + foreach my $e (@{$d->{ELEMENTS}}) { + my $l = $e->{LEVELS}[0]; + if ($l->{TYPE} eq "POINTER" and ($l->{POINTER_TYPE} eq "relative")) { + $got_relative = 1; + last; + } + } + } + if ($got_relative == 0) { + $self->pidl("err = ndr_pull_struct_blob_all(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); + } else { + $self->pidl("err = ndr_pull_struct_blob(&blob, py_talloc_get_mem_ctx(py_obj), NULL, object, (ndr_pull_flags_fn_t)ndr_pull_$name);"); + } $self->pidl("if (err != NDR_ERR_SUCCESS) {"); $self->indent; $self->pidl("PyErr_SetNdrError(err);"); -- cgit From 2f1b12890a31baceee6a4d446b4782caefb1fcaa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Feb 2009 17:52:00 +1100 Subject: Credit tridge's work on fixing GnuTLS --- WHATSNEW4.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index 2093a4ee1f..2df23fd624 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -83,6 +83,8 @@ continued to evolve, but you may particularly notice these areas the corrected IDL back into Samba4 Fixes to allow use of C++ compilers and to increase portability + + Fixed TLS (SSL) support with modern versions of GnuTLS These are just some of the highlights of the work done in the past month. More details can be found in our GIT history. -- cgit From dc0e46afb7018a1da666729c6d61e8ea85dcf07d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 08:42:33 +0100 Subject: s4:build: add some comments to the SMB_EXT_LIB() definition metze --- source4/build/m4/public.m4 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index 1927e9977f..ffdf92f784 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -157,6 +157,13 @@ mkinclude $1 " ]) +dnl +dnl SMB_EXT_LIB() just specifies the details of the library. +dnl Note: the library isn't enabled by default. +dnl You need to enable it with SMB_ENABLE(name) if configure +dnl find it should be used. E.g. it should not be enabled +dnl if the library is present, but the header file is missing. +dnl dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) AC_DEFUN([SMB_EXT_LIB], [ -- cgit From 662f996b1554508baf7344b8618f152c179f1680 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 25 Feb 2009 00:11:31 -0800 Subject: s3: Fix 'assignment differ in signedness' warning --- source3/auth/auth_wbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c index b0af9ffb1d..580c8b550d 100644 --- a/source3/auth/auth_wbc.c +++ b/source3/auth/auth_wbc.c @@ -74,7 +74,7 @@ static NTSTATUS check_wbc_security(const struct auth_context *auth_context, user_info->internal_username)); params.level = WBC_AUTH_USER_LEVEL_PLAIN; - params.password.plaintext = user_info->plaintext_password.data; + params.password.plaintext = (char *)user_info->plaintext_password.data; } else { DEBUG(3,("Checking encrypted password for %s.\n", user_info->internal_username)); -- cgit From eb5efd1978acd38cf6cc97e067b5105743ca5469 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 23:38:42 -0800 Subject: s4 heimdal: Link libintl correctly --- source4/heimdal_build/internal.m4 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index 50a3c8adda..a48777fab1 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -170,6 +170,12 @@ SMB_ENABLE(OPENPTY,YES) SMB_EXT_LIB(OPENPTY,[${OPENPTY_LIBS}],[${OPENPTY_CFLAGS}],[${OPENPTY_CPPFLAGS}],[${OPENPTY_LDFLAGS}]) +AC_CHECK_LIB_EXT(intl, INTL_LIBS, gettext) + +SMB_ENABLE(INTL,YES) + +SMB_EXT_LIB(INTL, $INTL_LIBS) + smb_save_LIBS=$LIBS RESOLV_LIBS="" LIBS="" -- cgit From 4823e988b6360646931f9b6369bf7b8f512069a8 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Wed, 25 Feb 2009 20:26:27 +1100 Subject: WHATSNEW updates Signed-off-by: Andrew Bartlett --- WHATSNEW4.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WHATSNEW4.txt b/WHATSNEW4.txt index 2df23fd624..7c637ccd66 100644 --- a/WHATSNEW4.txt +++ b/WHATSNEW4.txt @@ -69,8 +69,11 @@ In the time since Samba4 alpha6 was released in Janurary 2009, Samba has continued to evolve, but you may particularly notice these areas (in no particular order): - OpenLDAP Multi Master Replication can now also replicate the OpenLDAP - configuration itself. + Multi Master Replication (MMR) configuration can now be generated + for the OpenLDAP-Backend. + + OpenLDAP-Online-Configuration (olc) can now be generated for the + OpenLDAP-Backend. (OpenLDAP-Versions >=2.4.15 required). Support for Windows 7 beta as a member of the Samba4 domain -- cgit From 9d165fa5c69d3c98d1a76a155bb794a7e4c9744a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 01:07:50 +0100 Subject: s3-spoolss: add rpccli_spoolss_addprinterex convenience wrapper. Guenther --- source3/include/proto.h | 3 +++ source3/rpc_client/cli_spoolss.c | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9366607995..5c9e5d3170 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5476,6 +5476,9 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, union spoolss_DriverInfo *info, uint32_t *server_major_version, uint32_t *server_minor_version); +WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterInfoCtr *info_ctr); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 19e9aae0f8..20599d12b6 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -137,6 +137,48 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, return werror; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_AddPrinterEx +**********************************************************************/ + +WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterInfoCtr *info_ctr) +{ + WERROR result; + NTSTATUS status; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + struct spoolss_UserLevelCtr userlevel_ctr; + struct spoolss_UserLevel1 level1; + struct policy_handle handle; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + level1.size = 28; + level1.build = 1381; + level1.major = 2; + level1.minor = 0; + level1.processor = 0; + level1.client = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); + W_ERROR_HAVE_NO_MEMORY(level1.client); + level1.user = cli->auth->user_name; + + userlevel_ctr.level = 1; + userlevel_ctr.user_info.level1 = &level1; + + status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx, + cli->srv_name_slash, + info_ctr, + &devmode_ctr, + &secdesc_ctr, + &userlevel_ctr, + &handle, + &result); + return result; +} + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ -- cgit From 9e3178e8387cd85858a145bb4918073f91127d20 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 10:54:19 +0100 Subject: Attempt to fix the OpenChange build -- sorry for the break --- lib/tevent/tevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 33747f0986..b3d1c6d59a 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -31,7 +31,7 @@ #include #include #include -#include <../lib/replace/replace.h> +#include struct tevent_context; struct tevent_ops; -- cgit From 6366084c4a7aa4845816cef6f1782e9d1c1f138c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 14 Feb 2009 03:07:01 +0100 Subject: s3-spoolss: add rpccli_spoolss_getprinter convenience wrapper. Guenther --- source3/include/proto.h | 6 +++++ source3/rpc_client/cli_spoolss.c | 50 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 5c9e5d3170..9ed8901fb3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5479,6 +5479,12 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct spoolss_SetPrinterInfoCtr *info_ctr); +WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + union spoolss_PrinterInfo *info); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 20599d12b6..4fe05a5ff4 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -179,6 +179,55 @@ WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, return result; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetPrinter +**********************************************************************/ + +WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + union spoolss_PrinterInfo *info) +{ + NTSTATUS status; + WERROR werror; + DATA_BLOB buffer; + uint32_t needed; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetPrinter(cli, mem_ctx, + handle, + level, + (offered > 0) ? &buffer : NULL, + offered, + info, + &needed, + &werror); + + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetPrinter(cli, mem_ctx, + handle, + level, + &buffer, + offered, + info, + &needed, + &werror); + } + + return werror; +} + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ @@ -1401,5 +1450,4 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me return out.status; } - /** @} **/ -- cgit From 1a77218dca0222aafff81aae6cd17462706e226e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 14 Feb 2009 03:08:06 +0100 Subject: s3-rpcclient: use rpccli_spoolss_SetPrinter and rpccli_spoolss_getprinter. Guenther --- source3/rpcclient/cmd_spoolss.c | 185 +++++++++++++++++++++++++++------------- 1 file changed, 124 insertions(+), 61 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 17ff818de6..4e1c7f1422 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -283,12 +283,10 @@ static void display_print_info_3(PRINTER_INFO_3 *i3) /**************************************************************************** ****************************************************************************/ -static void display_print_info_7(PRINTER_INFO_7 *i7) +static void display_print_info7(struct spoolss_PrinterInfo7 *r) { - fstring guid = ""; - rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE); - printf("\tguid:[%s]\n", guid); - printf("\taction:[0x%x]\n", i7->action); + printf("\tguid:[%s]\n", r->guid); + printf("\taction:[0x%x]\n", r->action); } @@ -469,10 +467,14 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 info_level = 2; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; if (argc == 1 || argc > 3) { printf("Usage: %s printername comment\n", argv[0]); @@ -485,6 +487,9 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, comment = argv[2]; } + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); /* get a printer handle */ @@ -498,18 +503,28 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, opened_hnd = True; /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Modify the comment. */ - init_unistr(&ctr.printers_2->comment, comment); - ctr.printers_2->devmode = NULL; - ctr.printers_2->secdesc = NULL; + info.info2.comment = comment; - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0); + info_ctr.level = 2; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (W_ERROR_IS_OK(result)) printf("Success in setting comment.\n"); @@ -529,11 +544,18 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 info_level = 2; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); if (argc == 1 || argc > 3) { printf("Usage: %s printername new_printername\n", argv[0]); @@ -559,17 +581,29 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, opened_hnd = True; /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Modify the printername. */ - init_unistr(&ctr.printers_2->printername, new_printername); - ctr.printers_2->devmode = NULL; - ctr.printers_2->secdesc = NULL; - - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0); + info.info2.printername = new_printername; + info.info2.devmode = NULL; + info.info2.secdesc = NULL; + + info_ctr.level = info_level; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (W_ERROR_IS_OK(result)) printf("Success in setting printername.\n"); @@ -591,8 +625,8 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, WERROR result; uint32 info_level = 1; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; const char *printername; + union spoolss_PrinterInfo info; if (argc == 1 || argc > 3) { printf("Usage: %s [level]\n", argv[0]); @@ -619,14 +653,17 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Display printer info */ - switch (info_level) { +#if 0 /* FIXME GD */ case 0: display_print_info_0(ctr.printers_0); break; @@ -639,14 +676,14 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, case 3: display_print_info_3(ctr.printers_3); break; +#endif case 7: - display_print_info_7(ctr.printers_7); + display_print_info7(&info.info7); break; default: printf("unknown info level %d\n", info_level); break; } - done: if (opened_hnd) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); @@ -1570,11 +1607,17 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 level = 2; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; - PRINTER_INFO_2 info2; const char *printername; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); /* parse the command arguments */ if (argc != 3) @@ -1598,11 +1641,11 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, /* Get printer info */ - ZERO_STRUCT (info2); - ctr.printers_2 = &info2; - - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + level, + 0, + &info); if (!W_ERROR_IS_OK(result)) { printf ("Unable to retrieve printer information!\n"); goto done; @@ -1610,10 +1653,17 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, /* Set the printer driver */ - init_unistr(&ctr.printers_2->drivername, argv[2]); - - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0); - + info.info2.drivername = argv[2]; + info_ctr.level = 2; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (!W_ERROR_IS_OK(result)) { printf("SetPrinter call failed!\n"); goto done;; @@ -2167,8 +2217,7 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, const char *printername; POLICY_HND pol; bool opened_hnd = False; - PRINTER_INFO_CTR ctr; - PRINTER_INFO_0 info; + union spoolss_PrinterInfo info; REGISTRY_VALUE value; TALLOC_CTX *tmp_ctx = talloc_stackframe(); @@ -2218,15 +2267,16 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, opened_hnd = True; - ctr.printers_0 = &info; - - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + 0, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; printf("%s\n", current_timestring(tmp_ctx, True)); - printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id); + printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id); /* Set the printer data */ @@ -2306,13 +2356,16 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, } printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]); - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + 0, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; printf("%s\n", current_timestring(tmp_ctx, True)); - printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id); + printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id); done: /* cleanup */ @@ -2706,12 +2759,16 @@ done: static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) { - PRINTER_INFO_CTR ctr1, ctr2; + union spoolss_PrinterInfo info1, info2; WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer"); printf("Retrieving printer propertiesfor %s...", cli1->desthost); - werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1); + werror = rpccli_spoolss_getprinter(cli1, mem_ctx, + hnd1, + 2, + 0, + &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); @@ -2720,7 +2777,11 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, printf("ok\n"); printf("Retrieving printer properties for %s...", cli2->desthost); - werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2); + werror = rpccli_spoolss_getprinter(cli2, mem_ctx, + hnd2, + 2, + 0, + &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); @@ -2739,7 +2800,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) { - PRINTER_INFO_CTR ctr1, ctr2; + union spoolss_PrinterInfo info1, info2; WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc"); SEC_DESC *sd1, *sd2; @@ -2747,7 +2808,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("Retrieving printer security for %s...", cli1->desthost); - werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1); + werror = rpccli_spoolss_getprinter(cli1, mem_ctx, + hnd1, + 3, + 0, + &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); result = False; @@ -2756,7 +2821,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("ok\n"); printf("Retrieving printer security for %s...", cli2->desthost); - werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2); + werror = rpccli_spoolss_getprinter(cli2, mem_ctx, + hnd2, + 3, + 0, + &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); result = False; @@ -2767,14 +2836,8 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("++ "); - if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) { - printf("NULL PRINTER_INFO_3!\n"); - result = False; - goto done; - } - - sd1 = ctr1.printers_3->secdesc; - sd2 = ctr2.printers_3->secdesc; + sd1 = info1.info3.secdesc; + sd2 = info2.info3.secdesc; if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) { printf("NULL secdesc!\n"); -- cgit From f8af5130d5515e017330a2123b933109599e072c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 10:58:53 +0100 Subject: s3-net: use rpccli_spoolss_getprinter and rpccli_spoolss_SetPrinter. Guenther --- source3/utils/net_rpc_printer.c | 169 +++++++++++++++++++++++++++++----------- 1 file changed, 123 insertions(+), 46 deletions(-) diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 17df69597f..0f21e1758b 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -775,13 +775,16 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo *info) { WERROR result; /* getprinter call */ - result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, hnd, level, ctr); - + result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, + hnd, + level, + 0, /* offered */ + info); if (!W_ERROR_IS_OK(result)) { printf("cannot get printer-info: %s\n", win_errstr(result)); return false; @@ -794,12 +797,64 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo *info) { WERROR result; + NTSTATUS status; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); /* setprinter call */ - result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, hnd, level, ctr, 0); + + info_ctr.level = level; + switch (level) { + case 0: + info_ctr.info.info0 = (struct spoolss_SetPrinterInfo0 *)&info->info0; + break; + case 1: + info_ctr.info.info1 = (struct spoolss_SetPrinterInfo1 *)&info->info1; + break; + case 2: + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info->info2; + break; + case 3: + info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *)&info->info3; + break; + case 4: + info_ctr.info.info4 = (struct spoolss_SetPrinterInfo4 *)&info->info4; + break; + case 5: + info_ctr.info.info5 = (struct spoolss_SetPrinterInfo5 *)&info->info5; + break; + case 6: + info_ctr.info.info6 = (struct spoolss_SetPrinterInfo6 *)&info->info6; + break; + case 7: + info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info->info7; + break; +#if 0 /* FIXME GD */ + case 8: + info_ctr.info.info8 = (struct spoolss_SetPrinterInfo8 *)&info->info8; + break; + case 9: + info_ctr.info.info9 = (struct spoolss_SetPrinterInfo9 *)&info->info9; + break; +#endif + default: + break; /* FIXME */ + } + + status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + hnd, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (!W_ERROR_IS_OK(result)) { printf("cannot set printer-info: %s\n", win_errstr(result)); @@ -1027,6 +1082,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, { POLICY_HND hnd; + union spoolss_PrinterInfo info; /* no arguments given, enumerate all printers */ if (argc == 0) { @@ -1039,6 +1095,8 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, goto out; } + /* FIXME GD */ + return false; /* argument given, get a single printer by name */ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0], @@ -1047,7 +1105,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, &hnd)) return false; - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, ctr)) { + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return false; } @@ -1216,7 +1274,11 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ uint32 i, num_printers; uint32 level = 7; char *printername, *sharename; - PRINTER_INFO_CTR ctr, ctr_pub; + PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; POLICY_HND hnd; bool got_hnd = false; WERROR result; @@ -1249,7 +1311,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ got_hnd = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; /* check action and set string */ @@ -1269,9 +1331,21 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ break; } - ctr_pub.printers_7->action = action; + info.info7.action = action; + info_ctr.level = 7; + info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info.info7; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + &hnd, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); - result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub, 0); if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) { printf("cannot set printer-info: %s\n", win_errstr(result)); goto done; @@ -1355,8 +1429,8 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, uint32 i, num_printers; uint32 level = 7; char *printername, *sharename; - char *guid; PRINTER_INFO_CTR ctr, ctr_pub; + union spoolss_PrinterInfo info; POLICY_HND hnd; bool got_hnd = false; int state; @@ -1390,23 +1464,18 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, got_hnd = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; - rpcstr_pull_talloc(mem_ctx, - &guid, - ctr_pub.printers_7->guid.buffer, - -1, - STR_TERMINATE); - if (!guid) { + if (!info.info7.guid) { goto done; } - state = ctr_pub.printers_7->action; + state = info.info7.action; switch (state) { case SPOOL_DS_PUBLISH: printf("printer [%s] is published", sharename); if (c->opt_verbose) - printf(", guid: %s", guid); + printf(", guid: %s", info.info7.guid); printf("\n"); break; case SPOOL_DS_UNPUBLISH: @@ -1468,8 +1537,9 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; + PRINTER_INFO_CTR ctr_src, ctr_enum; struct cli_state *cli_dst = NULL; + union spoolss_PrinterInfo info_src, info_dst; ZERO_STRUCT(ctr_src); @@ -1540,23 +1610,23 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, got_hnd_dst = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; /* check for existing src printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &ctr_src)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &info_src)) goto done; /* Copy Security Descriptor */ /* copy secdesc (info level 2) */ - ctr_dst.printers_2->devmode = NULL; - ctr_dst.printers_2->secdesc = dup_sec_desc(mem_ctx, ctr_src.printers_3->secdesc); + info_dst.info2.devmode = NULL; + info_dst.info2.secdesc = dup_sec_desc(mem_ctx, info_src.info3.secdesc); if (c->opt_verbose) - display_sec_desc(ctr_dst.printers_2->secdesc); + display_sec_desc(info_dst.info2.secdesc); - if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &ctr_dst)) + if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n")); @@ -1629,7 +1699,8 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum, ctr_dst; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst; uint32 num_forms; FORM_1 *forms; struct cli_state *cli_dst = NULL; @@ -1698,7 +1769,7 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; /* finally migrate forms */ @@ -1824,6 +1895,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, POLICY_HND hnd_src, hnd_dst; union spoolss_DriverInfo drv_info_src; PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst; + union spoolss_PrinterInfo info_dst; struct cli_state *cli_dst = NULL; struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; @@ -1903,7 +1975,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, got_hnd_dst = true; /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; @@ -1965,9 +2037,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, } /* setdriver dst */ - init_unistr(&info_ctr_dst.printers_2->drivername, drivername); + info_dst.info2.drivername = drivername; - if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) { + if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -2043,7 +2115,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, num_printers; uint32 level = 2; - PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst, info_src; struct cli_state *cli_dst = NULL; POLICY_HND hnd_dst, hnd_src; char *printername, *sharename; @@ -2105,7 +2178,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) { + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) { printf ("could not get printer, creating printer.\n"); } else { DEBUG(1,("printer already exists: %s\n", sharename)); @@ -2128,7 +2201,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, got_hnd_src = true; /* getprinter on the src server */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &ctr_src)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src)) goto done; /* copy each src printer to a dst printer 1:1, @@ -2212,7 +2285,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst_publish, info_dst; REGVAL_CTR *reg_ctr; struct cli_state *cli_dst = NULL; char *devicename = NULL, *unc_name = NULL, *url = NULL; @@ -2221,6 +2295,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint16 *keylist = NULL, *curkey; ZERO_STRUCT(ctr_enum); + /* FIXME GD */ + ZERO_STRUCT(info_dst_publish); DEBUG(3,("copying printer settings\n")); @@ -2293,31 +2369,32 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, - level, &ctr_dst)) + level, &info_dst)) goto done; +#if 0 /* FIXME GD */ /* STEP 1: COPY DEVICE-MODE and other PRINTER_INFO_2-attributes */ - ctr_dst.printers_2 = &ctr_enum.printers_2[i]; + info_dst.info2 = &ctr_enum.printers_2[i]; /* why is the port always disconnected when the printer is correctly installed (incl. driver ???) */ - init_unistr( &ctr_dst.printers_2->portname, SAMBA_PRINTER_PORT_NAME); + info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME; /* check if printer is published */ if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) { /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish)) goto done; - ctr_dst_publish.printers_7->action = SPOOL_DS_PUBLISH; + info_dst_publish.info7.action = SPOOL_DS_PUBLISH; /* ignore false from setprinter due to WERR_IO_PENDING */ - net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish); + net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish); DEBUG(3,("republished printer\n")); } @@ -2325,14 +2402,14 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, if (ctr_enum.printers_2[i].devmode != NULL) { /* copy devmode (info level 2) */ - ctr_dst.printers_2->devmode = (DEVICEMODE *) + info_dst.info2.devmode = (DEVICEMODE *) TALLOC_MEMDUP(mem_ctx, ctr_enum.printers_2[i].devmode, sizeof(DEVICEMODE)); /* do not copy security descriptor (we have another * command for that) */ - ctr_dst.printers_2->secdesc = NULL; + info_dst.info2.secdesc = NULL; #if 0 if (asprintf(&devicename, "\\\\%s\\%s", longname, @@ -2345,12 +2422,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, devicename); #endif if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, - level, &ctr_dst)) + level, &info_dst)) goto done; DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n")); } - +#endif /* STEP 2: COPY REGISTRY VALUES */ /* please keep in mind that samba parse_spools gives horribly -- cgit From 109ba07b0e2ce45cc0a960bcafd0e8d28c877ae3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 01:11:01 +0100 Subject: s3-spoolss: use rpccli_spoolss_addprinterex wrapper. Guenther --- source3/rpcclient/cmd_spoolss.c | 29 ++--------------------------- source3/utils/net_rpc_printer.c | 9 ++++++++- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 4e1c7f1422..ba01f7aa8b 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1526,14 +1526,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR result; - NTSTATUS status; struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_SetPrinterInfo2 info2; - struct policy_handle handle; - struct spoolss_DevmodeContainer devmode_ctr; - struct sec_desc_buf sd; - struct spoolss_UserLevelCtr userlevel_ctr; - struct spoolss_UserLevel1 level1; /* parse the command arguments */ if (argc != 5) @@ -1543,9 +1537,7 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, } /* Fill in the DRIVER_INFO_2 struct */ - ZERO_STRUCT(devmode_ctr); ZERO_STRUCT(info2); - ZERO_STRUCT(sd); info2.printername = argv[1]; info2.drivername = argv[3]; @@ -1573,25 +1565,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, info_ctr.level = 2; info_ctr.info.info2 = &info2; - level1.size = 28; /* wild guess */ - level1.build = 1381; - level1.major = 2; - level1.minor = 0; - level1.processor = 0; - level1.client = global_myname(); - level1.user = cli->auth->user_name; - - userlevel_ctr.level = 1; - userlevel_ctr.user_info.level1 = &level1; - - status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx, - cli->srv_name_slash, - &info_ctr, - &devmode_ctr, - &sd, - &userlevel_ctr, - &handle, - &result); + result = rpccli_spoolss_addprinterex(cli, mem_ctx, + &info_ctr); if (W_ERROR_IS_OK(result)) printf ("Printer %s successfully installed.\n", argv[1]); diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 0f21e1758b..f4dd824c84 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -2123,6 +2123,7 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, bool got_hnd_src = false; bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; + struct spoolss_SetPrinterInfoCtr info_ctr; DEBUG(3,("copying printers\n")); @@ -2207,7 +2208,13 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, /* copy each src printer to a dst printer 1:1, maybe some values have to be changed though */ d_printf("creating printer: %s\n", printername); - result = rpccli_spoolss_addprinterex (pipe_hnd_dst, mem_ctx, level, &ctr_src); + + info_ctr.level = level; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info_src.info2; + + result = rpccli_spoolss_addprinterex(pipe_hnd_dst, + mem_ctx, + &info_ctr); if (W_ERROR_IS_OK(result)) d_printf ("printer [%s] successfully added.\n", printername); -- cgit From c7ba20b465e4c2bf893891ab7ace8172704bb27c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 10 Feb 2009 23:37:00 +0100 Subject: s3-spoolss: remove rpccli_spoolss_addprinterex. Guenther --- source3/include/proto.h | 9 -- source3/include/rpc_spoolss.h | 34 ------ source3/rpc_client/cli_spoolss.c | 35 ------ source3/rpc_parse/parse_spoolss.c | 221 -------------------------------------- 4 files changed, 299 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 9ed8901fb3..4691dc70ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5501,8 +5501,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, uint32 level, const char *env, uint32 *num_drivers, PRINTER_DRIVER_CTR *ctr); -WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr); WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *handle, int level, uint32 *num_forms, FORM_1 **forms); @@ -5813,11 +5811,7 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ); bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); -bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, - const char *srv_name, const char* clientname, const char* user_name, - uint32 level, PRINTER_INFO_CTR *ctr); bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, PRINTER_INFO_2 *info); bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, @@ -5930,9 +5924,6 @@ bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth); bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth); bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); -bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, - prs_struct *ps, int depth); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, NT_PRINTER_INFO_LEVEL_2 *d); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 48609a3cd6..65fab7d319 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -261,25 +261,6 @@ PRINTER_MESSAGE_INFO; #define DRIVER_MAX_VERSION 4 -/* this struct is undocumented */ -/* thanks to the ddk ... */ -typedef struct { - uint32 size; /* length of user_name & client_name + 2? */ - UNISTR2 *client_name; - UNISTR2 *user_name; - uint32 build; - uint32 major; - uint32 minor; - uint32 processor; -} SPOOL_USER_1; - -typedef struct { - uint32 level; - union { - SPOOL_USER_1 *user1; - } user; -} SPOOL_USER_CTR; - /* * Devicemode structure */ @@ -966,21 +947,6 @@ SPOOL_R_SETPRINTER; /********************************************/ -typedef struct { - UNISTR2 *server_name; - uint32 level; - SPOOL_PRINTER_INFO_LEVEL info; - DEVMODE_CTR devmode_ctr; - SEC_DESC_BUF *secdesc_ctr; - uint32 user_switch; - SPOOL_USER_CTR user_ctr; -} SPOOL_Q_ADDPRINTEREX; - -typedef struct { - POLICY_HND handle; - WERROR status; -} SPOOL_R_ADDPRINTEREX; - typedef struct spool_q_enumprintprocessors { uint32 name_ptr; diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 4fe05a5ff4..b063a33ca6 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -977,41 +977,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTEREX in; - SPOOL_R_ADDPRINTEREX out; - fstring server, client, user; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname()); - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - - strupper_m(client); - strupper_m(server); - - fstrcpy (user, cli->auth->user_name); - - make_spoolss_q_addprinterex( mem_ctx, &in, server, client, - user, level, ctr); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX, - in, out, - qbuf, rbuf, - spoolss_io_q_addprinterex, - spoolss_io_r_addprinterex, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *handle, int level, uint32 *num_forms, FORM_1 **forms) diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 12c7af49cf..4bf831c53d 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -70,78 +70,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) return True; } -/******************************************************************* -********************************************************************/ - -bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ) -{ - prs_debug(ps, depth, desc, ""); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &q_u->size)) - return False; - - if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name)) - return False; - if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name)) - return False; - - if (!prs_uint32("build", ps, depth, &q_u->build)) - return False; - if (!prs_uint32("major", ps, depth, &q_u->major)) - return False; - if (!prs_uint32("minor", ps, depth, &q_u->minor)) - return False; - if (!prs_uint32("processor", ps, depth, &q_u->processor)) - return False; - - if (!prs_io_unistr2("", ps, depth, q_u->client_name)) - return False; - if (!prs_align(ps)) - return False; - - if (!prs_io_unistr2("", ps, depth, q_u->user_name)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth) -{ - if (q_u==NULL) - return False; - - prs_debug(ps, depth, desc, "spool_io_user_level"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - switch ( q_u->level ) - { - case 1: - if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, - sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) - { - return False; - } - break; - default: - return False; - } - - return True; -} - /******************************************************************* * read or write a DEVICEMODE struct. * on reading allocate memory for the private member @@ -376,72 +304,6 @@ static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_str return True; } -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, - const char *srv_name, const char* clientname, const char* user_name, - uint32 level, PRINTER_INFO_CTR *ctr) -{ - DEBUG(5,("make_spoolss_q_addprinterex\n")); - - if (!ctr || !ctr->printers_2) - return False; - - ZERO_STRUCTP(q_u); - - q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->server_name) { - return False; - } - init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE); - - q_u->level = level; - - q_u->info.level = level; - q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0; - switch (level) { - case 2: - /* init q_u->info.info2 from *info */ - if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) { - DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n")); - return False; - } - break; - default : - break; - } - - q_u->user_switch=1; - - q_u->user_ctr.level = 1; - q_u->user_ctr.user.user1 = TALLOC_P( talloc_tos(), SPOOL_USER_1 ); - if (!q_u->user_ctr.user.user1) { - return False; - } - q_u->user_ctr.user.user1->build = 1381; - q_u->user_ctr.user.user1->major = 2; - q_u->user_ctr.user.user1->minor = 0; - q_u->user_ctr.user.user1->processor = 0; - - q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->user_ctr.user.user1->client_name) { - return False; - } - q_u->user_ctr.user.user1->user_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->user_ctr.user.user1->user_name) { - return False; - } - init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE); - init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE); - - q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len + - q_u->user_ctr.user.user1->client_name->uni_str_len + 2; - - return True; -} - /******************************************************************* create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct *******************************************************************/ @@ -3017,89 +2879,6 @@ bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, return True; } -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth) -{ - uint32 ptr_sec_desc = 0; - - prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name)) - return False; - if (!prs_io_unistr2("servername", ps, depth, q_u->server_name)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("info_level", ps, depth, &q_u->level)) - return False; - - if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) - return False; - - if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - switch (q_u->level) { - case 2: - ptr_sec_desc = q_u->info.info_2->secdesc_ptr; - break; - case 3: - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; - break; - } - if (ptr_sec_desc) { - if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) - return False; - } else { - uint32 dummy = 0; - - /* Parse a NULL security descriptor. This should really - happen inside the sec_io_desc_buf() function. */ - - prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) - return False; - if (!prs_uint32("ptr", ps, depth + 1, &dummy)) - return False; - } - - if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch)) - return False; - if(!spool_io_user_level("", &q_u->user_ctr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex"); - depth++; - - if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ -- cgit From c03f2072762d91240fe90a2f02542e521313e7ef Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 00:12:58 +0100 Subject: s3-spoolss: remove rpccli_spoolss_setprinter. Guenther --- source3/include/proto.h | 21 -- source3/include/rpc_spoolss.h | 92 ------ source3/rpc_client/cli_spoolss.c | 26 -- source3/rpc_parse/parse_spoolss.c | 585 -------------------------------------- 4 files changed, 724 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 4691dc70ec..d6ec7013cf 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5493,9 +5493,6 @@ WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr); -WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, @@ -5812,12 +5809,6 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); -bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info); -bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, - PRINTER_INFO_3 *info); -bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, - PRINTER_INFO_7 *info); bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, const POLICY_HND *handle, const char *valuename, uint32 size); @@ -5895,11 +5886,6 @@ bool make_spoolss_q_getprinter( RPC_BUFFER *buffer, uint32 offered ); -bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, - uint32 command); -bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth); bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, @@ -5919,14 +5905,7 @@ bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth); -bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); -bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, - NT_PRINTER_INFO_LEVEL_2 *d); bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 65fab7d319..c494fdd6bf 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -853,98 +853,6 @@ typedef struct spool_r_enumforms } SPOOL_R_ENUMFORMS; -typedef struct spool_printer_info_level_1 -{ - uint32 flags; - uint32 description_ptr; - uint32 name_ptr; - uint32 comment_ptr; - UNISTR2 description; - UNISTR2 name; - UNISTR2 comment; -} SPOOL_PRINTER_INFO_LEVEL_1; - -typedef struct spool_printer_info_level_2 -{ - uint32 servername_ptr; - uint32 printername_ptr; - uint32 sharename_ptr; - uint32 portname_ptr; - uint32 drivername_ptr; - uint32 comment_ptr; - uint32 location_ptr; - uint32 devmode_ptr; - uint32 sepfile_ptr; - uint32 printprocessor_ptr; - uint32 datatype_ptr; - uint32 parameters_ptr; - uint32 secdesc_ptr; - uint32 attributes; - uint32 priority; - uint32 default_priority; - uint32 starttime; - uint32 untiltime; - uint32 status; - uint32 cjobs; - uint32 averageppm; - UNISTR2 servername; - UNISTR2 printername; - UNISTR2 sharename; - UNISTR2 portname; - UNISTR2 drivername; - UNISTR2 comment; - UNISTR2 location; - UNISTR2 sepfile; - UNISTR2 printprocessor; - UNISTR2 datatype; - UNISTR2 parameters; -} -SPOOL_PRINTER_INFO_LEVEL_2; - -typedef struct spool_printer_info_level_3 -{ - uint32 secdesc_ptr; -} -SPOOL_PRINTER_INFO_LEVEL_3; - -typedef struct spool_printer_info_level_7 -{ - uint32 guid_ptr; - uint32 action; - UNISTR2 guid; -} -SPOOL_PRINTER_INFO_LEVEL_7; - -typedef struct spool_printer_info_level -{ - uint32 level; - uint32 info_ptr; - SPOOL_PRINTER_INFO_LEVEL_1 *info_1; - SPOOL_PRINTER_INFO_LEVEL_2 *info_2; - SPOOL_PRINTER_INFO_LEVEL_3 *info_3; - SPOOL_PRINTER_INFO_LEVEL_7 *info_7; -} -SPOOL_PRINTER_INFO_LEVEL; - -typedef struct spool_q_setprinter -{ - POLICY_HND handle; - uint32 level; - SPOOL_PRINTER_INFO_LEVEL info; - SEC_DESC_BUF *secdesc_ctr; - DEVMODE_CTR devmode_ctr; - - uint32 command; - -} -SPOOL_Q_SETPRINTER; - -typedef struct spool_r_setprinter -{ - WERROR status; -} -SPOOL_R_SETPRINTER; - /********************************************/ typedef struct spool_q_enumprintprocessors diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index b063a33ca6..3986766e43 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -866,32 +866,6 @@ WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTER in; - SPOOL_R_SETPRINTER out; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_setprinter, - spoolss_io_r_setprinter, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 4bf831c53d..d749d2ef9b 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -258,154 +258,6 @@ bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE return True; } -/******************************************************************* - Read or write a DEVICEMODE container -********************************************************************/ - -static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth) -{ - if (dm_c==NULL) - return False; - - prs_debug(ps, depth, desc, "spoolss_io_devmode_cont"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &dm_c->size)) - return False; - - if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr)) - return False; - - if (dm_c->size==0 || dm_c->devmode_ptr==0) { - if (UNMARSHALLING(ps)) - /* if while reading there is no DEVMODE ... */ - dm_c->devmode=NULL; - return True; - } - - /* so we have a DEVICEMODE to follow */ - if (UNMARSHALLING(ps)) { - DEBUG(9,("Allocating memory for spoolss_io_devmode\n")); - dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1); - if(dm_c->devmode == NULL) - return False; - } - - /* this is bad code, shouldn't be there */ - if (!prs_uint32("size", ps, depth, &dm_c->size)) - return False; - - if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode)) - return False; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct -*******************************************************************/ - -bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_2 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) { - DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n")); - return False; - } - - inf->servername_ptr = (info->servername.buffer!=NULL)?1:0; - inf->printername_ptr = (info->printername.buffer!=NULL)?1:0; - inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0; - inf->portname_ptr = (info->portname.buffer!=NULL)?1:0; - inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0; - inf->comment_ptr = (info->comment.buffer!=NULL)?1:0; - inf->location_ptr = (info->location.buffer!=NULL)?1:0; - inf->devmode_ptr = (info->devmode!=NULL)?1:0; - inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0; - inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0; - inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0; - inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0; - inf->secdesc_ptr = (info->secdesc!=NULL)?1:0; - inf->attributes = info->attributes; - inf->priority = info->priority; - inf->default_priority = info->defaultpriority; - inf->starttime = info->starttime; - inf->untiltime = info->untiltime; - inf->cjobs = info->cjobs; - inf->averageppm = info->averageppm; - init_unistr2_from_unistr(inf, &inf->servername, &info->servername); - init_unistr2_from_unistr(inf, &inf->printername, &info->printername); - init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename); - init_unistr2_from_unistr(inf, &inf->portname, &info->portname); - init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername); - init_unistr2_from_unistr(inf, &inf->comment, &info->comment); - init_unistr2_from_unistr(inf, &inf->location, &info->location); - init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile); - init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor); - init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype); - init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters); - init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype); - - *spool_info2 = inf; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct -*******************************************************************/ - -bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, - PRINTER_INFO_3 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_3 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) { - DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n")); - return False; - } - - inf->secdesc_ptr = (info->secdesc!=NULL)?1:0; - - *spool_info3 = inf; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct -*******************************************************************/ - -bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, - PRINTER_INFO_7 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_7 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) { - DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n")); - return False; - } - - inf->guid_ptr = (info->guid.buffer!=NULL)?1:0; - inf->action = info->action; - init_unistr2_from_unistr(inf, &inf->guid, &info->guid); - - *spool_info7 = inf; - - return True; -} - /******************************************************************* * make a structure. ********************************************************************/ @@ -2178,185 +2030,6 @@ bool make_spoolss_q_getprinter( return True; } -/******************************************************************* - * init a structure. - ********************************************************************/ -bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, - uint32 command) -{ - SEC_DESC *secdesc; - DEVICEMODE *devmode; - - if (!q_u || !info) - return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level = level; - q_u->info.level = level; - q_u->info.info_ptr = 1; /* Info is != NULL, see above */ - switch (level) { - - /* There's no such thing as a setprinter level 1 */ - - case 2: - secdesc = info->printers_2->secdesc; - devmode = info->printers_2->devmode; - - make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2); -#if 1 /* JERRY TEST */ - q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF); - if (!q_u->secdesc_ctr) - return False; - q_u->secdesc_ctr->sd = secdesc; - q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; - - q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0; - q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0; - q_u->devmode_ctr.devmode = devmode; -#else - q_u->secdesc_ctr = NULL; - - q_u->devmode_ctr.devmode_ptr = 0; - q_u->devmode_ctr.size = 0; - q_u->devmode_ctr.devmode = NULL; -#endif - break; - case 3: - secdesc = info->printers_3->secdesc; - - make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3); - - q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF); - if (!q_u->secdesc_ctr) - return False; - q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; - q_u->secdesc_ctr->sd = secdesc; - - break; - case 7: - make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7); - break; - - default: - DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level)); - break; - } - - - q_u->command = command; - - return True; -} - - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_setprinter"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - Marshall/unmarshall a SPOOL_Q_SETPRINTER struct. -********************************************************************/ - -bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth) -{ - uint32 ptr_sec_desc = 0; - - prs_debug(ps, depth, desc, "spoolss_io_q_setprinter"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth)) - return False; - if(!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - /* check for supported levels and structures we know about */ - - switch ( q_u->level ) { - case 0: - case 2: - case 3: - case 7: - /* supported levels */ - break; - default: - DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", - q_u->level)); - return True; - } - - - if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) - return False; - - if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - switch (q_u->level) - { - case 2: - { - ptr_sec_desc = q_u->info.info_2->secdesc_ptr; - break; - } - case 3: - { - /* FIXME ! Our parsing here is wrong I think, - * but for a level3 it makes no sense for - * ptr_sec_desc to be NULL. JRA. Based on - * a Vista sniff from Martin Zielinski . - */ - if (UNMARSHALLING(ps)) { - ptr_sec_desc = 1; - } else { - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; - } - break; - } - } - if (ptr_sec_desc) - { - if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) - return False; - } else { - uint32 dummy = 0; - - /* Parse a NULL security descriptor. This should really - happen inside the sec_io_desc_buf() function. */ - - prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) - return False; - if (!prs_uint32("ptr", ps, depth + 1, &dummy)) - return False; - } - - if(!prs_uint32("command", ps, depth, &q_u->command)) - return False; - - return True; -} - /******************************************************************* ********************************************************************/ @@ -2652,233 +2325,6 @@ bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct return True; } -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure. -********************************************************************/ - -bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_1"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("flags", ps, depth, &il->flags)) - return False; - if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr)) - return False; - if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) - return False; - - if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure. -********************************************************************/ - -bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure. -********************************************************************/ - -bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr)) - return False; - if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr)) - return False; - if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr)) - return False; - if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr)) - return False; - - if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr)) - return False; - if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) - return False; - if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr)) - return False; - if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr)) - return False; - if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr)) - return False; - if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr)) - return False; - if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr)) - return False; - if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr)) - return False; - if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) - return False; - - if(!prs_uint32("attributes", ps, depth, &il->attributes)) - return False; - if(!prs_uint32("priority", ps, depth, &il->priority)) - return False; - if(!prs_uint32("default_priority", ps, depth, &il->default_priority)) - return False; - if(!prs_uint32("starttime", ps, depth, &il->starttime)) - return False; - if(!prs_uint32("untiltime", ps, depth, &il->untiltime)) - return False; - if(!prs_uint32("status", ps, depth, &il->status)) - return False; - if(!prs_uint32("cjobs", ps, depth, &il->cjobs)) - return False; - if(!prs_uint32("averageppm", ps, depth, &il->averageppm)) - return False; - - if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth)) - return False; - - return True; -} - -bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_7"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr)) - return False; - if(!prs_uint32("action", ps, depth, &il->action)) - return False; - - if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth)) - return False; - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("level", ps, depth, &il->level)) - return False; - if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr)) - return False; - - /* if no struct inside just return */ - if (il->info_ptr==0) { - if (UNMARSHALLING(ps)) { - il->info_1=NULL; - il->info_2=NULL; - } - return True; - } - - switch (il->level) { - /* - * level 0 is used by setprinter when managing the queue - * (hold, stop, start a queue) - */ - case 0: - break; - /* DOCUMENT ME!!! What is level 1 used for? */ - case 1: - { - if (UNMARSHALLING(ps)) { - if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_1("", il->info_1, ps, depth)) - return False; - break; - } - /* - * level 2 is used by addprinter - * and by setprinter when updating printer's info - */ - case 2: - if (UNMARSHALLING(ps)) { - if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_2("", il->info_2, ps, depth)) - return False; - break; - /* DOCUMENT ME!!! What is level 3 used for? */ - case 3: - { - if (UNMARSHALLING(ps)) { - if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_3("", il->info_3, ps, depth)) - return False; - break; - } - case 7: - if (UNMARSHALLING(ps)) - if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL) - return False; - if (!spool_io_printer_info_level_7("", il->info_7, ps, depth)) - return False; - break; - } - - return True; -} - /******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ @@ -2903,37 +2349,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 return True; } -/******************************************************************* - ********************************************************************/ - -bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, - NT_PRINTER_INFO_LEVEL_2 *d) -{ - DEBUG(7,("Converting from UNICODE to ASCII\n")); - - d->attributes=uni->attributes; - d->priority=uni->priority; - d->default_priority=uni->default_priority; - d->starttime=uni->starttime; - d->untiltime=uni->untiltime; - d->status=uni->status; - d->cjobs=uni->cjobs; - - unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)); - unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)); - unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)); - unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)); - unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)); - unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)); - unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)); - unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)); - unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)); - unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)); - unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)); - - return True; -} - /******************************************************************* ********************************************************************/ -- cgit From 59e90d3715a577503434ace9e01bfe63dfcfa714 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 01:23:40 +0100 Subject: s3-spoolss: remove rpccli_spoolss_getprinter. Guenther --- source3/include/proto.h | 11 ----- source3/rpc_client/cli_spoolss.c | 84 --------------------------------------- source3/rpc_parse/parse_spoolss.c | 26 ------------ 3 files changed, 121 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d6ec7013cf..8084111145 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5490,9 +5490,6 @@ WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem uint32 *num_printers, PRINTER_INFO_CTR *ctr); WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr); -WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, @@ -5878,14 +5875,6 @@ bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_ bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); -bool make_spoolss_q_getprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_GETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -); bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 3986766e43..c9d23efdf2 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -782,90 +782,6 @@ WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTER in; - SPOOL_R_GETPRINTER out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - /* Initialise input parameters */ - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinter, - spoolss_io_r_getprinter, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinter, - spoolss_io_r_getprinter, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 0: - if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) { - return WERR_GENERAL_FAILURE; - } - break; - case 1: - if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) { - return WERR_GENERAL_FAILURE; - } - break; - case 7: - if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index d749d2ef9b..c9c897253a 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -2004,32 +2004,6 @@ bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru return True; } -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_GETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -) -{ - if (q_u == NULL) - { - return False; - } - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level=level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - /******************************************************************* ********************************************************************/ -- cgit From a041d9061922b1a90e5b5047af77934d908afdd5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 12:09:15 +0100 Subject: s3-spoolss: use is_valid_policy_hnd to check for valid policy handles. Guenther --- source3/rpcclient/cmd_spoolss.c | 40 ++++------------- source3/utils/net_rpc_printer.c | 98 ++++++++++------------------------------- 2 files changed, 31 insertions(+), 107 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index ba01f7aa8b..fe2554e02d 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -469,7 +469,6 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, WERROR result; NTSTATUS status; uint32 info_level = 2; - bool opened_hnd = False; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; @@ -500,8 +499,6 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, @@ -529,7 +526,7 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, printf("Success in setting comment.\n"); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -546,7 +543,6 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, WERROR result; NTSTATUS status; uint32 info_level = 2; - bool opened_hnd = False; union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; @@ -578,8 +574,6 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, @@ -608,7 +602,7 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, printf("Success in setting printername.\n"); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -624,7 +618,6 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR result; uint32 info_level = 1; - bool opened_hnd = False; const char *printername; union spoolss_PrinterInfo info; @@ -649,8 +642,6 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, @@ -685,7 +676,7 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, break; } done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -761,7 +752,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; - bool opened_hnd = False; fstring printername; const char *valuename; REGISTRY_VALUE value; @@ -790,8 +780,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value); @@ -806,7 +794,7 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -822,7 +810,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR result; NTSTATUS status; - bool opened_hnd = False; fstring printername; const char *valuename, *keyname; REGISTRY_VALUE value; @@ -858,8 +845,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx, @@ -907,7 +892,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, display_reg_value(value); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -1095,7 +1080,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR werror; uint32 info_level = 3; - bool opened_hnd = False; const char *printername; uint32 i; bool success = False; @@ -1127,8 +1111,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, return werror; } - opened_hnd = True; - /* loop through and print driver info level for each architecture */ for (i=0; archi_table[i].long_archi!=NULL; i++) { @@ -1170,7 +1152,7 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, /* Cleanup */ - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); if ( success ) @@ -1584,7 +1566,6 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, WERROR result; NTSTATUS status; uint32 level = 2; - bool opened_hnd = False; const char *printername; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -1612,8 +1593,6 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinter(cli, mem_ctx, @@ -1649,7 +1628,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, done: /* Cleanup */ - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -2191,7 +2170,6 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, WERROR result; const char *printername; POLICY_HND pol; - bool opened_hnd = False; union spoolss_PrinterInfo info; REGISTRY_VALUE value; TALLOC_CTX *tmp_ctx = talloc_stackframe(); @@ -2240,8 +2218,6 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, @@ -2345,7 +2321,7 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, done: /* cleanup */ TALLOC_FREE(tmp_ctx); - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index f4dd824c84..99012ddf2d 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -1280,7 +1280,6 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ struct spoolss_DevmodeContainer devmode_ctr; struct sec_desc_buf secdesc_ctr; POLICY_HND hnd; - bool got_hnd = false; WERROR result; const char *action_str; @@ -1308,8 +1307,6 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ PRINTER_ALL_ACCESS, pipe_hnd->auth->user_name, &hnd)) goto done; - got_hnd = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; @@ -1357,7 +1354,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ nt_status = NT_STATUS_OK; done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return nt_status; @@ -1432,7 +1429,6 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, PRINTER_INFO_CTR ctr, ctr_pub; union spoolss_PrinterInfo info; POLICY_HND hnd; - bool got_hnd = false; int state; if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr)) @@ -1461,8 +1457,6 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd)) goto done; - got_hnd = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; @@ -1493,7 +1487,7 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, nt_status = NT_STATUS_OK; done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return nt_status; @@ -1533,8 +1527,6 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, uint32 num_printers; uint32 level = 2; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_src, ctr_enum; @@ -1600,15 +1592,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; @@ -1633,14 +1621,12 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -1649,11 +1635,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, done: - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); } @@ -1695,8 +1681,6 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, uint32 num_printers; uint32 level = 1; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_enum; @@ -1757,17 +1741,11 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; @@ -1829,14 +1807,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -1844,10 +1820,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -1887,8 +1863,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, uint32 num_printers; uint32 level = 3; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; bool got_src_driver_share = false; bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; @@ -1972,8 +1946,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; @@ -1986,9 +1958,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, &hnd_src)) goto done; - got_hnd_src = true; - - /* in a first step call getdriver for each shared printer (per arch) to get a list of all files that have to be copied */ @@ -2048,15 +2017,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, drivername, printername)); /* close dst */ - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } /* close src */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } } @@ -2064,10 +2031,10 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -2120,8 +2087,6 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, struct cli_state *cli_dst = NULL; POLICY_HND hnd_dst, hnd_src; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -2174,8 +2139,6 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) { DEBUG(1,("could not open printer: %s\n", sharename)); - } else { - got_hnd_dst = true; } /* check for existing dst printer */ @@ -2184,9 +2147,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } else { DEBUG(1,("printer already exists: %s\n", sharename)); /* close printer handle here - dst only, not got src yet. */ - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } continue; } @@ -2199,8 +2161,6 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - /* getprinter on the src server */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src)) goto done; @@ -2226,24 +2186,22 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } nt_status = NT_STATUS_OK; done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -2288,8 +2246,6 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint32 num_printers, val_needed, data_needed; uint32 level = 2; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_enum; @@ -2363,17 +2319,11 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) @@ -2613,14 +2563,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, SAFE_FREE(keylist); /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -2632,10 +2580,10 @@ done: SAFE_FREE(url); SAFE_FREE(unc_name); - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { -- cgit