From d1c7bbd893c27ebff28571b4ea611bd3e35148c1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:35:48 +0100 Subject: [PATCH 01/15] Convert rpc_sock_read to use tevent_req base async_read --- source3/rpc_client/rpc_transport_sock.c | 57 ++++++++++++++++++++----- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index c0fa41b0de0..68421b3b4cb 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -35,6 +35,12 @@ static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state * return 0; } +struct rpc_sock_read_state { + ssize_t received; +}; + +static void rpc_sock_read_done(struct tevent_req *subreq); + static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, uint8_t *data, size_t size, @@ -42,22 +48,53 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - return async_recv(mem_ctx, ev, sock_transp->fd, data, size, 0); + struct async_req *result; + struct tevent_req *subreq; + struct rpc_sock_read_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_sock_read_state)) { + return NULL; + } + + subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_sock_read_done; + subreq->async.private_data = result; + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_sock_read_done(struct tevent_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.private_data, struct async_req); + struct rpc_sock_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_read_state); + int err; + + state->received = async_recv_recv(subreq, &err); + if (state->received == -1) { + async_req_nterror(req, map_nt_error_from_unix(err)); + return; + } + async_req_done(req); } static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) { - ssize_t received; - int sys_errno; + struct rpc_sock_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_read_state); + NTSTATUS status; - received = async_syscall_result_ssize_t(req, &sys_errno); - if (received == -1) { - return map_nt_error_from_unix(sys_errno); + if (async_req_is_nterror(req, &status)) { + return status; } - if (received == 0) { - return NT_STATUS_END_OF_FILE; - } - *preceived = received; + *preceived = state->received; return NT_STATUS_OK; } From 00ad0c4a4317db810bf2197503006ae5a6bb8bce Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:38:32 +0100 Subject: [PATCH 02/15] Remove async_req based async_recv --- lib/async_req/async_sock.c | 68 -------------------------------------- lib/async_req/async_sock.h | 3 -- 2 files changed, 71 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 3563421e0e5..302265c8053 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -310,74 +310,6 @@ struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return result; } -/** - * fde event handler for the "recv" syscall - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the recv - * @param[in] flags Can only be TEVENT_FD_READ here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_recv_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_recv *p = &state->param.param_recv; - - if (state->syscall_type != ASYNC_SYSCALL_RECV) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = recv(p->fd, p->buffer, p->length, - p->flags); - state->sys_errno = errno; - - TALLOC_FREE(state->fde); - - async_req_done(req); -} - -/** - * Async version of recv(2) - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to recv from - * @param[in] buffer The buffer to recv into - * @param[in] length How many bytes to recv - * @param[in] flags flags passed to recv(2) - * - * This function is a direct counterpart of recv(2) - */ - -struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_RECV, - fd, TEVENT_FD_READ, async_recv_callback, - &state); - - if (result == NULL) { - return NULL; - } - - state->param.param_recv.fd = fd; - state->param.param_recv.buffer = buffer; - state->param.param_recv.length = length; - state->param.param_recv.flags = flags; - - return result; -} - struct async_send_state { int fd; const void *buf; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index bfc4346d39a..1d0558b41ea 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -32,9 +32,6 @@ int async_syscall_result_int(struct async_req *req, int *perrno); struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buffer, size_t length, int flags); -struct async_req *async_recv(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, void *buffer, size_t length, - int flags); struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, From be4913fbe6f6bb2fefbeeb1559692e04a15758f9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:44:26 +0100 Subject: [PATCH 03/15] Convert rpc_sock_write to use tevent_req base async_send --- source3/rpc_client/rpc_transport_sock.c | 53 +++++++++++++++++++++---- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index 68421b3b4cb..658ffe30d6d 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -98,6 +98,12 @@ static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) return NT_STATUS_OK; } +struct rpc_sock_write_state { + ssize_t sent; +}; + +static void rpc_sock_write_done(struct tevent_req *subreq); + static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, const uint8_t *data, size_t size, @@ -105,19 +111,52 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - return async_send(mem_ctx, ev, sock_transp->fd, data, size, 0); + struct async_req *result; + struct tevent_req *subreq; + struct rpc_sock_write_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_sock_write_state)) { + return NULL; + } + subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_sock_write_done; + subreq->async.private_data = result; + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_sock_write_done(struct tevent_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.private_data, struct async_req); + struct rpc_sock_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_write_state); + int err; + + state->sent = async_send_recv(subreq, &err); + if (state->sent == -1) { + async_req_nterror(req, map_nt_error_from_unix(err)); + return; + } + async_req_done(req); } static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent) { - ssize_t sent; - int sys_errno; + struct rpc_sock_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_write_state); + NTSTATUS status; - sent = async_syscall_result_ssize_t(req, &sys_errno); - if (sent == -1) { - return map_nt_error_from_unix(sys_errno); + if (async_req_is_nterror(req, &status)) { + return status; } - *psent = sent; + *psent = state->sent; return NT_STATUS_OK; } From 423c1d88fcd0f128bceaf8b0c371281aa4a41003 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:45:39 +0100 Subject: [PATCH 04/15] Remove async_req based async_send --- lib/async_req/async_sock.c | 232 ------------------------------------- lib/async_req/async_sock.h | 8 -- 2 files changed, 240 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 302265c8053..40e7bca4c86 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -29,45 +29,6 @@ #define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) #endif -/** - * Discriminator for async_syscall_state - */ -enum async_syscall_type { - ASYNC_SYSCALL_SEND, - ASYNC_SYSCALL_RECV, -}; - -/** - * Holder for syscall arguments and the result - */ - -struct async_syscall_state { - enum async_syscall_type syscall_type; - struct tevent_fd *fde; - - union { - struct param_send { - int fd; - const void *buffer; - size_t length; - int flags; - } param_send; - struct param_recv { - int fd; - void *buffer; - size_t length; - int flags; - } param_recv; - } param; - - union { - ssize_t result_ssize_t; - size_t result_size_t; - int result_int; - } result; - int sys_errno; -}; - /** * @brief Map async_req states to unix-style errnos * @param[in] req The async req to get the state from @@ -117,199 +78,6 @@ int async_req_simple_recv_errno(struct async_req *req) return 0; } -/** - * @brief Create a new async syscall req - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] type Which syscall will this be - * @param[in] pstate Where to put the newly created private_data state - * @retval The new request - * - * This is a helper function to prepare a new struct async_req with an - * associated struct async_syscall_state. The async_syscall_state will be put - * into the async_req as private_data. - */ - -static struct async_req *async_syscall_new(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - enum async_syscall_type type, - struct async_syscall_state **pstate) -{ - struct async_req *result; - struct async_syscall_state *state; - - if (!async_req_setup(mem_ctx, &result, &state, - struct async_syscall_state)) { - return NULL; - } - state->syscall_type = type; - - result->private_data = state; - - *pstate = state; - - return result; -} - -/** - * @brief Create a new async syscall req based on a fd - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] type Which syscall will this be - * @param[in] fd The file descriptor we work on - * @param[in] fde_flags TEVENT_FD_READ/WRITE -- what are we interested in? - * @param[in] fde_cb The callback function for the file descriptor event - * @param[in] pstate Where to put the newly created private_data state - * @retval The new request - * - * This is a helper function to prepare a new struct async_req with an - * associated struct async_syscall_state and an associated file descriptor - * event. - */ - -static struct async_req *async_fde_syscall_new( - TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - enum async_syscall_type type, - int fd, - uint16_t fde_flags, - void (*fde_cb)(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv), - struct async_syscall_state **pstate) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_syscall_new(mem_ctx, ev, type, &state); - if (result == NULL) { - return NULL; - } - - state->fde = tevent_add_fd(ev, state, fd, fde_flags, fde_cb, result); - if (state->fde == NULL) { - TALLOC_FREE(result); - return NULL; - } - *pstate = state; - return result; -} - -/** - * Retrieve a ssize_t typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_ssize_t; -} - -/** - * Retrieve a size_t typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -size_t async_syscall_result_size_t(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_size_t; -} - -/** - * Retrieve a int typed result from an async syscall - * @param[in] req The syscall that has just finished - * @param[out] perrno Where to put the syscall's errno - * @retval The return value from the asynchronously called syscall - */ - -int async_syscall_result_int(struct async_req *req, int *perrno) -{ - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - - *perrno = state->sys_errno; - return state->result.result_int; -} - -/** - * fde event handler for the "send" syscall - * @param[in] ev The event context that sent us here - * @param[in] fde The file descriptor event associated with the send - * @param[in] flags Can only be TEVENT_FD_WRITE here - * @param[in] priv private data, "struct async_req *" in this case - */ - -static void async_send_callback(struct tevent_context *ev, - struct tevent_fd *fde, uint16_t flags, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - struct async_syscall_state *state = talloc_get_type_abort( - req->private_data, struct async_syscall_state); - struct param_send *p = &state->param.param_send; - - if (state->syscall_type != ASYNC_SYSCALL_SEND) { - async_req_error(req, EIO); - return; - } - - state->result.result_ssize_t = send(p->fd, p->buffer, p->length, - p->flags); - state->sys_errno = errno; - - TALLOC_FREE(state->fde); - - async_req_done(req); -} - -/** - * Async version of send(2) - * @param[in] mem_ctx The memory context to hang the result off - * @param[in] ev The event context to work from - * @param[in] fd The socket to send to - * @param[in] buffer The buffer to send - * @param[in] length How many bytes to send - * @param[in] flags flags passed to send(2) - * - * This function is a direct counterpart of send(2) - */ - -struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags) -{ - struct async_req *result; - struct async_syscall_state *state; - - result = async_fde_syscall_new( - mem_ctx, ev, ASYNC_SYSCALL_SEND, - fd, TEVENT_FD_WRITE, async_send_callback, - &state); - if (result == NULL) { - return NULL; - } - - state->param.param_send.fd = fd; - state->param.param_send.buffer = buffer; - state->param.param_send.length = length; - state->param.param_send.flags = flags; - - return result; -} - struct async_send_state { int fd; const void *buf; diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h index 1d0558b41ea..e001709d278 100644 --- a/lib/async_req/async_sock.h +++ b/lib/async_req/async_sock.h @@ -25,14 +25,6 @@ bool async_req_is_errno(struct async_req *req, int *err); int async_req_simple_recv_errno(struct async_req *req); -ssize_t async_syscall_result_ssize_t(struct async_req *req, int *perrno); -size_t async_syscall_result_size_t(struct async_req *req, int *perrno); -int async_syscall_result_int(struct async_req *req, int *perrno); - -struct async_req *async_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - int fd, const void *buffer, size_t length, - int flags); - struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const void *buf, size_t len, From 06b018767b6e6f3ee0221c3aee142cb2b4836fc9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 12:55:47 +0100 Subject: [PATCH 05/15] Fix an incompatible pointer passed to winbind_get_groups This is the same bug that was fixed in other places of the code a few times already: A C compiler ONLY does automatic type conversions during an assignment. Passing down a pointer to type A to a function taking type B as an argument does NOT do any automatic type conversions. If required, I can dig up the relevant portions of the C standard. --- source3/passdb/pdb_wbc_sam.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index 33dc03fe4cd..d2c7fda2936 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -115,10 +115,12 @@ static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, { size_t i; const char *username = pdb_get_username(user); + uint32_t num_groups; - if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + if (!winbind_get_groups(mem_ctx, username, &num_groups, pp_gids)) { return NT_STATUS_NO_SUCH_USER; } + *p_num_groups = num_groups; if (*p_num_groups == 0) { smb_panic("primary group missing"); From 5bab95b58366ff001b4967bdb0674f42dc990a77 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2009 13:03:03 +0100 Subject: [PATCH 06/15] Fix a missing prototype --- source3/include/proto.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/include/proto.h b/source3/include/proto.h index 80841111451..2d92b0fc908 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4693,6 +4693,10 @@ NTSTATUS pdb_nds_init(void); NTSTATUS pdb_smbpasswd_init(void) ; +/* The following definitions come from passdb/pdb_wbc_sam.c */ + +NTSTATUS pdb_wbc_sam_init(void); + /* The following definitions come from passdb/pdb_tdb.c */ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen); From 13ac0dc4565b1cbdb977b6959562f3f8f9ac5ff8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 13:53:19 +0100 Subject: [PATCH 07/15] tevent: add tevent_req_poll() function metze --- lib/tevent/tevent.h | 3 +++ lib/tevent/tevent_req.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b3d1c6d59a5..b3611228aa2 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -296,6 +296,9 @@ struct tevent_req *tevent_req_post(struct tevent_req *req, bool tevent_req_is_in_progress(struct tevent_req *req); +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev); + bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error); diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 800e3855d19..c17587b16c1 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -235,6 +235,21 @@ bool tevent_req_is_in_progress(struct tevent_req *req) return false; } +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev) +{ + while (tevent_req_is_in_progress(req)) { + int ret; + + ret = tevent_loop_once(ev); + if (ret != 0) { + return false; + } + } + + return true; +} + bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, uint64_t *error) { From 2390ea274bff7a8878a488db0893a393c9d1b51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 25 Feb 2009 13:19:12 +0100 Subject: [PATCH 08/15] s3-rpcclient: more uses of is_valid_policy_hnd in spoolss and samr commands. Guenther --- source3/rpcclient/cmd_samr.c | 32 +++++++------------------------- source3/rpcclient/cmd_spoolss.c | 25 +++++-------------------- 2 files changed, 12 insertions(+), 45 deletions(-) diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 31977e95546..936c2081f36 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -789,7 +789,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, struct samr_SamArray *dom_users = NULL; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; uint32 acb_mask = ACB_NORMAL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 1) || (argc > 3)) { printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]); @@ -811,8 +810,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = rpccli_samr_OpenDomain(cli, mem_ctx, @@ -824,8 +821,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate domain users */ start_idx = 0; @@ -852,10 +847,10 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -872,7 +867,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, uint32 start_idx, size, num_dom_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; struct samr_SamArray *dom_groups = NULL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 1) || (argc > 2)) { printf("Usage: %s [access_mask]\n", argv[0]); @@ -891,8 +885,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = rpccli_samr_OpenDomain(cli, mem_ctx, @@ -904,8 +896,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate domain groups */ start_idx = 0; @@ -930,10 +920,10 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -950,7 +940,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, uint32 start_idx, size, num_als_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; struct samr_SamArray *als_groups = NULL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 2) || (argc > 3)) { printf("Usage: %s builtin|domain [access mask]\n", argv[0]); @@ -969,8 +958,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = get_domain_handle(cli, mem_ctx, argv[1], @@ -982,8 +969,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate alias groups */ start_idx = 0; @@ -1008,10 +993,10 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -1027,7 +1012,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_entries, i; uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - bool got_connect_pol = false; struct samr_SamArray *sam = NULL; if ((argc < 1) || (argc > 2)) { @@ -1049,8 +1033,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, goto done; } - got_connect_pol = true; - /* Enumerate alias groups */ start_idx = 0; @@ -1075,7 +1057,7 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_connect_pol) { + if (is_valid_policy_hnd(&connect_pol)) { rpccli_samr_Close(cli, mem_ctx, &connect_pol); } diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index fe2554e02d2..eaee516ad56 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1812,7 +1812,6 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; @@ -1834,8 +1833,6 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Dummy up some values for the form data */ info1.flags = FORM_USER; @@ -1859,7 +1856,7 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c &werror); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -1875,7 +1872,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; @@ -1897,8 +1893,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Dummy up some values for the form data */ info1.flags = FORM_PRINTER; @@ -1922,7 +1916,7 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c &werror); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -1991,7 +1985,6 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; DATA_BLOB buffer; uint32_t offered = 0; union spoolss_FormInfo info; @@ -2015,8 +2008,6 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Get the form */ status = rpccli_spoolss_GetForm(cli, mem_ctx, @@ -2048,7 +2039,7 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c display_form_info1(&info.info1); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2065,7 +2056,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; /* Parse the command arguments */ @@ -2085,8 +2075,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Delete the form */ status = rpccli_spoolss_DeleteForm(cli, mem_ctx, @@ -2098,7 +2086,7 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, } done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2114,7 +2102,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, POLICY_HND handle; WERROR werror; const char *printername; - bool got_handle = False; uint32 num_forms, level = 1, i; FORM_1 *forms; @@ -2136,8 +2123,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Enumerate forms */ werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms); @@ -2154,7 +2139,7 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, } done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; From c46fad3d1bdf1082a695d3df90e55e739e494a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 25 Feb 2009 13:45:15 +0100 Subject: [PATCH 09/15] spoolss: add spoolss_FormInfo2 used by Vista. Guenther --- librpc/idl/spoolss.idl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl index 3e35399f8d9..5359fdf4a2d 100644 --- a/librpc/idl/spoolss.idl +++ b/librpc/idl/spoolss.idl @@ -1237,8 +1237,28 @@ import "misc.idl", "security.idl", "winreg.idl"; spoolss_FormArea area; } spoolss_FormInfo1; + typedef [bitmap32bit] bitmap { + SPOOLSS_FORM_STRING_TYPE_NONE = 0x00000001, + SPOOLSS_FORM_STRING_TYPE_MUI_DLL = 0x00000002, + SPOOLSS_FORM_STRING_TYPE_LANG_PAIR = 0x00000004 + } spoolss_FormStringType; + + typedef struct { + spoolss_FormFlags flags; + [relative] nstring *form_name; + spoolss_FormSize size; + spoolss_FormArea area; + [relative] nstring *keyword; + spoolss_FormStringType string_type; + [relative] nstring *mui_dll; + uint32 ressource_id; + [relative] nstring *display_name; + uint32 lang_id; + } spoolss_FormInfo2; + typedef [nodiscriminant,relative_base,public,gensize] union { [case(1)] spoolss_FormInfo1 info1; + [case(2)] spoolss_FormInfo2 info2; [default]; } spoolss_FormInfo; From 80a9a41d412aa61877a7497661197fd16ddb4903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 25 Feb 2009 14:20:40 +0100 Subject: [PATCH 10/15] s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/ndr_spoolss.c | 293 +++++++++++++++++++++++++++++++++++ librpc/gen_ndr/ndr_spoolss.h | 2 + librpc/gen_ndr/spoolss.h | 19 +++ 3 files changed, 314 insertions(+) diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c index fdafa2582b5..25c9dc49d74 100644 --- a/librpc/gen_ndr/ndr_spoolss.c +++ b/librpc/gen_ndr/ndr_spoolss.c @@ -12232,6 +12232,275 @@ _PUBLIC_ void ndr_print_spoolss_FormInfo1(struct ndr_print *ndr, const char *nam ndr->depth--; } +static enum ndr_err_code ndr_push_spoolss_FormStringType(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_FormStringType(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_FormStringType(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), "SPOOLSS_FORM_STRING_TYPE_NONE", SPOOLSS_FORM_STRING_TYPE_NONE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SPOOLSS_FORM_STRING_TYPE_MUI_DLL", SPOOLSS_FORM_STRING_TYPE_MUI_DLL, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "SPOOLSS_FORM_STRING_TYPE_LANG_PAIR", SPOOLSS_FORM_STRING_TYPE_LANG_PAIR, r); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_spoolss_FormInfo2(struct ndr_push *ndr, int ndr_flags, const struct spoolss_FormInfo2 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_spoolss_FormFlags(ndr, NDR_SCALARS, r->flags)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->form_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_FormSize(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_push_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->keyword)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_spoolss_FormStringType(ndr, NDR_SCALARS, r->string_type)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->mui_dll)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ressource_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->display_name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->lang_id)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->form_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->form_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->form_name)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->keyword) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->keyword)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->keyword)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->mui_dll) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->mui_dll)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->mui_dll)); + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->display_name) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->display_name)); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->display_name)); + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_spoolss_FormInfo2(struct ndr_pull *ndr, int ndr_flags, struct spoolss_FormInfo2 *r) +{ + uint32_t _ptr_form_name; + TALLOC_CTX *_mem_save_form_name_0; + uint32_t _ptr_keyword; + TALLOC_CTX *_mem_save_keyword_0; + uint32_t _ptr_mui_dll; + TALLOC_CTX *_mem_save_mui_dll_0; + uint32_t _ptr_display_name; + TALLOC_CTX *_mem_save_display_name_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_spoolss_FormFlags(ndr, NDR_SCALARS, &r->flags)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_form_name)); + if (_ptr_form_name) { + NDR_PULL_ALLOC(ndr, r->form_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->form_name, _ptr_form_name)); + } else { + r->form_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_FormSize(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_spoolss_FormArea(ndr, NDR_SCALARS, &r->area)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_keyword)); + if (_ptr_keyword) { + NDR_PULL_ALLOC(ndr, r->keyword); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->keyword, _ptr_keyword)); + } else { + r->keyword = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_spoolss_FormStringType(ndr, NDR_SCALARS, &r->string_type)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_mui_dll)); + if (_ptr_mui_dll) { + NDR_PULL_ALLOC(ndr, r->mui_dll); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->mui_dll, _ptr_mui_dll)); + } else { + r->mui_dll = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ressource_id)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_display_name)); + if (_ptr_display_name) { + NDR_PULL_ALLOC(ndr, r->display_name); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->display_name, _ptr_display_name)); + } else { + r->display_name = NULL; + } + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->lang_id)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->form_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->form_name)); + _mem_save_form_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->form_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->form_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_form_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->keyword) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->keyword)); + _mem_save_keyword_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->keyword, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->keyword)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_keyword_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->mui_dll) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->mui_dll)); + _mem_save_mui_dll_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->mui_dll, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->mui_dll)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_mui_dll_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + if (r->display_name) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->display_name)); + _mem_save_display_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->display_name, 0); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->display_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_display_name_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_string; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_spoolss_FormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo2 *r) +{ + ndr_print_struct(ndr, name, "spoolss_FormInfo2"); + ndr->depth++; + ndr_print_spoolss_FormFlags(ndr, "flags", r->flags); + ndr_print_ptr(ndr, "form_name", r->form_name); + ndr->depth++; + if (r->form_name) { + ndr_print_string(ndr, "form_name", r->form_name); + } + ndr->depth--; + ndr_print_spoolss_FormSize(ndr, "size", &r->size); + ndr_print_spoolss_FormArea(ndr, "area", &r->area); + ndr_print_ptr(ndr, "keyword", r->keyword); + ndr->depth++; + if (r->keyword) { + ndr_print_string(ndr, "keyword", r->keyword); + } + ndr->depth--; + ndr_print_spoolss_FormStringType(ndr, "string_type", r->string_type); + ndr_print_ptr(ndr, "mui_dll", r->mui_dll); + ndr->depth++; + if (r->mui_dll) { + ndr_print_string(ndr, "mui_dll", r->mui_dll); + } + ndr->depth--; + ndr_print_uint32(ndr, "ressource_id", r->ressource_id); + ndr_print_ptr(ndr, "display_name", r->display_name); + ndr->depth++; + if (r->display_name) { + ndr_print_string(ndr, "display_name", r->display_name); + } + ndr->depth--; + ndr_print_uint32(ndr, "lang_id", r->lang_id); + ndr->depth--; +} + _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_FormInfo *r) { uint32_t _save_relative_base_offset = ndr_push_get_relative_base_offset(ndr); @@ -12244,6 +12513,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int n NDR_CHECK(ndr_push_spoolss_FormInfo1(ndr, NDR_SCALARS, &r->info1)); break; } + case 2: { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_push_spoolss_FormInfo2(ndr, NDR_SCALARS, &r->info2)); + break; } + default: { break; } @@ -12257,6 +12532,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int n NDR_CHECK(ndr_push_spoolss_FormInfo1(ndr, NDR_BUFFERS, &r->info1)); break; + case 2: + NDR_CHECK(ndr_push_spoolss_FormInfo2(ndr, NDR_BUFFERS, &r->info2)); + break; + default: break; @@ -12279,6 +12558,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int n NDR_CHECK(ndr_pull_spoolss_FormInfo1(ndr, NDR_SCALARS, &r->info1)); break; } + case 2: { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset)); + NDR_CHECK(ndr_pull_spoolss_FormInfo2(ndr, NDR_SCALARS, &r->info2)); + break; } + default: { break; } @@ -12291,6 +12576,10 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int n NDR_CHECK(ndr_pull_spoolss_FormInfo1(ndr, NDR_BUFFERS, &r->info1)); break; + case 2: + NDR_CHECK(ndr_pull_spoolss_FormInfo2(ndr, NDR_BUFFERS, &r->info2)); + break; + default: break; @@ -12310,6 +12599,10 @@ _PUBLIC_ void ndr_print_spoolss_FormInfo(struct ndr_print *ndr, const char *name ndr_print_spoolss_FormInfo1(ndr, "info1", &r->info1); break; + case 2: + ndr_print_spoolss_FormInfo2(ndr, "info2", &r->info2); + break; + default: break; diff --git a/librpc/gen_ndr/ndr_spoolss.h b/librpc/gen_ndr/ndr_spoolss.h index 5b32d510c08..5ecadc04d6a 100644 --- a/librpc/gen_ndr/ndr_spoolss.h +++ b/librpc/gen_ndr/ndr_spoolss.h @@ -344,6 +344,8 @@ void ndr_print_spoolss_FormFlags(struct ndr_print *ndr, const char *name, enum s void ndr_print_spoolss_FormSize(struct ndr_print *ndr, const char *name, const struct spoolss_FormSize *r); void ndr_print_spoolss_FormArea(struct ndr_print *ndr, const char *name, const struct spoolss_FormArea *r); void ndr_print_spoolss_FormInfo1(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo1 *r); +void ndr_print_spoolss_FormStringType(struct ndr_print *ndr, const char *name, uint32_t r); +void ndr_print_spoolss_FormInfo2(struct ndr_print *ndr, const char *name, const struct spoolss_FormInfo2 *r); enum ndr_err_code ndr_push_spoolss_FormInfo(struct ndr_push *ndr, int ndr_flags, const union spoolss_FormInfo *r); enum ndr_err_code ndr_pull_spoolss_FormInfo(struct ndr_pull *ndr, int ndr_flags, union spoolss_FormInfo *r); void ndr_print_spoolss_FormInfo(struct ndr_print *ndr, const char *name, const union spoolss_FormInfo *r); diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h index ad4554dbe53..ff2eb1b8c0d 100644 --- a/librpc/gen_ndr/spoolss.h +++ b/librpc/gen_ndr/spoolss.h @@ -958,8 +958,27 @@ struct spoolss_FormInfo1 { struct spoolss_FormArea area; }; +/* bitmap spoolss_FormStringType */ +#define SPOOLSS_FORM_STRING_TYPE_NONE ( 0x00000001 ) +#define SPOOLSS_FORM_STRING_TYPE_MUI_DLL ( 0x00000002 ) +#define SPOOLSS_FORM_STRING_TYPE_LANG_PAIR ( 0x00000004 ) + +struct spoolss_FormInfo2 { + enum spoolss_FormFlags flags; + const char * form_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + struct spoolss_FormSize size; + struct spoolss_FormArea area; + const char * keyword;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + uint32_t string_type; + const char * mui_dll;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + uint32_t ressource_id; + const char * display_name;/* [relative,flag(LIBNDR_FLAG_STR_NULLTERM)] */ + uint32_t lang_id; +}; + union spoolss_FormInfo { struct spoolss_FormInfo1 info1;/* [case] */ + struct spoolss_FormInfo2 info2;/* [case(2)] */ }/* [relative_base,gensize,public,nodiscriminant] */; struct spoolss_AddFormInfo1 { From 01d1aaf63e8170936139a01814211f6567c4b125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 25 Feb 2009 13:46:08 +0100 Subject: [PATCH 11/15] s3-rpcclient: allow to set level in spoolss getform query and display all levels. Guenther --- source3/rpcclient/cmd_spoolss.c | 47 ++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index eaee516ad56..51fcaaa54c6 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1978,6 +1978,28 @@ static void display_form_info1(struct spoolss_FormInfo1 *r) /**************************************************************************** ****************************************************************************/ +static void display_form_info2(struct spoolss_FormInfo2 *r) +{ + printf("%s\n" \ + "\tflag: %s (%d)\n" \ + "\twidth: %d, length: %d\n" \ + "\tleft: %d, right: %d, top: %d, bottom: %d\n", + r->form_name, get_form_flag(r->flags), r->flags, + r->size.width, r->size.height, + r->area.left, r->area.right, + r->area.top, r->area.bottom); + printf("\tkeyword: %s\n", r->keyword); + printf("\tstring_type: 0x%08x\n", r->string_type); + printf("\tmui_dll: %s\n", r->mui_dll); + printf("\tressource_id: 0x%08x\n", r->ressource_id); + printf("\tdisplay_name: %s\n", r->display_name); + printf("\tlang_id: %d\n", r->lang_id); + printf("\n"); +} + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { @@ -1989,11 +2011,12 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c uint32_t offered = 0; union spoolss_FormInfo info; uint32_t needed; + uint32_t level = 1; /* Parse the command arguments */ - if (argc != 3) { - printf ("Usage: %s \n", argv[0]); + if (argc < 3 || argc > 5) { + printf ("Usage: %s [level]\n", argv[0]); return WERR_OK; } @@ -2008,24 +2031,28 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; + if (argc == 4) { + level = atoi(argv[3]); + } + /* Get the form */ status = rpccli_spoolss_GetForm(cli, mem_ctx, &handle, argv[2], - 1, + level, NULL, offered, &info, &needed, &werror); if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { - buffer = data_blob_talloc(mem_ctx, NULL, needed); + buffer = data_blob_talloc_zero(mem_ctx, needed); offered = needed; status = rpccli_spoolss_GetForm(cli, mem_ctx, &handle, argv[2], - 1, + level, &buffer, offered, &info, @@ -2037,7 +2064,15 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c return werror; } - display_form_info1(&info.info1); + switch (level) { + case 1: + display_form_info1(&info.info1); + break; + case 2: + display_form_info2(&info.info2); + break; + } + done: if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); From e2f37ec106fb51ec894e0d6160949545e80dfe69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 14:29:31 +0100 Subject: [PATCH 12/15] tevent: add private_print function feature to tevent_req metze --- lib/tevent/tevent.h | 11 +++++++++++ lib/tevent/tevent_req.c | 27 ++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b3611228aa2..185a8fa193e 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -211,6 +211,15 @@ struct tevent_req { */ void *private_state; + /** + * @brief A function to overwrite the default print function + * + * The implementation doing the work may want to imeplement a + * custom function to print the text representation of the async + * request. + */ + char *(*private_print)(struct tevent_req *req, TALLOC_CTX *mem_ctx); + /** * @brief Internal state of the request * @@ -267,6 +276,8 @@ struct tevent_req { } internal; }; +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); + char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index c17587b16c1..e243c7de5de 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -28,14 +28,17 @@ #include "tevent_util.h" /** - * @brief Print an tevent_req structure in debug messages - * @param[in] mem_ctx The memory context for the result + * @brief The default print function for creating debug messages * @param[in] req The request to be printed + * @param[in] mem_ctx The memory context for the result * @retval Text representation of req * + * The function should not be used by users of the asynx API, + * but custom print function can use it and append custom text + * to the string. */ -char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) { return talloc_asprintf(mem_ctx, "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " @@ -50,6 +53,24 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) ); } +/** + * @brief Print an tevent_req structure in debug messages + * @param[in] mem_ctx The memory context for the result + * @param[in] req The request to be printed + * @retval Text representation of req + * + * This function should be used by callers of the async API + */ + +char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +{ + if (!req->private_print) { + return tevent_req_default_print(req, mem_ctx); + } + + return req->private_print(req, mem_ctx); +} + /** * @brief Create an async request * @param[in] mem_ctx The memory context for the result From 543db0f94aa4cdeb6499f62aee8791cda7a670d7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 15:04:55 +0100 Subject: [PATCH 13/15] s3:events: map TEVENT_DEBUG_TRACE to debug level 10 metze --- source3/lib/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/lib/events.c b/source3/lib/events.c index 44b45627577..9e81a477961 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -282,7 +282,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 5; + samba_level = 10; break; }; From 2bd8cacf0e5ed6965f5791c4a86320d4978d9b15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 15:05:24 +0100 Subject: [PATCH 14/15] s4:lib/events: map TEVENT_DEBUG_TRACE to debug level 10 metze --- source4/lib/events/tevent_s4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c index a05ac0796fc..89ca7bbe5ca 100644 --- a/source4/lib/events/tevent_s4.c +++ b/source4/lib/events/tevent_s4.c @@ -41,7 +41,7 @@ static void ev_wrap_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 5; + samba_level = 10; break; }; From b6457c78d61992f12903ed0966d9d1608de68da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 25 Feb 2009 14:27:30 +0100 Subject: [PATCH 15/15] s3-spoolss: remove unused decode_printer_info_7. Guenther --- source3/rpc_client/cli_spoolss.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index c9d23efdf26..4c1d57e063f 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -359,38 +359,6 @@ static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, return True; } -/********************************************************************** -**********************************************************************/ - -static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_7 **info) -{ - uint32 i; - PRINTER_INFO_7 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_7)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); - - for (i=0; i