diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2009-02-12 16:00:46 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2009-02-12 16:00:46 +0100 |
commit | 082ba6a1ad3a68aff118d96f855a2aa65eaeb359 (patch) | |
tree | d70b7e8012e787a11ea1c12224318643cdd552c3 | |
parent | 762fdc8c5c2db304f3dc4536c19d69366d1399df (diff) | |
parent | 4f6d1728254c8503e71c6fdd008fb7264dec26c5 (diff) | |
download | samba-082ba6a1ad3a68aff118d96f855a2aa65eaeb359.tar.gz samba-082ba6a1ad3a68aff118d96f855a2aa65eaeb359.tar.bz2 samba-082ba6a1ad3a68aff118d96f855a2aa65eaeb359.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
39 files changed, 1688 insertions, 637 deletions
diff --git a/lib/replace/libreplace_network.m4 b/lib/replace/libreplace_network.m4 index 30be30f4ab..78fb1abaf0 100644 --- a/lib/replace/libreplace_network.m4 +++ b/lib/replace/libreplace_network.m4 @@ -353,6 +353,7 @@ AC_CACHE_CHECK([for ipv6 support],libreplace_cv_HAVE_IPV6,[ #include <sys/socket.h> #include <sys/types.h> #include <netdb.h> +#include <netinet/in.h> ], [ struct sockaddr_storage sa_store; diff --git a/libcli/util/ntstatus.h b/libcli/util/ntstatus.h index 139562d8c2..1608e2874f 100644 --- a/libcli/util/ntstatus.h +++ b/libcli/util/ntstatus.h @@ -60,6 +60,9 @@ typedef uint32_t NTSTATUS; #define ERROR_INSUFFICIENT_BUFFER NT_STATUS(0x007a) #define ERROR_INVALID_DATATYPE NT_STATUS(0x070c) +/* XXX Win7 Status code: Name unknown. */ +#define NT_STATUS_WIN7_INVALID_RANGE NT_STATUS(0xC0000000 | 0x01a1) + /* Win32 Error codes extracted using a loop in smbclient then printing a netmon sniff to a file. */ diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c index 492f2c2a71..2f15cb30bb 100644 --- a/librpc/gen_ndr/cli_spoolss.c +++ b/librpc/gen_ndr/cli_spoolss.c @@ -3107,23 +3107,34 @@ NTSTATUS rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct rpc_pipe_cli return werror_to_ntstatus(r.out.result); } -NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotification(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - WERROR *werror) +NTSTATUS rpccli_spoolss_RouterReplyPrinterEx(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + uint32_t color /* [in] */, + uint32_t flags /* [in] */, + uint32_t *reply_result /* [out] [ref] */, + uint32_t reply_type /* [in] */, + union spoolss_ReplyPrinterInfo info /* [in] [switch_is(reply_type)] */, + WERROR *werror) { - struct spoolss_RouterRefreshPrinterChangeNotification r; + struct spoolss_RouterReplyPrinterEx r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.color = color; + r.in.flags = flags; + r.in.reply_type = reply_type; + r.in.info = info; if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(spoolss_RouterRefreshPrinterChangeNotification, &r); + NDR_PRINT_IN_DEBUG(spoolss_RouterReplyPrinterEx, &r); } status = cli->dispatch(cli, mem_ctx, &ndr_table_spoolss, - NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION, + NDR_SPOOLSS_ROUTERREPLYPRINTEREX, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3131,7 +3142,7 @@ NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotification(struct rpc_pipe_c } if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(spoolss_RouterRefreshPrinterChangeNotification, &r); + NDR_PRINT_OUT_DEBUG(spoolss_RouterReplyPrinterEx, &r); } if (NT_STATUS_IS_ERR(status)) { @@ -3139,6 +3150,7 @@ NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotification(struct rpc_pipe_c } /* Return variables */ + *reply_result = *r.out.reply_result; /* Return result */ if (werror) { @@ -3148,15 +3160,15 @@ NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotification(struct rpc_pipe_c return werror_to_ntstatus(r.out.result); } -NTSTATUS rpccli_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct policy_handle *handle /* [in] [ref] */, - uint32_t change_low /* [in] */, - struct spoolss_NotifyOptionsContainer *container /* [in] [unique] */, - struct spoolss_NotifyInfo **info /* [out] [ref] */, - WERROR *werror) +NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotify(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + uint32_t change_low /* [in] */, + struct spoolss_NotifyOptionsContainer *container /* [in] [unique] */, + struct spoolss_NotifyInfo **info /* [out] [ref] */, + WERROR *werror) { - struct spoolss_RemoteFindNextPrinterChangeNotifyEx r; + struct spoolss_RouterRefreshPrinterChangeNotify r; NTSTATUS status; /* In parameters */ @@ -3165,13 +3177,13 @@ NTSTATUS rpccli_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct rpc_pipe_clie r.in.container = container; if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(spoolss_RemoteFindNextPrinterChangeNotifyEx, &r); + NDR_PRINT_IN_DEBUG(spoolss_RouterRefreshPrinterChangeNotify, &r); } status = cli->dispatch(cli, mem_ctx, &ndr_table_spoolss, - NDR_SPOOLSS_REMOTEFINDNEXTPRINTERCHANGENOTIFYEX, + NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3179,7 +3191,7 @@ NTSTATUS rpccli_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct rpc_pipe_clie } if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(spoolss_RemoteFindNextPrinterChangeNotifyEx, &r); + NDR_PRINT_OUT_DEBUG(spoolss_RouterRefreshPrinterChangeNotify, &r); } if (NT_STATUS_IS_ERR(status)) { diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h index 25000a4cc4..6903aa6909 100644 --- a/librpc/gen_ndr/cli_spoolss.h +++ b/librpc/gen_ndr/cli_spoolss.h @@ -382,16 +382,22 @@ NTSTATUS rpccli_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct rpc_pipe_cli uint32_t printer_local /* [in] */, struct spoolss_NotifyOptionsContainer *t1 /* [in] [unique] */, WERROR *werror); -NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotification(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - WERROR *werror); -NTSTATUS rpccli_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct policy_handle *handle /* [in] [ref] */, - uint32_t change_low /* [in] */, - struct spoolss_NotifyOptionsContainer *container /* [in] [unique] */, - struct spoolss_NotifyInfo **info /* [out] [ref] */, - WERROR *werror); +NTSTATUS rpccli_spoolss_RouterReplyPrinterEx(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + uint32_t color /* [in] */, + uint32_t flags /* [in] */, + uint32_t *reply_result /* [out] [ref] */, + uint32_t reply_type /* [in] */, + union spoolss_ReplyPrinterInfo info /* [in] [switch_is(reply_type)] */, + WERROR *werror); +NTSTATUS rpccli_spoolss_RouterRefreshPrinterChangeNotify(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + uint32_t change_low /* [in] */, + struct spoolss_NotifyOptionsContainer *container /* [in] [unique] */, + struct spoolss_NotifyInfo **info /* [out] [ref] */, + WERROR *werror); NTSTATUS rpccli_spoolss_44(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, WERROR *werror); diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index 9ef5d37336..5525ad4586 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -10602,6 +10602,124 @@ _PUBLIC_ void ndr_print_spoolss_NotifyInfo(struct ndr_print *ndr, const char *na ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_ReplyPrinterInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_ReplyPrinterInfo *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level)); + switch (level) { + case 0: { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info0)); + break; } + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case 0: + if (r->info0) { + NDR_CHECK(ndr_push_spoolss_NotifyInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->info0)); + } + break; + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_ReplyPrinterInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_ReplyPrinterInfo *r) +{ + int level; + uint32_t _level; + TALLOC_CTX *_mem_save_info0_0; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level)); + if (_level != level) { + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level); + } + switch (level) { + case 0: { + uint32_t _ptr_info0; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info0)); + if (_ptr_info0) { + NDR_PULL_ALLOC(ndr, r->info0); + } else { + r->info0 = NULL; + } + break; } + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case 0: + if (r->info0) { + _mem_save_info0_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info0, 0); + NDR_CHECK(ndr_pull_spoolss_NotifyInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->info0)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info0_0, 0); + } + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_ReplyPrinterInfo(struct ndr_print *ndr, const char *name, const union spoolss_ReplyPrinterInfo *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "spoolss_ReplyPrinterInfo"); + switch (level) { + case 0: + ndr_print_ptr(ndr, "info0", r->info0); + ndr->depth++; + if (r->info0) { + ndr_print_spoolss_NotifyInfo(ndr, "info0", r->info0); + } + ndr->depth--; + break; + + default: + ndr_print_bad_level(ndr, name, level); + } +} + +static enum ndr_err_code ndr_push_spoolss_PrinterNotifyFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_PrinterNotifyFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_PrinterNotifyFlags(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_NOTIFY_INFO_DISCARDED", PRINTER_NOTIFY_INFO_DISCARDED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_NOTIFY_INFO_DISCARDNOTED", PRINTER_NOTIFY_INFO_DISCARDNOTED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "PRINTER_NOTIFY_INFO_COLOR_MISMATCH", PRINTER_NOTIFY_INFO_COLOR_MISMATCH, r); + ndr->depth--; +} + static enum ndr_err_code ndr_push_spoolss_UserLevel1(struct ndr_push *ndr, int ndr_flags, const struct spoolss_UserLevel1 *r) { if (ndr_flags & NDR_SCALARS) { @@ -10828,6 +10946,35 @@ _PUBLIC_ void ndr_print_spoolss_DeleteDriverFlags(struct ndr_print *ndr, const c ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_AddPrinterDriverExFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_AddPrinterDriverExFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_AddPrinterDriverExFlags(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_STRICT_UPGRADE", APD_STRICT_UPGRADE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_STRICT_DOWNGRADE", APD_STRICT_DOWNGRADE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_COPY_ALL_FILES", APD_COPY_ALL_FILES, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_COPY_NEW_FILES", APD_COPY_NEW_FILES, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_COPY_FROM_DIRECTORY", APD_COPY_FROM_DIRECTORY, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_DONT_COPY_FILES_TO_CLUSTER", APD_DONT_COPY_FILES_TO_CLUSTER, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_COPY_TO_ALL_SPOOLERS", APD_COPY_TO_ALL_SPOOLERS, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "APD_RETURN_BLOCKING_STATUS_CODE", APD_RETURN_BLOCKING_STATUS_CODE, r); + ndr->depth--; +} + _PUBLIC_ enum ndr_err_code ndr_push__spoolss_EnumPrinters(struct ndr_push *ndr, int flags, const struct _spoolss_EnumPrinters *r) { if (flags & NDR_IN) { @@ -16638,48 +16785,99 @@ _PUBLIC_ void ndr_print_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct ndr_ ndr->depth--; } -static enum ndr_err_code ndr_push_spoolss_RouterRefreshPrinterChangeNotification(struct ndr_push *ndr, int flags, const struct spoolss_RouterRefreshPrinterChangeNotification *r) +static enum ndr_err_code ndr_push_spoolss_RouterReplyPrinterEx(struct ndr_push *ndr, int flags, const struct spoolss_RouterReplyPrinterEx *r) { if (flags & NDR_IN) { + if (r->in.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.color)); + NDR_CHECK(ndr_push_spoolss_PrinterChangeFlags(ndr, NDR_SCALARS, r->in.flags)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.reply_type)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.info, r->in.reply_type)); + NDR_CHECK(ndr_push_spoolss_ReplyPrinterInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); } if (flags & NDR_OUT) { + if (r->out.reply_result == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_spoolss_PrinterNotifyFlags(ndr, NDR_SCALARS, *r->out.reply_result)); NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_spoolss_RouterRefreshPrinterChangeNotification(struct ndr_pull *ndr, int flags, struct spoolss_RouterRefreshPrinterChangeNotification *r) +static enum ndr_err_code ndr_pull_spoolss_RouterReplyPrinterEx(struct ndr_pull *ndr, int flags, struct spoolss_RouterReplyPrinterEx *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_reply_result_0; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.color)); + NDR_CHECK(ndr_pull_spoolss_PrinterChangeFlags(ndr, NDR_SCALARS, &r->in.flags)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.reply_type)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.info, r->in.reply_type)); + NDR_CHECK(ndr_pull_spoolss_ReplyPrinterInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); + NDR_PULL_ALLOC(ndr, r->out.reply_result); + ZERO_STRUCTP(r->out.reply_result); } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.reply_result); + } + _mem_save_reply_result_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.reply_result, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_spoolss_PrinterNotifyFlags(ndr, NDR_SCALARS, r->out.reply_result)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_reply_result_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; } -_PUBLIC_ void ndr_print_spoolss_RouterRefreshPrinterChangeNotification(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RouterRefreshPrinterChangeNotification *r) +_PUBLIC_ void ndr_print_spoolss_RouterReplyPrinterEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RouterReplyPrinterEx *r) { - ndr_print_struct(ndr, name, "spoolss_RouterRefreshPrinterChangeNotification"); + ndr_print_struct(ndr, name, "spoolss_RouterReplyPrinterEx"); ndr->depth++; if (flags & NDR_SET_VALUES) { ndr->flags |= LIBNDR_PRINT_SET_VALUES; } if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "spoolss_RouterRefreshPrinterChangeNotification"); + ndr_print_struct(ndr, "in", "spoolss_RouterReplyPrinterEx"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_uint32(ndr, "color", r->in.color); + ndr_print_spoolss_PrinterChangeFlags(ndr, "flags", r->in.flags); + ndr_print_uint32(ndr, "reply_type", r->in.reply_type); + ndr_print_set_switch_value(ndr, &r->in.info, r->in.reply_type); + ndr_print_spoolss_ReplyPrinterInfo(ndr, "info", &r->in.info); ndr->depth--; } if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "spoolss_RouterRefreshPrinterChangeNotification"); + ndr_print_struct(ndr, "out", "spoolss_RouterReplyPrinterEx"); + ndr->depth++; + ndr_print_ptr(ndr, "reply_result", r->out.reply_result); ndr->depth++; + ndr_print_spoolss_PrinterNotifyFlags(ndr, "reply_result", *r->out.reply_result); + ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } ndr->depth--; } -_PUBLIC_ enum ndr_err_code ndr_push_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_push *ndr, int flags, const struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r) +_PUBLIC_ enum ndr_err_code ndr_push_spoolss_RouterRefreshPrinterChangeNotify(struct ndr_push *ndr, int flags, const struct spoolss_RouterRefreshPrinterChangeNotify *r) { if (flags & NDR_IN) { if (r->in.handle == NULL) { @@ -16705,7 +16903,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_RemoteFindNextPrinterChangeNotifyEx( return NDR_ERR_SUCCESS; } -_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_pull *ndr, int flags, struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r) +_PUBLIC_ enum ndr_err_code ndr_pull_spoolss_RouterRefreshPrinterChangeNotify(struct ndr_pull *ndr, int flags, struct spoolss_RouterRefreshPrinterChangeNotify *r) { uint32_t _ptr_container; uint32_t _ptr_info; @@ -16763,15 +16961,15 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_RemoteFindNextPrinterChangeNotifyEx( return NDR_ERR_SUCCESS; } -_PUBLIC_ void ndr_print_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r) +_PUBLIC_ void ndr_print_spoolss_RouterRefreshPrinterChangeNotify(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RouterRefreshPrinterChangeNotify *r) { - ndr_print_struct(ndr, name, "spoolss_RemoteFindNextPrinterChangeNotifyEx"); + ndr_print_struct(ndr, name, "spoolss_RouterRefreshPrinterChangeNotify"); ndr->depth++; if (flags & NDR_SET_VALUES) { ndr->flags |= LIBNDR_PRINT_SET_VALUES; } if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "spoolss_RemoteFindNextPrinterChangeNotifyEx"); + ndr_print_struct(ndr, "in", "spoolss_RouterRefreshPrinterChangeNotify"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->in.handle); ndr->depth++; @@ -16787,7 +16985,7 @@ _PUBLIC_ void ndr_print_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_p ndr->depth--; } if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "spoolss_RemoteFindNextPrinterChangeNotifyEx"); + ndr_print_struct(ndr, "out", "spoolss_RouterRefreshPrinterChangeNotify"); ndr->depth++; ndr_print_ptr(ndr, "info", r->out.info); ndr->depth++; @@ -18580,7 +18778,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_AddPrinterDriverEx(struct ndr_push * NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level)); NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.info, r->in.level)); NDR_CHECK(ndr_push_spoolss_AddDriverInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags)); + NDR_CHECK(ndr_push_spoolss_AddPrinterDriverExFlags(ndr, NDR_SCALARS, r->in.flags)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); @@ -18601,7 +18799,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_AddPrinterDriverEx(struct ndr_pull * NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level)); NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.info, r->in.level)); NDR_CHECK(ndr_pull_spoolss_AddDriverInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.flags)); + NDR_CHECK(ndr_pull_spoolss_AddPrinterDriverExFlags(ndr, NDR_SCALARS, &r->in.flags)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); @@ -18626,7 +18824,7 @@ _PUBLIC_ void ndr_print_spoolss_AddPrinterDriverEx(struct ndr_print *ndr, const ndr_print_uint32(ndr, "level", r->in.level); ndr_print_set_switch_value(ndr, &r->in.info, r->in.level); ndr_print_spoolss_AddDriverInfo(ndr, "info", &r->in.info); - ndr_print_uint32(ndr, "flags", r->in.flags); + ndr_print_spoolss_AddPrinterDriverExFlags(ndr, "flags", r->in.flags); ndr->depth--; } if (flags & NDR_OUT) { @@ -19414,19 +19612,19 @@ static const struct ndr_interface_call spoolss_calls[] = { false, }, { - "spoolss_RouterRefreshPrinterChangeNotification", - sizeof(struct spoolss_RouterRefreshPrinterChangeNotification), - (ndr_push_flags_fn_t) ndr_push_spoolss_RouterRefreshPrinterChangeNotification, - (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterRefreshPrinterChangeNotification, - (ndr_print_function_t) ndr_print_spoolss_RouterRefreshPrinterChangeNotification, + "spoolss_RouterReplyPrinterEx", + sizeof(struct spoolss_RouterReplyPrinterEx), + (ndr_push_flags_fn_t) ndr_push_spoolss_RouterReplyPrinterEx, + (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterReplyPrinterEx, + (ndr_print_function_t) ndr_print_spoolss_RouterReplyPrinterEx, false, }, { - "spoolss_RemoteFindNextPrinterChangeNotifyEx", - sizeof(struct spoolss_RemoteFindNextPrinterChangeNotifyEx), - (ndr_push_flags_fn_t) ndr_push_spoolss_RemoteFindNextPrinterChangeNotifyEx, - (ndr_pull_flags_fn_t) ndr_pull_spoolss_RemoteFindNextPrinterChangeNotifyEx, - (ndr_print_function_t) ndr_print_spoolss_RemoteFindNextPrinterChangeNotifyEx, + "spoolss_RouterRefreshPrinterChangeNotify", + sizeof(struct spoolss_RouterRefreshPrinterChangeNotify), + (ndr_push_flags_fn_t) ndr_push_spoolss_RouterRefreshPrinterChangeNotify, + (ndr_pull_flags_fn_t) ndr_pull_spoolss_RouterRefreshPrinterChangeNotify, + (ndr_print_function_t) ndr_print_spoolss_RouterRefreshPrinterChangeNotify, false, }, { diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index 6240290e4c..ef97a01ecd 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -144,9 +144,9 @@ extern const struct ndr_interface_table ndr_table_spoolss; #define NDR_SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX (0x41) -#define NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION (0x42) +#define NDR_SPOOLSS_ROUTERREPLYPRINTEREX (0x42) -#define NDR_SPOOLSS_REMOTEFINDNEXTPRINTERCHANGENOTIFYEX (0x43) +#define NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY (0x43) #define NDR_SPOOLSS_44 (0x44) @@ -315,11 +315,14 @@ void ndr_print_spoolss_NotifyBlob(struct ndr_print *ndr, const char *name, const void ndr_print_spoolss_NotifyData(struct ndr_print *ndr, const char *name, const union spoolss_NotifyData *r); void ndr_print_spoolss_Notify(struct ndr_print *ndr, const char *name, const struct spoolss_Notify *r); void ndr_print_spoolss_NotifyInfo(struct ndr_print *ndr, const char *name, const struct spoolss_NotifyInfo *r); +void ndr_print_spoolss_ReplyPrinterInfo(struct ndr_print *ndr, const char *name, const union spoolss_ReplyPrinterInfo *r); +void ndr_print_spoolss_PrinterNotifyFlags(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_spoolss_UserLevel1(struct ndr_print *ndr, const char *name, const struct spoolss_UserLevel1 *r); void ndr_print_spoolss_UserLevel(struct ndr_print *ndr, const char *name, const union spoolss_UserLevel *r); enum ndr_err_code ndr_push_spoolss_DeleteDriverFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r); enum ndr_err_code ndr_pull_spoolss_DeleteDriverFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r); void ndr_print_spoolss_DeleteDriverFlags(struct ndr_print *ndr, const char *name, uint32_t r); +void ndr_print_spoolss_AddPrinterDriverExFlags(struct ndr_print *ndr, const char *name, uint32_t r); enum ndr_err_code ndr_push__spoolss_EnumPrinters(struct ndr_push *ndr, int flags, const struct _spoolss_EnumPrinters *r); enum ndr_err_code ndr_pull__spoolss_EnumPrinters(struct ndr_pull *ndr, int flags, struct _spoolss_EnumPrinters *r); void ndr_print__spoolss_EnumPrinters(struct ndr_print *ndr, const char *name, int flags, const struct _spoolss_EnumPrinters *r); @@ -473,10 +476,10 @@ void ndr_print_spoolss_ResetPrinterEx(struct ndr_print *ndr, const char *name, i enum ndr_err_code ndr_push_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct ndr_push *ndr, int flags, const struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r); enum ndr_err_code ndr_pull_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct ndr_pull *ndr, int flags, struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r); void ndr_print_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r); -void ndr_print_spoolss_RouterRefreshPrinterChangeNotification(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RouterRefreshPrinterChangeNotification *r); -enum ndr_err_code ndr_push_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_push *ndr, int flags, const struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r); -enum ndr_err_code ndr_pull_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_pull *ndr, int flags, struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r); -void ndr_print_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r); +void ndr_print_spoolss_RouterReplyPrinterEx(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RouterReplyPrinterEx *r); +enum ndr_err_code ndr_push_spoolss_RouterRefreshPrinterChangeNotify(struct ndr_push *ndr, int flags, const struct spoolss_RouterRefreshPrinterChangeNotify *r); +enum ndr_err_code ndr_pull_spoolss_RouterRefreshPrinterChangeNotify(struct ndr_pull *ndr, int flags, struct spoolss_RouterRefreshPrinterChangeNotify *r); +void ndr_print_spoolss_RouterRefreshPrinterChangeNotify(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_RouterRefreshPrinterChangeNotify *r); void ndr_print_spoolss_44(struct ndr_print *ndr, const char *name, int flags, const struct spoolss_44 *r); enum ndr_err_code ndr_push_spoolss_OpenPrinterEx(struct ndr_push *ndr, int flags, const struct spoolss_OpenPrinterEx *r); enum ndr_err_code ndr_pull_spoolss_OpenPrinterEx(struct ndr_pull *ndr, int flags, struct spoolss_OpenPrinterEx *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index 4e854db009..3554d37b39 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -877,6 +877,15 @@ struct spoolss_NotifyInfo { struct spoolss_Notify *notifies;/* [size_is(count)] */ }; +union spoolss_ReplyPrinterInfo { + struct spoolss_NotifyInfo *info0;/* [unique,case(0)] */ +}/* [switch_type(uint32)] */; + +/* bitmap spoolss_PrinterNotifyFlags */ +#define PRINTER_NOTIFY_INFO_DISCARDED ( 0x00000001 ) +#define PRINTER_NOTIFY_INFO_DISCARDNOTED ( 0x00010000 ) +#define PRINTER_NOTIFY_INFO_COLOR_MISMATCH ( 0x00080000 ) + struct spoolss_UserLevel1 { uint32_t size; const char *client;/* [unique,charset(UTF16)] */ @@ -903,6 +912,16 @@ union spoolss_UserLevel { #define DPD_DELETE_SPECIFIC_VERSION ( 0x00000002 ) #define DPD_DELETE_ALL_FILES ( 0x00000004 ) +/* bitmap spoolss_AddPrinterDriverExFlags */ +#define APD_STRICT_UPGRADE ( 0x00000001 ) +#define APD_STRICT_DOWNGRADE ( 0x00000002 ) +#define APD_COPY_ALL_FILES ( 0x00000004 ) +#define APD_COPY_NEW_FILES ( 0x00000008 ) +#define APD_COPY_FROM_DIRECTORY ( 0x00000010 ) +#define APD_DONT_COPY_FILES_TO_CLUSTER ( 0x00001000 ) +#define APD_COPY_TO_ALL_SPOOLERS ( 0x00002000 ) +#define APD_RETURN_BLOCKING_STATUS_CODE ( 0x00010000 ) + struct _spoolss_EnumPrinters { struct { @@ -2017,15 +2036,24 @@ struct spoolss_RemoteFindFirstPrinterChangeNotifyEx { }; -struct spoolss_RouterRefreshPrinterChangeNotification { +struct spoolss_RouterReplyPrinterEx { + struct { + struct policy_handle *handle;/* [ref] */ + uint32_t color; + uint32_t flags; + uint32_t reply_type; + union spoolss_ReplyPrinterInfo info;/* [switch_is(reply_type)] */ + } in; + struct { + uint32_t *reply_result;/* [ref] */ WERROR result; } out; }; -struct spoolss_RemoteFindNextPrinterChangeNotifyEx { +struct spoolss_RouterRefreshPrinterChangeNotify { struct { struct policy_handle *handle;/* [ref] */ uint32_t change_low; diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c index c6f5d62b32..1f8c89a53f 100644 --- a/librpc/gen_ndr/srv_spoolss.c +++ b/librpc/gen_ndr/srv_spoolss.c @@ -5058,18 +5058,18 @@ static bool api_spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p) return true; } -static bool api_spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p) +static bool api_spoolss_RouterReplyPrinterEx(pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; DATA_BLOB blob; - struct spoolss_RouterRefreshPrinterChangeNotification *r; + struct spoolss_RouterReplyPrinterEx *r; - call = &ndr_table_spoolss.calls[NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION]; + call = &ndr_table_spoolss.calls[NDR_SPOOLSS_ROUTERREPLYPRINTEREX]; - r = talloc(talloc_tos(), struct spoolss_RouterRefreshPrinterChangeNotification); + r = talloc(talloc_tos(), struct spoolss_RouterReplyPrinterEx); if (r == NULL) { return false; } @@ -5093,10 +5093,17 @@ static bool api_spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p) } if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(spoolss_RouterRefreshPrinterChangeNotification, r); + NDR_PRINT_IN_DEBUG(spoolss_RouterReplyPrinterEx, r); } - r->out.result = _spoolss_RouterRefreshPrinterChangeNotification(p, r); + ZERO_STRUCT(r->out); + r->out.reply_result = talloc_zero(r, uint32_t); + if (r->out.reply_result == NULL) { + talloc_free(r); + return false; + } + + r->out.result = _spoolss_RouterReplyPrinterEx(p, r); if (p->rng_fault_state) { talloc_free(r); @@ -5105,7 +5112,7 @@ static bool api_spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p) } if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(spoolss_RouterRefreshPrinterChangeNotification, r); + NDR_PRINT_OUT_DEBUG(spoolss_RouterReplyPrinterEx, r); } push = ndr_push_init_ctx(r, NULL); @@ -5131,18 +5138,18 @@ static bool api_spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p) return true; } -static bool api_spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p) +static bool api_spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; DATA_BLOB blob; - struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r; + struct spoolss_RouterRefreshPrinterChangeNotify *r; - call = &ndr_table_spoolss.calls[NDR_SPOOLSS_REMOTEFINDNEXTPRINTERCHANGENOTIFYEX]; + call = &ndr_table_spoolss.calls[NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY]; - r = talloc(talloc_tos(), struct spoolss_RemoteFindNextPrinterChangeNotifyEx); + r = talloc(talloc_tos(), struct spoolss_RouterRefreshPrinterChangeNotify); if (r == NULL) { return false; } @@ -5166,7 +5173,7 @@ static bool api_spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p) } if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(spoolss_RemoteFindNextPrinterChangeNotifyEx, r); + NDR_PRINT_IN_DEBUG(spoolss_RouterRefreshPrinterChangeNotify, r); } ZERO_STRUCT(r->out); @@ -5176,7 +5183,7 @@ static bool api_spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p) return false; } - r->out.result = _spoolss_RemoteFindNextPrinterChangeNotifyEx(p, r); + r->out.result = _spoolss_RouterRefreshPrinterChangeNotify(p, r); if (p->rng_fault_state) { talloc_free(r); @@ -5185,7 +5192,7 @@ static bool api_spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p) } if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(spoolss_RemoteFindNextPrinterChangeNotifyEx, r); + NDR_PRINT_OUT_DEBUG(spoolss_RouterRefreshPrinterChangeNotify, r); } push = ndr_push_init_ctx(r, NULL); @@ -7428,8 +7435,8 @@ static struct api_struct api_spoolss_cmds[] = {"SPOOLSS_SPOOLERINIT", NDR_SPOOLSS_SPOOLERINIT, api_spoolss_SpoolerInit}, {"SPOOLSS_RESETPRINTEREX", NDR_SPOOLSS_RESETPRINTEREX, api_spoolss_ResetPrinterEx}, {"SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX", NDR_SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFYEX, api_spoolss_RemoteFindFirstPrinterChangeNotifyEx}, - {"SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION", NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION, api_spoolss_RouterRefreshPrinterChangeNotification}, - {"SPOOLSS_REMOTEFINDNEXTPRINTERCHANGENOTIFYEX", NDR_SPOOLSS_REMOTEFINDNEXTPRINTERCHANGENOTIFYEX, api_spoolss_RemoteFindNextPrinterChangeNotifyEx}, + {"SPOOLSS_ROUTERREPLYPRINTEREX", NDR_SPOOLSS_ROUTERREPLYPRINTEREX, api_spoolss_RouterReplyPrinterEx}, + {"SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY", NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY, api_spoolss_RouterRefreshPrinterChangeNotify}, {"SPOOLSS_44", NDR_SPOOLSS_44, api_spoolss_44}, {"SPOOLSS_OPENPRINTEREX", NDR_SPOOLSS_OPENPRINTEREX, api_spoolss_OpenPrinterEx}, {"SPOOLSS_ADDPRINTEREX", NDR_SPOOLSS_ADDPRINTEREX, api_spoolss_AddPrinterEx}, @@ -8069,21 +8076,27 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - case NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION: { - struct spoolss_RouterRefreshPrinterChangeNotification *r = (struct spoolss_RouterRefreshPrinterChangeNotification *)_r; - r->out.result = _spoolss_RouterRefreshPrinterChangeNotification(cli->pipes_struct, r); + case NDR_SPOOLSS_ROUTERREPLYPRINTEREX: { + struct spoolss_RouterReplyPrinterEx *r = (struct spoolss_RouterReplyPrinterEx *)_r; + ZERO_STRUCT(r->out); + r->out.reply_result = talloc_zero(mem_ctx, uint32_t); + if (r->out.reply_result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + r->out.result = _spoolss_RouterReplyPrinterEx(cli->pipes_struct, r); return NT_STATUS_OK; } - case NDR_SPOOLSS_REMOTEFINDNEXTPRINTERCHANGENOTIFYEX: { - struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r = (struct spoolss_RemoteFindNextPrinterChangeNotifyEx *)_r; + case NDR_SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFY: { + struct spoolss_RouterRefreshPrinterChangeNotify *r = (struct spoolss_RouterRefreshPrinterChangeNotify *)_r; ZERO_STRUCT(r->out); r->out.info = talloc_zero(mem_ctx, struct spoolss_NotifyInfo *); if (r->out.info == NULL) { return NT_STATUS_NO_MEMORY; } - r->out.result = _spoolss_RemoteFindNextPrinterChangeNotifyEx(cli->pipes_struct, r); + r->out.result = _spoolss_RouterRefreshPrinterChangeNotify(cli->pipes_struct, r); return NT_STATUS_OK; } diff --git a/librpc/gen_ndr/srv_spoolss.h b/librpc/gen_ndr/srv_spoolss.h index 82e9faf993..da31eb78b6 100644 --- a/librpc/gen_ndr/srv_spoolss.h +++ b/librpc/gen_ndr/srv_spoolss.h @@ -67,8 +67,8 @@ WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p, struct WERROR _spoolss_SpoolerInit(pipes_struct *p, struct spoolss_SpoolerInit *r); WERROR _spoolss_ResetPrinterEx(pipes_struct *p, struct spoolss_ResetPrinterEx *r); WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r); -WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p, struct spoolss_RouterRefreshPrinterChangeNotification *r); -WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p, struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r); +WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p, struct spoolss_RouterReplyPrinterEx *r); +WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, struct spoolss_RouterRefreshPrinterChangeNotify *r); WERROR _spoolss_44(pipes_struct *p, struct spoolss_44 *r); WERROR _spoolss_OpenPrinterEx(pipes_struct *p, struct spoolss_OpenPrinterEx *r); WERROR _spoolss_AddPrinterEx(pipes_struct *p, struct spoolss_AddPrinterEx *r); @@ -165,8 +165,8 @@ WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p, struct WERROR _spoolss_SpoolerInit(pipes_struct *p, struct spoolss_SpoolerInit *r); WERROR _spoolss_ResetPrinterEx(pipes_struct *p, struct spoolss_ResetPrinterEx *r); WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r); -WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p, struct spoolss_RouterRefreshPrinterChangeNotification *r); -WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p, struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r); +WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p, struct spoolss_RouterReplyPrinterEx *r); +WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, struct spoolss_RouterRefreshPrinterChangeNotify *r); WERROR _spoolss_44(pipes_struct *p, struct spoolss_44 *r); WERROR _spoolss_OpenPrinterEx(pipes_struct *p, struct spoolss_OpenPrinterEx *r); WERROR _spoolss_AddPrinterEx(pipes_struct *p, struct spoolss_AddPrinterEx *r); diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 294ab50aaf..3e1d6620f7 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1442,8 +1442,6 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x42 */ - [todo] WERROR spoolss_RouterRefreshPrinterChangeNotification( - ); typedef struct { uint32 size; @@ -1487,9 +1485,28 @@ import "misc.idl", "security.idl", "winreg.idl"; [size_is(count)] spoolss_Notify notifies[]; } spoolss_NotifyInfo; + typedef [switch_type(uint32)] union { + [case(0)] spoolss_NotifyInfo *info0; + } spoolss_ReplyPrinterInfo; + + typedef [bitmap32bit] bitmap { + PRINTER_NOTIFY_INFO_DISCARDED = 0x00000001, + PRINTER_NOTIFY_INFO_DISCARDNOTED = 0x00010000, + PRINTER_NOTIFY_INFO_COLOR_MISMATCH = 0x00080000 + } spoolss_PrinterNotifyFlags; + + WERROR spoolss_RouterReplyPrinterEx( + [in,ref] policy_handle *handle, + [in] uint32 color, + [in] spoolss_PrinterChangeFlags flags, + [out,ref] spoolss_PrinterNotifyFlags *reply_result, + [in] uint32 reply_type, + [in,switch_is(reply_type)] spoolss_ReplyPrinterInfo info + ); + /******************/ /* Function: 0x43 */ - [public] WERROR spoolss_RemoteFindNextPrinterChangeNotifyEx( + [public] WERROR spoolss_RouterRefreshPrinterChangeNotify( [in,ref] policy_handle *handle, [in] uint32 change_low, [in,unique] spoolss_NotifyOptionsContainer *container, @@ -1751,11 +1768,23 @@ import "misc.idl", "security.idl", "winreg.idl"; /******************/ /* Function: 0x59 */ + + typedef [bitmap32bit] bitmap { + APD_STRICT_UPGRADE = 0x00000001, + APD_STRICT_DOWNGRADE = 0x00000002, + APD_COPY_ALL_FILES = 0x00000004, + APD_COPY_NEW_FILES = 0x00000008, + APD_COPY_FROM_DIRECTORY = 0x00000010, + APD_DONT_COPY_FILES_TO_CLUSTER = 0x00001000, + APD_COPY_TO_ALL_SPOOLERS = 0x00002000, + APD_RETURN_BLOCKING_STATUS_CODE = 0x00010000 + } spoolss_AddPrinterDriverExFlags; + [public] WERROR spoolss_AddPrinterDriverEx( [in] [string,charset(UTF16)] uint16 *servername, [in] uint32 level, [in,switch_is(level)] spoolss_AddDriverInfo info, - [in] uint32 flags + [in] spoolss_AddPrinterDriverExFlags flags ); /******************/ diff --git a/nsswitch/libwbclient/wbc_pwd.c b/nsswitch/libwbclient/wbc_pwd.c index cd945996c8..dacd9499dd 100644 --- a/nsswitch/libwbclient/wbc_pwd.c +++ b/nsswitch/libwbclient/wbc_pwd.c @@ -190,6 +190,45 @@ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd) return wbc_status; } +/* Fill in a struct passwd* for a domain user based on sid */ +wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct winbindd_request request; + struct winbindd_response response; + char * sid_string = NULL; + + if (!pwd) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = wbcSidToString(sid, &sid_string); + BAIL_ON_WBC_ERROR(wbc_status); + + /* Initialize request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.sid, sid_string, sizeof(request.data.sid)); + + wbc_status = wbcRequestResponse(WINBINDD_GETPWSID, + &request, + &response); + BAIL_ON_WBC_ERROR(wbc_status); + + *pwd = copy_passwd_entry(&response.data.pw); + BAIL_ON_PTR_ERROR(*pwd, wbc_status); + + done: + if (sid_string) { + wbcFreeMemory(sid_string); + } + + return wbc_status; +} + /* Fill in a struct passwd* for a domain user based on username */ wbcErr wbcGetgrnam(const char *name, struct group **grp) { diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c index e2157b9609..46c59a9513 100644 --- a/nsswitch/libwbclient/wbc_sid.c +++ b/nsswitch/libwbclient/wbc_sid.c @@ -491,6 +491,145 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, return wbc_status; } +static inline +wbcErr _sid_to_rid(struct wbcDomainSid *sid, uint32_t *rid) +{ + if (sid->num_auths < 1) { + return WBC_ERR_INVALID_RESPONSE; + } + *rid = sid->sub_auths[sid->num_auths - 1]; + + return WBC_ERR_SUCCESS; +} + +/* Get alias membership for sids */ +wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, + struct wbcDomainSid *sids, + uint32_t num_sids, + uint32_t **alias_rids, + uint32_t *num_alias_rids) +{ + uint32_t i; + const char *s; + struct winbindd_request request; + struct winbindd_response response; + char *sid_string = NULL; + ssize_t sid_len; + ssize_t extra_data_len = 0; + char * extra_data = NULL; + ssize_t buflen = 0; + struct wbcDomainSid sid; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + uint32_t * rids = NULL; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (!dom_sid) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = wbcSidToString(dom_sid, &sid_string); + BAIL_ON_WBC_ERROR(wbc_status); + + strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1); + wbcFreeMemory(sid_string); + sid_string = NULL; + + /* Lets assume each sid is around 54 characters + * S-1-5-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */ + buflen = 54 * num_sids; + extra_data = talloc_array(NULL, char, buflen); + if (!extra_data) { + wbc_status = WBC_ERR_NO_MEMORY; + BAIL_ON_WBC_ERROR(wbc_status); + } + + /* Build the sid list */ + for (i=0; i<num_sids; i++) { + if (sid_string) { + wbcFreeMemory(sid_string); + sid_string = NULL; + } + wbc_status = wbcSidToString(&sids[i], &sid_string); + BAIL_ON_WBC_ERROR(wbc_status); + + sid_len = strlen(sid_string); + + if (buflen < extra_data_len + sid_len + 2) { + buflen *= 2; + extra_data = talloc_realloc(NULL, extra_data, + char, buflen); + if (!extra_data) { + wbc_status = WBC_ERR_NO_MEMORY; + BAIL_ON_WBC_ERROR(wbc_status); + } + } + + strncpy(&extra_data[extra_data_len], sid_string, + buflen - extra_data_len); + extra_data_len += sid_len; + extra_data[extra_data_len++] = '\n'; + extra_data[extra_data_len] = '\0'; + } + + request.extra_data.data = extra_data; + request.extra_len = extra_data_len; + + wbc_status = wbcRequestResponse(WINBINDD_GETSIDALIASES, + &request, + &response); + BAIL_ON_WBC_ERROR(wbc_status); + + if (response.data.num_entries && + !response.extra_data.data) { + wbc_status = WBC_ERR_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + rids = talloc_array(NULL, uint32_t, + response.data.num_entries); + BAIL_ON_PTR_ERROR(sids, wbc_status); + + s = (const char *)response.extra_data.data; + for (i = 0; i < response.data.num_entries; i++) { + char *n = strchr(s, '\n'); + if (n) { + *n = '\0'; + } + wbc_status = wbcStringToSid(s, &sid); + BAIL_ON_WBC_ERROR(wbc_status); + wbc_status = _sid_to_rid(&sid, &rids[i]); + BAIL_ON_WBC_ERROR(wbc_status); + s += strlen(s) + 1; + } + + *num_alias_rids = response.data.num_entries; + *alias_rids = rids; + rids = NULL; + wbc_status = WBC_ERR_SUCCESS; + + done: + if (sid_string) { + wbcFreeMemory(sid_string); + } + if (extra_data) { + talloc_free(extra_data); + } + if (response.extra_data.data) { + free(response.extra_data.data); + } + if (rids) { + talloc_free(rids); + } + + return wbc_status; +} + + /* Lists Users */ wbcErr wbcListUsers(const char *domain_name, uint32_t *_num_users, diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h index 990cc52df7..9d29951ae5 100644 --- a/nsswitch/libwbclient/wbclient.h +++ b/nsswitch/libwbclient/wbclient.h @@ -60,9 +60,11 @@ const char *wbcErrorString(wbcErr error); * 0.1: Initial version * 0.2: Added wbcRemoveUidMapping() * Added wbcRemoveGidMapping() + * 0.3: Added wbcGetpwsid() + * Added wbcGetSidAliases() **/ #define WBCLIENT_MAJOR_VERSION 0 -#define WBCLIENT_MINOR_VERSION 2 +#define WBCLIENT_MINOR_VERSION 3 #define WBCLIENT_VENDOR_VERSION "Samba libwbclient" struct wbcLibraryDetails { uint16_t major_version; @@ -615,6 +617,15 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, uint32_t *num_sids, struct wbcDomainSid **sids); +/* + * @brief Get alias membership for sids + **/ +wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, + struct wbcDomainSid *sids, + uint32_t num_sids, + uint32_t **alias_rids, + uint32_t *num_alias_rids); + /** * @brief Lists Users **/ @@ -838,6 +849,17 @@ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based + * on sid + * + * @param sid Sid to lookup + * @param **pwd Pointer to resulting struct passwd* from the query. + * + * @return #wbcErr + **/ +wbcErr wbcGetpwsid(struct wbcDomainSid * sid, struct passwd **pwd); + +/** + * @brief Fill in a struct passwd* for a domain user based * on username * * @param *name Username to lookup diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c index ce53cadc58..4d935f5239 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -202,6 +202,31 @@ static bool wbinfo_get_uidinfo(int uid) return true; } +static bool wbinfo_get_user_sidinfo(const char *sid_str) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct passwd *pwd = NULL; + struct wbcDomainSid sid; + + wbc_status = wbcStringToSid(sid_str, &sid); + wbc_status = wbcGetpwsid(&sid, &pwd); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return false; + } + + d_printf("%s:%s:%d:%d:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, + pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); + + return true; +} + + /* pull grent for a given group */ static bool wbinfo_get_groupinfo(const char *group) { @@ -341,6 +366,64 @@ static bool wbinfo_get_userdomgroups(const char *user_sid_str) return true; } +static bool wbinfo_get_sidaliases(const char *domain, + const char *user_sid_str) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcDomainInfo *dinfo = NULL; + uint32_t i; + struct wbcDomainSid user_sid; + uint32_t *alias_rids = NULL; + uint32_t num_alias_rids; + char *domain_sid_str = NULL; + + /* Send request */ + if ((domain == NULL) || (strequal(domain, ".")) || + (domain[0] == '\0')) { + domain = get_winbind_domain(); + } + + /* Send request */ + + wbc_status = wbcDomainInfo(domain, &dinfo); + if (!WBC_ERROR_IS_OK(wbc_status)) { + d_printf("wbcDomainInfo(%s) failed: %s\n", domain, + wbcErrorString(wbc_status)); + goto done; + } + wbc_status = wbcStringToSid(user_sid_str, &user_sid); + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto done; + } + + wbc_status = wbcGetSidAliases(&dinfo->sid, &user_sid, 1, + &alias_rids, &num_alias_rids); + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto done; + } + + wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str); + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto done; + } + + for (i = 0; i < num_alias_rids; i++) { + d_printf("%s-%d\n", domain_sid_str, alias_rids[i]); + } + + wbcFreeMemory(alias_rids); + +done: + if (domain_sid_str) { + wbcFreeMemory(domain_sid_str); + } + if (dinfo) { + wbcFreeMemory(dinfo); + } + return (WBC_ERR_SUCCESS == wbc_status); +} + + /* Convert NetBIOS name to IP */ static bool wbinfo_wins_byname(const char *name) @@ -1553,6 +1636,7 @@ enum { OPT_GETDCNAME, OPT_DSGETDCNAME, OPT_USERDOMGROUPS, + OPT_SIDALIASES, OPT_USERSIDS, OPT_ALLOCATE_UID, OPT_ALLOCATE_GID, @@ -1564,6 +1648,7 @@ enum { OPT_LIST_ALL_DOMAINS, OPT_LIST_OWN_DOMAIN, OPT_UID_INFO, + OPT_USER_SIDINFO, OPT_GROUP_INFO, OPT_GID_INFO, OPT_VERBOSE, @@ -1622,10 +1707,12 @@ int main(int argc, char **argv, char **envp) { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" }, { "uid-info", 0, POPT_ARG_INT, &int_arg, OPT_UID_INFO, "Get user info from uid", "UID" }, { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" }, + { "user-sidinfo", 0, POPT_ARG_STRING, &string_arg, OPT_USER_SIDINFO, "Get user info from sid", "SID" }, { "gid-info", 0, POPT_ARG_INT, &int_arg, OPT_GID_INFO, "Get group info from gid", "GID" }, { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" }, { "user-domgroups", 0, POPT_ARG_STRING, &string_arg, OPT_USERDOMGROUPS, "Get user domain groups", "SID" }, + { "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" }, { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" }, { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, @@ -1860,6 +1947,13 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_USER_SIDINFO: + if ( !wbinfo_get_user_sidinfo(string_arg)) { + d_fprintf(stderr, "Could not get info for user sid %s\n", + string_arg); + goto done; + } + break; case OPT_UID_INFO: if ( !wbinfo_get_uidinfo(int_arg)) { d_fprintf(stderr, "Could not get info for uid " @@ -1902,6 +1996,13 @@ int main(int argc, char **argv, char **envp) goto done; } break; + case OPT_SIDALIASES: + if (!wbinfo_get_sidaliases(opt_domain_name, string_arg)) { + d_fprintf(stderr, "Could not get sid aliases " + "for user SID %s\n", string_arg); + goto done; + } + break; case 'a': { bool got_error = false; diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h index 0b3e74492c..11b2069c3a 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -39,9 +39,11 @@ #define WINBINDD_DONT_ENV "_NO_WINBINDD" #define WINBINDD_LOCATOR_KDC_ADDRESS "WINBINDD_LOCATOR_KDC_ADDRESS" -/* Update this when you change the interface. */ - -#define WINBIND_INTERFACE_VERSION 20 +/* Update this when you change the interface. + * 21: added WINBINDD_GETPWSID + * added WINBINDD_GETSIDALIASES + */ +#define WINBIND_INTERFACE_VERSION 21 /* Have to deal with time_t being 4 or 8 bytes due to structure alignment. On a 64bit Linux box, we have to support a constant structure size @@ -60,6 +62,7 @@ enum winbindd_cmd { WINBINDD_GETPWNAM, WINBINDD_GETPWUID, + WINBINDD_GETPWSID, WINBINDD_GETGRNAM, WINBINDD_GETGRGID, WINBINDD_GETGROUPS, @@ -140,6 +143,9 @@ enum winbindd_cmd { /* Various group queries */ WINBINDD_GETUSERDOMGROUPS, + /* lookup local groups */ + WINBINDD_GETSIDALIASES, + /* Initialize connection in a child */ WINBINDD_INIT_CONNECTION, diff --git a/packaging/bin/fill-templates b/packaging/bin/fill-templates index e74020fb69..204003c53b 100755 --- a/packaging/bin/fill-templates +++ b/packaging/bin/fill-templates @@ -13,7 +13,7 @@ # License: GPL DIRNAME=$(dirname $0) -TOPDIR=${DIRNAME}/../../ +TOPDIR=${DIRNAME}/../.. SRCDIR=${TOPDIR}/source3 VERSION_H=${SRCDIR}/include/version.h @@ -26,14 +26,14 @@ if [ ! -f ${VERSION_H} ] ; then exit 1 fi -VERSION=`grep SAMBA_VERSION_OFFICIAL_STRING ${VERSION_H} | awk '{print $3}'` +VERSION=`grep "define SAMBA_VERSION_OFFICIAL_STRING" ${VERSION_H} | awk '{print $3}'` -vendor_version=`grep SAMBA_VERSION_VENDOR_SUFFIX ${VERSION_H} | awk '{print $3}'` +vendor_version=`grep "define SAMBA_VERSION_VENDOR_SUFFIX" ${VERSION_H} | awk '{print $3}'` if test "x${vendor_version}" != "x" ; then VERSION="${VERSION}-${vendor_version}" fi -vendor_patch=`grep SAMBA_VERSION_VENDOR_PATCH ${VERSION_H} | awk '{print $3}'` +vendor_patch=`grep "define SAMBA_VERSION_VENDOR_PATCH" ${VERSION_H} | awk '{print $3}'` if test "x${vendor_patch}" != "x" ; then VERSION="${VERSION}-${vendor_patch}" fi @@ -43,5 +43,5 @@ VERSION=`echo ${VERSION} | sed 's/\"//g'` echo "VERSION: ${VERSION}" pushd ${TOPDIR}/packaging > /dev/null 2>&1 -${TOPDIR}/packaging/bin/update-pkginfo "${VERSION}" 1 "" +./bin/update-pkginfo "${VERSION}" 1 "" popd > /dev/null 2>&1 diff --git a/source3/Makefile.in b/source3/Makefile.in index 2d2d9a0c6d..948403248d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -2813,7 +2813,8 @@ TOPFILES=dynconfig.o localedir.o cleanlibs:: -rm -f ../lib/*/*.o ../lib/*/*/*.o \ - ../libcli/*.o ../libcli/*/*.o + ../libcli/*.o ../libcli/*/*.o \ + ../librpc/*/*.o clean:: cleanlibs -rm -f include/build_env.h @@ -2822,15 +2823,13 @@ clean:: cleanlibs -rm -f core */*~ *~ \ */*.o */*/*.o */*/*/*.o \ ../testsuite/*/*.o \ + ../nsswitch/*.o ../nsswitch/*/*.o ../nsswitch/*.@SHLIBEXT@ \ */*.@SHLIBEXT@ */*/*.@SHLIBEXT@ */*/*/*.@SHLIBEXT@ \ $(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(ROOT_SBIN_PROGS) \ $(MODULES) $(TORTURE_PROGS) \ $(EVERYTHING_PROGS) \ bin/timelimit \ - .headers.stamp */src/*.o \ - ../lib/*/*.o \ - ../libcli/*.o ../libcli/*/*.o \ - ../librpc/*/*.o + .headers.stamp */src/*.o -rm -rf t_dir include/build_env.h: script/build_env.sh diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index e3677c41a4..f942b2e50a 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -186,13 +186,15 @@ static NTSTATUS make_user_info(auth_usersupplied_info **user_info, Create an auth_usersupplied_data structure after appropriate mapping. ****************************************************************************/ -NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, - const char *smb_name, - const char *client_domain, - const char *wksta_name, - DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd, - DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd, - DATA_BLOB *plaintext, +NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, + const char *smb_name, + const char *client_domain, + const char *wksta_name, + DATA_BLOB *lm_pwd, + DATA_BLOB *nt_pwd, + DATA_BLOB *lm_interactive_pwd, + DATA_BLOB *nt_interactive_pwd, + DATA_BLOB *plaintext, bool encrypted) { const char *domain; @@ -200,12 +202,12 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, bool was_mapped; fstring internal_username; fstrcpy(internal_username, smb_name); - was_mapped = map_username(internal_username); - - DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n", - client_domain, smb_name, wksta_name)); - - /* don't allow "" as a domain, fixes a Win9X bug + was_mapped = map_username(internal_username); + + DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n", + client_domain, smb_name, wksta_name)); + + /* don't allow "" as a domain, fixes a Win9X bug where it doens't supply a domain for logon script 'net use' commands. */ @@ -214,16 +216,27 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, else domain = lp_workgroup(); - /* do what win2k does. Always map unknown domains to our own - and let the "passdb backend" handle unknown users. */ + /* If you connect to a Windows domain member using a bogus domain name, + * the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if + * the Windows box is a DC the name will become DOMAIN\user and be + * authenticated against AD, if the Windows box is a member server but + * not a DC the name will become WORKSTATION\user. A standalone + * non-domain member box will also map to WORKSTATION\user. */ - if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) - domain = my_sam_name(); - - /* we know that it is a trusted domain (and we are allowing them) or it is our domain */ - - result = make_user_info(user_info, smb_name, internal_username, - client_domain, domain, wksta_name, + if (!is_trusted_domain(domain) && + !strequal(domain, get_global_sam_name()) ) + { + domain = get_global_sam_name(); + DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] on " + "workstation [%s]\n", + client_domain, domain, smb_name, wksta_name)); + } + + /* we know that it is a trusted domain (and we are allowing them) or it + * is our domain */ + + result = make_user_info(user_info, smb_name, internal_username, + client_domain, domain, wksta_name, lm_pwd, nt_pwd, lm_interactive_pwd, nt_interactive_pwd, plaintext, encrypted); @@ -573,8 +586,6 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, } result->sam_account = sampass; - /* Ensure that the sampass will be freed with the result */ - talloc_steal(result, sampass); result->unix_name = pwd->pw_name; /* Ensure that we keep pwd->pw_name, because we will free pwd below */ talloc_steal(result, pwd->pw_name); @@ -665,6 +676,8 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, pdb_get_username(sampass), result->unix_name)); *server_info = result; + /* Ensure that the sampass will be freed with the result */ + talloc_steal(result, sampass); return NT_STATUS_OK; } diff --git a/source3/configure.in b/source3/configure.in index 10ce6f6e5e..d11ece1b53 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -703,18 +703,6 @@ CPPFLAGS="$old_CPPFLAGS" # subdirectory of headers. AC_CHECK_HEADERS(valgrind.h valgrind/valgrind.h valgrind/memcheck.h) -# check for linux on amd64 since valgrind is not quite there yet -case "$host_os" in - *linux*) - case "$UNAME_P" in - *x86_64*) - AC_DEFINE(HAVE_64BIT_LINUX,1,[Whether we are running on 64bit linux]) - ;; - esac - ;; -esac - - # # HPUX has a bug in that including shadow.h causes a re-definition of MAXINT. # This causes configure to fail to detect it. Check for shadow separately on HPUX. @@ -1041,8 +1029,7 @@ AC_CHECK_FUNCS(getdents64) AC_CHECK_FUNCS(setenv strcasecmp fcvt fcvtl) AC_CHECK_FUNCS(syslog vsyslog timegm) AC_CHECK_FUNCS(setlocale nl_langinfo) -AC_CHECK_FUNCS(nanosleep) -AC_CHECK_LIB_EXT(rt, LIBS, nanosleep) +AC_CHECK_FUNCS(nanosleep,,[AC_CHECK_LIB_EXT(rt, LIBS, nanosleep)]) AC_CHECK_FUNCS(mlock munlock mlockall munlockall) AC_CHECK_FUNCS(memalign posix_memalign hstrerror) AC_CHECK_HEADERS(sys/mman.h) @@ -1311,301 +1298,29 @@ fi ################################################# # Check whether struct stat has timestamps with sub-second resolution. -# At least IRIX and Solaris have these. FREEBSD does as well, -# but with different members -# -# We check that -# all of st_mtim, st_atim and st_ctim exist -# all of the members are in fact of type struct timespec # -# There is some conflicting standards weirdness about whether we should use -# "struct timespec" or "timespec_t". Linux doesn't have timespec_t, so we -# prefer struct timespec. -AC_CACHE_CHECK([whether struct stat has timespec timestamps], - samba_cv_stat_timespec_hires, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t = s.st_mtimespec; - t = s.st_ctimespec; - t = s.st_atimespec; - ], - samba_cv_stat_timespec_hires=yes, samba_cv_stat_timespec_hires=no) - ]) - -if test x"$samba_cv_stat_timespec_hires" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_MTIMESPEC, 1, [whether struct stat contains st_mtimepec]) - AC_DEFINE(HAVE_STAT_ST_ATIMESPEC, 1, [whether struct stat contains st_atimespec]) - AC_DEFINE(HAVE_STAT_ST_CTIMESPEC, 1, [whether struct stat contains st_ctimespec]) - AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1, [whether struct stat has sub-second timestamps]) -fi - - -AC_CACHE_CHECK([whether struct stat has sub-second timestamps], samba_cv_stat_hires, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t.tv_sec = s.st_mtim.tv_sec; - t.tv_nsec = s.st_mtim.tv_nsec; - t.tv_sec = s.st_ctim.tv_sec; - t.tv_nsec = s.st_ctim.tv_nsec; - t.tv_sec = s.st_atim.tv_sec; - t.tv_nsec = s.st_atim.tv_nsec; - ], - samba_cv_stat_hires=yes, samba_cv_stat_hires=no) - ]) +samba_cv_stat_hires=no +AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec], # Linux, Solaris + [samba_cv_stat_hires=yes]) +AC_CHECK_MEMBERS([struct stat.st_mtimensec], # BSD, if defined _POSIX_SOURCE + [samba_cv_stat_hires=yes]) +AC_CHECK_MEMBERS([struct stat.st_mtimespec.tv_nsec], # BSD, if not defined _POSIX_SOURCE + [samba_cv_stat_hires=yes]) +AC_CHECK_MEMBERS([struct stat.st_mtime_n], # AIX + [samba_cv_stat_hires=yes]) +AC_CHECK_MEMBERS([struct stat.st_umtime], # Tru64 + [samba_cv_stat_hires=yes]) if test x"$samba_cv_stat_hires" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_MTIM, 1, [whether struct stat contains st_mtim]) - AC_DEFINE(HAVE_STAT_ST_ATIM, 1, [whether struct stat contains st_atim]) - AC_DEFINE(HAVE_STAT_ST_CTIM, 1, [whether struct stat contains st_ctim]) AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1, [whether struct stat has sub-second timestamps]) fi -AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct timespec suffixed nsec], samba_cv_stat_hires_notimespec, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t.tv_sec = s.st_mtime; - t.tv_nsec = s.st_mtimensec; - t.tv_sec = s.st_ctime; - t.tv_nsec = s.st_ctimensec; - t.tv_sec = s.st_atime; - t.tv_nsec = s.st_atimensec; - ], - samba_cv_stat_hires_notimespec=yes, samba_cv_stat_hires_notimespec=no) - ]) - -if test x"$samba_cv_stat_hires_notimespec" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_MTIMENSEC, 1, [whether struct stat contains st_mtimensec]) - AC_DEFINE(HAVE_STAT_ST_ATIMENSEC, 1, [whether struct stat contains st_atimensec]) - AC_DEFINE(HAVE_STAT_ST_CTIMENSEC, 1, [whether struct stat contains st_ctimensec]) - AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1, - [whether struct stat has sub-second timestamps without struct timespec suffixed nsec]) -fi - -dnl AIX stype sub-second timestamps: -AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct timespec suffixed _n], samba_cv_stat_hires_notimespec_n, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t.tv_sec = s.st_mtime; - t.tv_nsec = s.st_mtime_n; - t.tv_sec = s.st_ctime; - t.tv_nsec = s.st_ctime_n; - t.tv_sec = s.st_atime; - t.tv_nsec = s.st_atime_n; - ], - samba_cv_stat_hires_notimespec_n=yes, samba_cv_stat_hires_notimespec_n=no) - ]) - -if test x"$samba_cv_stat_hires_notimespec_n" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_MTIME_N, 1, [whether struct stat contains st_mtime_n]) - AC_DEFINE(HAVE_STAT_ST_ATIME_N, 1, [whether struct stat contains st_atime_n]) - AC_DEFINE(HAVE_STAT_ST_CTIME_N, 1, [whether struct stat contains st_ctime_n]) - AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1, - [whether struct stat has sub-second timestamps without struct timespec suffixed _n]) -fi - -dnl Tru64 has _micro_second_ resolution: -AC_CACHE_CHECK([whether struct stat has sub-second timestamps in st_uXtime], samba_cv_stat_hires_uxtime, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t.tv_sec = s.st_mtime; - t.tv_nsec = s.st_umtime * 1000; - t.tv_sec = s.st_ctime; - t.tv_nsec = s.st_uctime * 1000; - t.tv_sec = s.st_atime; - t.tv_nsec = s.st_uatime * 1000; - ], - samba_cv_stat_hires_uxtime=yes, samba_cv_stat_hires_uxtime=no) - ]) - -if test x"$samba_cv_stat_hires_uxtime" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_UMTIME, 1, [whether struct stat contains st_umtime]) - AC_DEFINE(HAVE_STAT_ST_UATIME, 1, [whether struct stat contains st_uatime]) - AC_DEFINE(HAVE_STAT_ST_UCTIME, 1, [whether struct stat contains st_uctime]) - AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1, - [whether struct stat has sub-second timestamps in st_uXtime]) -fi - -AC_CACHE_CHECK([whether struct stat has st_birthtimespec], samba_cv_stat_st_birthtimespec, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t = s.st_birthtimespec; - ], - samba_cv_stat_st_birthtimespec=yes, samba_cv_stat_st_birthtimespec=no) - ]) - -if test x"$samba_cv_stat_st_birthtimespec" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_BIRTHTIMESPEC, 1, [whether struct stat contains st_birthtimespec]) -fi - -AC_CACHE_CHECK([whether struct stat has st_birthtimensec], samba_cv_stat_st_birthtimensec, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct timespec t; - struct stat s = {0}; - t.tv_nsec = s.st_birthtimensec; - ], - samba_cv_stat_st_birthtimensec=yes, samba_cv_stat_st_birthtimensec=no) - ]) +# recent FreeBSD, NetBSD have creation timestamps called birthtime: +AC_CHECK_MEMBERS([struct stat.st_birthtimespec.tv_nsec]) +AC_CHECK_MEMBERS([struct stat.st_birthtime], AC_CHECK_MEMBERS([struct stat.st_birthtimensec])) -if test x"$samba_cv_stat_st_birthtimensec" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_BIRTHTIMENSEC, 1, [whether struct stat contains st_birthtimensec]) -fi - -AC_CACHE_CHECK([whether struct stat has st_birthtime], samba_cv_stat_st_birthtime, - [ - AC_TRY_COMPILE( - [ -#if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -#else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -#endif -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - ], - [ - struct time_t t; - struct stat s = {0}; - t = s.st_birthtime; - ], - samba_cv_stat_st_birthtime=yes, samba_cv_stat_st_birthtime=no) - ]) - -if test x"$samba_cv_stat_st_birthtime" = x"yes" ; then - AC_DEFINE(HAVE_STAT_ST_BIRTHTIME, 1, [whether struct stat contains st_birthtime]) -fi AC_CACHE_CHECK([whether there is DOS flags support in the stat struct], samba_cv_stat_dos_flags, [ diff --git a/source3/include/includes.h b/source3/include/includes.h index 095fcaa3da..fc77534402 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -241,8 +241,6 @@ typedef int ber_int_t; #include <aio.h> #endif -/* skip valgrind headers on 64bit AMD boxes */ -#ifndef HAVE_64BIT_LINUX /* Special macros that are no-ops except when run under Valgrind on * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */ #if HAVE_VALGRIND_MEMCHECK_H @@ -251,12 +249,11 @@ typedef int ber_int_t; #elif HAVE_VALGRIND_H #include <valgrind.h> #endif -#endif /* If we have --enable-developer and the valgrind header is present, * then we're OK to use it. Set a macro so this logic can be done only * once. */ -#if defined(DEVELOPER) && !defined(HAVE_64BIT_LINUX) +#if defined(DEVELOPER) #if (HAVE_VALGRIND_H || HAVE_VALGRIND_VALGRIND_H) #define VALGRIND #endif diff --git a/source3/include/proto.h b/source3/include/proto.h index 8f05c9473d..3478ea4f85 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1660,6 +1660,8 @@ bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid); bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid); bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid); bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid); +struct passwd * winbind_getpwnam(const char * sname); +struct passwd * winbind_getpwsid(const DOM_SID *sid); wbcErr wb_is_trusted_domain(const char *domain); bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, @@ -1668,22 +1670,17 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, const char ***names, enum lsa_SidType **types); bool winbind_allocate_uid(uid_t *uid); bool winbind_allocate_gid(gid_t *gid); -bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, - enum lsa_SidType *name_type); -bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - const char **domain, const char **name, - enum lsa_SidType *name_type); -bool winbind_ping(void); -bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid); -bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid); -bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid); -bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid); -wbcErr wb_is_trusted_domain(const char *domain); -bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, - const DOM_SID *domain_sid, - int num_rids, uint32 *rids, - const char **domain_name, - const char ***names, enum lsa_SidType **types); +bool winbind_get_groups(TALLOC_CTX *mem_ctx, + const char *account, + uint32_t *num_groups, + gid_t ** _groups); +bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx, + const DOM_SID *dom_sid, + const DOM_SID *members, + size_t num_members, + uint32_t **pp_alias_rids, + size_t *p_num_alias_rids); + /* The following definitions come from lib/wins_srv.c */ @@ -4423,7 +4420,6 @@ bool sid_check_is_in_our_domain(const DOM_SID *sid); /* The following definitions come from passdb/passdb.c */ -const char *my_sam_name(void); struct samu *samu_new( TALLOC_CTX *ctx ); NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd); NTSTATUS samu_alloc_rid_unix(struct samu *user, const struct passwd *pwd); diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index ac306e69e3..472ce45758 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -122,12 +122,6 @@ #define SPL_XCV_MONITOR_TCPMON ",XcvMonitor Standard TCP/IP Port" -#define PRINTER_CONTROL_UNPAUSE 0x00000000 -#define PRINTER_CONTROL_PAUSE 0x00000001 -#define PRINTER_CONTROL_RESUME 0x00000002 -#define PRINTER_CONTROL_PURGE 0x00000003 -#define PRINTER_CONTROL_SET_STATUS 0x00000004 - #define PRINTER_STATUS_OK 0x00000000 #define JOB_ACCESS_READ 0x00000020 @@ -217,8 +211,6 @@ #define PRINTER_NOTIFY_OPTIONS_REFRESH 0x01 -#define PRINTER_NOTIFY_INFO_DISCARDED 0x1 - /* * Set of macros for flagging what changed in the PRINTER_INFO_2 struct * when sending messages to other smbd's @@ -270,13 +262,6 @@ PRINTER_MESSAGE_INFO; #define DRIVER_ANY_VERSION 0xffffffff #define DRIVER_MAX_VERSION 4 -/* FLAGS for SPOOLSS_ADDPRINTERDRIVEREX */ - -#define APD_STRICT_UPGRADE 0x00000001 -#define APD_STRICT_DOWNGRADE 0x00000002 -#define APD_COPY_ALL_FILES 0x00000004 -#define APD_COPY_NEW_FILES 0x00000008 - /* this struct is undocumented */ /* thanks to the ddk ... */ diff --git a/source3/lib/time.c b/source3/lib/time.c index e2cfe687b2..865456b23b 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -360,12 +360,12 @@ struct timespec get_create_timespec(const SMB_STRUCT_STAT *pst,bool fake_dirs) return ret; } -#if defined(HAVE_STAT_ST_BIRTHTIMESPEC) +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC) ret = pst->st_birthtimespec; -#elif defined(HAVE_STAT_ST_BIRTHTIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) ret.tv_sec = pst->st_birthtime; ret.tv_nsec = pst->st_birthtimenspec; -#elif defined(HAVE_STAT_ST_BIRTHTIME) +#elif defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) ret.tv_sec = pst->st_birthtime; ret.tv_nsec = 0; #else @@ -397,24 +397,24 @@ struct timespec get_atimespec(const SMB_STRUCT_STAT *pst) ret.tv_nsec = 0; return ret; #else -#if defined(HAVE_STAT_ST_ATIM) +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) return pst->st_atim; -#elif defined(HAVE_STAT_ST_ATIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) struct timespec ret; ret.tv_sec = pst->st_atime; ret.tv_nsec = pst->st_atimensec; return ret; -#elif defined(HAVE_STAT_ST_ATIME_N) +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) struct timespec ret; ret.tv_sec = pst->st_atime; ret.tv_nsec = pst->st_atime_n; return ret; -#elif defined(HAVE_STAT_ST_UATIME) +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) struct timespec ret; ret.tv_sec = pst->st_atime; ret.tv_nsec = pst->st_uatime * 1000; return ret; -#elif defined(HAVE_STAT_ST_ATIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) return pst->st_atimespec; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT @@ -428,18 +428,18 @@ void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts) /* Old system - no ns timestamp. */ pst->st_atime = ts.tv_sec; #else -#if defined(HAVE_STAT_ST_ATIM) +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) pst->st_atim = ts; -#elif defined(HAVE_STAT_ST_ATIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) pst->st_atime = ts.tv_sec; pst->st_atimensec = ts.tv_nsec; -#elif defined(HAVE_STAT_ST_ATIME_N) +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) pst->st_atime = ts.tv_sec; pst->st_atime_n = ts.tv_nsec; -#elif defined(HAVE_STAT_ST_UATIME) +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) pst->st_atime = ts.tv_sec; pst->st_uatime = ts.tv_nsec / 1000; -#elif defined(HAVE_STAT_ST_ATIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) pst->st_atimespec = ts; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT @@ -457,24 +457,24 @@ struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst) ret.tv_nsec = 0; return ret; #else -#if defined(HAVE_STAT_ST_MTIM) +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) return pst->st_mtim; -#elif defined(HAVE_STAT_ST_MTIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) struct timespec ret; ret.tv_sec = pst->st_mtime; ret.tv_nsec = pst->st_mtimensec; return ret; -#elif defined(HAVE_STAT_ST_MTIME_N) +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) struct timespec ret; ret.tv_sec = pst->st_mtime; ret.tv_nsec = pst->st_mtime_n; return ret; -#elif defined(HAVE_STAT_ST_UMTIME) +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) struct timespec ret; ret.tv_sec = pst->st_mtime; ret.tv_nsec = pst->st_umtime * 1000; return ret; -#elif defined(HAVE_STAT_ST_MTIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) return pst->st_mtimespec; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT @@ -488,18 +488,18 @@ void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts) /* Old system - no ns timestamp. */ pst->st_mtime = ts.tv_sec; #else -#if defined(HAVE_STAT_ST_MTIM) +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) pst->st_mtim = ts; -#elif defined(HAVE_STAT_ST_MTIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) pst->st_mtime = ts.tv_sec; pst->st_mtimensec = ts.tv_nsec; -#elif defined(HAVE_STAT_ST_MTIME_N) +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) pst->st_mtime = ts.tv_sec; pst->st_mtime_n = ts.tv_nsec; -#elif defined(HAVE_STAT_ST_UMTIME) +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) pst->st_mtime = ts.tv_sec; pst->st_umtime = ts.tv_nsec / 1000; -#elif defined(HAVE_STAT_ST_MTIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) pst->st_mtimespec = ts; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT @@ -517,24 +517,24 @@ struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst) ret.tv_nsec = 0; return ret; #else -#if defined(HAVE_STAT_ST_CTIM) +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) return pst->st_ctim; -#elif defined(HAVE_STAT_ST_CTIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) struct timespec ret; ret.tv_sec = pst->st_ctime; ret.tv_nsec = pst->st_ctimensec; return ret; -#elif defined(HAVE_STAT_ST_CTIME_N) +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) struct timespec ret; ret.tv_sec = pst->st_ctime; ret.tv_nsec = pst->st_ctime_n; return ret; -#elif defined(HAVE_STAT_ST_UCTIME) +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) struct timespec ret; ret.tv_sec = pst->st_ctime; ret.tv_nsec = pst->st_uctime * 1000; return ret; -#elif defined(HAVE_STAT_ST_CTIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) return pst->st_ctimespec; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT @@ -548,18 +548,18 @@ void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts) /* Old system - no ns timestamp. */ pst->st_ctime = ts.tv_sec; #else -#if defined(HAVE_STAT_ST_CTIM) +#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) pst->st_ctim = ts; -#elif defined(HAVE_STAT_ST_CTIMENSEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) pst->st_ctime = ts.tv_sec; pst->st_ctimensec = ts.tv_nsec; -#elif defined(HAVE_STAT_ST_CTIME_N) +#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N) pst->st_ctime = ts.tv_sec; pst->st_ctime_n = ts.tv_nsec; -#elif defined(HAVE_STAT_ST_UCTIME) +#elif defined(HAVE_STRUCT_STAT_ST_UMTIME) pst->st_ctime = ts.tv_sec; pst->st_uctime = ts.tv_nsec / 1000; -#elif defined(HAVE_STAT_ST_CTIMESPEC) +#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) pst->st_ctimespec = ts; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index 14356b09cf..f64a4d3b45 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -24,6 +24,43 @@ #include "nsswitch/libwbclient/wbclient.h" +struct passwd * winbind_getpwnam(const char * name) +{ + wbcErr result; + struct passwd * tmp_pwd = NULL; + struct passwd * pwd = NULL; + + result = wbcGetpwnam(name, &tmp_pwd); + if (result != WBC_ERR_SUCCESS) + return pwd; + + pwd = tcopy_passwd(talloc_tos(), tmp_pwd); + + wbcFreeMemory(tmp_pwd); + + return pwd; +} + +struct passwd * winbind_getpwsid(const DOM_SID *sid) +{ + wbcErr result; + struct passwd * tmp_pwd = NULL; + struct passwd * pwd = NULL; + struct wbcDomainSid dom_sid; + + memcpy(&dom_sid, sid, sizeof(dom_sid)); + + result = wbcGetpwsid(&dom_sid, &tmp_pwd); + if (result != WBC_ERR_SUCCESS) + return pwd; + + pwd = tcopy_passwd(talloc_tos(), tmp_pwd); + + wbcFreeMemory(tmp_pwd); + + return pwd; +} + /* Call winbindd to convert a name to a sid */ bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, @@ -234,8 +271,87 @@ bool winbind_allocate_gid(gid_t *gid) return (ret == WBC_ERR_SUCCESS); } +bool winbind_get_groups(TALLOC_CTX * mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups) +{ + wbcErr ret; + uint32_t ngroups; + gid_t *group_list = NULL; + + ret = wbcGetGroups(account, &ngroups, &group_list); + if (ret != WBC_ERR_SUCCESS) + return false; + + *_groups = TALLOC_ARRAY(mem_ctx, gid_t, ngroups); + if (*_groups == NULL) { + wbcFreeMemory(group_list); + return false; + } + + memcpy(*_groups, group_list, ngroups* sizeof(gid_t)); + *num_groups = ngroups; + + wbcFreeMemory(group_list); + return true; +} + +bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx, + const DOM_SID *dom_sid, + const DOM_SID *members, + size_t num_members, + uint32_t **pp_alias_rids, + size_t *p_num_alias_rids) +{ + wbcErr ret; + struct wbcDomainSid domain_sid; + struct wbcDomainSid *sid_list = NULL; + size_t i; + uint32_t * rids; + size_t num_rids; + + memcpy(&domain_sid, dom_sid, sizeof(*dom_sid)); + + sid_list = TALLOC_ARRAY(mem_ctx, struct wbcDomainSid, num_members); + + for (i=0; i < num_members; i++) { + memcpy(&sid_list[i], &members[i], sizeof(sid_list[i])); + } + + ret = wbcGetSidAliases(&domain_sid, + sid_list, + num_members, + &rids, + &num_rids); + if (ret != WBC_ERR_SUCCESS) { + wbcFreeMemory(rids); + return false; + } + + *pp_alias_rids = TALLOC_ARRAY(mem_ctx, uint32_t, num_rids); + if (*pp_alias_rids == NULL) { + wbcFreeMemory(rids); + return false; + } + + memcpy(*pp_alias_rids, rids, sizeof(uint32_t) * num_rids); + + *p_num_alias_rids = num_rids; + wbcFreeMemory(rids); + + return true; +} + #else /* WITH_WINBIND */ +struct passwd * winbind_getpwnam(const char * name) +{ + return NULL; +} + +struct passwd * winbind_getpwsid(const DOM_SID *sid) +{ + return NULL; +} + bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, enum lsa_SidType *name_type) { @@ -318,4 +434,19 @@ bool winbind_allocate_gid(gid_t *gid) return false; } +bool winbind_get_groups(TALLOC_CTX *mem_ctx, const char *account, uint32_t *num_groups, gid_t **_groups) +{ + return false; +} + +bool winbind_get_sid_aliases(TALLOC_CTX *mem_ctx, + const DOM_SID *dom_sid, + const DOM_SID *members, + size_t num_members, + uint32_t **pp_alias_rids, + size_t *p_num_alias_rids) +{ + return false; +} + #endif /* WITH_WINBIND */ diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 0ef7e0be51..02394794c2 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -619,6 +619,12 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5, ("Getting sd for file %s. security_info=%u\n", fsp->fsp_name, security_info)); + if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_SACL, PARM_IGNORE_SACL_DEFAULT)) { + DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name)); + security_info &= ~SACL_SECURITY_INFORMATION; + } + if (fsp->fh->fd == -1) { if ((fsp->fh->fd = onefs_sys_create_file(handle->conn, -1, diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index b2b11ebaac..e335dc7e28 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -744,6 +744,11 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn, open_access_mask |= FILE_WRITE_DATA; } + if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_SACL, PARM_IGNORE_SACL_DEFAULT)) { + access_mask &= ~SYSTEM_SECURITY_ACCESS; + } + DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping " "open_access_mask=%#x, access_mask=0x%x\n", fname, open_access_mask, access_mask)); diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index d26a667f44..c526a175f2 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -27,25 +27,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB -/****************************************************************** - get the default domain/netbios name to be used when - testing authentication. For example, if you connect - to a Windows member server using a bogus domain name, the - Windows box will map the BOGUS\user to DOMAIN\user. A - standalone box will map to WKS\user. -******************************************************************/ - -const char *my_sam_name(void) -{ - /* standalone servers can only use the local netbios name */ - if ( lp_server_role() == ROLE_STANDALONE ) - return global_myname(); - - /* Windows domain members default to the DOMAIN - name when not specified */ - return lp_workgroup(); -} - /********************************************************************** ***********************************************************************/ diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 36984fc209..5c4ff61b17 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -5925,18 +5925,18 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command, return WERR_BADFID; switch (command) { - case PRINTER_CONTROL_PAUSE: + case SPOOLSS_PRINTER_CONTROL_PAUSE: if (print_queue_pause(p->server_info, snum, &errcode)) { errcode = WERR_OK; } break; - case PRINTER_CONTROL_RESUME: - case PRINTER_CONTROL_UNPAUSE: + case SPOOLSS_PRINTER_CONTROL_RESUME: + case SPOOLSS_PRINTER_CONTROL_UNPAUSE: if (print_queue_resume(p->server_info, snum, &errcode)) { errcode = WERR_OK; } break; - case PRINTER_CONTROL_PURGE: + case SPOOLSS_PRINTER_CONTROL_PURGE: if (print_queue_purge(p->server_info, snum, &errcode)) { errcode = WERR_OK; } @@ -7381,6 +7381,8 @@ WERROR _spoolss_GetForm(pipes_struct *p, return WERR_BADFID; } + ZERO_STRUCT(form_1); + switch (level) { case 1: if (foundBuiltin) { @@ -10473,22 +10475,22 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, } /**************************************************************** - _spoolss_RouterRefreshPrinterChangeNotification + _spoolss_RouterReplyPrinterEx ****************************************************************/ -WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p, - struct spoolss_RouterRefreshPrinterChangeNotification *r) +WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p, + struct spoolss_RouterReplyPrinterEx *r) { p->rng_fault_state = true; return WERR_NOT_SUPPORTED; } /**************************************************************** - _spoolss_RemoteFindNextPrinterChangeNotifyEx + _dcesrv_spoolss_RouterRefreshPrinterChangeNotify ****************************************************************/ -WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p, - struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r) +WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, + struct spoolss_RouterRefreshPrinterChangeNotify *r) { p->rng_fault_state = true; return WERR_NOT_SUPPORTED; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 5720bfc517..be91611bfb 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -420,6 +420,7 @@ static struct winbindd_dispatch_table { { WINBINDD_GETPWNAM, winbindd_getpwnam, "GETPWNAM" }, { WINBINDD_GETPWUID, winbindd_getpwuid, "GETPWUID" }, + { WINBINDD_GETPWSID, winbindd_getpwsid, "GETPWSID" }, { WINBINDD_SETPWENT, winbindd_setpwent, "SETPWENT" }, { WINBINDD_ENDPWENT, winbindd_endpwent, "ENDPWENT" }, @@ -429,6 +430,8 @@ static struct winbindd_dispatch_table { { WINBINDD_GETUSERSIDS, winbindd_getusersids, "GETUSERSIDS" }, { WINBINDD_GETUSERDOMGROUPS, winbindd_getuserdomgroups, "GETUSERDOMGROUPS" }, + { WINBINDD_GETSIDALIASES, winbindd_getsidaliases, + "LOOKUPUSERALIASES" }, /* Group functions */ diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c index 7b93f963b4..0271abbd2b 100644 --- a/source3/winbindd/winbindd_async.c +++ b/source3/winbindd/winbindd_async.c @@ -632,8 +632,8 @@ bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, return True; } -static bool parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, - DOM_SID **sids, size_t *num_sids) +bool parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, + DOM_SID **sids, size_t *num_sids) { char *p, *q; @@ -822,92 +822,6 @@ void winbindd_getsidaliases_async(struct winbindd_domain *domain, (void *)cont, private_data); } -enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID *sids = NULL; - size_t num_sids = 0; - char *sidstr = NULL; - ssize_t len; - size_t i; - uint32 num_aliases; - uint32 *alias_rids; - NTSTATUS result; - - DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid)); - - sidstr = state->request.extra_data.data; - if (sidstr == NULL) { - sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */ - if (!sidstr) { - DEBUG(0, ("Out of memory\n")); - return WINBINDD_ERROR; - } - } - - DEBUG(10, ("Sidlist: %s\n", sidstr)); - - if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) { - DEBUG(0, ("Could not parse SID list: %s\n", sidstr)); - return WINBINDD_ERROR; - } - - num_aliases = 0; - alias_rids = NULL; - - result = domain->methods->lookup_useraliases(domain, - state->mem_ctx, - num_sids, sids, - &num_aliases, - &alias_rids); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3, ("Could not lookup_useraliases: %s\n", - nt_errstr(result))); - return WINBINDD_ERROR; - } - - num_sids = 0; - sids = NULL; - sidstr = NULL; - - DEBUG(10, ("Got %d aliases\n", num_aliases)); - - for (i=0; i<num_aliases; i++) { - DOM_SID sid; - DEBUGADD(10, (" rid %d\n", alias_rids[i])); - sid_copy(&sid, &domain->sid); - sid_append_rid(&sid, alias_rids[i]); - result = add_sid_to_array(state->mem_ctx, &sid, &sids, - &num_sids); - if (!NT_STATUS_IS_OK(result)) { - return WINBINDD_ERROR; - } - } - - - if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) { - DEBUG(0, ("Could not print_sidlist\n")); - state->response.extra_data.data = NULL; - return WINBINDD_ERROR; - } - - state->response.extra_data.data = NULL; - - if (sidstr) { - state->response.extra_data.data = SMB_STRDUP(sidstr); - if (!state->response.extra_data.data) { - DEBUG(0, ("Out of memory\n")); - return WINBINDD_ERROR; - } - DEBUG(10, ("aliases_list: %s\n", - (char *)state->response.extra_data.data)); - state->response.length += len+1; - } - - return WINBINDD_OK; -} - struct gettoken_state { TALLOC_CTX *mem_ctx; DOM_SID user_sid; diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c index 2e8c6175ca..1fc3ce7304 100644 --- a/source3/winbindd/winbindd_domain.c +++ b/source3/winbindd/winbindd_domain.c @@ -110,6 +110,10 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_DUAL_GETSIDALIASES, .struct_fn = winbindd_dual_getsidaliases, },{ + .name = "GETSIDALIASES", + .struct_cmd = WINBINDD_GETSIDALIASES, + .struct_fn = winbindd_dual_getsidaliases, + },{ .name = "CCACHE_NTLM_AUTH", .struct_cmd = WINBINDD_CCACHE_NTLMAUTH, .struct_fn = winbindd_dual_ccache_ntlm_auth, diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index 9d9b264124..043f26e578 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -1867,3 +1867,118 @@ enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *doma return WINBINDD_OK; } + +void winbindd_getsidaliases(struct winbindd_cli_state *state) +{ + DOM_SID domain_sid; + struct winbindd_domain *domain; + + /* Ensure null termination */ + state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; + + if (!string_to_sid(&domain_sid, state->request.data.sid)) { + DEBUG(1, ("Could not get convert sid %s from string\n", + state->request.data.sid)); + request_error(state); + return; + } + + /* Get info for the domain */ + if ((domain = find_domain_from_sid_noinit(&domain_sid)) == NULL) { + DEBUG(0,("could not find domain entry for sid %s\n", + sid_string_dbg(&domain_sid))); + request_error(state); + return; + } + + sendto_domain(state, domain); +} + +enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, + struct winbindd_cli_state *state) +{ + DOM_SID *sids = NULL; + size_t num_sids = 0; + char *sidstr = NULL; + ssize_t len; + size_t i; + uint32 num_aliases; + uint32 *alias_rids; + NTSTATUS result; + + DEBUG(3, ("[%5lu]: getsidaliases\n", (unsigned long)state->pid)); + + sidstr = state->request.extra_data.data; + if (sidstr == NULL) { + sidstr = talloc_strdup(state->mem_ctx, "\n"); /* No SID */ + if (!sidstr) { + DEBUG(0, ("Out of memory\n")); + return WINBINDD_ERROR; + } + } + + DEBUG(10, ("Sidlist: %s\n", sidstr)); + + if (!parse_sidlist(state->mem_ctx, sidstr, &sids, &num_sids)) { + DEBUG(0, ("Could not parse SID list: %s\n", sidstr)); + return WINBINDD_ERROR; + } + + num_aliases = 0; + alias_rids = NULL; + + result = domain->methods->lookup_useraliases(domain, + state->mem_ctx, + num_sids, sids, + &num_aliases, + &alias_rids); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("Could not lookup_useraliases: %s\n", + nt_errstr(result))); + return WINBINDD_ERROR; + } + + num_sids = 0; + sids = NULL; + sidstr = NULL; + + DEBUG(10, ("Got %d aliases\n", num_aliases)); + + for (i=0; i<num_aliases; i++) { + DOM_SID sid; + DEBUGADD(10, (" rid %d\n", alias_rids[i])); + sid_copy(&sid, &domain->sid); + sid_append_rid(&sid, alias_rids[i]); + result = add_sid_to_array(state->mem_ctx, &sid, &sids, + &num_sids); + if (!NT_STATUS_IS_OK(result)) { + return WINBINDD_ERROR; + } + } + + + if (!print_sidlist(state->mem_ctx, sids, num_sids, &sidstr, &len)) { + DEBUG(0, ("Could not print_sidlist\n")); + state->response.extra_data.data = NULL; + return WINBINDD_ERROR; + } + + state->response.extra_data.data = NULL; + + if (sidstr) { + state->response.extra_data.data = SMB_STRDUP(sidstr); + if (!state->response.extra_data.data) { + DEBUG(0, ("Out of memory\n")); + return WINBINDD_ERROR; + } + DEBUG(10, ("aliases_list: %s\n", + (char *)state->response.extra_data.data)); + state->response.length += len+1; + state->response.data.num_entries = num_sids; + } + + return WINBINDD_OK; +} + + diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index c302dd1d62..5120402e3d 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -112,6 +112,8 @@ enum winbindd_result winbindd_dual_list_groups(struct winbindd_domain *domain, struct winbindd_cli_state *state); bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, size_t num_sids, char **result, ssize_t *len); +bool parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, + DOM_SID **sids, size_t *num_sids); enum winbindd_result winbindd_dual_lookuprids(struct winbindd_domain *domain, struct winbindd_cli_state *state); void winbindd_getsidaliases_async(struct winbindd_domain *domain, @@ -342,6 +344,7 @@ void winbindd_list_groups(struct winbindd_cli_state *state); void winbindd_getgroups(struct winbindd_cli_state *state); void winbindd_getusersids(struct winbindd_cli_state *state); void winbindd_getuserdomgroups(struct winbindd_cli_state *state); +void winbindd_getsidaliases(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_getuserdomgroups(struct winbindd_domain *domain, struct winbindd_cli_state *state); bool get_sam_group_entries(struct getent_state *ent); @@ -495,6 +498,7 @@ enum winbindd_result winbindd_dual_userinfo(struct winbindd_domain *domain, struct winbindd_cli_state *state); void winbindd_getpwnam(struct winbindd_cli_state *state); void winbindd_getpwuid(struct winbindd_cli_state *state); +void winbindd_getpwsid(struct winbindd_cli_state *state); void winbindd_setpwent(struct winbindd_cli_state *state); void winbindd_endpwent(struct winbindd_cli_state *state); void winbindd_getpwent(struct winbindd_cli_state *state); diff --git a/source3/winbindd/winbindd_user.c b/source3/winbindd/winbindd_user.c index a6740b1fb8..50aea4e0cb 100644 --- a/source3/winbindd/winbindd_user.c +++ b/source3/winbindd/winbindd_user.c @@ -217,8 +217,8 @@ static void getpwsid_queryuser_recv(void *private_data, bool success, static void getpwsid_sid2uid_recv(void *private_data, bool success, uid_t uid); static void getpwsid_sid2gid_recv(void *private_data, bool success, gid_t gid); -static void winbindd_getpwsid(struct winbindd_cli_state *state, - const DOM_SID *sid) +static void getpwsid_queryuser(struct winbindd_cli_state *state, + const DOM_SID *sid) { struct getpwsid_state *s; @@ -509,7 +509,7 @@ static void getpwnam_name2sid_recv(void *private_data, bool success, check_domain_trusted(domname, sid); } - winbindd_getpwsid(state, sid); + getpwsid_queryuser(state, sid); } static void getpwuid_recv(void *private_data, bool success, const char *sid) @@ -535,7 +535,7 @@ static void getpwuid_recv(void *private_data, bool success, const char *sid) return; } - winbindd_getpwsid(state, &user_sid); + getpwsid_queryuser(state, &user_sid); } /* Return a password structure given a uid number */ @@ -553,6 +553,26 @@ void winbindd_getpwuid(struct winbindd_cli_state *state) winbindd_uid2sid_async(state->mem_ctx, uid, getpwuid_recv, state); } +/* Return a password structure given a sid */ +void winbindd_getpwsid(struct winbindd_cli_state *state) +{ + DOM_SID sid; + + /* Ensure null termination */ + state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; + + DEBUG(3, ("[%5lu]: getpwsid %s\n", (unsigned long)state->pid, + state->request.data.sid)); + + if (!string_to_sid(&sid, state->request.data.sid)) { + DEBUG(5, ("%s not a SID\n", state->request.data.sid)); + request_error(state); + return; + } + + getpwsid_queryuser(state, &sid); +} + /* * set/get/endpwent functions */ diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index d127837382..c0330c0ae8 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -1197,20 +1197,20 @@ static WERROR dcesrv_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_ /* - spoolss_RouterRefreshPrinterChangeNotification + spoolss_RouterReplyPrinterEx */ -static WERROR dcesrv_spoolss_RouterRefreshPrinterChangeNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct spoolss_RouterRefreshPrinterChangeNotification *r) +static WERROR dcesrv_spoolss_RouterReplyPrinterEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RouterReplyPrinterEx *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* - spoolss_RemoteFindNextPrinterChangeNotifyEx + spoolss_RouterRefreshPrinterChangeNotify */ -static WERROR dcesrv_spoolss_RemoteFindNextPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r) +static WERROR dcesrv_spoolss_RouterRefreshPrinterChangeNotify(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct spoolss_RouterRefreshPrinterChangeNotify *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } diff --git a/source4/torture/basic/locking.c b/source4/torture/basic/locking.c index fcac52ca6a..06a960bc81 100644 --- a/source4/torture/basic/locking.c +++ b/source4/torture/basic/locking.c @@ -610,7 +610,7 @@ ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) && NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)); EXPECTED(ret, true); - torture_comment(tctx, "the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); + torture_comment(tctx, "the same process %s unlock the stack of 3 locks\n", ret?"can":"cannot"); /* Ensure the next unlock fails. */ ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)); diff --git a/source4/torture/ndr/spoolss.c b/source4/torture/ndr/spoolss.c index eecd91edba..c1ca0c20c9 100644 --- a/source4/torture/ndr/spoolss.c +++ b/source4/torture/ndr/spoolss.c @@ -109,14 +109,14 @@ static const uint8_t RFFPCNEX_out_data[] = { 0x00, 0x00, 0x00, 0x00 }; -static const uint8_t RFNPCNEX_in_data[] = { +static const uint8_t RRPCN_in_data[] = { 0x00, 0x00, 0x00, 0x00, 0x1e, 0x9b, 0x8b, 0xe5, 0x32, 0x9a, 0xd5, 0x45, 0xa8, 0x0a, 0x10, 0x30, 0x5b, 0x87, 0x6f, 0x69, 0x01, 0x00, 0x00, 0x00, 0x44, 0x0d, 0x0b, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const uint8_t RFNPCNEX_out_data[] = { +static const uint8_t RRPCN_out_data[] = { 0x00, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, @@ -459,8 +459,8 @@ struct torture_suite *ndr_spoolss_suite(TALLOC_CTX *ctx) torture_suite_add_ndr_pull_fn_test(suite, spoolss_RemoteFindFirstPrinterChangeNotifyEx, RFFPCNEX_in_data, NDR_IN, NULL ); torture_suite_add_ndr_pull_fn_test(suite, spoolss_RemoteFindFirstPrinterChangeNotifyEx, RFFPCNEX_out_data, NDR_OUT, NULL ); - torture_suite_add_ndr_pull_fn_test(suite, spoolss_RemoteFindNextPrinterChangeNotifyEx, RFNPCNEX_in_data, NDR_IN, NULL ); - torture_suite_add_ndr_pull_fn_test(suite, spoolss_RemoteFindNextPrinterChangeNotifyEx, RFNPCNEX_out_data, NDR_OUT, NULL ); + torture_suite_add_ndr_pull_fn_test(suite, spoolss_RouterRefreshPrinterChangeNotify, RRPCN_in_data, NDR_IN, NULL ); + torture_suite_add_ndr_pull_fn_test(suite, spoolss_RouterRefreshPrinterChangeNotify, RRPCN_out_data, NDR_OUT, NULL ); torture_suite_add_ndr_pull_fn_test(suite, spoolss_EnumForms, enumforms_in_data, NDR_IN, NULL ); torture_suite_add_ndr_pull_fn_test(suite, spoolss_EnumForms, enumforms_out_data, NDR_OUT, NULL ); diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c index 2d1eae3a69..72a03e1623 100644 --- a/source4/torture/raw/lock.c +++ b/source4/torture/raw/lock.c @@ -38,8 +38,34 @@ goto done; \ }} while (0) +#define CHECK_STATUS_CONT(status, correct) do { \ + if (!NT_STATUS_EQUAL(status, correct)) { \ + printf("(%s) Incorrect status %s - should be %s\n", \ + __location__, nt_errstr(status), nt_errstr(correct)); \ + ret = false; \ + }} while (0) + +#define CHECK_STATUS_OR(status, correct1, correct2) do { \ + if ((!NT_STATUS_EQUAL(status, correct1)) && \ + (!NT_STATUS_EQUAL(status, correct2))) { \ + printf("(%s) Incorrect status %s - should be %s or %s\n", \ + __location__, nt_errstr(status), nt_errstr(correct1), \ + nt_errstr(correct2)); \ + ret = false; \ + goto done; \ + }} while (0) + +#define CHECK_STATUS_OR_CONT(status, correct1, correct2) do { \ + if ((!NT_STATUS_EQUAL(status, correct1)) && \ + (!NT_STATUS_EQUAL(status, correct2))) { \ + printf("(%s) Incorrect status %s - should be %s or %s\n", \ + __location__, nt_errstr(status), nt_errstr(correct1), \ + nt_errstr(correct2)); \ + ret = false; \ + }} while (0) #define BASEDIR "\\testlock" +#define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false)) /* test SMBlock and SMBunlock ops @@ -337,15 +363,25 @@ static bool test_lockx(struct torture_context *tctx, struct smbcli_state *cli) lock[0].pid++; lock[0].count = 2; status = smb_raw_lock(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_OK); + if (TARGET_IS_WIN7(tctx)) + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + else + CHECK_STATUS(status, NT_STATUS_OK); lock[0].pid--; io.lockx.in.ulock_cnt = 1; io.lockx.in.lock_cnt = 0; lock[0].count = 1; status = smb_raw_lock(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_OK); - status = smb_raw_lock(cli->tree, &io); - CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); + + /* XXX This is very strange - Win7 gives us an invalid range when we + * unlock the range even though the range is locked! Win7 bug? */ + if (TARGET_IS_WIN7(tctx)) + CHECK_STATUS(status, NT_STATUS_WIN7_INVALID_RANGE); + else { + CHECK_STATUS(status, NT_STATUS_OK); + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); + } done: smbcli_close(cli->tree, fnum); @@ -354,7 +390,6 @@ done: return ret; } - /* test high pid */ @@ -410,8 +445,6 @@ static bool test_pidhigh(struct torture_context *tctx, goto done; } - cli->session->pid |= 0x10000; - cli->session->pid = 2; if (smbcli_read(cli->tree, fnum, &c, 0, 1) == 1) { @@ -1321,6 +1354,525 @@ done: return ret; } +struct double_lock_test { + struct smb_lock_entry lock1; + struct smb_lock_entry lock2; + NTSTATUS exp_status; +}; + +/** + * Tests zero byte locks. + */ +struct double_lock_test zero_byte_tests[] = { + /* {pid, offset, count}, {pid, offset, count}, status */ + + /** First, takes a zero byte lock at offset 10. Then: + * - Taking 0 byte lock at 10 should succeed. + * - Taking 1 byte locks at 9,10,11 should succeed. + * - Taking 2 byte lock at 9 should fail. + * - Taking 2 byte lock at 10 should succeed. + * - Taking 3 byte lock at 9 should fail. + */ + {{1000, 10, 0}, {1001, 10, 0}, NT_STATUS_OK}, + {{1000, 10, 0}, {1001, 9, 1}, NT_STATUS_OK}, + {{1000, 10, 0}, {1001, 10, 1}, NT_STATUS_OK}, + {{1000, 10, 0}, {1001, 11, 1}, NT_STATUS_OK}, + {{1000, 10, 0}, {1001, 9, 2}, NT_STATUS_LOCK_NOT_GRANTED}, + {{1000, 10, 0}, {1001, 10, 2}, NT_STATUS_OK}, + {{1000, 10, 0}, {1001, 9, 3}, NT_STATUS_LOCK_NOT_GRANTED}, + + /** Same, but opposite order. */ + {{1001, 10, 0}, {1000, 10, 0}, NT_STATUS_OK}, + {{1001, 9, 1}, {1000, 10, 0}, NT_STATUS_OK}, + {{1001, 10, 1}, {1000, 10, 0}, NT_STATUS_OK}, + {{1001, 11, 1}, {1000, 10, 0}, NT_STATUS_OK}, + {{1001, 9, 2}, {1000, 10, 0}, NT_STATUS_LOCK_NOT_GRANTED}, + {{1001, 10, 2}, {1000, 10, 0}, NT_STATUS_OK}, + {{1001, 9, 3}, {1000, 10, 0}, NT_STATUS_LOCK_NOT_GRANTED}, + + /** Zero zero case. */ + {{1000, 0, 0}, {1001, 0, 0}, NT_STATUS_OK}, +}; + +static bool test_zerobytelocks(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_lock io; + struct smb_lock_entry zerozero; + NTSTATUS status; + bool ret = true; + int fnum, i; + const char *fname = BASEDIR "\\zero.txt"; + + printf("Testing zero length byte range locks:\n"); + + if (!torture_setup_dir(cli, BASEDIR)) { + return false; + } + + io.generic.level = RAW_LOCK_LOCKX; + + fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum == -1) { + printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + + /* Setup initial parameters */ + io.lockx.level = RAW_LOCK_LOCKX; + io.lockx.in.file.fnum = fnum; + io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; /* Exclusive */ + io.lockx.in.timeout = 0; + + /* Try every combination of locks in zero_byte_tests. The first lock is + * assumed to succeed. The second lock may contend, depending on the + * expected status. */ + for (i = 0; + i < sizeof(zero_byte_tests) / sizeof(struct double_lock_test); + i++) { + printf(" ... {%d, %llu, %llu} + {%d, %llu, %llu} = %s\n", + zero_byte_tests[i].lock1.pid, + zero_byte_tests[i].lock1.offset, + zero_byte_tests[i].lock1.count, + zero_byte_tests[i].lock2.pid, + zero_byte_tests[i].lock2.offset, + zero_byte_tests[i].lock2.count, + nt_errstr(zero_byte_tests[i].exp_status)); + + /* Lock both locks. */ + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + + io.lockx.in.locks = &zero_byte_tests[i].lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + io.lockx.in.locks = &zero_byte_tests[i].lock2; + status = smb_raw_lock(cli->tree, &io); + + if (NT_STATUS_EQUAL(zero_byte_tests[i].exp_status, + NT_STATUS_LOCK_NOT_GRANTED)) { + /* Allow either of the failure messages and keep going + * if we see the wrong status. */ + CHECK_STATUS_OR_CONT(status, + NT_STATUS_LOCK_NOT_GRANTED, + NT_STATUS_FILE_LOCK_CONFLICT); + + } else { + CHECK_STATUS_CONT(status, + zero_byte_tests[i].exp_status); + } + + /* Unlock both locks. */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + + if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + } + + io.lockx.in.locks = &zero_byte_tests[i].lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + } + +done: + smbcli_close(cli->tree, fnum); + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + return ret; +} + +static bool test_unlock(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_lock io; + NTSTATUS status; + bool ret = true; + int fnum1, fnum2; + const char *fname = BASEDIR "\\unlock.txt"; + struct smb_lock_entry lock1; + struct smb_lock_entry lock2; + + printf("Testing LOCKX unlock:\n"); + + if (!torture_setup_dir(cli, BASEDIR)) { + return false; + } + + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + fnum2 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum2 == -1) { + printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + + /* Setup initial parameters */ + io.lockx.level = RAW_LOCK_LOCKX; + io.lockx.in.timeout = 0; + + lock1.pid = cli->session->pid; + lock1.offset = 0; + lock1.count = 10; + lock2.pid = cli->session->pid - 1; + lock2.offset = 0; + lock2.count = 10; + + /** + * Take exclusive lock, then unlock it with a shared-unlock call. + */ + printf(" taking exclusive lock.\n"); + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = 0; + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + printf(" unlock the exclusive with a shared unlock call.\n"); + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + printf(" try shared lock on pid2/fnum2, testing the unlock.\n"); + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; + io.lockx.in.file.fnum = fnum2; + io.lockx.in.locks = &lock2; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /** + * Unlock a shared lock with an exclusive-unlock call. + */ + printf(" unlock new shared lock with exclusive unlock call.\n"); + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + io.lockx.in.mode = 0; + io.lockx.in.file.fnum = fnum2; + io.lockx.in.locks = &lock2; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + printf(" try exclusive lock on pid1, testing the unlock.\n"); + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = 0; + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* cleanup */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /** + * Test unlocking of 0-byte locks. + */ + + printf(" lock shared and exclusive 0-byte locks, testing that Windows " + "always unlocks the exclusive first.\n"); + lock1.pid = cli->session->pid; + lock1.offset = 10; + lock1.count = 0; + lock2.pid = cli->session->pid; + lock2.offset = 5; + lock2.count = 10; + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + + /* lock 0-byte shared + * Note: Order of the shared/exclusive locks doesn't matter. */ + io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* lock 0-byte exclusive */ + io.lockx.in.mode = 0; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* test contention */ + io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; + io.lockx.in.locks = &lock2; + io.lockx.in.file.fnum = fnum2; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS_OR(status, NT_STATUS_LOCK_NOT_GRANTED, + NT_STATUS_FILE_LOCK_CONFLICT); + + /* unlock */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* test - can we take a shared lock? */ + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; + io.lockx.in.file.fnum = fnum2; + io.lockx.in.locks = &lock2; + status = smb_raw_lock(cli->tree, &io); + + /* XXX Samba will fail this test. This is temporary(because this isn't + * new to Win7, it succeeds in WinXP too), until I can come to a + * resolution as to whether Samba should support this or not. There is + * code to preference unlocking exclusive locks before shared locks, + * but its wrapped with "#ifdef ZERO_ZERO". -zkirsch */ + if (TARGET_IS_WIN7(tctx)) + CHECK_STATUS(status, NT_STATUS_OK); + else { + CHECK_STATUS_OR(status, NT_STATUS_LOCK_NOT_GRANTED, + NT_STATUS_FILE_LOCK_CONFLICT); + } + + /* cleanup */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + status = smb_raw_lock(cli->tree, &io); + + /* XXX Same as above. */ + if (TARGET_IS_WIN7(tctx)) + CHECK_STATUS(status, NT_STATUS_OK); + else + CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); + + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + +done: + smbcli_close(cli->tree, fnum1); + smbcli_close(cli->tree, fnum2); + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + return ret; +} + +static bool test_multiple_unlock(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_lock io; + NTSTATUS status; + bool ret = true; + int fnum1; + const char *fname = BASEDIR "\\unlock_multiple.txt"; + struct smb_lock_entry lock1; + struct smb_lock_entry lock2; + struct smb_lock_entry locks[2]; + + printf("Testing LOCKX multiple unlock:\n"); + + if (!torture_setup_dir(cli, BASEDIR)) { + return false; + } + + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + + /* Setup initial parameters */ + io.lockx.level = RAW_LOCK_LOCKX; + io.lockx.in.timeout = 0; + + lock1.pid = cli->session->pid; + lock1.offset = 0; + lock1.count = 10; + lock2.pid = cli->session->pid; + lock2.offset = 10; + lock2.count = 10; + + locks[0] = lock1; + locks[1] = lock2; + + io.lockx.in.file.fnum = fnum1; + io.lockx.in.mode = 0; /* exclusive */ + + /** Test1: Take second lock, but not first. */ + printf(" unlock 2 locks, first one not locked. Expect no locks " + "unlocked. \n"); + + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.locks = &lock2; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Try to unlock both locks. */ + io.lockx.in.ulock_cnt = 2; + io.lockx.in.lock_cnt = 0; + io.lockx.in.locks = locks; + + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); + + /* Second lock should not be unlocked. */ + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.locks = &lock2; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); + + /* cleanup */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + io.lockx.in.locks = &lock2; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /** Test2: Take first lock, but not second. */ + printf(" unlock 2 locks, second one not locked. Expect first lock " + "unlocked.\n"); + + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* Try to unlock both locks. */ + io.lockx.in.ulock_cnt = 2; + io.lockx.in.lock_cnt = 0; + io.lockx.in.locks = locks; + + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED); + + /* First lock should be unlocked. */ + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /* cleanup */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + io.lockx.in.locks = &lock1; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + +done: + smbcli_close(cli->tree, fnum1); + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + return ret; +} + +/** + * torture_locktest5 covers stacking pretty well, but its missing two tests: + * - stacking an exclusive on top of shared fails + * - stacking two exclusives fail + */ +static bool test_stacking(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_lock io; + NTSTATUS status; + bool ret = true; + int fnum1; + const char *fname = BASEDIR "\\stacking.txt"; + struct smb_lock_entry lock1; + struct smb_lock_entry lock2; + + printf("Testing stacking:\n"); + + if (!torture_setup_dir(cli, BASEDIR)) { + return false; + } + + io.generic.level = RAW_LOCK_LOCKX; + + fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum1 == -1) { + printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + + /* Setup initial parameters */ + io.lockx.level = RAW_LOCK_LOCKX; + io.lockx.in.timeout = 0; + + lock1.pid = cli->session->pid; + lock1.offset = 0; + lock1.count = 10; + lock2.pid = cli->session->pid - 1; + lock2.offset = 0; + lock2.count = 10; + + /** + * Try to take a shared lock, then stack an exclusive. + */ + printf(" stacking an exclusive on top of a shared lock fails.\n"); + io.lockx.in.file.fnum = fnum1; + io.lockx.in.locks = &lock1; + + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = 0; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS_OR(status, NT_STATUS_LOCK_NOT_GRANTED, + NT_STATUS_FILE_LOCK_CONFLICT); + + /* cleanup */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + /** + * Prove that two exclusive locks do not stack. + */ + printf(" two exclusive locks do not stack.\n"); + io.lockx.in.ulock_cnt = 0; + io.lockx.in.lock_cnt = 1; + io.lockx.in.mode = 0; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS_OR(status, NT_STATUS_LOCK_NOT_GRANTED, + NT_STATUS_FILE_LOCK_CONFLICT); + + /* cleanup */ + io.lockx.in.ulock_cnt = 1; + io.lockx.in.lock_cnt = 0; + status = smb_raw_lock(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + +done: + smbcli_close(cli->tree, fnum1); + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + return ret; +} /* basic testing of lock calls @@ -1336,5 +1888,12 @@ struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx) torture_suite_add_1smb_test(suite, "errorcode", test_errorcode); torture_suite_add_1smb_test(suite, "changetype", test_changetype); + torture_suite_add_1smb_test(suite, "stacking", test_stacking); + torture_suite_add_1smb_test(suite, "unlock", test_unlock); + torture_suite_add_1smb_test(suite, "multiple_unlock", + test_multiple_unlock); + torture_suite_add_1smb_test(suite, "zerobytelocks", + test_zerobytelocks); + return suite; } diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c index 635990354c..d01dc9a856 100644 --- a/source4/torture/smbtorture.c +++ b/source4/torture/smbtorture.c @@ -559,6 +559,8 @@ int main(int argc,char *argv[]) lp_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true"); } else if (strcmp(target, "samba4") == 0) { lp_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true"); + } else if (strcmp(target, "win7") == 0) { + lp_set_cmdline(cmdline_lp_ctx, "torture:win7", "true"); } if (max_runtime) { |