From 42fa1441bf17ae486ebca5553e503242a653c92c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 18:50:37 +0100 Subject: Add struct rpc_cli_transport --- source3/include/client.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/source3/include/client.h b/source3/include/client.h index 09fdb81462..c47f058318 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -61,6 +61,56 @@ struct cli_pipe_auth_data { } a_u; }; +/** + * rpc_cli_transport defines a transport mechanism to ship rpc requests + * asynchronously to a server and receive replies + */ + +struct rpc_cli_transport { + + /** + * Trigger an async read from the server. May return a short read. + */ + struct async_req *(*read_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv); + /** + * Get the result from the read_send operation. + */ + NTSTATUS (*read_recv)(struct async_req *req, ssize_t *preceived); + + /** + * Trigger an async write to the server. May return a short write. + */ + struct async_req *(*write_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv); + /** + * Get the result from the read_send operation. + */ + NTSTATUS (*write_recv)(struct async_req *req, ssize_t *psent); + + /** + * This is an optimization for the SMB transport. It models the + * TransactNamedPipe API call: Send and receive data in one round + * trip. The transport implementation is free to set this to NULL, + * cli_pipe.c will fall back to the explicit write/read routines. + */ + struct async_req *(*trans_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len, + void *priv); + /** + * Get the result from the read_send operation. + */ + NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx, + uint8_t **prdata, uint32_t *prdata_len); + void *priv; +}; + struct rpc_pipe_client { struct rpc_pipe_client *prev, *next; -- cgit From 9b140c7c81c87c229fb7b95cf817bafb0da7fae0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 22:04:55 +0100 Subject: RPC_CLIENT_OBJ is the right variable for cli_pipe.o --- source3/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 1924ade8fb..b4d9841a4a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -761,7 +761,7 @@ SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \ $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ - rpc_client/cli_pipe.o ../librpc/rpc/binding.o $(RPC_PARSE_OBJ2) \ + $(RPC_CLIENT_OBJ) ../librpc/rpc/binding.o $(RPC_PARSE_OBJ2) \ $(RPC_CLIENT_OBJ1) \ $(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ $(SMBLDAP_OBJ) $(LDB_OBJ) $(GROUPDB_OBJ) \ $(LIBMSRPC_GEN_OBJ) @@ -844,7 +844,7 @@ LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ \ $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ) -CLIENT_OBJ1 = client/client.o client/clitar.o rpc_client/cli_pipe.o \ +CLIENT_OBJ1 = client/client.o client/clitar.o $(RPC_CLIENT_OBJ) \ ../librpc/rpc/binding.o \ client/dnsbrowse.o \ $(RPC_CLIENT_OBJ1) \ -- cgit From c5b43710543a83e25c387566691031a357f5a1da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 18:34:06 +0100 Subject: Add the named pipe rpc client transport --- source3/Makefile.in | 2 +- source3/include/proto.h | 7 +- source3/rpc_client/rpc_transport_np.c | 329 ++++++++++++++++++++++++++++++++++ 3 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 source3/rpc_client/rpc_transport_np.c diff --git a/source3/Makefile.in b/source3/Makefile.in index b4d9841a4a..7fbe22fded 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -576,7 +576,7 @@ RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) \ rpc_parse/parse_spoolss.o \ rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o -RPC_CLIENT_OBJ = rpc_client/cli_pipe.o +RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o diff --git a/source3/include/proto.h b/source3/include/proto.h index d55546f94c..1e71533156 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5216,7 +5216,6 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, unsigned int timeout); bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]); -struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p); NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, struct cli_pipe_auth_data **presult); NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, @@ -5296,6 +5295,12 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, DATA_BLOB *session_key); +/* The following definitions come from rpc_client/rpc_transport_np.c */ + +NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_cli_transport **presult); +struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p); /* The following definitions come from rpc_client/cli_reg.c */ diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c new file mode 100644 index 0000000000..e8a333e509 --- /dev/null +++ b/source3/rpc_client/rpc_transport_np.c @@ -0,0 +1,329 @@ +/* + * Unix SMB/CIFS implementation. + * RPC client transport over named pipes + * Copyright (C) Volker Lendecke 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_CLI + +struct rpc_transport_np_state { + struct cli_state *cli; + const char *pipe_name; + uint16_t fnum; +}; + +static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s) +{ + bool ret; + ret = cli_close(s->cli, s->fnum); + if (!ret) { + DEBUG(1, ("rpc_transport_np_state_destructor: cli_close " + "failed on pipe %s. Error was %s\n", s->pipe_name, + cli_errstr(s->cli))); + } + DEBUG(10, ("rpc_pipe_destructor: closed %s\n", s->pipe_name)); + /* + * We can't do much on failure + */ + return 0; +} + +struct rpc_np_write_state { + size_t size; + size_t written; +}; + +static void rpc_np_write_done(struct async_req *subreq); + +static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) +{ + struct rpc_transport_np_state *np_transport = talloc_get_type_abort( + priv, struct rpc_transport_np_state); + struct async_req *result, *subreq; + struct rpc_np_write_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_np_write_state)) { + return NULL; + } + state->size = size; + + subreq = cli_write_andx_send(mem_ctx, ev, np_transport->cli, + np_transport->fnum, + 8, /* 8 means message mode. */ + data, 0, size); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_np_write_done; + subreq->async.priv = result; + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_np_write_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_np_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_np_write_state); + NTSTATUS status; + + status = cli_write_andx_recv(subreq, &state->written); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +static NTSTATUS rpc_np_write_recv(struct async_req *req, ssize_t *pwritten) +{ + struct rpc_np_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_np_write_state); + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + *pwritten = state->written; + return NT_STATUS_OK; +} + +struct rpc_np_read_state { + uint8_t *data; + size_t size; + ssize_t received; +}; + +static void rpc_np_read_done(struct async_req *subreq); + +static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) +{ + struct rpc_transport_np_state *np_transport = talloc_get_type_abort( + priv, struct rpc_transport_np_state); + struct async_req *result, *subreq; + struct rpc_np_read_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_np_read_state)) { + return NULL; + } + state->data = data; + state->size = size; + + subreq = cli_read_andx_send(mem_ctx, ev, np_transport->cli, + np_transport->fnum, 0, size); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_np_read_done; + subreq->async.priv = result; + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_np_read_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_np_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_np_read_state); + NTSTATUS status; + uint8_t *rcvbuf; + + status = cli_read_andx_recv(subreq, &state->received, &rcvbuf); + /* + * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a + * child of that. + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { + status = NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(subreq); + async_req_error(req, status); + return; + } + + if (state->received > state->size) { + TALLOC_FREE(subreq); + async_req_error(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + memcpy(state->data, rcvbuf, state->received); + async_req_done(req); +} + +static NTSTATUS rpc_np_read_recv(struct async_req *req, ssize_t *preceived) +{ + struct rpc_np_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_np_read_state); + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + *preceived = state->received; + return NT_STATUS_OK; +} + +struct rpc_np_trans_state { + uint16_t setup[2]; + uint8_t *rdata; + uint32_t rdata_len; +}; + +static void rpc_np_trans_done(struct async_req *subreq); + +static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len, + void *priv) +{ + struct rpc_transport_np_state *np_transport = talloc_get_type_abort( + priv, struct rpc_transport_np_state); + struct async_req *result, *subreq; + struct rpc_np_trans_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_np_trans_state)) { + return NULL; + } + + SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD); + SSVAL(state->setup+1, 0, np_transport->fnum); + + subreq = cli_trans_send( + state, ev, np_transport->cli, SMBtrans, + "\\PIPE\\", 0, 0, 0, state->setup, 2, 0, + NULL, 0, 0, data, data_len, max_rdata_len); + if (subreq == NULL) { + goto fail; + } + subreq->async.fn = rpc_np_trans_done; + subreq->async.priv = result; + return result; + + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_np_trans_done(struct async_req *subreq) +{ + struct async_req *req = talloc_get_type_abort( + subreq->async.priv, struct async_req); + struct rpc_np_trans_state *state = talloc_get_type_abort( + req->private_data, struct rpc_np_trans_state); + NTSTATUS status; + + status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, + &state->rdata, &state->rdata_len); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + async_req_done(req); +} + +static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx, + uint8_t **prdata, uint32_t *prdata_len) +{ + struct rpc_np_trans_state *state = talloc_get_type_abort( + req->private_data, struct rpc_np_trans_state); + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + *prdata = talloc_move(mem_ctx, &state->rdata); + *prdata_len = state->rdata_len; + return NT_STATUS_OK; +} + +NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_cli_transport **presult) +{ + struct rpc_cli_transport *result; + struct rpc_transport_np_state *state; + int fnum; + + result = talloc(mem_ctx, struct rpc_cli_transport); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + state = talloc(result, struct rpc_transport_np_state); + if (state == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + result->priv = state; + + state->cli = cli; + state->pipe_name = cli_get_pipe_name_from_iface( + state, abstract_syntax); + + fnum = cli_nt_create(cli, state->pipe_name, DESIRED_ACCESS_PIPE); + if (fnum == -1) { + DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s " + "to machine %s. Error was %s\n", state->pipe_name, + cli->desthost, cli_errstr(cli))); + TALLOC_FREE(result); + return cli_get_nt_error(cli); + } + state->fnum = fnum; + talloc_set_destructor(state, rpc_transport_np_state_destructor); + + result->write_send = rpc_np_write_send; + result->write_recv = rpc_np_write_recv; + result->read_send = rpc_np_read_send; + result->read_recv = rpc_np_read_recv; + result->trans_send = rpc_np_trans_send; + result->trans_recv = rpc_np_trans_recv; + + *presult = result; + return NT_STATUS_OK; +} + +struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p) +{ + struct rpc_transport_np_state *state = talloc_get_type( + p->transport->priv, struct rpc_transport_np_state); + + if (state == NULL) { + return NULL; + } + return state->cli; +} -- cgit From b7bd71b34969927e39d5d24c766efeda262ee5bd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 18:39:29 +0100 Subject: Add the socket rpc client transport --- source3/Makefile.in | 3 +- source3/include/proto.h | 5 ++ source3/rpc_client/rpc_transport_sock.c | 116 ++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 source3/rpc_client/rpc_transport_sock.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 7fbe22fded..3cbefc8d85 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -576,7 +576,8 @@ RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) \ rpc_parse/parse_spoolss.o \ rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o -RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o +RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o \ + rpc_client/rpc_transport_sock.o LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o diff --git a/source3/include/proto.h b/source3/include/proto.h index 1e71533156..1554bfdb25 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5302,6 +5302,11 @@ NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli, struct rpc_cli_transport **presult); struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p); +/* The following definitions come from rpc_client/rpc_transport_sock.c */ + +NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, + struct rpc_cli_transport **presult); + /* The following definitions come from rpc_client/cli_reg.c */ NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c new file mode 100644 index 0000000000..c0fa41b0de --- /dev/null +++ b/source3/rpc_client/rpc_transport_sock.c @@ -0,0 +1,116 @@ +/* + * Unix SMB/CIFS implementation. + * RPC client transport over a socket + * Copyright (C) Volker Lendecke 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_CLI + +struct rpc_transport_sock_state { + int fd; +}; + +static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s) +{ + if (s->fd != -1) { + close(s->fd); + s->fd = -1; + } + return 0; +} + +static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) +{ + 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); +} + +static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +{ + ssize_t received; + int sys_errno; + + received = async_syscall_result_ssize_t(req, &sys_errno); + if (received == -1) { + return map_nt_error_from_unix(sys_errno); + } + if (received == 0) { + return NT_STATUS_END_OF_FILE; + } + *preceived = received; + return NT_STATUS_OK; +} + +static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) +{ + 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); +} + +static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent) +{ + ssize_t sent; + int sys_errno; + + sent = async_syscall_result_ssize_t(req, &sys_errno); + if (sent == -1) { + return map_nt_error_from_unix(sys_errno); + } + *psent = sent; + return NT_STATUS_OK; +} + +NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd, + struct rpc_cli_transport **presult) +{ + struct rpc_cli_transport *result; + struct rpc_transport_sock_state *state; + + result = talloc(mem_ctx, struct rpc_cli_transport); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + state = talloc(result, struct rpc_transport_sock_state); + if (state == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + result->priv = state; + + state->fd = fd; + talloc_set_destructor(state, rpc_transport_sock_state_destructor); + + result->trans_send = NULL; + result->trans_recv = NULL; + result->write_send = rpc_sock_write_send; + result->write_recv = rpc_sock_write_recv; + result->read_send = rpc_sock_read_send; + result->read_recv = rpc_sock_read_recv; + + *presult = result; + return NT_STATUS_OK; +} -- cgit From b7094c0b804984de8e0b50c17e7908a2685df557 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 22 Jan 2009 18:52:15 +0100 Subject: Abstract away the transport in cli_pipe.c Sorry for the monster checkin, I could not really find a way to do this in steps. --- source3/include/client.h | 13 +- source3/rpc_client/cli_pipe.c | 477 +++++++++++++++--------------------------- 2 files changed, 174 insertions(+), 316 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index c47f058318..d62d1c05d2 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -114,18 +114,7 @@ struct rpc_cli_transport { struct rpc_pipe_client { struct rpc_pipe_client *prev, *next; - enum dcerpc_transport_t transport_type; - - union { - struct { - struct cli_state *cli; - const char *pipe_name; - uint16 fnum; - } np; - struct { - int fd; - } sock; - } trans ; + struct rpc_cli_transport *transport; struct ndr_syntax_id abstract_syntax; struct ndr_syntax_id transfer_syntax; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index cf2c833c28..5a53c0d940 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -136,28 +136,13 @@ static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type) /******************************************************************** Pipe description for a DEBUG ********************************************************************/ -static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli) +static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *cli) { - char *result; - - switch (cli->transport_type) { - case NCACN_NP: - result = talloc_asprintf(mem_ctx, "host %s, pipe %s, " - "fnum 0x%x", - cli->desthost, - cli->trans.np.pipe_name, - (unsigned int)(cli->trans.np.fnum)); - break; - case NCACN_IP_TCP: - case NCACN_UNIX_STREAM: - result = talloc_asprintf(mem_ctx, "host %s, fd %d", - cli->desthost, cli->trans.sock.fd); - break; - default: - result = talloc_asprintf(mem_ctx, "host %s", cli->desthost); - break; + char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost); + if (result == NULL) { + return "pipe"; } - SMB_ASSERT(result != NULL); return result; } @@ -204,19 +189,18 @@ static bool rpc_grow_buffer(prs_struct *pdu, size_t size) struct rpc_read_state { struct event_context *ev; - struct rpc_pipe_client *cli; - char *data; + struct rpc_cli_transport *transport; + uint8_t *data; size_t size; size_t num_read; }; -static void rpc_read_np_done(struct async_req *subreq); -static void rpc_read_sock_done(struct async_req *subreq); +static void rpc_read_done(struct async_req *subreq); static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct rpc_pipe_client *cli, - char *data, size_t size) + struct rpc_cli_transport *transport, + uint8_t *data, size_t size) { struct async_req *result, *subreq; struct rpc_read_state *state; @@ -226,48 +210,28 @@ static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, return NULL; } state->ev = ev; - state->cli = cli; + state->transport = transport; state->data = data; state->size = size; state->num_read = 0; DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size)); - if (cli->transport_type == NCACN_NP) { - subreq = cli_read_andx_send( - state, ev, cli->trans.np.cli, - cli->trans.np.fnum, 0, size); - if (subreq == NULL) { - DEBUG(10, ("cli_read_andx_send failed\n")); - goto fail; - } - subreq->async.fn = rpc_read_np_done; - subreq->async.priv = result; - return result; - } - - if ((cli->transport_type == NCACN_IP_TCP) - || (cli->transport_type == NCACN_UNIX_STREAM)) { - subreq = recvall_send(state, ev, cli->trans.sock.fd, - data, size, 0); - if (subreq == NULL) { - DEBUG(10, ("recvall_send failed\n")); - goto fail; - } - subreq->async.fn = rpc_read_sock_done; - subreq->async.priv = result; - return result; + subreq = transport->read_send(state, ev, (uint8_t *)data, size, + transport->priv); + if (subreq == NULL) { + goto fail; } + subreq->async.fn = rpc_read_done; + subreq->async.priv = result; + return result; - if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) { - return result; - } fail: TALLOC_FREE(result); return NULL; } -static void rpc_read_np_done(struct async_req *subreq) +static void rpc_read_done(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); @@ -275,61 +239,31 @@ static void rpc_read_np_done(struct async_req *subreq) req->private_data, struct rpc_read_state); NTSTATUS status; ssize_t received; - uint8_t *rcvbuf; - status = cli_read_andx_recv(subreq, &received, &rcvbuf); - /* - * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a - * child of that. - */ - if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { - status = NT_STATUS_OK; - } + status = state->transport->read_recv(subreq, &received); + TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(subreq); async_req_error(req, status); return; } - memcpy(state->data + state->num_read, rcvbuf, received); - TALLOC_FREE(subreq); - state->num_read += received; - if (state->num_read == state->size) { async_req_done(req); return; } - subreq = cli_read_andx_send( - state, state->ev, state->cli->trans.np.cli, - state->cli->trans.np.fnum, 0, - state->size - state->num_read); - + subreq = state->transport->read_send(state, state->ev, + state->data + state->num_read, + state->size - state->num_read, + state->transport->priv); if (async_req_nomem(subreq, req)) { return; } - - subreq->async.fn = rpc_read_np_done; + subreq->async.fn = rpc_read_done; subreq->async.priv = req; } -static void rpc_read_sock_done(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - NTSTATUS status; - - status = recvall_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - async_req_error(req, status); - return; - } - - async_req_done(req); -} - static NTSTATUS rpc_read_recv(struct async_req *req) { return async_req_simple_recv(req); @@ -337,19 +271,18 @@ static NTSTATUS rpc_read_recv(struct async_req *req) struct rpc_write_state { struct event_context *ev; - struct rpc_pipe_client *cli; - const char *data; + struct rpc_cli_transport *transport; + const uint8_t *data; size_t size; size_t num_written; }; -static void rpc_write_np_done(struct async_req *subreq); -static void rpc_write_sock_done(struct async_req *subreq); +static void rpc_write_done(struct async_req *subreq); static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct rpc_pipe_client *cli, - const char *data, size_t size) + struct rpc_cli_transport *transport, + const uint8_t *data, size_t size) { struct async_req *result, *subreq; struct rpc_write_state *state; @@ -359,58 +292,35 @@ static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, return NULL; } state->ev = ev; - state->cli = cli; + state->transport = transport; state->data = data; state->size = size; state->num_written = 0; DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size)); - if (cli->transport_type == NCACN_NP) { - subreq = cli_write_andx_send( - state, ev, cli->trans.np.cli, - cli->trans.np.fnum, 8, /* 8 means message mode. */ - (uint8_t *)data, 0, size); - if (subreq == NULL) { - DEBUG(10, ("cli_write_andx_send failed\n")); - goto fail; - } - subreq->async.fn = rpc_write_np_done; - subreq->async.priv = result; - return result; - } - - if ((cli->transport_type == NCACN_IP_TCP) - || (cli->transport_type == NCACN_UNIX_STREAM)) { - subreq = sendall_send(state, ev, cli->trans.sock.fd, - data, size, 0); - if (subreq == NULL) { - DEBUG(10, ("sendall_send failed\n")); - goto fail; - } - subreq->async.fn = rpc_write_sock_done; - subreq->async.priv = result; - return result; - } - - if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) { - return result; + subreq = transport->write_send(state, ev, data, size, transport->priv); + if (subreq == NULL) { + goto fail; } + subreq->async.fn = rpc_write_done; + subreq->async.priv = result; + return result; fail: TALLOC_FREE(result); return NULL; } -static void rpc_write_np_done(struct async_req *subreq) +static void rpc_write_done(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); struct rpc_write_state *state = talloc_get_type_abort( req->private_data, struct rpc_write_state); NTSTATUS status; - size_t written; + ssize_t written; - status = cli_write_andx_recv(subreq, &written); + status = state->transport->write_recv(subreq, &written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { async_req_error(req, status); @@ -424,36 +334,17 @@ static void rpc_write_np_done(struct async_req *subreq) return; } - subreq = cli_write_andx_send( - state, state->ev, state->cli->trans.np.cli, - state->cli->trans.np.fnum, 8, - (uint8_t *)(state->data + state->num_written), - 0, state->size - state->num_written); - + subreq = state->transport->write_send(state, state->ev, + state->data + state->num_written, + state->size - state->num_written, + state->transport->priv); if (async_req_nomem(subreq, req)) { return; } - - subreq->async.fn = rpc_write_np_done; + subreq->async.fn = rpc_write_done; subreq->async.priv = req; } -static void rpc_write_sock_done(struct async_req *subreq) -{ - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - NTSTATUS status; - - status = sendall_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - async_req_error(req, status); - return; - } - - async_req_done(req); -} - static NTSTATUS rpc_write_recv(struct async_req *req) { return async_req_simple_recv(req); @@ -525,9 +416,11 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq = rpc_read_send(state, state->ev, state->cli, - prs_data_p(state->pdu) + pdu_len, - RPC_HEADER_LEN - pdu_len); + subreq = rpc_read_send( + state, state->ev, + state->cli->transport, + (uint8_t *)(prs_data_p(state->pdu) + pdu_len), + RPC_HEADER_LEN - pdu_len); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; goto post_status; @@ -550,8 +443,9 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq = rpc_read_send(state, state->ev, state->cli, - prs_data_p(pdu) + pdu_len, + subreq = rpc_read_send(state, state->ev, + state->cli->transport, + (uint8_t *)(prs_data_p(pdu) + pdu_len), prhdr->frag_len - pdu_len); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; @@ -602,9 +496,10 @@ static void get_complete_frag_got_header(struct async_req *subreq) * RPC_HEADER_LEN bytes into state->pdu. */ - subreq = rpc_read_send(state, state->ev, state->cli, - prs_data_p(state->pdu) + RPC_HEADER_LEN, - state->prhdr->frag_len - RPC_HEADER_LEN); + subreq = rpc_read_send( + state, state->ev, state->cli->transport, + (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN), + state->prhdr->frag_len - RPC_HEADER_LEN); if (async_req_nomem(subreq, req)) { return; } @@ -1125,19 +1020,18 @@ static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR struct cli_api_pipe_state { struct event_context *ev; - struct rpc_pipe_client *cli; - uint32_t max_rdata_len; + struct rpc_cli_transport *transport; uint8_t *rdata; uint32_t rdata_len; }; -static void cli_api_pipe_np_trans_done(struct async_req *subreq); -static void cli_api_pipe_sock_send_done(struct async_req *subreq); -static void cli_api_pipe_sock_read_done(struct async_req *subreq); +static void cli_api_pipe_trans_done(struct async_req *subreq); +static void cli_api_pipe_write_done(struct async_req *subreq); +static void cli_api_pipe_read_done(struct async_req *subreq); static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct rpc_pipe_client *cli, + struct rpc_cli_transport *transport, uint8_t *data, size_t data_len, uint32_t max_rdata_len) { @@ -1150,10 +1044,9 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, return NULL; } state->ev = ev; - state->cli = cli; - state->max_rdata_len = max_rdata_len; + state->transport = transport; - if (state->max_rdata_len < RPC_HEADER_LEN) { + if (max_rdata_len < RPC_HEADER_LEN) { /* * For a RPC reply we always need at least RPC_HEADER_LEN * bytes. We check this here because we will receive @@ -1163,37 +1056,30 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, goto post_status; } - if (cli->transport_type == NCACN_NP) { - - uint16_t setup[2]; - SSVAL(setup+0, 0, TRANSACT_DCERPCCMD); - SSVAL(setup+1, 0, cli->trans.np.fnum); - - subreq = cli_trans_send( - state, ev, cli->trans.np.cli, SMBtrans, - "\\PIPE\\", 0, 0, 0, setup, 2, 0, - NULL, 0, 0, data, data_len, max_rdata_len); + if (transport->trans_send != NULL) { + subreq = transport->trans_send(state, ev, data, data_len, + max_rdata_len, transport->priv); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = cli_api_pipe_np_trans_done; + subreq->async.fn = cli_api_pipe_trans_done; subreq->async.priv = result; return result; } - if ((cli->transport_type == NCACN_IP_TCP) - || (cli->transport_type == NCACN_UNIX_STREAM)) { - subreq = sendall_send(state, ev, cli->trans.sock.fd, - data, data_len, 0); - if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; - } - subreq->async.fn = cli_api_pipe_sock_send_done; - subreq->async.priv = result; - return result; + /* + * If the transport does not provide a "trans" routine, i.e. for + * example the ncacn_ip_tcp transport, do the write/read step here. + */ + + subreq = rpc_write_send(state, ev, transport, data, data_len); + if (subreq == NULL) { + goto fail; } + subreq->async.fn = cli_api_pipe_write_done; + subreq->async.priv = result; + return result; status = NT_STATUS_INVALID_PARAMETER; @@ -1201,11 +1087,12 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, if (async_post_status(result, ev, status)) { return result; } + fail: TALLOC_FREE(result); return NULL; } -static void cli_api_pipe_np_trans_done(struct async_req *subreq) +static void cli_api_pipe_trans_done(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); @@ -1213,8 +1100,8 @@ static void cli_api_pipe_np_trans_done(struct async_req *subreq) req->private_data, struct cli_api_pipe_state); NTSTATUS status; - status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, - &state->rdata, &state->rdata_len); + status = state->transport->trans_recv(subreq, state, &state->rdata, + &state->rdata_len); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { async_req_error(req, status); @@ -1223,7 +1110,7 @@ static void cli_api_pipe_np_trans_done(struct async_req *subreq) async_req_done(req); } -static void cli_api_pipe_sock_send_done(struct async_req *subreq) +static void cli_api_pipe_write_done(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); @@ -1231,7 +1118,7 @@ static void cli_api_pipe_sock_send_done(struct async_req *subreq) req->private_data, struct cli_api_pipe_state); NTSTATUS status; - status = sendall_recv(subreq); + status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { async_req_error(req, status); @@ -1242,29 +1129,38 @@ static void cli_api_pipe_sock_send_done(struct async_req *subreq) if (async_req_nomem(state->rdata, req)) { return; } - state->rdata_len = RPC_HEADER_LEN; - subreq = recvall_send(state, state->ev, state->cli->trans.sock.fd, - state->rdata, RPC_HEADER_LEN, 0); + /* + * We don't need to use rpc_read_send here, the upper layer will cope + * with a short read, transport->trans_send could also return less + * than state->max_rdata_len. + */ + subreq = state->transport->read_send(state, state->ev, state->rdata, + RPC_HEADER_LEN, + state->transport->priv); if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = cli_api_pipe_sock_read_done; + subreq->async.fn = cli_api_pipe_read_done; subreq->async.priv = req; } -static void cli_api_pipe_sock_read_done(struct async_req *subreq) +static void cli_api_pipe_read_done(struct async_req *subreq) { struct async_req *req = talloc_get_type_abort( subreq->async.priv, struct async_req); + struct cli_api_pipe_state *state = talloc_get_type_abort( + req->private_data, struct cli_api_pipe_state); NTSTATUS status; + ssize_t received; - status = recvall_recv(subreq); + status = state->transport->read_recv(subreq, &received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { async_req_error(req, status); return; } + state->rdata_len = received; async_req_done(req); } @@ -1376,7 +1272,8 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32); #endif - subreq = cli_api_pipe_send(state, ev, cli, (uint8_t *)prs_data_p(data), + subreq = cli_api_pipe_send(state, ev, cli->transport, + (uint8_t *)prs_data_p(data), prs_offset(data), max_recv_frag); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; @@ -2194,9 +2091,10 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, subreq->async.fn = rpc_api_pipe_req_done; subreq->async.priv = result; } else { - subreq = rpc_write_send(state, ev, cli, - prs_data_p(&state->outgoing_frag), - prs_offset(&state->outgoing_frag)); + subreq = rpc_write_send( + state, ev, cli->transport, + (uint8_t *)prs_data_p(&state->outgoing_frag), + prs_offset(&state->outgoing_frag)); if (subreq == NULL) { status = NT_STATUS_NO_MEMORY; goto post_status; @@ -2331,9 +2229,11 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq) subreq->async.fn = rpc_api_pipe_req_done; subreq->async.priv = req; } else { - subreq = rpc_write_send(state, state->ev, state->cli, - prs_data_p(&state->outgoing_frag), - prs_offset(&state->outgoing_frag)); + subreq = rpc_write_send( + state, state->ev, + state->cli->transport, + (uint8_t *)prs_data_p(&state->outgoing_frag), + prs_offset(&state->outgoing_frag)); if (async_req_nomem(subreq, req)) { return; } @@ -2817,8 +2717,8 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, return status; } - subreq = rpc_write_send(state, state->ev, state->cli, - prs_data_p(&state->rpc_out), + subreq = rpc_write_send(state, state->ev, state->cli->transport, + (uint8_t *)prs_data_p(&state->rpc_out), prs_offset(&state->rpc_out)); if (subreq == NULL) { return NT_STATUS_NO_MEMORY; @@ -3030,56 +2930,33 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return status; } -unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, +unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli, unsigned int timeout) { - return cli_set_timeout(cli->trans.np.cli, timeout); -} - -bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]) -{ - if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) - || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) { - memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16); - return true; - } - - if (cli->transport_type == NCACN_NP) { - E_md4hash(cli->trans.np.cli->pwd.password, nt_hash); - return true; - } - - return false; -} + struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli); -struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p) -{ - if (p->transport_type == NCACN_NP) { - return p->trans.np.cli; + if (cli == NULL) { + return 0; } - return NULL; + return cli_set_timeout(cli, timeout); } -static int rpc_pipe_destructor(struct rpc_pipe_client *p) +bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16]) { - if (p->transport_type == NCACN_NP) { - bool ret; - ret = cli_close(p->trans.np.cli, p->trans.np.fnum); - if (!ret) { - DEBUG(1, ("rpc_pipe_destructor: cli_close failed on " - "pipe %s. Error was %s\n", - rpccli_pipe_txt(debug_ctx(), p), - cli_errstr(p->trans.np.cli))); - } - - DEBUG(10, ("rpc_pipe_destructor: closed %s\n", - rpccli_pipe_txt(debug_ctx(), p))); + struct cli_state *cli; - DLIST_REMOVE(p->trans.np.cli->pipe_list, p); - return ret ? -1 : 0; + if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) + || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) { + memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16); + return true; } - return -1; + cli = rpc_pipe_np_smb_conn(rpc_cli); + if (cli == NULL) { + return false; + } + E_md4hash(cli->pwd.password, nt_hash); + return true; } NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, @@ -3287,12 +3164,6 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, #endif } -static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p) -{ - close(p->trans.sock.fd); - return 0; -} - /** * Create an rpc pipe client struct, connecting to a tcp port. */ @@ -3304,14 +3175,13 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, struct rpc_pipe_client *result; struct sockaddr_storage addr; NTSTATUS status; + int fd; result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client); if (result == NULL) { return NT_STATUS_NO_MEMORY; } - result->transport_type = NCACN_IP_TCP; - result->abstract_syntax = *abstract_syntax; result->transfer_syntax = ndr_transfer_syntax; result->dispatch = cli_do_rpc_ndr; @@ -3332,12 +3202,17 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, goto fail; } - status = open_socket_out(&addr, port, 60, &result->trans.sock.fd); + status = open_socket_out(&addr, port, 60, &fd); if (!NT_STATUS_IS_OK(status)) { goto fail; } + set_socket_options(fd, lp_socket_options()); - talloc_set_destructor(result, rpc_pipe_sock_destructor); + status = rpc_transport_sock_init(result, fd, &result->transport); + if (!NT_STATUS_IS_OK(status)) { + close(fd); + goto fail; + } *presult = result; return NT_STATUS_OK; @@ -3512,14 +3387,13 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, struct rpc_pipe_client *result; struct sockaddr_un addr; NTSTATUS status; + int fd; result = talloc_zero(mem_ctx, struct rpc_pipe_client); if (result == NULL) { return NT_STATUS_NO_MEMORY; } - result->transport_type = NCACN_UNIX_STREAM; - result->abstract_syntax = *abstract_syntax; result->transfer_syntax = ndr_transfer_syntax; result->dispatch = cli_do_rpc_ndr; @@ -3535,26 +3409,29 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN; - result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (result->trans.sock.fd == -1) { + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { status = map_nt_error_from_unix(errno); goto fail; } - talloc_set_destructor(result, rpc_pipe_sock_destructor); - ZERO_STRUCT(addr); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); - if (sys_connect(result->trans.sock.fd, - (struct sockaddr *)&addr) == -1) { + if (sys_connect(fd, (struct sockaddr *)&addr) == -1) { DEBUG(0, ("connect(%s) failed: %s\n", socket_path, strerror(errno))); - close(result->trans.sock.fd); + close(fd); return map_nt_error_from_unix(errno); } + status = rpc_transport_sock_init(result, fd, &result->transport); + if (!NT_STATUS_IS_OK(status)) { + close(fd); + goto fail; + } + *presult = result; return NT_STATUS_OK; @@ -3563,6 +3440,16 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, return status; } +static int rpc_pipe_client_np_destructor(struct rpc_pipe_client *p) +{ + struct cli_state *cli; + + cli = rpc_pipe_np_smb_conn(p); + if (cli != NULL) { + DLIST_REMOVE(cli->pipe_list, p); + } + return 0; +} /**************************************************************************** Open a named pipe over SMB to a remote server. @@ -3582,7 +3469,7 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; - int fnum; + NTSTATUS status; /* sanity check to protect against crashes */ @@ -3595,17 +3482,6 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, return NT_STATUS_NO_MEMORY; } - result->transport_type = NCACN_NP; - - result->trans.np.pipe_name = cli_get_pipe_name_from_iface( - result, abstract_syntax); - if (result->trans.np.pipe_name == NULL) { - DEBUG(1, ("Could not find pipe for interface\n")); - TALLOC_FREE(result); - return NT_STATUS_INVALID_PARAMETER; - } - - result->trans.np.cli = cli; result->abstract_syntax = *abstract_syntax; result->transfer_syntax = ndr_transfer_syntax; result->dispatch = cli_do_rpc_ndr; @@ -3621,21 +3497,15 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, return NT_STATUS_NO_MEMORY; } - fnum = cli_nt_create(cli, result->trans.np.pipe_name, - DESIRED_ACCESS_PIPE); - if (fnum == -1) { - DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s " - "to machine %s. Error was %s\n", - result->trans.np.pipe_name, cli->desthost, - cli_errstr(cli))); + status = rpc_transport_np_init(result, cli, abstract_syntax, + &result->transport); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(result); - return cli_get_nt_error(cli); + return status; } - result->trans.np.fnum = fnum; - DLIST_ADD(cli->pipe_list, result); - talloc_set_destructor(result, rpc_pipe_destructor); + talloc_set_destructor(result, rpc_pipe_client_np_destructor); *presult = result; return NT_STATUS_OK; @@ -3725,7 +3595,8 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, } DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine " - "%s and bound anonymously.\n", result->trans.np.pipe_name, + "%s and bound anonymously.\n", + cli_get_pipe_name_from_iface(debug_ctx(), interface), cli->desthost )); *presult = result; @@ -3772,8 +3643,8 @@ static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to " "machine %s and bound NTLMSSP as user %s\\%s.\n", - result->trans.np.pipe_name, cli->desthost, - domain, username )); + cli_get_pipe_name_from_iface(debug_ctx(), interface), + cli->desthost, domain, username )); *presult = result; return NT_STATUS_OK; @@ -3963,9 +3834,9 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, } DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " - "for domain %s " - "and bound using schannel.\n", - result->trans.np.pipe_name, cli->desthost, domain )); + "for domain %s and bound using schannel.\n", + cli_get_pipe_name_from_iface(debug_ctx(), interface), + cli->desthost, domain )); *presult = result; return NT_STATUS_OK; @@ -4190,8 +4061,6 @@ NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id return NT_STATUS_NO_MEMORY; } - result->transport_type = NCACN_INTERNAL; - result->abstract_syntax = *abstract_syntax; result->transfer_syntax = ndr_transfer_syntax; result->dispatch = dispatch; -- cgit From 81533e2d39cae11b7ea06f289a7c398ed3c51da9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 2009 14:38:57 -0800 Subject: Second part of the attemt to fix #4308 - Excel save operation corrupts file ACLs. If the chown succeeds then the ACL set should also. Ensure this is the case (refactor some of this code to make it simpler to read also). Jeremy. --- source3/smbd/posix_acls.c | 275 ++++++++++++++++++++++++---------------------- 1 file changed, 144 insertions(+), 131 deletions(-) diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 951046c562..627bfb4634 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3426,8 +3426,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC bool acl_perms = False; mode_t orig_mode = (mode_t)0; NTSTATUS status; - uid_t orig_uid; - gid_t orig_gid; + bool set_acl_as_root = false; + bool acl_set_support = false; + bool ret = false; DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); @@ -3448,10 +3449,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC return map_nt_error_from_unix(errno); } - /* Save the original elements we check against. */ + /* Save the original element we check against. */ orig_mode = sbuf.st_mode; - orig_uid = sbuf.st_uid; - orig_gid = sbuf.st_gid; /* * Unpack the user/group/world id's. @@ -3468,7 +3467,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC * Noticed by Simo. */ - if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) { + if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -3493,174 +3492,188 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC } } else { - int ret; + int sret; if(fsp->fh->fd == -1) - ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); + sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); else - ret = SMB_VFS_FSTAT(fsp, &sbuf); + sret = SMB_VFS_FSTAT(fsp, &sbuf); - if(ret != 0) + if(sret != 0) return map_nt_error_from_unix(errno); } - /* Save the original elements we check against. */ + /* Save the original element we check against. */ orig_mode = sbuf.st_mode; - orig_uid = sbuf.st_uid; - orig_gid = sbuf.st_gid; + + /* If we successfully chowned, we know we must + * be able to set the acl, so do it as root. + */ + set_acl_as_root = true; } create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); -#if 0 - /* Disable this - prevents ACL inheritance from the ACL editor. JRA. */ - - /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx - * for details and also the log trace in bug #4308. JRA. - */ - - if ((security_info_sent & DACL_SECURITY_INFORMATION) && - psd->dacl != NULL && - (psd->type & (SE_DESC_DACL_AUTO_INHERITED| - SE_DESC_DACL_AUTO_INHERIT_REQ))== - (SE_DESC_DACL_AUTO_INHERITED| - SE_DESC_DACL_AUTO_INHERIT_REQ) ) { - SEC_DESC *new_sd = NULL; - status = append_parent_acl(fsp, psd, &new_sd); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - psd = new_sd; - } -#endif - acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid, &file_ace_list, &dir_ace_list, security_info_sent, psd); /* Ignore W2K traverse DACL set. */ - if (file_ace_list || dir_ace_list) { + if (!file_ace_list && !dir_ace_list) { + return NT_STATUS_OK; + } - if (!acl_perms) { - DEBUG(3,("set_nt_acl: cannot set permissions\n")); - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); - return NT_STATUS_ACCESS_DENIED; - } + if (!acl_perms) { + DEBUG(3,("set_nt_acl: cannot set permissions\n")); + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return NT_STATUS_ACCESS_DENIED; + } - /* - * Only change security if we got a DACL. - */ + /* + * Only change security if we got a DACL. + */ - if((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl != NULL)) { + if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) { + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return NT_STATUS_OK; + } - bool acl_set_support = False; - bool ret = False; + /* + * Try using the POSIX ACL set first. Fall back to chmod if + * we have no ACL support on this filesystem. + */ + + if (acl_perms && file_ace_list) { + if (set_acl_as_root) { + become_root(); + } + ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support); + if (set_acl_as_root) { + unbecome_root(); + } + if (acl_set_support && ret == false) { + DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) )); + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return map_nt_error_from_unix(errno); + } + } + + if (acl_perms && acl_set_support && fsp->is_directory) { + if (dir_ace_list) { + if (set_acl_as_root) { + become_root(); + } + ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support); + if (set_acl_as_root) { + unbecome_root(); + } + if (ret == false) { + DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return map_nt_error_from_unix(errno); + } + } else { + int sret = -1; /* - * Try using the POSIX ACL set first. Fall back to chmod if - * we have no ACL support on this filesystem. + * No default ACL - delete one if it exists. */ - if (acl_perms && file_ace_list) { - ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support); - if (acl_set_support && ret == False) { - DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) )); + if (set_acl_as_root) { + become_root(); + } + sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name); + if (set_acl_as_root) { + unbecome_root(); + } + if (sret == -1) { + if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { + DEBUG(5,("set_nt_acl: acl group control on and " + "current user in file %s primary group. Override delete_def_acl\n", + fsp->fsp_name )); + + become_root(); + sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name); + unbecome_root(); + } + + if (sret == -1) { + DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); + free_canon_ace_list(dir_ace_list); return map_nt_error_from_unix(errno); } } + } + } - if (acl_perms && acl_set_support && fsp->is_directory) { - if (dir_ace_list) { - if (!set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support)) { - DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); - return map_nt_error_from_unix(errno); - } - } else { + if (acl_set_support) { + if (set_acl_as_root) { + become_root(); + } + store_inheritance_attributes(fsp, file_ace_list, dir_ace_list, + (psd->type & SE_DESC_DACL_PROTECTED) ? True : False); + if (set_acl_as_root) { + unbecome_root(); + } + } - /* - * No default ACL - delete one if it exists. - */ + /* + * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod. + */ - if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) { - int sret = -1; - - if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { - DEBUG(5,("set_nt_acl: acl group control on and " - "current user in file %s primary group. Override delete_def_acl\n", - fsp->fsp_name )); - - become_root(); - sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name); - unbecome_root(); - } - - if (sret == -1) { - DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); - return map_nt_error_from_unix(errno); - } - } - } - } + if(!acl_set_support && acl_perms) { + mode_t posix_perms; - if (acl_set_support) { - store_inheritance_attributes(fsp, file_ace_list, dir_ace_list, - (psd->type & SE_DESC_DACL_PROTECTED) ? True : False); - } + if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) { + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n", + fsp->fsp_name )); + return NT_STATUS_ACCESS_DENIED; + } - /* - * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod. - */ + if (orig_mode != posix_perms) { + int sret = -1; - if(!acl_set_support && acl_perms) { - mode_t posix_perms; + DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", + fsp->fsp_name, (unsigned int)posix_perms )); - if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) { - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); - DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n", + if (set_acl_as_root) { + become_root(); + } + sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms); + if (set_acl_as_root) { + unbecome_root(); + } + if(sret == -1) { + if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { + DEBUG(5,("set_nt_acl: acl group control on and " + "current user in file %s primary group. Override chmod\n", fsp->fsp_name )); - return NT_STATUS_ACCESS_DENIED; + + become_root(); + sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms); + unbecome_root(); } - if (orig_mode != posix_perms) { - - DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", - fsp->fsp_name, (unsigned int)posix_perms )); - - if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) { - int sret = -1; - if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { - DEBUG(5,("set_nt_acl: acl group control on and " - "current user in file %s primary group. Override chmod\n", - fsp->fsp_name )); - - become_root(); - sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms); - unbecome_root(); - } - - if (sret == -1) { - DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) )); - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); - return map_nt_error_from_unix(errno); - } - } + if (sret == -1) { + DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n", + fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) )); + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return map_nt_error_from_unix(errno); } } } - - free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); } + free_canon_ace_list(file_ace_list); + free_canon_ace_list(dir_ace_list); + return NT_STATUS_OK; } -- cgit From 634cc6b64ad7e840a26400b0ee9c075176d2db3a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 2009 15:57:41 -0800 Subject: Fix logic error in try_chown - we shouldn't arbitrarily chown to ourselves unless that was passed in. Jeremy. --- source3/modules/vfs_aixacl2.c | 2 -- source3/smbd/posix_acls.c | 15 +++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index a078b9f9f6..5ebc3a12f8 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -25,8 +25,6 @@ #define AIXACL2_MODULE_NAME "aixacl2" -extern int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid); - extern SMB_ACL_T aixacl_to_smbacl( struct acl *file_acl); extern struct acl *aixacl_smb_to_aixacl(SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 627bfb4634..72f5c94bc5 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3187,6 +3187,15 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } + /* only allow chown to the current user. This is more secure, + and also copes with the case where the SID in a take ownership ACL is + a local SID on the users workstation + */ + if (uid != current_user.ut.uid) { + errno = EPERM; + return -1; + } + if (SMB_VFS_STAT(conn,fname,&st)) { return -1; } @@ -3195,12 +3204,6 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } - /* only allow chown to the current user. This is more secure, - and also copes with the case where the SID in a take ownership ACL is - a local SID on the users workstation - */ - uid = current_user.ut.uid; - become_root(); /* Keep the current file gid the same. */ ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1); -- cgit From b30b1cfcaf81bfe091893f51ce6a33fdf9a6dbc6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 2009 16:21:02 -0800 Subject: Apply same logic fix for #4308 Excel save operation corrupts file ACLs to NFSv4 ACL code as this uses the same flawed logic as posix_acls.c. Jeremy. --- source3/modules/nfs4_acls.c | 84 ++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index f411176590..556dad6b5e 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -698,9 +698,10 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, bool result; SMB_STRUCT_STAT sbuf; - bool need_chown = False; + bool set_acl_as_root = false; uid_t newUID = (uid_t)-1; gid_t newGID = (gid_t)-1; + int saved_errno; DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name)); @@ -728,59 +729,48 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, } if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) || ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) { - need_chown = True; - } - if (need_chown) { - if ((newUID == (uid_t)-1 - || newUID == fsp->conn->server_info->utok.uid)) { - if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { - DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, - strerror(errno))); - return map_nt_error_from_unix(errno); - } - - DEBUG(10,("chown %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf)) - return map_nt_error_from_unix(errno); - need_chown = False; - } else { /* chown is needed, but _after_ changing acl */ - sbuf.st_uid = newUID; /* OWNER@ in case of e_special */ - sbuf.st_gid = newGID; /* GROUP@ in case of e_special */ + if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { + DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", + fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, + strerror(errno))); + return map_nt_error_from_unix(errno); } + + DEBUG(10,("chown %s, %u, %u succeeded.\n", + fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); + if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf)) + return map_nt_error_from_unix(errno); + + /* If we successfully chowned, we know we must + * be able to set the acl, so do it as root. + */ + set_acl_as_root = true; } } - if ((security_info_sent & DACL_SECURITY_INFORMATION)!=0 && psd->dacl!=NULL) - { - acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, sbuf.st_uid, sbuf.st_gid); - if (!acl) - return map_nt_error_from_unix(errno); + if (!(security_info_sent & DACL_SECURITY_INFORMATION) || psd->dacl ==NULL) { + DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent)); + return NT_STATUS_OK; + } - smbacl4_dump_nfs4acl(10, acl); + acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, ¶ms, sbuf.st_uid, sbuf.st_gid); + if (!acl) + return map_nt_error_from_unix(errno); - result = set_nfs4_native(fsp, acl); - if (result!=True) - { - DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno))); - return map_nt_error_from_unix(errno); - } - } else - DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent)); + smbacl4_dump_nfs4acl(10, acl); - /* Any chown pending? */ - if (need_chown) { - DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { - DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, - strerror(errno))); - return map_nt_error_from_unix(errno); - } - DEBUG(10,("chown#2 %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); + if (set_acl_as_root) { + become_root(); + } + result = set_nfs4_native(fsp, acl); + saved_errno = errno; + if (set_acl_as_root) { + unbecome_root(); + } + if (result!=True) { + errno = saved_errno; + DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno))); + return map_nt_error_from_unix(errno); } DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n")); -- cgit From 232560627f97931a62014246e4e3731d6981844e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Jan 2009 11:24:25 +0100 Subject: s4: we're on the way to alhpa7 metze --- source4/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/VERSION b/source4/VERSION index 272086492c..e7d05f6a09 100644 --- a/source4/VERSION +++ b/source4/VERSION @@ -57,7 +57,7 @@ SAMBA_VERSION_TP_RELEASE= # e.g. SAMBA_VERSION_ALPHA_RELEASE=1 # # -> "4.0.0alpha1" # ######################################################## -SAMBA_VERSION_ALPHA_RELEASE=6 +SAMBA_VERSION_ALPHA_RELEASE=7 ######################################################## # For 'pre' releases the version will be # -- cgit From aa2fb0efb7ce2bc732569b4baf20c57375fdce59 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 23 Jan 2009 13:02:46 +0100 Subject: docs: Fix formatting issue in man libsmbclient. Karolin --- docs-xml/manpages-3/libsmbclient.7.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs-xml/manpages-3/libsmbclient.7.xml b/docs-xml/manpages-3/libsmbclient.7.xml index ec9500420b..9257e1c7ba 100644 --- a/docs-xml/manpages-3/libsmbclient.7.xml +++ b/docs-xml/manpages-3/libsmbclient.7.xml @@ -18,10 +18,11 @@ - Browser URL: - smb://[[[domain:]user[:password@]]server[/share[/path[/file]]]] [?options] - + Browser URL: + smb://[[[domain:]user[:password@]]server[/share[/path[/file]]]] [?options] + + -- cgit From 85b36d95fbede3e65cad3bd98d29689de6e13b2e Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 23 Jan 2009 11:54:30 +0100 Subject: async_req: Move to top level dir --- lib/async_req/async_req.c | 340 ++++++++++++++++++++++++++++++++++++++++++++ lib/async_req/async_req.h | 160 +++++++++++++++++++++ source3/Makefile.in | 2 +- source3/configure.in | 1 + source3/include/async_req.h | 160 --------------------- source3/lib/async_req.c | 340 -------------------------------------------- 6 files changed, 502 insertions(+), 501 deletions(-) create mode 100644 lib/async_req/async_req.c create mode 100644 lib/async_req/async_req.h delete mode 100644 source3/include/async_req.h delete mode 100644 source3/lib/async_req.c diff --git a/lib/async_req/async_req.c b/lib/async_req/async_req.c new file mode 100644 index 0000000000..011948a158 --- /dev/null +++ b/lib/async_req/async_req.c @@ -0,0 +1,340 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +/** + * @brief Print an async_req structure + * @param[in] mem_ctx The memory context for the result + * @param[in] req The request to be printed + * @retval Text representation of req + * + * This is a default print function for async requests. Implementations should + * override this with more specific information. + * + * This function should not be used by async API users, this is non-static + * only to allow implementations to easily provide default information in + * their specific functions. + */ + +char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req) +{ + return talloc_asprintf(mem_ctx, "async_req: state=%d, status=%s, " + "priv=%s", req->state, nt_errstr(req->status), + talloc_get_name(req->private_data)); +} + +/** + * @brief Create an async request + * @param[in] mem_ctx The memory context for the result + * @param[in] ev The event context this async request will be driven by + * @retval A new async request + * + * The new async request will be initialized in state ASYNC_REQ_IN_PROGRESS + */ + +struct async_req *async_req_new(TALLOC_CTX *mem_ctx) +{ + struct async_req *result; + + result = TALLOC_ZERO_P(mem_ctx, struct async_req); + if (result == NULL) { + return NULL; + } + result->state = ASYNC_REQ_IN_PROGRESS; + result->print = async_req_print; + return result; +} + +/** + * @brief An async request has successfully finished + * @param[in] req The finished request + * + * async_req_done is to be used by implementors of async requests. When a + * request is successfully finished, this function calls the user's completion + * function. + */ + +void async_req_done(struct async_req *req) +{ + req->status = NT_STATUS_OK; + req->state = ASYNC_REQ_DONE; + if (req->async.fn != NULL) { + req->async.fn(req); + } +} + +/** + * @brief An async request has seen an error + * @param[in] req The request with an error + * @param[in] status The error code + * + * async_req_done is to be used by implementors of async requests. When a + * request can not successfully completed, the implementation should call this + * function with the appropriate status code. + */ + +void async_req_error(struct async_req *req, NTSTATUS status) +{ + req->status = status; + req->state = ASYNC_REQ_ERROR; + if (req->async.fn != NULL) { + req->async.fn(req); + } +} + +/** + * @brief Timed event callback + * @param[in] ev Event context + * @param[in] te The timed event + * @param[in] now zero time + * @param[in] priv The async request to be finished + */ + +static void async_trigger(struct event_context *ev, struct timed_event *te, + struct timeval now, void *priv) +{ + struct async_req *req = talloc_get_type_abort(priv, struct async_req); + + TALLOC_FREE(te); + if (NT_STATUS_IS_OK(req->status)) { + async_req_done(req); + } + else { + async_req_error(req, req->status); + } +} + +/** + * @brief Finish a request before it started processing + * @param[in] req The finished request + * @param[in] status The success code + * + * An implementation of an async request might find that it can either finish + * the request without waiting for an external event, or it can't even start + * the engine. To present the illusion of a callback to the user of the API, + * the implementation can call this helper function which triggers an + * immediate timed event. This way the caller can use the same calling + * conventions, independent of whether the request was actually deferred. + */ + +bool async_post_status(struct async_req *req, struct event_context *ev, + NTSTATUS status) +{ + req->status = status; + + if (event_add_timed(ev, req, timeval_zero(), + async_trigger, req) == NULL) { + return false; + } + return true; +} + +/** + * @brief Helper function for nomem check + * @param[in] p The pointer to be checked + * @param[in] req The request being processed + * + * Convenience helper to easily check alloc failure within a callback + * implementing the next step of an async request. + * + * Call pattern would be + * \code + * p = talloc(mem_ctx, bla); + * if (async_req_nomem(p, req)) { + * return; + * } + * \endcode + */ + +bool async_req_nomem(const void *p, struct async_req *req) +{ + if (p != NULL) { + return false; + } + async_req_error(req, NT_STATUS_NO_MEMORY); + return true; +} + +bool async_req_is_error(struct async_req *req, NTSTATUS *status) +{ + if (req->state < ASYNC_REQ_DONE) { + *status = NT_STATUS_INTERNAL_ERROR; + return true; + } + if (req->state == ASYNC_REQ_ERROR) { + *status = req->status; + return true; + } + return false; +} + +NTSTATUS async_req_simple_recv(struct async_req *req) +{ + NTSTATUS status; + + if (async_req_is_error(req, &status)) { + return status; + } + return NT_STATUS_OK; +} + +static void async_req_timedout(struct event_context *ev, + struct timed_event *te, + struct timeval now, + void *priv) +{ + struct async_req *req = talloc_get_type_abort( + priv, struct async_req); + TALLOC_FREE(te); + async_req_error(req, NT_STATUS_IO_TIMEOUT); +} + +bool async_req_set_timeout(struct async_req *req, struct event_context *ev, + struct timeval to) +{ + return (event_add_timed(ev, req, + timeval_current_ofs(to.tv_sec, to.tv_usec), + async_req_timedout, req) + != NULL); +} + +struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct timeval to) +{ + struct async_req *result; + + result = async_req_new(mem_ctx); + if (result == NULL) { + return result; + } + if (!async_req_set_timeout(result, ev, to)) { + TALLOC_FREE(result); + return NULL; + } + return result; +} + +NTSTATUS async_wait_recv(struct async_req *req) +{ + return NT_STATUS_OK; +} + +struct async_queue_entry { + struct async_queue_entry *prev, *next; + struct async_req_queue *queue; + struct async_req *req; + void (*trigger)(struct async_req *req); +}; + +struct async_req_queue { + struct async_queue_entry *queue; +}; + +struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx) +{ + return TALLOC_ZERO_P(mem_ctx, struct async_req_queue); +} + +static int async_queue_entry_destructor(struct async_queue_entry *e) +{ + struct async_req_queue *queue = e->queue; + + DLIST_REMOVE(queue->queue, e); + + if (queue->queue != NULL) { + queue->queue->trigger(queue->queue->req); + } + + return 0; +} + +static void async_req_immediate_trigger(struct event_context *ev, + struct timed_event *te, + struct timeval now, + void *priv) +{ + struct async_queue_entry *e = talloc_get_type_abort( + priv, struct async_queue_entry); + + TALLOC_FREE(te); + e->trigger(e->req); +} + +bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev, + struct async_req *req, + void (*trigger)(struct async_req *req)) +{ + struct async_queue_entry *e; + bool busy; + + busy = (queue->queue != NULL); + + e = talloc(req, struct async_queue_entry); + if (e == NULL) { + return false; + } + + e->req = req; + e->trigger = trigger; + e->queue = queue; + + DLIST_ADD_END(queue->queue, e, struct async_queue_entry *); + talloc_set_destructor(e, async_queue_entry_destructor); + + if (!busy) { + struct timed_event *te; + + te = event_add_timed(ev, e, timeval_zero(), + async_req_immediate_trigger, + e); + if (te == NULL) { + TALLOC_FREE(e); + return false; + } + } + + return true; +} + +bool _async_req_setup(TALLOC_CTX *mem_ctx, struct async_req **preq, + void *pstate, size_t state_size, const char *typename) +{ + struct async_req *req; + void **ppstate = (void **)pstate; + void *state; + + req = async_req_new(mem_ctx); + if (req == NULL) { + return false; + } + state = talloc_size(req, state_size); + if (state == NULL) { + TALLOC_FREE(req); + return false; + } + talloc_set_name(state, typename); + req->private_data = state; + + *preq = req; + *ppstate = state; + + return true; +} diff --git a/lib/async_req/async_req.h b/lib/async_req/async_req.h new file mode 100644 index 0000000000..3907a08f67 --- /dev/null +++ b/lib/async_req/async_req.h @@ -0,0 +1,160 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __ASYNC_REQ_H__ +#define __ASYNC_REQ_H__ + +#include "includes.h" + +/** + * An async request moves between the following 4 states: + */ + +enum async_req_state { + /** + * we are creating the request + */ + ASYNC_REQ_INIT, + /** + * we are waiting the request to complete + */ + ASYNC_REQ_IN_PROGRESS, + /** + * the request is finished + */ + ASYNC_REQ_DONE, + /** + * an error has occured + */ + ASYNC_REQ_ERROR +}; + +/** + * @brief An async request + * + * This represents an async request being processed by callbacks via an event + * context. A user can issue for example a write request to a socket, giving + * an implementation function the fd, the buffer and the number of bytes to + * transfer. The function issuing the request will immediately return without + * blocking most likely without having sent anything. The API user then fills + * in req->async.fn and req->async.priv, functions that are called when the + * request is finished. + * + * It is up to the user of the async request to talloc_free it after it has + * finished. This can happen while the completion function is called. + */ + +struct async_req { + /** + * @brief The external state - will be queried by the caller + * + * While the async request is being processed, state will remain in + * ASYNC_REQ_IN_PROGRESS. A request is finished if + * req->state>=ASYNC_REQ_DONE. + */ + enum async_req_state state; + + /** + * @brief Private pointer for the actual implementation + * + * The implementation doing the work for the async request needs a + * current state like for example a fd event. The user of an async + * request should not touch this. + */ + void *private_data; + + /** + * @brief Print yourself, for debugging purposes + * + * Async requests are opaque data structures. The implementation of an + * async request can define a custom function to print more debug + * info. + */ + char *(*print)(TALLOC_CTX *mem_ctx, struct async_req *); + + /** + * @brief status code when finished + * + * This status can be queried in the async completion function. It + * will be set to NT_STATUS_OK when everything went fine. + **/ + NTSTATUS status; + + /** + * @brief What to do on completion + * + * This is used for the user of an async request, fn is called when + * the request completes, either successfully or with an error. + */ + struct { + /** + * @brief Completion function + * Completion function, to be filled by the API user + */ + void (*fn)(struct async_req *); + /** + * @brief Private data for the completion function + */ + void *priv; + } async; +}; + +struct async_req *async_req_new(TALLOC_CTX *mem_ctx); + +char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req); + +void async_req_done(struct async_req *req); + +void async_req_error(struct async_req *req, NTSTATUS status); + +bool async_post_status(struct async_req *req, struct event_context *ev, + NTSTATUS status); + +bool async_req_nomem(const void *p, struct async_req *req); + +bool async_req_is_error(struct async_req *req, NTSTATUS *status); + +NTSTATUS async_req_simple_recv(struct async_req *req); + +bool async_req_set_timeout(struct async_req *req, struct event_context *ev, + struct timeval to); + +struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct timeval to); + +NTSTATUS async_wait_recv(struct async_req *req); + +struct async_req_queue; + +struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx); + +bool async_req_enqueue(struct async_req_queue *queue, + struct event_context *ev, + struct async_req *req, + void (*trigger)(struct async_req *req)); + +bool _async_req_setup(TALLOC_CTX *mem_ctx, struct async_req **preq, + void *pstate, size_t state_size, const char *typename); + +#define async_req_setup(_mem_ctx, _preq, _pstate, type) \ + _async_req_setup((_mem_ctx), (_preq), (_pstate), sizeof(type), #type) + + +#endif diff --git a/source3/Makefile.in b/source3/Makefile.in index 3cbefc8d85..cbbf821b22 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -340,7 +340,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/messages.o librpc/gen_ndr/ndr_messaging.o lib/messages_local.o \ lib/messages_ctdbd.o lib/packet.o lib/ctdbd_conn.o \ lib/interfaces.o lib/memcache.o \ - lib/util_transfer_file.o lib/async_req.o \ + lib/util_transfer_file.o ../lib/async_req/async_req.o \ lib/async_sock.o \ $(TDB_LIB_OBJ) \ $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \ diff --git a/source3/configure.in b/source3/configure.in index 44a932c6f5..88843a49c4 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -63,6 +63,7 @@ SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TEVENT_CFLAGS}" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TDB_CFLAGS}" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/libaddns" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/librpc" +SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/async_req" SAMBA_CONFIGURE_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/../lib/popt" diff --git a/source3/include/async_req.h b/source3/include/async_req.h deleted file mode 100644 index 3907a08f67..0000000000 --- a/source3/include/async_req.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async requests - Copyright (C) Volker Lendecke 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef __ASYNC_REQ_H__ -#define __ASYNC_REQ_H__ - -#include "includes.h" - -/** - * An async request moves between the following 4 states: - */ - -enum async_req_state { - /** - * we are creating the request - */ - ASYNC_REQ_INIT, - /** - * we are waiting the request to complete - */ - ASYNC_REQ_IN_PROGRESS, - /** - * the request is finished - */ - ASYNC_REQ_DONE, - /** - * an error has occured - */ - ASYNC_REQ_ERROR -}; - -/** - * @brief An async request - * - * This represents an async request being processed by callbacks via an event - * context. A user can issue for example a write request to a socket, giving - * an implementation function the fd, the buffer and the number of bytes to - * transfer. The function issuing the request will immediately return without - * blocking most likely without having sent anything. The API user then fills - * in req->async.fn and req->async.priv, functions that are called when the - * request is finished. - * - * It is up to the user of the async request to talloc_free it after it has - * finished. This can happen while the completion function is called. - */ - -struct async_req { - /** - * @brief The external state - will be queried by the caller - * - * While the async request is being processed, state will remain in - * ASYNC_REQ_IN_PROGRESS. A request is finished if - * req->state>=ASYNC_REQ_DONE. - */ - enum async_req_state state; - - /** - * @brief Private pointer for the actual implementation - * - * The implementation doing the work for the async request needs a - * current state like for example a fd event. The user of an async - * request should not touch this. - */ - void *private_data; - - /** - * @brief Print yourself, for debugging purposes - * - * Async requests are opaque data structures. The implementation of an - * async request can define a custom function to print more debug - * info. - */ - char *(*print)(TALLOC_CTX *mem_ctx, struct async_req *); - - /** - * @brief status code when finished - * - * This status can be queried in the async completion function. It - * will be set to NT_STATUS_OK when everything went fine. - **/ - NTSTATUS status; - - /** - * @brief What to do on completion - * - * This is used for the user of an async request, fn is called when - * the request completes, either successfully or with an error. - */ - struct { - /** - * @brief Completion function - * Completion function, to be filled by the API user - */ - void (*fn)(struct async_req *); - /** - * @brief Private data for the completion function - */ - void *priv; - } async; -}; - -struct async_req *async_req_new(TALLOC_CTX *mem_ctx); - -char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req); - -void async_req_done(struct async_req *req); - -void async_req_error(struct async_req *req, NTSTATUS status); - -bool async_post_status(struct async_req *req, struct event_context *ev, - NTSTATUS status); - -bool async_req_nomem(const void *p, struct async_req *req); - -bool async_req_is_error(struct async_req *req, NTSTATUS *status); - -NTSTATUS async_req_simple_recv(struct async_req *req); - -bool async_req_set_timeout(struct async_req *req, struct event_context *ev, - struct timeval to); - -struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct timeval to); - -NTSTATUS async_wait_recv(struct async_req *req); - -struct async_req_queue; - -struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx); - -bool async_req_enqueue(struct async_req_queue *queue, - struct event_context *ev, - struct async_req *req, - void (*trigger)(struct async_req *req)); - -bool _async_req_setup(TALLOC_CTX *mem_ctx, struct async_req **preq, - void *pstate, size_t state_size, const char *typename); - -#define async_req_setup(_mem_ctx, _preq, _pstate, type) \ - _async_req_setup((_mem_ctx), (_preq), (_pstate), sizeof(type), #type) - - -#endif diff --git a/source3/lib/async_req.c b/source3/lib/async_req.c deleted file mode 100644 index 011948a158..0000000000 --- a/source3/lib/async_req.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async requests - Copyright (C) Volker Lendecke 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/** - * @brief Print an async_req structure - * @param[in] mem_ctx The memory context for the result - * @param[in] req The request to be printed - * @retval Text representation of req - * - * This is a default print function for async requests. Implementations should - * override this with more specific information. - * - * This function should not be used by async API users, this is non-static - * only to allow implementations to easily provide default information in - * their specific functions. - */ - -char *async_req_print(TALLOC_CTX *mem_ctx, struct async_req *req) -{ - return talloc_asprintf(mem_ctx, "async_req: state=%d, status=%s, " - "priv=%s", req->state, nt_errstr(req->status), - talloc_get_name(req->private_data)); -} - -/** - * @brief Create an async request - * @param[in] mem_ctx The memory context for the result - * @param[in] ev The event context this async request will be driven by - * @retval A new async request - * - * The new async request will be initialized in state ASYNC_REQ_IN_PROGRESS - */ - -struct async_req *async_req_new(TALLOC_CTX *mem_ctx) -{ - struct async_req *result; - - result = TALLOC_ZERO_P(mem_ctx, struct async_req); - if (result == NULL) { - return NULL; - } - result->state = ASYNC_REQ_IN_PROGRESS; - result->print = async_req_print; - return result; -} - -/** - * @brief An async request has successfully finished - * @param[in] req The finished request - * - * async_req_done is to be used by implementors of async requests. When a - * request is successfully finished, this function calls the user's completion - * function. - */ - -void async_req_done(struct async_req *req) -{ - req->status = NT_STATUS_OK; - req->state = ASYNC_REQ_DONE; - if (req->async.fn != NULL) { - req->async.fn(req); - } -} - -/** - * @brief An async request has seen an error - * @param[in] req The request with an error - * @param[in] status The error code - * - * async_req_done is to be used by implementors of async requests. When a - * request can not successfully completed, the implementation should call this - * function with the appropriate status code. - */ - -void async_req_error(struct async_req *req, NTSTATUS status) -{ - req->status = status; - req->state = ASYNC_REQ_ERROR; - if (req->async.fn != NULL) { - req->async.fn(req); - } -} - -/** - * @brief Timed event callback - * @param[in] ev Event context - * @param[in] te The timed event - * @param[in] now zero time - * @param[in] priv The async request to be finished - */ - -static void async_trigger(struct event_context *ev, struct timed_event *te, - struct timeval now, void *priv) -{ - struct async_req *req = talloc_get_type_abort(priv, struct async_req); - - TALLOC_FREE(te); - if (NT_STATUS_IS_OK(req->status)) { - async_req_done(req); - } - else { - async_req_error(req, req->status); - } -} - -/** - * @brief Finish a request before it started processing - * @param[in] req The finished request - * @param[in] status The success code - * - * An implementation of an async request might find that it can either finish - * the request without waiting for an external event, or it can't even start - * the engine. To present the illusion of a callback to the user of the API, - * the implementation can call this helper function which triggers an - * immediate timed event. This way the caller can use the same calling - * conventions, independent of whether the request was actually deferred. - */ - -bool async_post_status(struct async_req *req, struct event_context *ev, - NTSTATUS status) -{ - req->status = status; - - if (event_add_timed(ev, req, timeval_zero(), - async_trigger, req) == NULL) { - return false; - } - return true; -} - -/** - * @brief Helper function for nomem check - * @param[in] p The pointer to be checked - * @param[in] req The request being processed - * - * Convenience helper to easily check alloc failure within a callback - * implementing the next step of an async request. - * - * Call pattern would be - * \code - * p = talloc(mem_ctx, bla); - * if (async_req_nomem(p, req)) { - * return; - * } - * \endcode - */ - -bool async_req_nomem(const void *p, struct async_req *req) -{ - if (p != NULL) { - return false; - } - async_req_error(req, NT_STATUS_NO_MEMORY); - return true; -} - -bool async_req_is_error(struct async_req *req, NTSTATUS *status) -{ - if (req->state < ASYNC_REQ_DONE) { - *status = NT_STATUS_INTERNAL_ERROR; - return true; - } - if (req->state == ASYNC_REQ_ERROR) { - *status = req->status; - return true; - } - return false; -} - -NTSTATUS async_req_simple_recv(struct async_req *req) -{ - NTSTATUS status; - - if (async_req_is_error(req, &status)) { - return status; - } - return NT_STATUS_OK; -} - -static void async_req_timedout(struct event_context *ev, - struct timed_event *te, - struct timeval now, - void *priv) -{ - struct async_req *req = talloc_get_type_abort( - priv, struct async_req); - TALLOC_FREE(te); - async_req_error(req, NT_STATUS_IO_TIMEOUT); -} - -bool async_req_set_timeout(struct async_req *req, struct event_context *ev, - struct timeval to) -{ - return (event_add_timed(ev, req, - timeval_current_ofs(to.tv_sec, to.tv_usec), - async_req_timedout, req) - != NULL); -} - -struct async_req *async_wait_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct timeval to) -{ - struct async_req *result; - - result = async_req_new(mem_ctx); - if (result == NULL) { - return result; - } - if (!async_req_set_timeout(result, ev, to)) { - TALLOC_FREE(result); - return NULL; - } - return result; -} - -NTSTATUS async_wait_recv(struct async_req *req) -{ - return NT_STATUS_OK; -} - -struct async_queue_entry { - struct async_queue_entry *prev, *next; - struct async_req_queue *queue; - struct async_req *req; - void (*trigger)(struct async_req *req); -}; - -struct async_req_queue { - struct async_queue_entry *queue; -}; - -struct async_req_queue *async_req_queue_init(TALLOC_CTX *mem_ctx) -{ - return TALLOC_ZERO_P(mem_ctx, struct async_req_queue); -} - -static int async_queue_entry_destructor(struct async_queue_entry *e) -{ - struct async_req_queue *queue = e->queue; - - DLIST_REMOVE(queue->queue, e); - - if (queue->queue != NULL) { - queue->queue->trigger(queue->queue->req); - } - - return 0; -} - -static void async_req_immediate_trigger(struct event_context *ev, - struct timed_event *te, - struct timeval now, - void *priv) -{ - struct async_queue_entry *e = talloc_get_type_abort( - priv, struct async_queue_entry); - - TALLOC_FREE(te); - e->trigger(e->req); -} - -bool async_req_enqueue(struct async_req_queue *queue, struct event_context *ev, - struct async_req *req, - void (*trigger)(struct async_req *req)) -{ - struct async_queue_entry *e; - bool busy; - - busy = (queue->queue != NULL); - - e = talloc(req, struct async_queue_entry); - if (e == NULL) { - return false; - } - - e->req = req; - e->trigger = trigger; - e->queue = queue; - - DLIST_ADD_END(queue->queue, e, struct async_queue_entry *); - talloc_set_destructor(e, async_queue_entry_destructor); - - if (!busy) { - struct timed_event *te; - - te = event_add_timed(ev, e, timeval_zero(), - async_req_immediate_trigger, - e); - if (te == NULL) { - TALLOC_FREE(e); - return false; - } - } - - return true; -} - -bool _async_req_setup(TALLOC_CTX *mem_ctx, struct async_req **preq, - void *pstate, size_t state_size, const char *typename) -{ - struct async_req *req; - void **ppstate = (void **)pstate; - void *state; - - req = async_req_new(mem_ctx); - if (req == NULL) { - return false; - } - state = talloc_size(req, state_size); - if (state == NULL) { - TALLOC_FREE(req); - return false; - } - talloc_set_name(state, typename); - req->private_data = state; - - *preq = req; - *ppstate = state; - - return true; -} -- cgit From 481183ab025a84dd8d08c1e365251b274597b6c9 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 23 Jan 2009 12:25:49 +0100 Subject: s4: add ../lib/async_req to the s4 build --- lib/async_req/config.mk | 3 +++ source4/main.mk | 1 + 2 files changed, 4 insertions(+) create mode 100644 lib/async_req/config.mk diff --git a/lib/async_req/config.mk b/lib/async_req/config.mk new file mode 100644 index 0000000000..08d5288a48 --- /dev/null +++ b/lib/async_req/config.mk @@ -0,0 +1,3 @@ +[SUBSYSTEM::LIBASYNC_REQ] + +LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_req.o) diff --git a/source4/main.mk b/source4/main.mk index df31c90f64..bfff04d13c 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -48,3 +48,4 @@ mkinclude libcli/config.mk mkinclude scripting/python/config.mk mkinclude kdc/config.mk mkinclude ../lib/smbconf/config.mk +mkinclude ../lib/async_req/config.mk -- cgit From b7eabeb347d6815a7a4a0ece282dba5da94777ca Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Thu, 8 Jan 2009 17:09:28 -0800 Subject: s3: OneFS unmappable sids support. Updates the onefs vfs module to add configurable behavior to deal with sids that are unknown to us. The best examples are aces that come from robocopy/xcopy. Adds the following share level options (which are specific to the vfs_onefs module): onefs: ignore unmappable sids (Default = false) If this option is set to true, sids which could not be resolved to a uid/gid are ignored. If an unmappable sid is encountered as the owner or group, the owner/group is converted to BUILTIN\Administrators. onefs: unmappable sids ignore list (Default = empty) Only the sids in the list are ignored. onefs: ignore sacls (Default = false) SACLs are ignored onefs: unmappable sids deny everyone (Default = false) If an unmappable sid is found in a deny ACE, the ACE's identity is changed to Everyone. --- source3/modules/onefs.h | 10 +- source3/modules/onefs_acl.c | 238 ++++++++++++++++++++++++++++++----------- source3/modules/onefs_system.c | 2 +- 3 files changed, 183 insertions(+), 67 deletions(-) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 6e5eae3085..e189fc4570 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -45,6 +45,14 @@ enum onefs_acl_wire_format #define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false #define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control" #define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true +#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone" +#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids" +#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list" +#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL +#define PARM_IGNORE_SACL "ignore sacl" +#define PARM_IGNORE_SACL_DEFAULT false /* * vfs interface handlers @@ -105,7 +113,7 @@ NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, * Utility functions */ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, - struct ifs_security_descriptor *sd); + struct ifs_security_descriptor *sd, int snum); NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, char **pbase, char **pstream); diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 9258e0cddc..b9ec2d68e0 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -35,7 +35,8 @@ const struct enum_list enum_onefs_acl_wire_format[] = { * Turn SID into UID/GID and setup a struct ifs_identity */ static bool -onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id, bool is_group) +onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id, + bool is_group) { enum ifs_identity_type type = IFS_ID_TYPE_LAST+1; uid_t uid = 0; @@ -111,18 +112,137 @@ onefs_identity_to_sid(struct ifs_identity *id, DOM_SID *sid) return true; } +static bool +onefs_og_to_identity(DOM_SID *sid, struct ifs_identity * ident, + bool is_group, int snum) +{ + const DOM_SID *b_admin_sid = &global_sid_Builtin_Administrators; + + if (!onefs_sid_to_identity(sid, ident, is_group)) { + if (!lp_parm_bool(snum, PARM_ONEFS_TYPE, + PARM_UNMAPPABLE_SIDS_IGNORE, + PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT)) { + DEBUG(3, ("Unresolvable SID (%s) found.\n", + sid_string_dbg(sid))); + return false; + } + if (!onefs_sid_to_identity(b_admin_sid, ident, is_group)) { + return false; + } + DEBUG(3, ("Mapping unresolvable owner SID (%s) to Builtin " + "Administrators group.\n", + sid_string_dbg(sid))); + } + return true; +} + +static bool +sid_in_ignore_list(DOM_SID * sid, int snum) +{ + const char ** sid_list = NULL; + DOM_SID match; + + sid_list = lp_parm_string_list(snum, PARM_ONEFS_TYPE, + PARM_UNMAPPABLE_SIDS_IGNORE_LIST, + PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT); + + /* Fast path a NULL list */ + if (!sid_list || *sid_list == NULL) + return false; + + while (*sid_list) { + if (string_to_sid(&match, *sid_list)) + if (sid_equal(sid, &match)) + return true; + sid_list++; + } + + return false; +} + +/** + * Convert a trustee to a struct identity + */ +static bool +onefs_samba_ace_to_ace(SEC_ACE * samba_ace, struct ifs_ace * ace, + bool *mapped, int snum) +{ + struct ifs_identity ident = {.type=IFS_ID_TYPE_LAST, .id.uid=0}; + + SMB_ASSERT(ace); + SMB_ASSERT(mapped); + SMB_ASSERT(samba_ace); + + if (onefs_sid_to_identity(&samba_ace->trustee, &ident, false)) { + *mapped = true; + } else { + + SMB_ASSERT(ident.id.uid >= 0); + + /* Ignore the sid if it's in the list */ + if (sid_in_ignore_list(&samba_ace->trustee, snum)) { + DEBUG(3, ("Silently failing to set ACE for SID (%s) " + "because it is in the ignore sids list\n", + sid_string_dbg(&samba_ace->trustee))); + *mapped = false; + } else if ((samba_ace->type == SEC_ACE_TYPE_ACCESS_DENIED) && + lp_parm_bool(snum, PARM_ONEFS_TYPE, + PARM_UNMAPPABLE_SIDS_DENY_EVERYONE, + PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT)) { + /* If the ace is deny translated to Everyone */ + DEBUG(3, ("Mapping unresolvable deny ACE SID (%s) " + "to Everyone.\n", + sid_string_dbg(&samba_ace->trustee))); + if (aclu_initialize_identity(&ident, + IFS_ID_TYPE_EVERYONE, 0, 0, False) != 0) { + DEBUG(2, ("aclu_initialize_identity() " + "failed making Everyone\n")); + return false; + } + *mapped = true; + } else if (lp_parm_bool(snum, PARM_ONEFS_TYPE, + PARM_UNMAPPABLE_SIDS_IGNORE, + PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT)) { + DEBUG(3, ("Silently failing to set ACE for SID (%s) " + "because it is unresolvable\n", + sid_string_dbg(&samba_ace->trustee))); + *mapped = false; + } else { + /* Fail for lack of a better option */ + return false; + } + } + + if (*mapped) { + if (aclu_initialize_ace(ace, samba_ace->type, + samba_ace->access_mask, samba_ace->flags, 0, + &ident)) + return false; + + if ((ace->trustee.type == IFS_ID_TYPE_CREATOR_OWNER || + ace->trustee.type == IFS_ID_TYPE_CREATOR_GROUP) && + nt4_compatible_acls()) + ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY; + } + + return true; +} + /** * Convert a SEC_ACL to a struct ifs_security_acl */ static bool -onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl) +onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl, + bool * ignore_aces, int snum) { int num_aces = 0; struct ifs_ace *aces = NULL; - struct ifs_identity temp; SEC_ACE *samba_aces; + bool mapped; int i, j; + SMB_ASSERT(ignore_aces); + if ((!acl) || (!samba_acl)) return false; @@ -134,39 +254,30 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl) aces = SMB_MALLOC_ARRAY(struct ifs_ace, num_aces); for (i = 0, j = 0; j < num_aces; i++, j++) { - if (!onefs_sid_to_identity(&samba_aces[j].trustee, - &temp, false)) + if (!onefs_samba_ace_to_ace(&samba_aces[j], + &aces[i], &mapped, snum)) goto err_free; - /* - * XXX Act like we did pre-Thai: Silently fail setting - * ACEs for BUILTIN accounts. - */ - if (temp.id.uid == -1) { - DEBUG(3, ("Silently failing to set ACE " - "because our id was == -1.\n")); + if (!mapped) i--; - continue; - } - - if (aclu_initialize_ace(&aces[i], samba_aces[i].type, - samba_aces[i].access_mask, samba_aces[i].flags, - 0, &temp)) - goto err_free; - - if ((aces[i].trustee.type == IFS_ID_TYPE_CREATOR_OWNER || - aces[i].trustee.type == IFS_ID_TYPE_CREATOR_GROUP) && - nt4_compatible_acls()) - aces[i].flags |= IFS_ACE_FLAG_INHERIT_ONLY; } num_aces = i; } + /* If aces are given but we cannot apply them due to the reasons + * above we do not change the SD. However, if we are told to + * explicitly set an SD with 0 aces we honor this operation */ + *ignore_aces = samba_acl->num_aces > 0 && num_aces < 1; + + if (*ignore_aces == false) + if (aclu_initialize_acl(acl, aces, num_aces)) + goto err_free; + if (aclu_initialize_acl(acl, aces, num_aces)) goto err_free; - /* Currently aclu_initialize_acl should copy the aces over, allowing us - * to immediately free */ + /* Currently aclu_initialize_acl should copy the aces over, allowing + * us to immediately free */ free(aces); return true; @@ -697,10 +808,11 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name, * @return NTSTATUS_OK if successful */ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, - struct ifs_security_descriptor *sd) + struct ifs_security_descriptor *sd, int snum) { - struct ifs_security_acl dacl, sacl, *daclp, *saclp; + struct ifs_security_acl *daclp, *saclp; struct ifs_identity owner, group, *ownerp, *groupp; + bool ignore_aces; ownerp = NULL; groupp = NULL; @@ -709,58 +821,53 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, /* Setup owner */ if (security_info_sent & OWNER_SECURITY_INFORMATION) { - if (!onefs_sid_to_identity(psd->owner_sid, &owner, false)) + if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum)) return NT_STATUS_UNSUCCESSFUL; - /* - * XXX Act like we did pre-Thai: Silently fail setting the - * owner to a BUILTIN account. - */ - if (owner.id.uid == -1) { - DEBUG(3, ("Silently failing to set owner because our " - "id was == -1.\n")); - security_info_sent &= ~OWNER_SECURITY_INFORMATION; - if (!security_info_sent) - return NT_STATUS_OK; - } - else - ownerp = &owner; + SMB_ASSERT(owner.id.uid >= 0); + + ownerp = &owner; } /* Setup group */ if (security_info_sent & GROUP_SECURITY_INFORMATION) { - if (!onefs_sid_to_identity(psd->group_sid, &group, true)) + if (!onefs_og_to_identity(psd->group_sid, &group, true, snum)) return NT_STATUS_UNSUCCESSFUL; - /* - * XXX Act like we did pre-Thai: Silently fail setting the - * group to a BUILTIN account. - */ - if (group.id.gid == -1) { - DEBUG(3, ("Silently failing to set group because our " - "id was == -1.\n")); - security_info_sent &= ~GROUP_SECURITY_INFORMATION; - if (!security_info_sent) - return NT_STATUS_OK; - } - else - groupp = &group; + SMB_ASSERT(group.id.gid >= 0); + + groupp = &group; } /* Setup DACL */ if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) { - daclp = &dacl; - - if (!onefs_samba_acl_to_acl(psd->dacl, &daclp)) + if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces, + snum)) return NT_STATUS_UNSUCCESSFUL; + + if (ignore_aces == true) + security_info_sent &= ~DACL_SECURITY_INFORMATION; } /* Setup SACL */ - if ((security_info_sent & SACL_SECURITY_INFORMATION) && (psd->sacl)) { - saclp = &sacl; - - if (!onefs_samba_acl_to_acl(psd->sacl, &saclp)) - return NT_STATUS_UNSUCCESSFUL; + if (security_info_sent & SACL_SECURITY_INFORMATION) { + + if (lp_parm_bool(snum, PARM_ONEFS_TYPE, + PARM_IGNORE_SACL, PARM_IGNORE_SACL_DEFAULT)) { + DEBUG(5, ("Ignoring SACLs.\n")); + security_info_sent &= ~SACL_SECURITY_INFORMATION; + } else { + if (psd->sacl) { + if (!onefs_samba_acl_to_acl(psd->sacl, + &saclp, &ignore_aces, snum)) + return NT_STATUS_UNSUCCESSFUL; + + if (ignore_aces == true) { + security_info_sent &= + ~SACL_SECURITY_INFORMATION; + } + } + } } /* Setup ifs_security_descriptor */ @@ -789,7 +896,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); - status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd); + status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd, + SNUM(handle->conn)); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index ee257d8f90..4ebdf12a50 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -152,7 +152,7 @@ int onefs_sys_create_file(connection_struct *conn, secinfo = (get_sec_info(sd) & IFS_SEC_INFO_KNOWN_MASK); - status = onefs_samba_sd_to_sd(secinfo, sd, &ifs_sd); + status = onefs_samba_sd_to_sd(secinfo, sd, &ifs_sd, SNUM(conn)); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("SD initialization failure: %s", -- cgit From 48a6feef402f7b91098341dc6e5eabbfd4beaa91 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 23 Jan 2009 23:15:05 +0100 Subject: talloc_free() copes with a NULL pointer just fine Saved around 10kb of code on my box :-) --- source3/include/smb_macros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 5149da0cb3..92c60a7530 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -256,7 +256,7 @@ NULL returns on zero request. JRA. #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__) #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type) #define talloc_destroy(ctx) talloc_free(ctx) -#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0) +#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) /* only define PARANOID_MALLOC_CHECKER with --enable-developer */ -- cgit From 0998d172dbeb5f9d7198bbea9ee9124c0558f41b Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 23 Jan 2009 16:09:13 -0800 Subject: s3 ldb: Fix vasprintf segfault that has been the source of build machine failures this week The bug was introduced when converting samba3's ldb_search interface to match samba4: 47951fc5d0085e124666b7667715bba98076820e f3ecb701335b1129947127d4c45eef970b66875c --- source3/lib/ldb/common/ldb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source3/lib/ldb/common/ldb.c b/source3/lib/ldb/common/ldb.c index 6e28528dbf..cef7373c26 100644 --- a/source3/lib/ldb/common/ldb.c +++ b/source3/lib/ldb/common/ldb.c @@ -808,15 +808,18 @@ int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_result * va_list ap; int ret; + expression = NULL; res = NULL; *result = NULL; - va_start(ap, exp_fmt); - expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); - va_end(ap); + if (exp_fmt) { + va_start(ap, exp_fmt); + expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); + va_end(ap); - if ( ! expression) { - return LDB_ERR_OPERATIONS_ERROR; + if ( ! expression) { + return LDB_ERR_OPERATIONS_ERROR; + } } ret = _ldb_search(ldb, ldb, &res, base, scope, attrs, expression); -- cgit From d629ba480b7cd7344d842069f18fd07f088c4f2f Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Fri, 23 Jan 2009 17:29:21 -0800 Subject: talloc: Change the two other definitions of TALLOC_FREE to match the primary version Eventually these two other definitions should be removed and all of the TALLOC macros should live in the same header. Until then, this patch eliminates some build warnings. --- nsswitch/pam_winbind.h | 2 +- source3/libaddns/dns.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nsswitch/pam_winbind.h b/nsswitch/pam_winbind.h index d21fc04a78..0395a1fd5b 100644 --- a/nsswitch/pam_winbind.h +++ b/nsswitch/pam_winbind.h @@ -171,6 +171,6 @@ struct pwb_context { uint32_t ctrl; }; -#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0) +#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) #define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) #define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h index 3f95c739d5..42662a224b 100644 --- a/source3/libaddns/dns.h +++ b/source3/libaddns/dns.h @@ -133,7 +133,7 @@ void *talloc_zeronull(const void *context, size_t size, const char *name); #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__) #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type) #define talloc_destroy(ctx) talloc_free(ctx) -#define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0) +#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) /******************************************************************* Type definitions for int16, int32, uint16 and uint32. Needed -- cgit From cf41042a3c4ccf613e312570d8d93932b54dcaee Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 24 Jan 2009 02:07:40 +0100 Subject: s3-eventlog: fix buffer allocation in eventlog read call. This broke with f6fa3080fee1b20df9f1968500840a88cf0ee592 back in April 2007... Guenther --- source3/rpc_parse/parse_eventlog.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source3/rpc_parse/parse_eventlog.c b/source3/rpc_parse/parse_eventlog.c index a55993cc2e..40930a2500 100644 --- a/source3/rpc_parse/parse_eventlog.c +++ b/source3/rpc_parse/parse_eventlog.c @@ -185,6 +185,7 @@ bool eventlog_io_r_read_eventlog(const char *desc, /* Now pad with whitespace until the end of the response buffer */ if (q_u->max_read_size - r_u->num_bytes_in_resp) { + r_u->end_of_entries_padding = PRS_ALLOC_MEM(ps, uint8_t, q_u->max_read_size - r_u->num_bytes_in_resp); if (!r_u->end_of_entries_padding) { return False; } @@ -192,11 +193,8 @@ bool eventlog_io_r_read_eventlog(const char *desc, if(!(prs_uint8s(False, "end of entries padding", ps, depth, r_u->end_of_entries_padding, (q_u->max_read_size - r_u->num_bytes_in_resp)))) { - free(r_u->end_of_entries_padding); return False; } - - free(r_u->end_of_entries_padding); } /* We had better be DWORD aligned here */ -- cgit From dd2695fe52374cb72bf0954805ff614eef640eae Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 24 Jan 2009 02:10:47 +0100 Subject: s3-eventlog: fix various invalid memcpy in read_package_entry(). Guenther --- source3/rpc_server/srv_eventlog_nt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 0bf0730d39..5b98ea54f4 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -539,30 +539,30 @@ static Eventlog_entry *read_package_entry( TALLOC_CTX *mem_ctx, return NULL; } offset = entry->data; - memcpy( offset, &( entry->data_record.source_name ), + memcpy( offset, entry->data_record.source_name, entry->data_record.source_name_len ); offset += entry->data_record.source_name_len; - memcpy( offset, &( entry->data_record.computer_name ), + memcpy( offset, entry->data_record.computer_name, entry->data_record.computer_name_len ); offset += entry->data_record.computer_name_len; /* SID needs to be DWORD-aligned */ offset += entry->data_record.sid_padding; entry->record.user_sid_offset = sizeof( Eventlog_record ) + ( offset - entry->data ); - memcpy( offset, &( entry->data_record.sid ), + memcpy( offset, entry->data_record.sid, entry->record.user_sid_length ); offset += entry->record.user_sid_length; /* Now do the strings */ entry->record.string_offset = sizeof( Eventlog_record ) + ( offset - entry->data ); - memcpy( offset, &( entry->data_record.strings ), + memcpy( offset, entry->data_record.strings, entry->data_record.strings_len ); offset += entry->data_record.strings_len; /* Now do the data */ entry->record.data_length = entry->data_record.user_data_len; entry->record.data_offset = sizeof( Eventlog_record ) + ( offset - entry->data ); - memcpy( offset, &( entry->data_record.user_data ), + memcpy( offset, entry->data_record.user_data, entry->data_record.user_data_len ); offset += entry->data_record.user_data_len; -- cgit From 5bcd6d760b628832a43271293bee207819784001 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 24 Jan 2009 02:59:24 +0100 Subject: Revert "s3-eventlog: trying to avoid to pass around full ndr structures in rpc_server." This reverts commit c0f1309010b79be67557af5ffbd1c429a3f3d99a. --- source3/rpc_server/srv_eventlog_nt.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 5b98ea54f4..5f9df1ba81 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -578,17 +578,15 @@ static Eventlog_entry *read_package_entry( TALLOC_CTX *mem_ctx, /******************************************************************** ********************************************************************/ -static bool add_record_to_resp( Eventlog_entry *entry, - uint32_t *num_records, - uint32_t *num_bytes_in_resp, +static bool add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u, Eventlog_entry * ee_new ) { Eventlog_entry *insert_point; - insert_point = entry; + insert_point = r_u->entry; if ( NULL == insert_point ) { - entry = ee_new; + r_u->entry = ee_new; ee_new->next = NULL; } else { while ( ( NULL != insert_point->next ) ) { @@ -597,8 +595,8 @@ static bool add_record_to_resp( Eventlog_entry *entry, ee_new->next = NULL; insert_point->next = ee_new; } - (*num_records)++; - *num_bytes_in_resp += ee_new->record.length; + r_u->num_records++; + r_u->num_bytes_in_resp += ee_new->record.length; return True; } @@ -775,10 +773,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p, break; } - add_record_to_resp( r_u->entry, - &r_u->num_records, &r_u->num_bytes_in_resp, - ee_new ); - + add_record_to_resp( r_u, ee_new ); bytes_left -= ee_new->record.length; TALLOC_FREE(entry); num_records_read = r_u->num_records - num_records_read; -- cgit From 321983a68e949db61cbb87c3fee84919231ed2dc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 18:32:01 +0100 Subject: eventlog: fill in IDL for eventlog_ReportEventW. Guenther --- librpc/idl/eventlog.idl | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index 51b3ea706e..a85a5efeaf 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -130,7 +130,22 @@ import "lsa.idl", "security.idl"; /*****************/ /* Function 0x0b */ - [todo] NTSTATUS eventlog_ReportEventW(); + NTSTATUS eventlog_ReportEventW( + [in] policy_handle *handle, + [in] time_t timestamp, + [in] eventlogEventTypes event_type, + [in] uint16 event_category, + [in] uint32 event_id, + [in] [range(0,256)] uint16 num_of_strings, + [in] [range(0,0x3FFFF)] uint32 data_size, + [in,ref] lsa_String *servername, + [in,unique] dom_sid *user_sid, + [in,unique] [size_is(num_of_strings)] lsa_String **strings, + [in,unique] [size_is(data_size)] uint8 *data, + [in] uint16 flags, + [in,out,unique] uint32 *record_number, + [in,out,unique] time_t *time_written + ); /*****************/ /* Function 0x0c */ -- cgit From 02a3a7f1eda576b353207825875f676130874a00 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 18:56:34 +0100 Subject: eventlog: fill in IDL for eventlog_GetLogIntormation. Guenther --- librpc/idl/eventlog.idl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index a85a5efeaf..0b49379bf4 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -189,7 +189,18 @@ import "lsa.idl", "security.idl"; /*****************/ /* Function 0x16 */ - [todo] NTSTATUS eventlog_GetLogIntormation(); + + typedef struct { + boolean32 full; + } EVENTLOG_FULL_INFORMATION; + + NTSTATUS eventlog_GetLogIntormation( + [in] policy_handle *handle, + [in] uint32 level, + [out,ref] [size_is(buf_size)] uint8 *buffer, + [in] [range(0,1024)] uint32 buf_size, + [out,ref] uint32 *bytes_needed + ); /*****************/ /* Function 0x17 */ -- cgit From ab6e4dd9fdf43407a10fd67235b158e9022ead17 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 19:20:26 +0100 Subject: eventlog: add missing IDL (opnum 24) for eventlog_ReportEventAndSourceW. Guenther --- librpc/idl/eventlog.idl | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index 0b49379bf4..da08b35742 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -206,5 +206,25 @@ import "lsa.idl", "security.idl"; /* Function 0x17 */ NTSTATUS eventlog_FlushEventLog( [in] policy_handle *handle - ); + ); + + /*****************/ + /* Function 0x18 */ + NTSTATUS eventlog_ReportEventAndSourceW( + [in] policy_handle *handle, + [in] time_t timestamp, + [in] eventlogEventTypes event_type, + [in] uint16 event_category, + [in] uint32 event_id, + [in,ref] lsa_String *sourcename, + [in] [range(0,256)] uint16 num_of_strings, + [in] [range(0,0x3FFFF)] uint32 data_size, + [in,ref] lsa_String *servername, + [in,unique] dom_sid *user_sid, + [in,unique] [size_is(num_of_strings)] lsa_String **strings, + [in,unique] [size_is(data_size)] uint8 *data, + [in] uint16 flags, + [in,out,unique] uint32 *record_number, + [in,out,unique] time_t *time_written + ); } -- cgit From 7dad861627b2f1f131f019d4c5e3b4ce75a1ccd6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 19:58:17 +0100 Subject: eventlog: fill in IDL for eventlog_RegisterEventSourceW. Guenther --- librpc/idl/eventlog.idl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index da08b35742..6b7b6c58e6 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -110,7 +110,14 @@ import "lsa.idl", "security.idl"; /******************/ /* Function: 0x08 */ - [todo] NTSTATUS eventlog_RegisterEventSourceW(); + NTSTATUS eventlog_RegisterEventSourceW( + [in,unique] eventlog_OpenUnknown0 *unknown0, + [in,ref] lsa_String *module_name, + [in,ref] lsa_String *reg_module_name, + [in] uint32 major_version, + [in] uint32 minor_version, + [out] policy_handle *log_handle + ); /******************/ /* Function: 0x09 */ -- cgit From ca799da8231841cc7e10350dfe83d35a55316e39 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 20:00:02 +0100 Subject: eventlog: fill in IDL for eventlog_DeregisterEventSource. Guenther --- librpc/idl/eventlog.idl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index 6b7b6c58e6..40def82c69 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -77,7 +77,9 @@ import "lsa.idl", "security.idl"; /******************/ /* Function: 0x03 */ - [todo] NTSTATUS eventlog_DeregisterEventSource(); + NTSTATUS eventlog_DeregisterEventSource( + [in,out] policy_handle *handle + ); /******************/ /* Function: 0x04 */ -- cgit From 466872e9ff6d5aeb7900ca3ae17b1d7def3a9c60 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 22:06:01 +0100 Subject: eventlog: fill in IDL for eventlog_BackupEventLogW. Guenther --- librpc/idl/eventlog.idl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index 40def82c69..8c1df3d166 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -67,8 +67,11 @@ import "lsa.idl", "security.idl"; /******************/ /* Function: 0x01 */ - [todo] NTSTATUS eventlog_BackupEventLogW(); - + NTSTATUS eventlog_BackupEventLogW( + [in] policy_handle *handle, + [in,ref] lsa_String *backup_filename + ); + /******************/ /* Function: 0x02 */ NTSTATUS eventlog_CloseEventLog( -- cgit From b57c37d6aec28ef93c5d47aa3b20382bd8679361 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 22:18:53 +0100 Subject: eventlog: fill in IDL for eventlog_OpenBackupEventLogW. Guenther --- librpc/idl/eventlog.idl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index 8c1df3d166..ccdca008c5 100644 --- a/librpc/idl/eventlog.idl +++ b/librpc/idl/eventlog.idl @@ -126,7 +126,13 @@ import "lsa.idl", "security.idl"; /******************/ /* Function: 0x09 */ - [todo] NTSTATUS eventlog_OpenBackupEventLogW(); + NTSTATUS eventlog_OpenBackupEventLogW( + [in,unique] eventlog_OpenUnknown0 *unknown0, + [in,ref] lsa_String *backup_logname, + [in] uint32 major_version, + [in] uint32 minor_version, + [out] policy_handle *handle + ); /******************/ /* Function: 0x0a */ -- cgit From 4cac1da142aec103f1022aedeb068d9cc94c7f4e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 24 Jan 2009 03:30:48 +0100 Subject: s3: re-run make samba3-idl. Guenther --- librpc/gen_ndr/cli_eventlog.c | 157 +++++++- librpc/gen_ndr/cli_eventlog.h | 62 ++- librpc/gen_ndr/eventlog.h | 86 ++++ librpc/gen_ndr/ndr_eventlog.c | 908 +++++++++++++++++++++++++++++++++++++++++- librpc/gen_ndr/ndr_eventlog.h | 5 +- librpc/gen_ndr/srv_eventlog.c | 146 +++++++ librpc/gen_ndr/srv_eventlog.h | 2 + 7 files changed, 1352 insertions(+), 14 deletions(-) diff --git a/librpc/gen_ndr/cli_eventlog.c b/librpc/gen_ndr/cli_eventlog.c index 2f4b9f21af..6b084d2217 100644 --- a/librpc/gen_ndr/cli_eventlog.c +++ b/librpc/gen_ndr/cli_eventlog.c @@ -47,12 +47,16 @@ NTSTATUS rpccli_eventlog_ClearEventLogW(struct rpc_pipe_client *cli, } NTSTATUS rpccli_eventlog_BackupEventLogW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct lsa_String *backup_filename /* [in] [ref] */) { struct eventlog_BackupEventLogW r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.backup_filename = backup_filename; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(eventlog_BackupEventLogW, &r); @@ -122,12 +126,14 @@ NTSTATUS rpccli_eventlog_CloseEventLog(struct rpc_pipe_client *cli, } NTSTATUS rpccli_eventlog_DeregisterEventSource(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in,out] [ref] */) { struct eventlog_DeregisterEventSource r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(eventlog_DeregisterEventSource, &r); @@ -152,6 +158,7 @@ NTSTATUS rpccli_eventlog_DeregisterEventSource(struct rpc_pipe_client *cli, } /* Return variables */ + *handle = *r.out.handle; /* Return result */ return r.out.result; @@ -322,12 +329,23 @@ NTSTATUS rpccli_eventlog_OpenEventLogW(struct rpc_pipe_client *cli, } NTSTATUS rpccli_eventlog_RegisterEventSourceW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct eventlog_OpenUnknown0 *unknown0 /* [in] [unique] */, + struct lsa_String *module_name /* [in] [ref] */, + struct lsa_String *reg_module_name /* [in] [ref] */, + uint32_t major_version /* [in] */, + uint32_t minor_version /* [in] */, + struct policy_handle *log_handle /* [out] [ref] */) { struct eventlog_RegisterEventSourceW r; NTSTATUS status; /* In parameters */ + r.in.unknown0 = unknown0; + r.in.module_name = module_name; + r.in.reg_module_name = reg_module_name; + r.in.major_version = major_version; + r.in.minor_version = minor_version; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(eventlog_RegisterEventSourceW, &r); @@ -352,18 +370,28 @@ NTSTATUS rpccli_eventlog_RegisterEventSourceW(struct rpc_pipe_client *cli, } /* Return variables */ + *log_handle = *r.out.log_handle; /* Return result */ return r.out.result; } NTSTATUS rpccli_eventlog_OpenBackupEventLogW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct eventlog_OpenUnknown0 *unknown0 /* [in] [unique] */, + struct lsa_String *backup_logname /* [in] [ref] */, + uint32_t major_version /* [in] */, + uint32_t minor_version /* [in] */, + struct policy_handle *handle /* [out] [ref] */) { struct eventlog_OpenBackupEventLogW r; NTSTATUS status; /* In parameters */ + r.in.unknown0 = unknown0; + r.in.backup_logname = backup_logname; + r.in.major_version = major_version; + r.in.minor_version = minor_version; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(eventlog_OpenBackupEventLogW, &r); @@ -388,6 +416,7 @@ NTSTATUS rpccli_eventlog_OpenBackupEventLogW(struct rpc_pipe_client *cli, } /* Return variables */ + *handle = *r.out.handle; /* Return result */ return r.out.result; @@ -444,12 +473,40 @@ NTSTATUS rpccli_eventlog_ReadEventLogW(struct rpc_pipe_client *cli, } NTSTATUS rpccli_eventlog_ReportEventW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + time_t timestamp /* [in] */, + enum eventlogEventTypes event_type /* [in] */, + uint16_t event_category /* [in] */, + uint32_t event_id /* [in] */, + uint16_t num_of_strings /* [in] [range(0,256)] */, + uint32_t data_size /* [in] [range(0,0x3FFFF)] */, + struct lsa_String *servername /* [in] [ref] */, + struct dom_sid *user_sid /* [in] [unique] */, + struct lsa_String **strings /* [in] [unique,size_is(num_of_strings)] */, + uint8_t *data /* [in] [unique,size_is(data_size)] */, + uint16_t flags /* [in] */, + uint32_t *record_number /* [in,out] [unique] */, + time_t *time_written /* [in,out] [unique] */) { struct eventlog_ReportEventW r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.timestamp = timestamp; + r.in.event_type = event_type; + r.in.event_category = event_category; + r.in.event_id = event_id; + r.in.num_of_strings = num_of_strings; + r.in.data_size = data_size; + r.in.servername = servername; + r.in.user_sid = user_sid; + r.in.strings = strings; + r.in.data = data; + r.in.flags = flags; + r.in.record_number = record_number; + r.in.time_written = time_written; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(eventlog_ReportEventW, &r); @@ -474,6 +531,12 @@ NTSTATUS rpccli_eventlog_ReportEventW(struct rpc_pipe_client *cli, } /* Return variables */ + if (record_number && r.out.record_number) { + *record_number = *r.out.record_number; + } + if (time_written && r.out.time_written) { + *time_written = *r.out.time_written; + } /* Return result */ return r.out.result; @@ -840,12 +903,20 @@ NTSTATUS rpccli_eventlog_WriteClusterEvents(struct rpc_pipe_client *cli, } NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + uint32_t level /* [in] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,1024)] */, + uint32_t *bytes_needed /* [out] [ref] */) { struct eventlog_GetLogIntormation r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.level = level; + r.in.buf_size = buf_size; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(eventlog_GetLogIntormation, &r); @@ -870,6 +941,8 @@ NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, } /* Return variables */ + memcpy(buffer, r.out.buffer, r.in.buf_size * sizeof(*buffer)); + *bytes_needed = *r.out.bytes_needed; /* Return result */ return r.out.result; @@ -913,3 +986,75 @@ NTSTATUS rpccli_eventlog_FlushEventLog(struct rpc_pipe_client *cli, return r.out.result; } +NTSTATUS rpccli_eventlog_ReportEventAndSourceW(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + time_t timestamp /* [in] */, + enum eventlogEventTypes event_type /* [in] */, + uint16_t event_category /* [in] */, + uint32_t event_id /* [in] */, + struct lsa_String *sourcename /* [in] [ref] */, + uint16_t num_of_strings /* [in] [range(0,256)] */, + uint32_t data_size /* [in] [range(0,0x3FFFF)] */, + struct lsa_String *servername /* [in] [ref] */, + struct dom_sid *user_sid /* [in] [unique] */, + struct lsa_String **strings /* [in] [unique,size_is(num_of_strings)] */, + uint8_t *data /* [in] [unique,size_is(data_size)] */, + uint16_t flags /* [in] */, + uint32_t *record_number /* [in,out] [unique] */, + time_t *time_written /* [in,out] [unique] */) +{ + struct eventlog_ReportEventAndSourceW r; + NTSTATUS status; + + /* In parameters */ + r.in.handle = handle; + r.in.timestamp = timestamp; + r.in.event_type = event_type; + r.in.event_category = event_category; + r.in.event_id = event_id; + r.in.sourcename = sourcename; + r.in.num_of_strings = num_of_strings; + r.in.data_size = data_size; + r.in.servername = servername; + r.in.user_sid = user_sid; + r.in.strings = strings; + r.in.data = data; + r.in.flags = flags; + r.in.record_number = record_number; + r.in.time_written = time_written; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(eventlog_ReportEventAndSourceW, &r); + } + + status = cli->dispatch(cli, + mem_ctx, + &ndr_table_eventlog, + NDR_EVENTLOG_REPORTEVENTANDSOURCEW, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(eventlog_ReportEventAndSourceW, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + if (record_number && r.out.record_number) { + *record_number = *r.out.record_number; + } + if (time_written && r.out.time_written) { + *time_written = *r.out.time_written; + } + + /* Return result */ + return r.out.result; +} + diff --git a/librpc/gen_ndr/cli_eventlog.h b/librpc/gen_ndr/cli_eventlog.h index a1360cbc16..ae5544daf3 100644 --- a/librpc/gen_ndr/cli_eventlog.h +++ b/librpc/gen_ndr/cli_eventlog.h @@ -6,12 +6,15 @@ NTSTATUS rpccli_eventlog_ClearEventLogW(struct rpc_pipe_client *cli, struct policy_handle *handle /* [in] [ref] */, struct lsa_String *backupfile /* [in] [unique] */); NTSTATUS rpccli_eventlog_BackupEventLogW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + struct lsa_String *backup_filename /* [in] [ref] */); NTSTATUS rpccli_eventlog_CloseEventLog(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in,out] [ref] */); NTSTATUS rpccli_eventlog_DeregisterEventSource(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in,out] [ref] */); NTSTATUS rpccli_eventlog_GetNumRecords(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, @@ -31,9 +34,20 @@ NTSTATUS rpccli_eventlog_OpenEventLogW(struct rpc_pipe_client *cli, uint32_t minor_version /* [in] */, struct policy_handle *handle /* [out] [ref] */); NTSTATUS rpccli_eventlog_RegisterEventSourceW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct eventlog_OpenUnknown0 *unknown0 /* [in] [unique] */, + struct lsa_String *module_name /* [in] [ref] */, + struct lsa_String *reg_module_name /* [in] [ref] */, + uint32_t major_version /* [in] */, + uint32_t minor_version /* [in] */, + struct policy_handle *log_handle /* [out] [ref] */); NTSTATUS rpccli_eventlog_OpenBackupEventLogW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct eventlog_OpenUnknown0 *unknown0 /* [in] [unique] */, + struct lsa_String *backup_logname /* [in] [ref] */, + uint32_t major_version /* [in] */, + uint32_t minor_version /* [in] */, + struct policy_handle *handle /* [out] [ref] */); NTSTATUS rpccli_eventlog_ReadEventLogW(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, @@ -44,7 +58,21 @@ NTSTATUS rpccli_eventlog_ReadEventLogW(struct rpc_pipe_client *cli, uint32_t *sent_size /* [out] [ref] */, uint32_t *real_size /* [out] [ref] */); NTSTATUS rpccli_eventlog_ReportEventW(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + time_t timestamp /* [in] */, + enum eventlogEventTypes event_type /* [in] */, + uint16_t event_category /* [in] */, + uint32_t event_id /* [in] */, + uint16_t num_of_strings /* [in] [range(0,256)] */, + uint32_t data_size /* [in] [range(0,0x3FFFF)] */, + struct lsa_String *servername /* [in] [ref] */, + struct dom_sid *user_sid /* [in] [unique] */, + struct lsa_String **strings /* [in] [unique,size_is(num_of_strings)] */, + uint8_t *data /* [in] [unique,size_is(data_size)] */, + uint16_t flags /* [in] */, + uint32_t *record_number /* [in,out] [unique] */, + time_t *time_written /* [in,out] [unique] */); NTSTATUS rpccli_eventlog_ClearEventLogA(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx); NTSTATUS rpccli_eventlog_BackupEventLogA(struct rpc_pipe_client *cli, @@ -66,8 +94,30 @@ NTSTATUS rpccli_eventlog_DeregisterClusterSvc(struct rpc_pipe_client *cli, NTSTATUS rpccli_eventlog_WriteClusterEvents(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx); NTSTATUS rpccli_eventlog_GetLogIntormation(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + uint32_t level /* [in] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,1024)] */, + uint32_t *bytes_needed /* [out] [ref] */); NTSTATUS rpccli_eventlog_FlushEventLog(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */); +NTSTATUS rpccli_eventlog_ReportEventAndSourceW(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle /* [in] [ref] */, + time_t timestamp /* [in] */, + enum eventlogEventTypes event_type /* [in] */, + uint16_t event_category /* [in] */, + uint32_t event_id /* [in] */, + struct lsa_String *sourcename /* [in] [ref] */, + uint16_t num_of_strings /* [in] [range(0,256)] */, + uint32_t data_size /* [in] [range(0,0x3FFFF)] */, + struct lsa_String *servername /* [in] [ref] */, + struct dom_sid *user_sid /* [in] [unique] */, + struct lsa_String **strings /* [in] [unique,size_is(num_of_strings)] */, + uint8_t *data /* [in] [unique,size_is(data_size)] */, + uint16_t flags /* [in] */, + uint32_t *record_number /* [in,out] [unique] */, + time_t *time_written /* [in,out] [unique] */); #endif /* __CLI_EVENTLOG__ */ diff --git a/librpc/gen_ndr/eventlog.h b/librpc/gen_ndr/eventlog.h index 9c9a2ed218..8dc0d0d146 100644 --- a/librpc/gen_ndr/eventlog.h +++ b/librpc/gen_ndr/eventlog.h @@ -65,6 +65,10 @@ struct eventlog_Record { uint32_t size2;/* [value(size)] */ }/* [public,flag(LIBNDR_FLAG_NOALIGN)] */; +struct EVENTLOG_FULL_INFORMATION { + uint32_t full; +}; + struct eventlog_ClearEventLogW { struct { @@ -80,6 +84,11 @@ struct eventlog_ClearEventLogW { struct eventlog_BackupEventLogW { + struct { + struct policy_handle *handle;/* [ref] */ + struct lsa_String *backup_filename;/* [ref] */ + } in; + struct { NTSTATUS result; } out; @@ -102,6 +111,11 @@ struct eventlog_CloseEventLog { struct eventlog_DeregisterEventSource { struct { + struct policy_handle *handle;/* [ref] */ + } in; + + struct { + struct policy_handle *handle;/* [ref] */ NTSTATUS result; } out; @@ -161,6 +175,15 @@ struct eventlog_OpenEventLogW { struct eventlog_RegisterEventSourceW { struct { + struct eventlog_OpenUnknown0 *unknown0;/* [unique] */ + struct lsa_String *module_name;/* [ref] */ + struct lsa_String *reg_module_name;/* [ref] */ + uint32_t major_version; + uint32_t minor_version; + } in; + + struct { + struct policy_handle *log_handle;/* [ref] */ NTSTATUS result; } out; @@ -169,6 +192,14 @@ struct eventlog_RegisterEventSourceW { struct eventlog_OpenBackupEventLogW { struct { + struct eventlog_OpenUnknown0 *unknown0;/* [unique] */ + struct lsa_String *backup_logname;/* [ref] */ + uint32_t major_version; + uint32_t minor_version; + } in; + + struct { + struct policy_handle *handle;/* [ref] */ NTSTATUS result; } out; @@ -195,6 +226,25 @@ struct eventlog_ReadEventLogW { struct eventlog_ReportEventW { struct { + struct policy_handle *handle;/* [ref] */ + time_t timestamp; + enum eventlogEventTypes event_type; + uint16_t event_category; + uint32_t event_id; + uint16_t num_of_strings;/* [range(0,256)] */ + uint32_t data_size;/* [range(0,0x3FFFF)] */ + struct lsa_String *servername;/* [ref] */ + struct dom_sid *user_sid;/* [unique] */ + struct lsa_String **strings;/* [unique,size_is(num_of_strings)] */ + uint8_t *data;/* [unique,size_is(data_size)] */ + uint16_t flags; + uint32_t *record_number;/* [unique] */ + time_t *time_written;/* [unique] */ + } in; + + struct { + uint32_t *record_number;/* [unique] */ + time_t *time_written;/* [unique] */ NTSTATUS result; } out; @@ -283,6 +333,14 @@ struct eventlog_WriteClusterEvents { struct eventlog_GetLogIntormation { struct { + struct policy_handle *handle;/* [ref] */ + uint32_t level; + uint32_t buf_size;/* [range(0,1024)] */ + } in; + + struct { + uint8_t *buffer;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref] */ NTSTATUS result; } out; @@ -300,4 +358,32 @@ struct eventlog_FlushEventLog { }; + +struct eventlog_ReportEventAndSourceW { + struct { + struct policy_handle *handle;/* [ref] */ + time_t timestamp; + enum eventlogEventTypes event_type; + uint16_t event_category; + uint32_t event_id; + struct lsa_String *sourcename;/* [ref] */ + uint16_t num_of_strings;/* [range(0,256)] */ + uint32_t data_size;/* [range(0,0x3FFFF)] */ + struct lsa_String *servername;/* [ref] */ + struct dom_sid *user_sid;/* [unique] */ + struct lsa_String **strings;/* [unique,size_is(num_of_strings)] */ + uint8_t *data;/* [unique,size_is(data_size)] */ + uint16_t flags; + uint32_t *record_number;/* [unique] */ + time_t *time_written;/* [unique] */ + } in; + + struct { + uint32_t *record_number;/* [unique] */ + time_t *time_written;/* [unique] */ + NTSTATUS result; + } out; + +}; + #endif /* _HEADER_eventlog */ diff --git a/librpc/gen_ndr/ndr_eventlog.c b/librpc/gen_ndr/ndr_eventlog.c index ddc93f910b..938f0db8eb 100644 --- a/librpc/gen_ndr/ndr_eventlog.c +++ b/librpc/gen_ndr/ndr_eventlog.c @@ -371,6 +371,14 @@ _PUBLIC_ void ndr_print_eventlog_ClearEventLogW(struct ndr_print *ndr, const cha static enum ndr_err_code ndr_push_eventlog_BackupEventLogW(struct ndr_push *ndr, int flags, const struct eventlog_BackupEventLogW *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)); + if (r->in.backup_filename == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.backup_filename)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); @@ -380,7 +388,23 @@ static enum ndr_err_code ndr_push_eventlog_BackupEventLogW(struct ndr_push *ndr, static enum ndr_err_code ndr_pull_eventlog_BackupEventLogW(struct ndr_pull *ndr, int flags, struct eventlog_BackupEventLogW *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_backup_filename_0; if (flags & NDR_IN) { + 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); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.backup_filename); + } + _mem_save_backup_filename_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.backup_filename, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.backup_filename)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_backup_filename_0, LIBNDR_FLAG_REF_ALLOC); } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); @@ -398,6 +422,14 @@ _PUBLIC_ void ndr_print_eventlog_BackupEventLogW(struct ndr_print *ndr, const ch if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "eventlog_BackupEventLogW"); 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_ptr(ndr, "backup_filename", r->in.backup_filename); + ndr->depth++; + ndr_print_lsa_String(ndr, "backup_filename", r->in.backup_filename); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { @@ -488,8 +520,16 @@ _PUBLIC_ void ndr_print_eventlog_CloseEventLog(struct ndr_print *ndr, const char static enum ndr_err_code ndr_push_eventlog_DeregisterEventSource(struct ndr_push *ndr, int flags, const struct eventlog_DeregisterEventSource *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)); } if (flags & NDR_OUT) { + if (r->out.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.handle)); NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -497,9 +537,28 @@ static enum ndr_err_code ndr_push_eventlog_DeregisterEventSource(struct ndr_push static enum ndr_err_code ndr_pull_eventlog_DeregisterEventSource(struct ndr_pull *ndr, int flags, struct eventlog_DeregisterEventSource *r) { + TALLOC_CTX *_mem_save_handle_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_PULL_ALLOC(ndr, r->out.handle); + *r->out.handle = *r->in.handle; } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -515,11 +574,19 @@ _PUBLIC_ void ndr_print_eventlog_DeregisterEventSource(struct ndr_print *ndr, co if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "eventlog_DeregisterEventSource"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "eventlog_DeregisterEventSource"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->out.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->out.handle); + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } @@ -847,8 +914,26 @@ _PUBLIC_ void ndr_print_eventlog_OpenEventLogW(struct ndr_print *ndr, const char static enum ndr_err_code ndr_push_eventlog_RegisterEventSourceW(struct ndr_push *ndr, int flags, const struct eventlog_RegisterEventSourceW *r) { if (flags & NDR_IN) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.unknown0)); + if (r->in.unknown0) { + NDR_CHECK(ndr_push_eventlog_OpenUnknown0(ndr, NDR_SCALARS, r->in.unknown0)); + } + if (r->in.module_name == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.module_name)); + if (r->in.reg_module_name == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.reg_module_name)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.major_version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.minor_version)); } if (flags & NDR_OUT) { + if (r->out.log_handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.log_handle)); NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -856,9 +941,53 @@ static enum ndr_err_code ndr_push_eventlog_RegisterEventSourceW(struct ndr_push static enum ndr_err_code ndr_pull_eventlog_RegisterEventSourceW(struct ndr_pull *ndr, int flags, struct eventlog_RegisterEventSourceW *r) { + uint32_t _ptr_unknown0; + TALLOC_CTX *_mem_save_unknown0_0; + TALLOC_CTX *_mem_save_module_name_0; + TALLOC_CTX *_mem_save_reg_module_name_0; + TALLOC_CTX *_mem_save_log_handle_0; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown0)); + if (_ptr_unknown0) { + NDR_PULL_ALLOC(ndr, r->in.unknown0); + } else { + r->in.unknown0 = NULL; + } + if (r->in.unknown0) { + _mem_save_unknown0_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown0, 0); + NDR_CHECK(ndr_pull_eventlog_OpenUnknown0(ndr, NDR_SCALARS, r->in.unknown0)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown0_0, 0); + } + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.module_name); + } + _mem_save_module_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.module_name, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.module_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_module_name_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.reg_module_name); + } + _mem_save_reg_module_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.reg_module_name, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.reg_module_name)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_reg_module_name_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.major_version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.minor_version)); + NDR_PULL_ALLOC(ndr, r->out.log_handle); + ZERO_STRUCTP(r->out.log_handle); } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.log_handle); + } + _mem_save_log_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.log_handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.log_handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_log_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -874,11 +1003,31 @@ _PUBLIC_ void ndr_print_eventlog_RegisterEventSourceW(struct ndr_print *ndr, con if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "eventlog_RegisterEventSourceW"); ndr->depth++; + ndr_print_ptr(ndr, "unknown0", r->in.unknown0); + ndr->depth++; + if (r->in.unknown0) { + ndr_print_eventlog_OpenUnknown0(ndr, "unknown0", r->in.unknown0); + } + ndr->depth--; + ndr_print_ptr(ndr, "module_name", r->in.module_name); + ndr->depth++; + ndr_print_lsa_String(ndr, "module_name", r->in.module_name); + ndr->depth--; + ndr_print_ptr(ndr, "reg_module_name", r->in.reg_module_name); + ndr->depth++; + ndr_print_lsa_String(ndr, "reg_module_name", r->in.reg_module_name); + ndr->depth--; + ndr_print_uint32(ndr, "major_version", r->in.major_version); + ndr_print_uint32(ndr, "minor_version", r->in.minor_version); ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "eventlog_RegisterEventSourceW"); ndr->depth++; + ndr_print_ptr(ndr, "log_handle", r->out.log_handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "log_handle", r->out.log_handle); + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } @@ -888,8 +1037,22 @@ _PUBLIC_ void ndr_print_eventlog_RegisterEventSourceW(struct ndr_print *ndr, con static enum ndr_err_code ndr_push_eventlog_OpenBackupEventLogW(struct ndr_push *ndr, int flags, const struct eventlog_OpenBackupEventLogW *r) { if (flags & NDR_IN) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.unknown0)); + if (r->in.unknown0) { + NDR_CHECK(ndr_push_eventlog_OpenUnknown0(ndr, NDR_SCALARS, r->in.unknown0)); + } + if (r->in.backup_logname == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.backup_logname)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.major_version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.minor_version)); } if (flags & NDR_OUT) { + if (r->out.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.handle)); NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -897,9 +1060,45 @@ static enum ndr_err_code ndr_push_eventlog_OpenBackupEventLogW(struct ndr_push * static enum ndr_err_code ndr_pull_eventlog_OpenBackupEventLogW(struct ndr_pull *ndr, int flags, struct eventlog_OpenBackupEventLogW *r) { + uint32_t _ptr_unknown0; + TALLOC_CTX *_mem_save_unknown0_0; + TALLOC_CTX *_mem_save_backup_logname_0; + TALLOC_CTX *_mem_save_handle_0; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown0)); + if (_ptr_unknown0) { + NDR_PULL_ALLOC(ndr, r->in.unknown0); + } else { + r->in.unknown0 = NULL; + } + if (r->in.unknown0) { + _mem_save_unknown0_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown0, 0); + NDR_CHECK(ndr_pull_eventlog_OpenUnknown0(ndr, NDR_SCALARS, r->in.unknown0)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown0_0, 0); + } + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.backup_logname); + } + _mem_save_backup_logname_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.backup_logname, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.backup_logname)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_backup_logname_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.major_version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.minor_version)); + NDR_PULL_ALLOC(ndr, r->out.handle); + ZERO_STRUCTP(r->out.handle); } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -915,11 +1114,27 @@ _PUBLIC_ void ndr_print_eventlog_OpenBackupEventLogW(struct ndr_print *ndr, cons if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "eventlog_OpenBackupEventLogW"); ndr->depth++; + ndr_print_ptr(ndr, "unknown0", r->in.unknown0); + ndr->depth++; + if (r->in.unknown0) { + ndr_print_eventlog_OpenUnknown0(ndr, "unknown0", r->in.unknown0); + } + ndr->depth--; + ndr_print_ptr(ndr, "backup_logname", r->in.backup_logname); + ndr->depth++; + ndr_print_lsa_String(ndr, "backup_logname", r->in.backup_logname); + ndr->depth--; + ndr_print_uint32(ndr, "major_version", r->in.major_version); + ndr_print_uint32(ndr, "minor_version", r->in.minor_version); ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "eventlog_OpenBackupEventLogW"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->out.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->out.handle); + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } @@ -1054,9 +1269,62 @@ _PUBLIC_ void ndr_print_eventlog_ReadEventLogW(struct ndr_print *ndr, const char static enum ndr_err_code ndr_push_eventlog_ReportEventW(struct ndr_push *ndr, int flags, const struct eventlog_ReportEventW *r) { + uint32_t cntr_strings_1; 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_time_t(ndr, NDR_SCALARS, r->in.timestamp)); + NDR_CHECK(ndr_push_eventlogEventTypes(ndr, NDR_SCALARS, r->in.event_type)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.event_category)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.event_id)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.num_of_strings)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.data_size)); + if (r->in.servername == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.user_sid)); + if (r->in.user_sid) { + NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, r->in.user_sid)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.strings)); + if (r->in.strings) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.num_of_strings)); + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + } + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.strings[cntr_strings_1])); + if (r->in.strings[cntr_strings_1]) { + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.strings[cntr_strings_1])); + } + } + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.data)); + if (r->in.data) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.data_size)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->in.data, r->in.data_size)); + } + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.flags)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.record_number)); + if (r->in.record_number) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.record_number)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.time_written)); + if (r->in.time_written) { + NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, *r->in.time_written)); + } } if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.record_number)); + if (r->out.record_number) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.record_number)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.time_written)); + if (r->out.time_written) { + NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, *r->out.time_written)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -1064,9 +1332,165 @@ static enum ndr_err_code ndr_push_eventlog_ReportEventW(struct ndr_push *ndr, in static enum ndr_err_code ndr_pull_eventlog_ReportEventW(struct ndr_pull *ndr, int flags, struct eventlog_ReportEventW *r) { + uint32_t _ptr_user_sid; + uint32_t _ptr_strings; + uint32_t cntr_strings_1; + uint32_t _ptr_data; + uint32_t _ptr_record_number; + uint32_t _ptr_time_written; + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_servername_0; + TALLOC_CTX *_mem_save_user_sid_0; + TALLOC_CTX *_mem_save_strings_0; + TALLOC_CTX *_mem_save_strings_1; + TALLOC_CTX *_mem_save_strings_2; + TALLOC_CTX *_mem_save_data_0; + TALLOC_CTX *_mem_save_record_number_0; + TALLOC_CTX *_mem_save_time_written_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_time_t(ndr, NDR_SCALARS, &r->in.timestamp)); + NDR_CHECK(ndr_pull_eventlogEventTypes(ndr, NDR_SCALARS, &r->in.event_type)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.event_category)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.event_id)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.num_of_strings)); + if (r->in.num_of_strings > 256) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.data_size)); + if (r->in.data_size > 0x3FFFF) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.servername); + } + _mem_save_servername_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.servername, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_servername_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_sid)); + if (_ptr_user_sid) { + NDR_PULL_ALLOC(ndr, r->in.user_sid); + } else { + r->in.user_sid = NULL; + } + if (r->in.user_sid) { + _mem_save_user_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.user_sid, 0); + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->in.user_sid)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_sid_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_strings)); + if (_ptr_strings) { + NDR_PULL_ALLOC(ndr, r->in.strings); + } else { + r->in.strings = NULL; + } + if (r->in.strings) { + _mem_save_strings_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.strings, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.strings)); + NDR_PULL_ALLOC_N(ndr, r->in.strings, ndr_get_array_size(ndr, &r->in.strings)); + _mem_save_strings_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.strings, 0); + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + } + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_strings)); + if (_ptr_strings) { + NDR_PULL_ALLOC(ndr, r->in.strings[cntr_strings_1]); + } else { + r->in.strings[cntr_strings_1] = NULL; + } + if (r->in.strings[cntr_strings_1]) { + _mem_save_strings_2 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.strings[cntr_strings_1], 0); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.strings[cntr_strings_1])); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_2, 0); + } + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); + if (_ptr_data) { + NDR_PULL_ALLOC(ndr, r->in.data); + } else { + r->in.data = NULL; + } + if (r->in.data) { + _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.data, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.data)); + NDR_PULL_ALLOC_N(ndr, r->in.data, ndr_get_array_size(ndr, &r->in.data)); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->in.data, ndr_get_array_size(ndr, &r->in.data))); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0); + } + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.flags)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_record_number)); + if (_ptr_record_number) { + NDR_PULL_ALLOC(ndr, r->in.record_number); + } else { + r->in.record_number = NULL; + } + if (r->in.record_number) { + _mem_save_record_number_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.record_number, 0); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.record_number)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_record_number_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_time_written)); + if (_ptr_time_written) { + NDR_PULL_ALLOC(ndr, r->in.time_written); + } else { + r->in.time_written = NULL; + } + if (r->in.time_written) { + _mem_save_time_written_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.time_written, 0); + NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, r->in.time_written)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_time_written_0, 0); + } + if (r->in.strings) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.strings, r->in.num_of_strings)); + } + if (r->in.data) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.data, r->in.data_size)); + } } if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_record_number)); + if (_ptr_record_number) { + NDR_PULL_ALLOC(ndr, r->out.record_number); + } else { + r->out.record_number = NULL; + } + if (r->out.record_number) { + _mem_save_record_number_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.record_number, 0); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.record_number)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_record_number_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_time_written)); + if (_ptr_time_written) { + NDR_PULL_ALLOC(ndr, r->out.time_written); + } else { + r->out.time_written = NULL; + } + if (r->out.time_written) { + _mem_save_time_written_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.time_written, 0); + NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, r->out.time_written)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_time_written_0, 0); + } NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -1074,6 +1498,7 @@ static enum ndr_err_code ndr_pull_eventlog_ReportEventW(struct ndr_pull *ndr, in _PUBLIC_ void ndr_print_eventlog_ReportEventW(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_ReportEventW *r) { + uint32_t cntr_strings_1; ndr_print_struct(ndr, name, "eventlog_ReportEventW"); ndr->depth++; if (flags & NDR_SET_VALUES) { @@ -1082,11 +1507,82 @@ _PUBLIC_ void ndr_print_eventlog_ReportEventW(struct ndr_print *ndr, const char if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "eventlog_ReportEventW"); 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_time_t(ndr, "timestamp", r->in.timestamp); + ndr_print_eventlogEventTypes(ndr, "event_type", r->in.event_type); + ndr_print_uint16(ndr, "event_category", r->in.event_category); + ndr_print_uint32(ndr, "event_id", r->in.event_id); + ndr_print_uint16(ndr, "num_of_strings", r->in.num_of_strings); + ndr_print_uint32(ndr, "data_size", r->in.data_size); + ndr_print_ptr(ndr, "servername", r->in.servername); + ndr->depth++; + ndr_print_lsa_String(ndr, "servername", r->in.servername); + ndr->depth--; + ndr_print_ptr(ndr, "user_sid", r->in.user_sid); + ndr->depth++; + if (r->in.user_sid) { + ndr_print_dom_sid(ndr, "user_sid", r->in.user_sid); + } + ndr->depth--; + ndr_print_ptr(ndr, "strings", r->in.strings); + ndr->depth++; + if (r->in.strings) { + ndr->print(ndr, "%s: ARRAY(%d)", "strings", (int)r->in.num_of_strings); + ndr->depth++; + for (cntr_strings_1=0;cntr_strings_1in.num_of_strings;cntr_strings_1++) { + char *idx_1=NULL; + if (asprintf(&idx_1, "[%d]", cntr_strings_1) != -1) { + ndr_print_ptr(ndr, "strings", r->in.strings[cntr_strings_1]); + ndr->depth++; + if (r->in.strings[cntr_strings_1]) { + ndr_print_lsa_String(ndr, "strings", r->in.strings[cntr_strings_1]); + } + ndr->depth--; + free(idx_1); + } + } + ndr->depth--; + } + ndr->depth--; + ndr_print_ptr(ndr, "data", r->in.data); + ndr->depth++; + if (r->in.data) { + ndr_print_array_uint8(ndr, "data", r->in.data, r->in.data_size); + } + ndr->depth--; + ndr_print_uint16(ndr, "flags", r->in.flags); + ndr_print_ptr(ndr, "record_number", r->in.record_number); + ndr->depth++; + if (r->in.record_number) { + ndr_print_uint32(ndr, "record_number", *r->in.record_number); + } + ndr->depth--; + ndr_print_ptr(ndr, "time_written", r->in.time_written); + ndr->depth++; + if (r->in.time_written) { + ndr_print_time_t(ndr, "time_written", *r->in.time_written); + } + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "eventlog_ReportEventW"); ndr->depth++; + ndr_print_ptr(ndr, "record_number", r->out.record_number); + ndr->depth++; + if (r->out.record_number) { + ndr_print_uint32(ndr, "record_number", *r->out.record_number); + } + ndr->depth--; + ndr_print_ptr(ndr, "time_written", r->out.time_written); + ndr->depth++; + if (r->out.time_written) { + ndr_print_time_t(ndr, "time_written", *r->out.time_written); + } + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } @@ -1506,8 +2002,23 @@ _PUBLIC_ void ndr_print_eventlog_WriteClusterEvents(struct ndr_print *ndr, const static enum ndr_err_code ndr_push_eventlog_GetLogIntormation(struct ndr_push *ndr, int flags, const struct eventlog_GetLogIntormation *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.level)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); } if (flags & NDR_OUT) { + if (r->out.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); + if (r->out.bytes_needed == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.bytes_needed)); NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -1515,10 +2026,45 @@ static enum ndr_err_code ndr_push_eventlog_GetLogIntormation(struct ndr_push *nd static enum ndr_err_code ndr_pull_eventlog_GetLogIntormation(struct ndr_pull *ndr, int flags, struct eventlog_GetLogIntormation *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_bytes_needed_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.level)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); + if (r->in.buf_size > 1024) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); + memset(CONST_DISCARD(struct eventlog_GetLogIntormation *,r->out.buffer), 0, (r->in.buf_size) * sizeof(*r->out.buffer)); + NDR_PULL_ALLOC(ndr, r->out.bytes_needed); + ZERO_STRUCTP(r->out.bytes_needed); } if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer))); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.bytes_needed); + } + _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -1533,11 +2079,25 @@ _PUBLIC_ void ndr_print_eventlog_GetLogIntormation(struct ndr_print *ndr, const if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "eventlog_GetLogIntormation"); 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, "level", r->in.level); + ndr_print_uint32(ndr, "buf_size", r->in.buf_size); ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "eventlog_GetLogIntormation"); ndr->depth++; + ndr_print_ptr(ndr, "buffer", r->out.buffer); + ndr->depth++; + ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size); + ndr->depth--; + ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); + ndr->depth++; + ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } @@ -1601,6 +2161,344 @@ _PUBLIC_ void ndr_print_eventlog_FlushEventLog(struct ndr_print *ndr, const char ndr->depth--; } +static enum ndr_err_code ndr_push_eventlog_ReportEventAndSourceW(struct ndr_push *ndr, int flags, const struct eventlog_ReportEventAndSourceW *r) +{ + uint32_t cntr_strings_1; + 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_time_t(ndr, NDR_SCALARS, r->in.timestamp)); + NDR_CHECK(ndr_push_eventlogEventTypes(ndr, NDR_SCALARS, r->in.event_type)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.event_category)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.event_id)); + if (r->in.sourcename == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sourcename)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.num_of_strings)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.data_size)); + if (r->in.servername == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.user_sid)); + if (r->in.user_sid) { + NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, r->in.user_sid)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.strings)); + if (r->in.strings) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.num_of_strings)); + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + } + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.strings[cntr_strings_1])); + if (r->in.strings[cntr_strings_1]) { + NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.strings[cntr_strings_1])); + } + } + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.data)); + if (r->in.data) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.data_size)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->in.data, r->in.data_size)); + } + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.flags)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.record_number)); + if (r->in.record_number) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.record_number)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.time_written)); + if (r->in.time_written) { + NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, *r->in.time_written)); + } + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.record_number)); + if (r->out.record_number) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.record_number)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.time_written)); + if (r->out.time_written) { + NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, *r->out.time_written)); + } + NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_eventlog_ReportEventAndSourceW(struct ndr_pull *ndr, int flags, struct eventlog_ReportEventAndSourceW *r) +{ + uint32_t _ptr_user_sid; + uint32_t _ptr_strings; + uint32_t cntr_strings_1; + uint32_t _ptr_data; + uint32_t _ptr_record_number; + uint32_t _ptr_time_written; + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_sourcename_0; + TALLOC_CTX *_mem_save_servername_0; + TALLOC_CTX *_mem_save_user_sid_0; + TALLOC_CTX *_mem_save_strings_0; + TALLOC_CTX *_mem_save_strings_1; + TALLOC_CTX *_mem_save_strings_2; + TALLOC_CTX *_mem_save_data_0; + TALLOC_CTX *_mem_save_record_number_0; + TALLOC_CTX *_mem_save_time_written_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_time_t(ndr, NDR_SCALARS, &r->in.timestamp)); + NDR_CHECK(ndr_pull_eventlogEventTypes(ndr, NDR_SCALARS, &r->in.event_type)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.event_category)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.event_id)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.sourcename); + } + _mem_save_sourcename_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.sourcename, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sourcename)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sourcename_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.num_of_strings)); + if (r->in.num_of_strings > 256) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.data_size)); + if (r->in.data_size > 0x3FFFF) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.servername); + } + _mem_save_servername_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.servername, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_servername_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_user_sid)); + if (_ptr_user_sid) { + NDR_PULL_ALLOC(ndr, r->in.user_sid); + } else { + r->in.user_sid = NULL; + } + if (r->in.user_sid) { + _mem_save_user_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.user_sid, 0); + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->in.user_sid)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_user_sid_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_strings)); + if (_ptr_strings) { + NDR_PULL_ALLOC(ndr, r->in.strings); + } else { + r->in.strings = NULL; + } + if (r->in.strings) { + _mem_save_strings_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.strings, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.strings)); + NDR_PULL_ALLOC_N(ndr, r->in.strings, ndr_get_array_size(ndr, &r->in.strings)); + _mem_save_strings_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.strings, 0); + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + } + for (cntr_strings_1 = 0; cntr_strings_1 < r->in.num_of_strings; cntr_strings_1++) { + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_strings)); + if (_ptr_strings) { + NDR_PULL_ALLOC(ndr, r->in.strings[cntr_strings_1]); + } else { + r->in.strings[cntr_strings_1] = NULL; + } + if (r->in.strings[cntr_strings_1]) { + _mem_save_strings_2 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.strings[cntr_strings_1], 0); + NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.strings[cntr_strings_1])); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_2, 0); + } + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_strings_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_data)); + if (_ptr_data) { + NDR_PULL_ALLOC(ndr, r->in.data); + } else { + r->in.data = NULL; + } + if (r->in.data) { + _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.data, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.data)); + NDR_PULL_ALLOC_N(ndr, r->in.data, ndr_get_array_size(ndr, &r->in.data)); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->in.data, ndr_get_array_size(ndr, &r->in.data))); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, 0); + } + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.flags)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_record_number)); + if (_ptr_record_number) { + NDR_PULL_ALLOC(ndr, r->in.record_number); + } else { + r->in.record_number = NULL; + } + if (r->in.record_number) { + _mem_save_record_number_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.record_number, 0); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.record_number)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_record_number_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_time_written)); + if (_ptr_time_written) { + NDR_PULL_ALLOC(ndr, r->in.time_written); + } else { + r->in.time_written = NULL; + } + if (r->in.time_written) { + _mem_save_time_written_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.time_written, 0); + NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, r->in.time_written)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_time_written_0, 0); + } + if (r->in.strings) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.strings, r->in.num_of_strings)); + } + if (r->in.data) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.data, r->in.data_size)); + } + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_record_number)); + if (_ptr_record_number) { + NDR_PULL_ALLOC(ndr, r->out.record_number); + } else { + r->out.record_number = NULL; + } + if (r->out.record_number) { + _mem_save_record_number_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.record_number, 0); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.record_number)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_record_number_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_time_written)); + if (_ptr_time_written) { + NDR_PULL_ALLOC(ndr, r->out.time_written); + } else { + r->out.time_written = NULL; + } + if (r->out.time_written) { + _mem_save_time_written_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.time_written, 0); + NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, r->out.time_written)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_time_written_0, 0); + } + NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_eventlog_ReportEventAndSourceW(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_ReportEventAndSourceW *r) +{ + uint32_t cntr_strings_1; + ndr_print_struct(ndr, name, "eventlog_ReportEventAndSourceW"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "eventlog_ReportEventAndSourceW"); + 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_time_t(ndr, "timestamp", r->in.timestamp); + ndr_print_eventlogEventTypes(ndr, "event_type", r->in.event_type); + ndr_print_uint16(ndr, "event_category", r->in.event_category); + ndr_print_uint32(ndr, "event_id", r->in.event_id); + ndr_print_ptr(ndr, "sourcename", r->in.sourcename); + ndr->depth++; + ndr_print_lsa_String(ndr, "sourcename", r->in.sourcename); + ndr->depth--; + ndr_print_uint16(ndr, "num_of_strings", r->in.num_of_strings); + ndr_print_uint32(ndr, "data_size", r->in.data_size); + ndr_print_ptr(ndr, "servername", r->in.servername); + ndr->depth++; + ndr_print_lsa_String(ndr, "servername", r->in.servername); + ndr->depth--; + ndr_print_ptr(ndr, "user_sid", r->in.user_sid); + ndr->depth++; + if (r->in.user_sid) { + ndr_print_dom_sid(ndr, "user_sid", r->in.user_sid); + } + ndr->depth--; + ndr_print_ptr(ndr, "strings", r->in.strings); + ndr->depth++; + if (r->in.strings) { + ndr->print(ndr, "%s: ARRAY(%d)", "strings", (int)r->in.num_of_strings); + ndr->depth++; + for (cntr_strings_1=0;cntr_strings_1in.num_of_strings;cntr_strings_1++) { + char *idx_1=NULL; + if (asprintf(&idx_1, "[%d]", cntr_strings_1) != -1) { + ndr_print_ptr(ndr, "strings", r->in.strings[cntr_strings_1]); + ndr->depth++; + if (r->in.strings[cntr_strings_1]) { + ndr_print_lsa_String(ndr, "strings", r->in.strings[cntr_strings_1]); + } + ndr->depth--; + free(idx_1); + } + } + ndr->depth--; + } + ndr->depth--; + ndr_print_ptr(ndr, "data", r->in.data); + ndr->depth++; + if (r->in.data) { + ndr_print_array_uint8(ndr, "data", r->in.data, r->in.data_size); + } + ndr->depth--; + ndr_print_uint16(ndr, "flags", r->in.flags); + ndr_print_ptr(ndr, "record_number", r->in.record_number); + ndr->depth++; + if (r->in.record_number) { + ndr_print_uint32(ndr, "record_number", *r->in.record_number); + } + ndr->depth--; + ndr_print_ptr(ndr, "time_written", r->in.time_written); + ndr->depth++; + if (r->in.time_written) { + ndr_print_time_t(ndr, "time_written", *r->in.time_written); + } + ndr->depth--; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "eventlog_ReportEventAndSourceW"); + ndr->depth++; + ndr_print_ptr(ndr, "record_number", r->out.record_number); + ndr->depth++; + if (r->out.record_number) { + ndr_print_uint32(ndr, "record_number", *r->out.record_number); + } + ndr->depth--; + ndr_print_ptr(ndr, "time_written", r->out.time_written); + ndr->depth++; + if (r->out.time_written) { + ndr_print_time_t(ndr, "time_written", *r->out.time_written); + } + ndr->depth--; + ndr_print_NTSTATUS(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + static const struct ndr_interface_call eventlog_calls[] = { { "eventlog_ClearEventLogW", @@ -1794,6 +2692,14 @@ static const struct ndr_interface_call eventlog_calls[] = { (ndr_print_function_t) ndr_print_eventlog_FlushEventLog, false, }, + { + "eventlog_ReportEventAndSourceW", + sizeof(struct eventlog_ReportEventAndSourceW), + (ndr_push_flags_fn_t) ndr_push_eventlog_ReportEventAndSourceW, + (ndr_pull_flags_fn_t) ndr_pull_eventlog_ReportEventAndSourceW, + (ndr_print_function_t) ndr_print_eventlog_ReportEventAndSourceW, + false, + }, { NULL, 0, NULL, NULL, NULL, false } }; @@ -1823,7 +2729,7 @@ const struct ndr_interface_table ndr_table_eventlog = { NDR_EVENTLOG_VERSION }, .helpstring = NDR_EVENTLOG_HELPSTRING, - .num_calls = 24, + .num_calls = 25, .calls = eventlog_calls, .endpoints = &eventlog_endpoints, .authservices = &eventlog_authservices diff --git a/librpc/gen_ndr/ndr_eventlog.h b/librpc/gen_ndr/ndr_eventlog.h index f63fa9e569..3fa20e3a29 100644 --- a/librpc/gen_ndr/ndr_eventlog.h +++ b/librpc/gen_ndr/ndr_eventlog.h @@ -59,7 +59,9 @@ extern const struct ndr_interface_table ndr_table_eventlog; #define NDR_EVENTLOG_FLUSHEVENTLOG (0x17) -#define NDR_EVENTLOG_CALL_COUNT (24) +#define NDR_EVENTLOG_REPORTEVENTANDSOURCEW (0x18) + +#define NDR_EVENTLOG_CALL_COUNT (25) void ndr_print_eventlogReadFlags(struct ndr_print *ndr, const char *name, uint32_t r); enum ndr_err_code ndr_push_eventlogEventTypes(struct ndr_push *ndr, int ndr_flags, enum eventlogEventTypes r); enum ndr_err_code ndr_pull_eventlogEventTypes(struct ndr_pull *ndr, int ndr_flags, enum eventlogEventTypes *r); @@ -92,4 +94,5 @@ void ndr_print_eventlog_DeregisterClusterSvc(struct ndr_print *ndr, const char * void ndr_print_eventlog_WriteClusterEvents(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_WriteClusterEvents *r); void ndr_print_eventlog_GetLogIntormation(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_GetLogIntormation *r); void ndr_print_eventlog_FlushEventLog(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_FlushEventLog *r); +void ndr_print_eventlog_ReportEventAndSourceW(struct ndr_print *ndr, const char *name, int flags, const struct eventlog_ReportEventAndSourceW *r); #endif /* _HEADER_NDR_eventlog */ diff --git a/librpc/gen_ndr/srv_eventlog.c b/librpc/gen_ndr/srv_eventlog.c index 73c536d50f..795afc9a5a 100644 --- a/librpc/gen_ndr/srv_eventlog.c +++ b/librpc/gen_ndr/srv_eventlog.c @@ -265,6 +265,8 @@ static bool api_eventlog_DeregisterEventSource(pipes_struct *p) NDR_PRINT_IN_DEBUG(eventlog_DeregisterEventSource, r); } + ZERO_STRUCT(r->out); + r->out.handle = r->in.handle; r->out.result = _eventlog_DeregisterEventSource(p, r); if (p->rng_fault_state) { @@ -651,6 +653,13 @@ static bool api_eventlog_RegisterEventSourceW(pipes_struct *p) NDR_PRINT_IN_DEBUG(eventlog_RegisterEventSourceW, r); } + ZERO_STRUCT(r->out); + r->out.log_handle = talloc_zero(r, struct policy_handle); + if (r->out.log_handle == NULL) { + talloc_free(r); + return false; + } + r->out.result = _eventlog_RegisterEventSourceW(p, r); if (p->rng_fault_state) { @@ -724,6 +733,13 @@ static bool api_eventlog_OpenBackupEventLogW(pipes_struct *p) NDR_PRINT_IN_DEBUG(eventlog_OpenBackupEventLogW, r); } + ZERO_STRUCT(r->out); + r->out.handle = talloc_zero(r, struct policy_handle); + if (r->out.handle == NULL) { + talloc_free(r); + return false; + } + r->out.result = _eventlog_OpenBackupEventLogW(p, r); if (p->rng_fault_state) { @@ -889,6 +905,9 @@ static bool api_eventlog_ReportEventW(pipes_struct *p) NDR_PRINT_IN_DEBUG(eventlog_ReportEventW, r); } + ZERO_STRUCT(r->out); + r->out.record_number = r->in.record_number; + r->out.time_written = r->in.time_written; r->out.result = _eventlog_ReportEventW(p, r); if (p->rng_fault_state) { @@ -1692,6 +1711,19 @@ static bool api_eventlog_GetLogIntormation(pipes_struct *p) NDR_PRINT_IN_DEBUG(eventlog_GetLogIntormation, r); } + ZERO_STRUCT(r->out); + r->out.buffer = talloc_zero_array(r, uint8_t, r->in.buf_size); + if (r->out.buffer == NULL) { + talloc_free(r); + return false; + } + + r->out.bytes_needed = talloc_zero(r, uint32_t); + if (r->out.bytes_needed == NULL) { + talloc_free(r); + return false; + } + r->out.result = _eventlog_GetLogIntormation(p, r); if (p->rng_fault_state) { @@ -1800,6 +1832,82 @@ static bool api_eventlog_FlushEventLog(pipes_struct *p) return true; } +static bool api_eventlog_ReportEventAndSourceW(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 eventlog_ReportEventAndSourceW *r; + + call = &ndr_table_eventlog.calls[NDR_EVENTLOG_REPORTEVENTANDSOURCEW]; + + r = talloc(talloc_tos(), struct eventlog_ReportEventAndSourceW); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r, NULL); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(eventlog_ReportEventAndSourceW, r); + } + + ZERO_STRUCT(r->out); + r->out.record_number = r->in.record_number; + r->out.time_written = r->in.time_written; + r->out.result = _eventlog_ReportEventAndSourceW(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(eventlog_ReportEventAndSourceW, r); + } + + push = ndr_push_init_ctx(r, NULL); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + /* Tables */ static struct api_struct api_eventlog_cmds[] = @@ -1828,6 +1936,7 @@ static struct api_struct api_eventlog_cmds[] = {"EVENTLOG_WRITECLUSTEREVENTS", NDR_EVENTLOG_WRITECLUSTEREVENTS, api_eventlog_WriteClusterEvents}, {"EVENTLOG_GETLOGINTORMATION", NDR_EVENTLOG_GETLOGINTORMATION, api_eventlog_GetLogIntormation}, {"EVENTLOG_FLUSHEVENTLOG", NDR_EVENTLOG_FLUSHEVENTLOG, api_eventlog_FlushEventLog}, + {"EVENTLOG_REPORTEVENTANDSOURCEW", NDR_EVENTLOG_REPORTEVENTANDSOURCEW, api_eventlog_ReportEventAndSourceW}, }; void eventlog_get_pipe_fns(struct api_struct **fns, int *n_fns) @@ -1866,6 +1975,8 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_EVENTLOG_DEREGISTEREVENTSOURCE: { struct eventlog_DeregisterEventSource *r = (struct eventlog_DeregisterEventSource *)_r; + ZERO_STRUCT(r->out); + r->out.handle = r->in.handle; r->out.result = _eventlog_DeregisterEventSource(cli->pipes_struct, r); return NT_STATUS_OK; } @@ -1914,12 +2025,24 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_EVENTLOG_REGISTEREVENTSOURCEW: { struct eventlog_RegisterEventSourceW *r = (struct eventlog_RegisterEventSourceW *)_r; + ZERO_STRUCT(r->out); + r->out.log_handle = talloc_zero(mem_ctx, struct policy_handle); + if (r->out.log_handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + r->out.result = _eventlog_RegisterEventSourceW(cli->pipes_struct, r); return NT_STATUS_OK; } case NDR_EVENTLOG_OPENBACKUPEVENTLOGW: { struct eventlog_OpenBackupEventLogW *r = (struct eventlog_OpenBackupEventLogW *)_r; + ZERO_STRUCT(r->out); + r->out.handle = talloc_zero(mem_ctx, struct policy_handle); + if (r->out.handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + r->out.result = _eventlog_OpenBackupEventLogW(cli->pipes_struct, r); return NT_STATUS_OK; } @@ -1948,6 +2071,9 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_EVENTLOG_REPORTEVENTW: { struct eventlog_ReportEventW *r = (struct eventlog_ReportEventW *)_r; + ZERO_STRUCT(r->out); + r->out.record_number = r->in.record_number; + r->out.time_written = r->in.time_written; r->out.result = _eventlog_ReportEventW(cli->pipes_struct, r); return NT_STATUS_OK; } @@ -2014,6 +2140,17 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, case NDR_EVENTLOG_GETLOGINTORMATION: { struct eventlog_GetLogIntormation *r = (struct eventlog_GetLogIntormation *)_r; + ZERO_STRUCT(r->out); + r->out.buffer = talloc_zero_array(mem_ctx, uint8_t, r->in.buf_size); + if (r->out.buffer == NULL) { + return NT_STATUS_NO_MEMORY; + } + + r->out.bytes_needed = talloc_zero(mem_ctx, uint32_t); + if (r->out.bytes_needed == NULL) { + return NT_STATUS_NO_MEMORY; + } + r->out.result = _eventlog_GetLogIntormation(cli->pipes_struct, r); return NT_STATUS_OK; } @@ -2024,6 +2161,15 @@ NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } + case NDR_EVENTLOG_REPORTEVENTANDSOURCEW: { + struct eventlog_ReportEventAndSourceW *r = (struct eventlog_ReportEventAndSourceW *)_r; + ZERO_STRUCT(r->out); + r->out.record_number = r->in.record_number; + r->out.time_written = r->in.time_written; + r->out.result = _eventlog_ReportEventAndSourceW(cli->pipes_struct, r); + return NT_STATUS_OK; + } + default: return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/librpc/gen_ndr/srv_eventlog.h b/librpc/gen_ndr/srv_eventlog.h index c540f92242..11d6886a24 100644 --- a/librpc/gen_ndr/srv_eventlog.h +++ b/librpc/gen_ndr/srv_eventlog.h @@ -25,6 +25,7 @@ NTSTATUS _eventlog_DeregisterClusterSvc(pipes_struct *p, struct eventlog_Deregis NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClusterEvents *r); NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r); NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog *r); +NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r); void eventlog_get_pipe_fns(struct api_struct **fns, int *n_fns); NTSTATUS rpc_eventlog_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r); NTSTATUS _eventlog_ClearEventLogW(pipes_struct *p, struct eventlog_ClearEventLogW *r); @@ -51,5 +52,6 @@ NTSTATUS _eventlog_DeregisterClusterSvc(pipes_struct *p, struct eventlog_Deregis NTSTATUS _eventlog_WriteClusterEvents(pipes_struct *p, struct eventlog_WriteClusterEvents *r); NTSTATUS _eventlog_GetLogIntormation(pipes_struct *p, struct eventlog_GetLogIntormation *r); NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog *r); +NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r); NTSTATUS rpc_eventlog_init(void); #endif /* __SRV_EVENTLOG__ */ -- cgit From 9629897094fe11a7a50011e555efc8905c90dbf4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 22 Jan 2009 19:35:33 +0100 Subject: s3-eventlog: add missing _eventlog_ReportEventAndSourceW stub call. Guenther --- source3/rpc_server/srv_eventlog_nt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 5f9df1ba81..a687025ba6 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -956,3 +956,8 @@ NTSTATUS _eventlog_FlushEventLog(pipes_struct *p, struct eventlog_FlushEventLog return NT_STATUS_NOT_IMPLEMENTED; } +NTSTATUS _eventlog_ReportEventAndSourceW(pipes_struct *p, struct eventlog_ReportEventAndSourceW *r) +{ + p->rng_fault_state = True; + return NT_STATUS_NOT_IMPLEMENTED; +} -- cgit From a6131f2a8b662ef8acca15d772f3079426f07a48 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 18:42:47 +0100 Subject: s4-smbtorture: add ReportEventW test. Guenther --- source4/torture/rpc/eventlog.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index 245dda1978..5da205bcde 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -180,6 +180,55 @@ static bool test_ReadEventLog(struct torture_context *tctx, return true; } +static bool test_ReportEventLog(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + NTSTATUS status; + struct eventlog_ReportEventW r; + struct eventlog_CloseEventLog cr; + struct policy_handle handle; + + uint32_t record_number = 0; + time_t time_written = 0; + struct lsa_String servername, *strings; + + if (!get_policy_handle(tctx, p, &handle)) + return false; + + init_lsa_String(&servername, NULL); + + strings = talloc_array(tctx, struct lsa_String, 1); + init_lsa_String(&strings[0], "Currently tortured by samba 4"); + + ZERO_STRUCT(r); + + r.in.handle = &handle; + r.in.timestamp = time(NULL); + r.in.event_type = EVENTLOG_INFORMATION_TYPE; + r.in.event_category = 0; + r.in.event_id = 0; + r.in.num_of_strings = 1; + r.in.data_size = 0; + r.in.servername = &servername; + r.in.user_sid = NULL; + r.in.strings = &strings; + r.in.data = NULL; + r.in.flags = 0; + r.out.record_number = &record_number; + r.out.time_written = &time_written; + + status = dcerpc_eventlog_ReportEventW(p, tctx, &r); + + torture_assert_ntstatus_ok(tctx, r.out.result, "ReportEventW failed"); + + cr.in.handle = cr.out.handle = &handle; + + torture_assert_ntstatus_ok(tctx, + dcerpc_eventlog_CloseEventLog(p, tctx, &cr), + "CloseEventLog failed"); + return true; +} + static bool test_FlushEventLog(struct torture_context *tctx, struct dcerpc_pipe *p) { @@ -267,6 +316,7 @@ struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx) test->dangerous = true; torture_rpc_tcase_add_test(tcase, "GetNumRecords", test_GetNumRecords); torture_rpc_tcase_add_test(tcase, "ReadEventLog", test_ReadEventLog); + torture_rpc_tcase_add_test(tcase, "ReportEventLog", test_ReportEventLog); torture_rpc_tcase_add_test(tcase, "FlushEventLog", test_FlushEventLog); return suite; -- cgit From f1067c0ffcf00286332d44da54e2fbde40cc03df Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 19:09:53 +0100 Subject: s3-rpcclient: add eventlog_reportevent command. Guenther --- source3/rpcclient/cmd_eventlog.c | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index a8373f466d..2e1df623fa 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -197,10 +197,75 @@ static NTSTATUS cmd_eventlog_oldestrecord(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_eventlog_reportevent(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + + uint16_t num_of_strings = 1; + uint32_t data_size = 0; + struct lsa_String servername; + struct lsa_String *strings; + uint8_t *data = NULL; + uint32_t record_number = 0; + time_t time_written = 0; + + if (argc != 2) { + printf("Usage: %s logname\n", argv[0]); + return NT_STATUS_OK; + } + + status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings); + if (!strings) { + return NT_STATUS_NO_MEMORY; + } + + init_lsa_String(&strings[0], "test event written by rpcclient\n"); + init_lsa_String(&servername, NULL); + + status = rpccli_eventlog_ReportEventW(cli, mem_ctx, + &handle, + time(NULL), + EVENTLOG_INFORMATION_TYPE, + 0, /* event_category */ + 0, /* event_id */ + num_of_strings, + data_size, + &servername, + NULL, /* user_sid */ + &strings, + data, + 0, /* flags */ + &record_number, + &time_written); + + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + printf("entry: %d written at %s\n", record_number, + http_timestring(talloc_tos(), time_written)); + + done: + rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle); + + return status; +} + + struct cmd_set eventlog_commands[] = { { "EVENTLOG" }, { "eventlog_readlog", RPC_RTYPE_NTSTATUS, cmd_eventlog_readlog, NULL, &ndr_table_eventlog.syntax_id, NULL, "Read Eventlog", "" }, { "eventlog_numrecord", RPC_RTYPE_NTSTATUS, cmd_eventlog_numrecords, NULL, &ndr_table_eventlog.syntax_id, NULL, "Get number of records", "" }, { "eventlog_oldestrecord", RPC_RTYPE_NTSTATUS, cmd_eventlog_oldestrecord, NULL, &ndr_table_eventlog.syntax_id, NULL, "Get oldest record", "" }, + { "eventlog_reportevent", RPC_RTYPE_NTSTATUS, cmd_eventlog_reportevent, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event", "" }, { NULL } }; -- cgit From d3b8fdd71e16f2ed2f0c24b5d3ad1c22af3c0cc9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 19:01:43 +0100 Subject: s4-smbtorture: add test_GetLogIntormation test. Guenther --- source4/torture/rpc/eventlog.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index 5da205bcde..e1b6cd940f 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -282,6 +282,53 @@ static bool test_ClearEventLog(struct torture_context *tctx, return true; } +static bool test_GetLogInformation(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + NTSTATUS status; + struct eventlog_GetLogIntormation r; + struct eventlog_CloseEventLog cr; + struct policy_handle handle; + uint32_t bytes_needed = 0; + + if (!get_policy_handle(tctx, p, &handle)) + return false; + + r.in.handle = &handle; + r.in.level = 1; + r.in.buf_size = 0; + r.out.buffer = NULL; + r.out.bytes_needed = &bytes_needed; + + status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + + torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_LEVEL, + "GetLogInformation failed"); + + r.in.level = 0; + + status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + + torture_assert_ntstatus_equal(tctx, status, NT_STATUS_BUFFER_TOO_SMALL, + "GetLogInformation failed"); + + r.in.buf_size = bytes_needed; + r.out.buffer = talloc_array(tctx, uint8_t, bytes_needed); + + status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + + torture_assert_ntstatus_ok(tctx, status, "GetLogInformation failed"); + + cr.in.handle = cr.out.handle = &handle; + + torture_assert_ntstatus_ok(tctx, + dcerpc_eventlog_CloseEventLog(p, tctx, &cr), + "CloseEventLog failed"); + + return true; +} + + static bool test_OpenEventLog(struct torture_context *tctx, struct dcerpc_pipe *p) { @@ -318,6 +365,7 @@ struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx) torture_rpc_tcase_add_test(tcase, "ReadEventLog", test_ReadEventLog); torture_rpc_tcase_add_test(tcase, "ReportEventLog", test_ReportEventLog); torture_rpc_tcase_add_test(tcase, "FlushEventLog", test_FlushEventLog); + torture_rpc_tcase_add_test(tcase, "GetLogIntormation", test_GetLogInformation); return suite; } -- cgit From bfc2d3bf0a6fe565a61dbe5f55f2c12d0ebc3967 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 19:26:41 +0100 Subject: s3-rpcclient: add eventlog_reporteventsource command. Guenther --- source3/rpcclient/cmd_eventlog.c | 65 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index 2e1df623fa..a8b4e6bf8c 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -260,6 +260,70 @@ static NTSTATUS cmd_eventlog_reportevent(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + + uint16_t num_of_strings = 1; + uint32_t data_size = 0; + struct lsa_String servername, sourcename; + struct lsa_String *strings; + uint8_t *data = NULL; + uint32_t record_number = 0; + time_t time_written = 0; + + if (argc != 2) { + printf("Usage: %s logname\n", argv[0]); + return NT_STATUS_OK; + } + + status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + strings = talloc_array(mem_ctx, struct lsa_String, num_of_strings); + if (!strings) { + return NT_STATUS_NO_MEMORY; + } + + init_lsa_String(&strings[0], "test event written by rpcclient\n"); + init_lsa_String(&servername, NULL); + init_lsa_String(&sourcename, "rpcclient"); + + status = rpccli_eventlog_ReportEventAndSourceW(cli, mem_ctx, + &handle, + time(NULL), + EVENTLOG_INFORMATION_TYPE, + 0, /* event_category */ + 0, /* event_id */ + &sourcename, + num_of_strings, + data_size, + &servername, + NULL, /* user_sid */ + &strings, + data, + 0, /* flags */ + &record_number, + &time_written); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + printf("entry: %d written at %s\n", record_number, + http_timestring(talloc_tos(), time_written)); + + done: + rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle); + + return status; +} + struct cmd_set eventlog_commands[] = { { "EVENTLOG" }, @@ -267,5 +331,6 @@ struct cmd_set eventlog_commands[] = { { "eventlog_numrecord", RPC_RTYPE_NTSTATUS, cmd_eventlog_numrecords, NULL, &ndr_table_eventlog.syntax_id, NULL, "Get number of records", "" }, { "eventlog_oldestrecord", RPC_RTYPE_NTSTATUS, cmd_eventlog_oldestrecord, NULL, &ndr_table_eventlog.syntax_id, NULL, "Get oldest record", "" }, { "eventlog_reportevent", RPC_RTYPE_NTSTATUS, cmd_eventlog_reportevent, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event", "" }, + { "eventlog_reporteventsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_reporteventsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event and source", "" }, { NULL } }; -- cgit From c92ec31d305ee4f8b31f69d576cfbfb90bec8b49 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 20:10:16 +0100 Subject: s3-rpcclient: add eventlog_registerevsource command. Guenther --- source3/rpcclient/cmd_eventlog.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index a8b4e6bf8c..0da6d956f7 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -324,6 +324,44 @@ static NTSTATUS cmd_eventlog_reporteventsource(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_eventlog_registerevsource(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle log_handle; + struct lsa_String module_name, reg_module_name; + struct eventlog_OpenUnknown0 unknown0; + + unknown0.unknown0 = 0x005c; + unknown0.unknown1 = 0x0001; + + if (argc != 2) { + printf("Usage: %s logname\n", argv[0]); + return NT_STATUS_OK; + } + + init_lsa_String(&module_name, "rpcclient"); + init_lsa_String(®_module_name, NULL); + + status = rpccli_eventlog_RegisterEventSourceW(cli, mem_ctx, + &unknown0, + &module_name, + ®_module_name, + 1, /* major_version */ + 1, /* minor_version */ + &log_handle); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + rpccli_eventlog_DeregisterEventSource(cli, mem_ctx, &log_handle); + + return status; +} + struct cmd_set eventlog_commands[] = { { "EVENTLOG" }, @@ -332,5 +370,6 @@ struct cmd_set eventlog_commands[] = { { "eventlog_oldestrecord", RPC_RTYPE_NTSTATUS, cmd_eventlog_oldestrecord, NULL, &ndr_table_eventlog.syntax_id, NULL, "Get oldest record", "" }, { "eventlog_reportevent", RPC_RTYPE_NTSTATUS, cmd_eventlog_reportevent, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event", "" }, { "eventlog_reporteventsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_reporteventsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event and source", "" }, + { "eventlog_registerevsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_registerevsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Register event source", "" }, { NULL } }; -- cgit From ecad0b93351fa6886cad495c27a14e6b437cc123 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 22:18:29 +0100 Subject: s3-rpcclient: add eventlog_backuplog command. Guenther --- source3/rpcclient/cmd_eventlog.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index 0da6d956f7..21e263f68e 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -362,6 +362,44 @@ static NTSTATUS cmd_eventlog_registerevsource(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_eventlog_backuplog(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + struct lsa_String backup_filename; + const char *tmp; + + if (argc != 3) { + printf("Usage: %s logname backupname\n", argv[0]); + return NT_STATUS_OK; + } + + status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + tmp = talloc_asprintf(mem_ctx, "\\??\\%s", argv[2]); + if (!tmp) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + init_lsa_String(&backup_filename, tmp); + + status = rpccli_eventlog_BackupEventLogW(cli, mem_ctx, + &handle, + &backup_filename); + + done: + rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle); + + return status; +} + struct cmd_set eventlog_commands[] = { { "EVENTLOG" }, @@ -371,5 +409,6 @@ struct cmd_set eventlog_commands[] = { { "eventlog_reportevent", RPC_RTYPE_NTSTATUS, cmd_eventlog_reportevent, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event", "" }, { "eventlog_reporteventsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_reporteventsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event and source", "" }, { "eventlog_registerevsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_registerevsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Register event source", "" }, + { "eventlog_backuplog", RPC_RTYPE_NTSTATUS, cmd_eventlog_backuplog, NULL, &ndr_table_eventlog.syntax_id, NULL, "Backup Eventlog File", "" }, { NULL } }; -- cgit From 2eb5dacbb806a0e943ba2dbadd7d8b7b2ac32ec8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Jan 2009 23:01:58 +0100 Subject: s3-rpcclient: add eventlog_loginfo command. Guenther --- source3/rpcclient/cmd_eventlog.c | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index 21e263f68e..905b147ce6 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -400,6 +400,61 @@ static NTSTATUS cmd_eventlog_backuplog(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_eventlog_loginfo(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + struct policy_handle handle; + uint8_t *buffer = NULL; + uint32_t buf_size = 0; + uint32_t bytes_needed = 0; + + if (argc != 2) { + printf("Usage: %s logname\n", argv[0]); + return NT_STATUS_OK; + } + + status = get_eventlog_handle(cli, mem_ctx, argv[1], &handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = rpccli_eventlog_GetLogIntormation(cli, mem_ctx, + &handle, + 0, /* level */ + buffer, + buf_size, + &bytes_needed); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { + goto done; + } + + buf_size = bytes_needed; + buffer = talloc_array(mem_ctx, uint8_t, bytes_needed); + if (!buffer) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + status = rpccli_eventlog_GetLogIntormation(cli, mem_ctx, + &handle, + 0, /* level */ + buffer, + buf_size, + &bytes_needed); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + done: + rpccli_eventlog_CloseEventLog(cli, mem_ctx, &handle); + + return status; +} + struct cmd_set eventlog_commands[] = { { "EVENTLOG" }, @@ -410,5 +465,6 @@ struct cmd_set eventlog_commands[] = { { "eventlog_reporteventsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_reporteventsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Report event and source", "" }, { "eventlog_registerevsource", RPC_RTYPE_NTSTATUS, cmd_eventlog_registerevsource, NULL, &ndr_table_eventlog.syntax_id, NULL, "Register event source", "" }, { "eventlog_backuplog", RPC_RTYPE_NTSTATUS, cmd_eventlog_backuplog, NULL, &ndr_table_eventlog.syntax_id, NULL, "Backup Eventlog File", "" }, + { "eventlog_loginfo", RPC_RTYPE_NTSTATUS, cmd_eventlog_loginfo, NULL, &ndr_table_eventlog.syntax_id, NULL, "Get Eventlog Information", "" }, { NULL } }; -- cgit From da338efbf94e4210aca0c9cbba60e69e113a4b57 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 21 Jan 2009 00:25:50 +0100 Subject: s4-smbtorture: add BackupLog handling in eventlog test. Guenther --- source4/torture/rpc/eventlog.c | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index e1b6cd940f..aefe8126c0 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -27,6 +27,8 @@ #include "torture/rpc/rpc.h" #include "param/param.h" +#define TEST_BACKUP_NAME "samrtorturetest" + static void init_lsa_String(struct lsa_String *name, const char *s) { name->string = s; @@ -347,6 +349,72 @@ static bool test_OpenEventLog(struct torture_context *tctx, return true; } +static bool test_BackupLog(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + NTSTATUS status; + struct policy_handle handle, backup_handle; + struct eventlog_BackupEventLogW r; + struct eventlog_OpenBackupEventLogW b; + struct eventlog_CloseEventLog cr; + const char *tmp; + struct lsa_String backup_filename; + struct eventlog_OpenUnknown0 unknown0; + + if (!get_policy_handle(tctx, p, &handle)) + return false; + + tmp = talloc_asprintf(tctx, "C:\\%s", TEST_BACKUP_NAME); + init_lsa_String(&backup_filename, tmp); + + r.in.handle = &handle; + r.in.backup_filename = &backup_filename; + + status = dcerpc_eventlog_BackupEventLogW(p, tctx, &r); + torture_assert_ntstatus_equal(tctx, status, + NT_STATUS_OBJECT_PATH_SYNTAX_BAD, "BackupEventLogW failed"); + + tmp = talloc_asprintf(tctx, "\\??\\C:\\%s", TEST_BACKUP_NAME); + init_lsa_String(&backup_filename, tmp); + + r.in.handle = &handle; + r.in.backup_filename = &backup_filename; + + status = dcerpc_eventlog_BackupEventLogW(p, tctx, &r); + torture_assert_ntstatus_ok(tctx, status, "BackupEventLogW failed"); + + status = dcerpc_eventlog_BackupEventLogW(p, tctx, &r); + torture_assert_ntstatus_equal(tctx, status, + NT_STATUS_OBJECT_NAME_COLLISION, "BackupEventLogW failed"); + + cr.in.handle = cr.out.handle = &handle; + + torture_assert_ntstatus_ok(tctx, + dcerpc_eventlog_CloseEventLog(p, tctx, &cr), + "BackupLog failed"); + + unknown0.unknown0 = 0x005c; + unknown0.unknown1 = 0x0001; + + b.in.unknown0 = &unknown0; + b.in.backup_logname = &backup_filename; + b.in.major_version = 1; + b.in.minor_version = 1; + b.out.handle = &backup_handle; + + status = dcerpc_eventlog_OpenBackupEventLogW(p, tctx, &b); + + torture_assert_ntstatus_ok(tctx, status, "OpenBackupEventLogW failed"); + + cr.in.handle = cr.out.handle = &backup_handle; + + torture_assert_ntstatus_ok(tctx, + dcerpc_eventlog_CloseEventLog(p, tctx, &cr), + "CloseEventLog failed"); + + return true; +} + struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx) { struct torture_suite *suite; @@ -366,6 +434,7 @@ struct torture_suite *torture_rpc_eventlog(TALLOC_CTX *mem_ctx) torture_rpc_tcase_add_test(tcase, "ReportEventLog", test_ReportEventLog); torture_rpc_tcase_add_test(tcase, "FlushEventLog", test_FlushEventLog); torture_rpc_tcase_add_test(tcase, "GetLogIntormation", test_GetLogInformation); + torture_rpc_tcase_add_test(tcase, "BackupLog", test_BackupLog); return suite; } -- cgit From ab2ee0711e128ac068e54a180fe2deb4b0c082be Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 21 Jan 2009 00:33:01 +0100 Subject: s4-smbtorture: add my copyright. Guenther --- source4/torture/rpc/eventlog.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index aefe8126c0..d5bc4e6501 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -4,6 +4,7 @@ Copyright (C) Tim Potter 2003,2005 Copyright (C) Jelmer Vernooij 2004 + Copyright (C) Guenther Deschner 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 7bb3860f49cd8b09c2015f6646c07fe5ebaa0de3 Mon Sep 17 00:00:00 2001 From: todd stecher Date: Fri, 23 Jan 2009 14:38:40 -0800 Subject: This change allows for the autoconfigre detection of sub-second time resolution in the FreeBSD stat structure --- source3/configure.in | 40 +++++++++++++++++++++++++++++++++++++++- source3/lib/time.c | 12 ++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/source3/configure.in b/source3/configure.in index 88843a49c4..321924889a 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1308,7 +1308,8 @@ fi ################################################# # Check whether struct stat has timestamps with sub-second resolution. -# At least IRIX and Solaris have these. +# 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 @@ -1317,6 +1318,43 @@ fi # 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 +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#ifdef HAVE_SYS_STAT_H +#include +#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, [ diff --git a/source3/lib/time.c b/source3/lib/time.c index cae6b479b0..7dd0da8fa8 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -404,6 +404,8 @@ struct timespec get_atimespec(const SMB_STRUCT_STAT *pst) ret.tv_sec = pst->st_atime; ret.tv_nsec = pst->st_atimensec; return ret; +#elif defined(HAVE_STAT_ST_ATIMESPEC) + return pst->st_atimespec; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT #endif @@ -421,6 +423,8 @@ void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts) #elif defined(HAVE_STAT_ST_ATIMENSEC) pst->st_atime = ts.tv_sec; pst->st_atimensec = ts.tv_nsec +#elif defined(HAVE_STAT_ST_ATIMESPEC) + pst->st_atimespec = ts; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT #endif @@ -444,6 +448,8 @@ struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst) ret.tv_sec = pst->st_mtime; ret.tv_nsec = pst->st_mtimensec; return ret; +#elif defined(HAVE_STAT_ST_MTIMESPEC) + return pst->st_mtimespec; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT #endif @@ -461,6 +467,8 @@ void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts) #elif defined(HAVE_STAT_ST_MTIMENSEC) pst->st_mtime = ts.tv_sec; pst->st_mtimensec = ts.tv_nsec +#elif defined(HAVE_STAT_ST_ATIMESPEC) + pst->st_atimespec = ts; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT #endif @@ -484,6 +492,8 @@ struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst) ret.tv_sec = pst->st_ctime; ret.tv_nsec = pst->st_ctimensec; return ret; +#elif defined(HAVE_STAT_ST_CTIMESPEC) + return pst->st_ctimespec; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT #endif @@ -501,6 +511,8 @@ void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts) #elif defined(HAVE_STAT_ST_CTIMENSEC) pst->st_ctime = ts.tv_sec; pst->st_ctimensec = ts.tv_nsec +#elif defined(HAVE_STAT_ST_CTIMESPEC) + pst->st_ctimespec = ts; #else #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT #endif -- cgit From 48b0016cff4bad621b94fc0bf678ec15260dd7d7 Mon Sep 17 00:00:00 2001 From: todd stecher Date: Fri, 23 Jan 2009 14:40:19 -0800 Subject: Extend NTIMES to allow setting create_time 1) Add in smb_file_time struct to clarify code and make room for createtime. 2) Get and set create time from SMB messages. 3) Fixup existing VFS modules + examples Some OS'es allow for the setting of the birthtime through kernel interfaces. This value is generically used for Windows createtime, but is not settable in the code today. --- examples/VFS/skel_opaque.c | 4 +- examples/VFS/skel_transparent.c | 4 +- source3/include/proto.h | 5 +- source3/include/smb.h | 7 +++ source3/include/vfs.h | 4 +- source3/modules/vfs_cap.c | 5 +- source3/modules/vfs_catia.c | 4 +- source3/modules/vfs_default.c | 15 +++--- source3/modules/vfs_full_audit.c | 6 +-- source3/modules/vfs_recycle.c | 10 ++-- source3/modules/vfs_shadow_copy2.c | 4 +- source3/smbd/close.c | 8 +-- source3/smbd/dosmode.c | 13 +++-- source3/smbd/reply.c | 46 ++++++++++-------- source3/smbd/trans2.c | 99 +++++++++++++++++++++++--------------- source3/torture/cmd_vfs.c | 11 +++-- 16 files changed, 145 insertions(+), 100 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 3df1fcd5bf..48b497922a 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -231,9 +231,9 @@ static char *skel_getwd(vfs_handle_struct *handle, char *buf) return vfswrap_getwd(NULL, buf); } -static int skel_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +static int skel_ntimes(vfs_handle_struct *handle, const char *path, struct smb_file_time *ft) { - return vfswrap_ntimes(NULL, path, ts); + return vfswrap_ntimes(NULL, path, ft); } static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset) diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index e6dee97775..f5562a5f44 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -224,9 +224,9 @@ static char *skel_getwd(vfs_handle_struct *handle, char *buf) return SMB_VFS_NEXT_GETWD(handle, buf); } -static int skel_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +static int skel_ntimes(vfs_handle_struct *handle, const char *path, struct smb_file_time *ft) { - return SMB_VFS_NEXT_NTIMES(handle, path, ts); + return SMB_VFS_NEXT_NTIMES(handle, path, ft); } static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset) diff --git a/source3/include/proto.h b/source3/include/proto.h index 1554bfdb25..1414ba89ec 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6688,7 +6688,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, const char *parent_dir, bool newfile); -int file_ntimes(connection_struct *conn, const char *fname, const struct timespec ts[2]); +int file_ntimes(connection_struct *conn, const char *fname, + struct smb_file_time *ft); bool set_sticky_write_time_path(connection_struct *conn, const char *fname, struct file_id fileid, const struct timespec mtime); bool set_sticky_write_time_fsp(struct files_struct *fsp, const struct timespec mtime); @@ -7424,7 +7425,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, files_struct *fsp, const char *fname, const SMB_STRUCT_STAT *psbuf, - struct timespec ts[2], + struct smb_file_time *ft, bool setting_write_time); void reply_findclose(struct smb_request *req); void reply_findnclose(struct smb_request *req); diff --git a/source3/include/smb.h b/source3/include/smb.h index 19d2208ada..aa2db693a3 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1901,4 +1901,11 @@ struct smb_extended_info { */ #define CFF_DOS_PATH 0x00000001 +/* time info */ +struct smb_file_time { + struct timespec mtime; + struct timespec atime; + struct timespec create_time; +}; + #endif /* _SMB_H */ diff --git a/source3/include/vfs.h b/source3/include/vfs.h index d02d14b854..5df71da905 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -111,6 +111,7 @@ /* Changed to version 24 - make security descriptor const in fset_nt_acl. JRA. */ /* Changed to version 25 - Jelmer's change from SMB_BIG_UINT to uint64_t. */ /* Leave at 25 - not yet released. Add create_file call. -- tprouty. */ +/* Leave at 25 - not yet released. Add create time to ntimes. -- tstecher. */ #define SMB_VFS_INTERFACE_VERSION 25 @@ -137,6 +138,7 @@ struct security_descriptor; struct vfs_statvfs_struct; struct smb_request; struct ea_list; +struct smb_file_time; /* Available VFS operations. These values must be in sync with vfs_ops struct @@ -348,7 +350,7 @@ struct vfs_ops { int (*lchown)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid); int (*chdir)(struct vfs_handle_struct *handle, const char *path); char *(*getwd)(struct vfs_handle_struct *handle, char *buf); - int (*ntimes)(struct vfs_handle_struct *handle, const char *path, const struct timespec ts[2]); + int (*ntimes)(struct vfs_handle_struct *handle, const char *path, struct smb_file_time *ft); int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset); bool (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 share_mode); diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 6950ab2168..ac85d3a804 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -208,7 +208,8 @@ static int cap_chdir(vfs_handle_struct *handle, const char *path) return SMB_VFS_NEXT_CHDIR(handle, cappath); } -static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +static int cap_ntimes(vfs_handle_struct *handle, const char *path, + struct smb_file_time *ft) { char *cappath = capencode(talloc_tos(), path); @@ -216,7 +217,7 @@ static int cap_ntimes(vfs_handle_struct *handle, const char *path, const struct errno = ENOMEM; return -1; } - return SMB_VFS_NEXT_NTIMES(handle, cappath, ts); + return SMB_VFS_NEXT_NTIMES(handle, cappath, ft); } diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 47d178a33f..d0c341fdd3 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -252,9 +252,9 @@ static char *catia_getwd(vfs_handle_struct *handle, char *buf) } static int catia_ntimes(vfs_handle_struct *handle, - const char *path, const struct timespec ts[2]) + const char *path, struct smb_file_time *ft) { - return SMB_VFS_NEXT_NTIMES(handle, path, ts); + return SMB_VFS_NEXT_NTIMES(handle, path, ft); } static bool catia_symlink(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 61e1deb81e..a9aabab768 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -682,25 +682,26 @@ static char *vfswrap_getwd(vfs_handle_struct *handle, char *path) system will support. **********************************************************************/ -static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, const struct timespec ts[2]) +static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path, + struct smb_file_time *ft) { int result; START_PROFILE(syscall_ntimes); #if defined(HAVE_UTIMES) - if (ts != NULL) { + if (ft != NULL) { struct timeval tv[2]; - tv[0] = convert_timespec_to_timeval(ts[0]); - tv[1] = convert_timespec_to_timeval(ts[1]); + tv[0] = convert_timespec_to_timeval(ft->atime); + tv[1] = convert_timespec_to_timeval(ft->mtime); result = utimes(path, tv); } else { result = utimes(path, NULL); } #elif defined(HAVE_UTIME) - if (ts != NULL) { + if (ft != NULL) { struct utimbuf times; - times.actime = convert_timespec_to_time_t(ts[0]); - times.modtime = convert_timespec_to_time_t(ts[1]); + times.actime = convert_timespec_to_time_t(ft->atime); + times.modtime = convert_timespec_to_time_t(ft->mtime); result = utime(path, times); } else { result = utime(path, NULL); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 1d9983a753..73758a2d9d 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -172,7 +172,7 @@ static int smb_full_audit_chdir(vfs_handle_struct *handle, static char *smb_full_audit_getwd(vfs_handle_struct *handle, char *path); static int smb_full_audit_ntimes(vfs_handle_struct *handle, - const char *path, const struct timespec ts[2]); + const char *path, struct smb_file_time *ft); static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len); static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, @@ -1426,11 +1426,11 @@ static char *smb_full_audit_getwd(vfs_handle_struct *handle, } static int smb_full_audit_ntimes(vfs_handle_struct *handle, - const char *path, const struct timespec ts[2]) + const char *path, struct smb_file_time *ft) { int result; - result = SMB_VFS_NEXT_NTIMES(handle, path, ts); + result = SMB_VFS_NEXT_NTIMES(handle, path, ft); do_log(SMB_VFS_OP_NTIMES, (result >= 0), handle, "%s", path); diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index cb985e1be2..2b0edcdb4a 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -391,19 +391,21 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, bool touch_mtime) { SMB_STRUCT_STAT st; - struct timespec ts[2]; + struct smb_file_time ft; int ret, err; + ZERO_STRUCT(ft); + if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) { DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); return; } - ts[0] = timespec_current(); /* atime */ - ts[1] = touch_mtime ? ts[0] : get_mtimespec(&st); /* mtime */ + ft.atime = timespec_current(); /* atime */ + ft.mtime = touch_mtime ? ft.atime : get_mtimespec(&st); /* mtime */ become_root(); - ret = SMB_VFS_NEXT_NTIMES(handle, fname, ts); + ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft); err = errno; unbecome_root(); if (ret == -1 ) { diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index c95600b642..56dd6ea8d8 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -393,9 +393,9 @@ static int shadow_copy2_chdir(vfs_handle_struct *handle, } static int shadow_copy2_ntimes(vfs_handle_struct *handle, - const char *fname, const struct timespec ts[2]) + const char *fname, struct smb_file_time *ft) { - SHADOW2_NEXT(NTIMES, (handle, name, ts), int, -1); + SHADOW2_NEXT(NTIMES, (handle, name, ft), int, -1); } static int shadow_copy2_readlink(vfs_handle_struct *handle, diff --git a/source3/smbd/close.c b/source3/smbd/close.c index abcd651d93..2fb8ec2bb5 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -465,11 +465,11 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts) static NTSTATUS update_write_time_on_close(struct files_struct *fsp) { SMB_STRUCT_STAT sbuf; - struct timespec ts[2]; + struct smb_file_time ft; NTSTATUS status; ZERO_STRUCT(sbuf); - ZERO_STRUCT(ts); + ZERO_STRUCT(ft); if (!fsp->update_write_time_on_close) { return NT_STATUS_OK; @@ -495,9 +495,9 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) return NT_STATUS_OK; } - ts[1] = fsp->close_write_time; + ft.mtime = fsp->close_write_time; status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, - &sbuf, ts, true); + &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ade5e66e86..555718bd83 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -704,7 +704,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, than POSIX. *******************************************************************/ -int file_ntimes(connection_struct *conn, const char *fname, const struct timespec ts[2]) +int file_ntimes(connection_struct *conn, const char *fname, + struct smb_file_time *ft) { SMB_STRUCT_STAT sbuf; int ret = -1; @@ -713,9 +714,11 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe ZERO_STRUCT(sbuf); DEBUG(6, ("file_ntime: actime: %s", - time_to_asc(convert_timespec_to_time_t(ts[0])))); + time_to_asc(convert_timespec_to_time_t(ft->atime)))); DEBUG(6, ("file_ntime: modtime: %s", - time_to_asc(convert_timespec_to_time_t(ts[1])))); + time_to_asc(convert_timespec_to_time_t(ft->mtime)))); + DEBUG(6, ("file_ntime: createtime: %s", + time_to_asc(convert_timespec_to_time_t(ft->create_time)))); /* Don't update the time on read-only shares */ /* We need this as set_filetime (which can be called on @@ -728,7 +731,7 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe return 0; } - if(SMB_VFS_NTIMES(conn, fname, ts) == 0) { + if(SMB_VFS_NTIMES(conn, fname, ft) == 0) { return 0; } @@ -750,7 +753,7 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe if (can_write_to_file(conn, fname, &sbuf)) { /* We are allowed to become root and change the filetime. */ become_root(); - ret = SMB_VFS_NTIMES(conn, fname, ts); + ret = SMB_VFS_NTIMES(conn, fname, ft); unbecome_root(); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 28836144c2..52dab0a013 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1063,7 +1063,7 @@ void reply_getatr(struct smb_request *req) void reply_setatr(struct smb_request *req) { - struct timespec ts[2]; + struct smb_file_time ft; connection_struct *conn = req->conn; char *fname = NULL; int mode; @@ -1075,7 +1075,7 @@ void reply_setatr(struct smb_request *req) START_PROFILE(SMBsetatr); - ZERO_STRUCT(ts); + ZERO_STRUCT(ft); if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -1133,9 +1133,9 @@ void reply_setatr(struct smb_request *req) mode = SVAL(req->vwv+0, 0); mtime = srv_make_unix_date3(req->vwv+1); - ts[1] = convert_time_t_to_timespec(mtime); + ft.mtime = convert_time_t_to_timespec(mtime); status = smb_set_file_time(conn, NULL, fname, - &sbuf, ts, true); + &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { reply_unixerror(req, ERRDOS, ERRnoaccess); END_PROFILE(SMBsetatr); @@ -1924,7 +1924,7 @@ void reply_mknew(struct smb_request *req) connection_struct *conn = req->conn; char *fname = NULL; uint32 fattr = 0; - struct timespec ts[2]; + struct smb_file_time ft; files_struct *fsp; int oplock_request = 0; SMB_STRUCT_STAT sbuf; @@ -1936,6 +1936,7 @@ void reply_mknew(struct smb_request *req) TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBcreate); + ZERO_STRUCT(ft); if (req->wct < 3) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -1946,8 +1947,8 @@ void reply_mknew(struct smb_request *req) fattr = SVAL(req->vwv+0, 0); oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); - ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1)); - /* mtime. */ + /* mtime. */ + ft.mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1)); srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1, STR_TERMINATE, &status); @@ -1999,8 +2000,8 @@ void reply_mknew(struct smb_request *req) return; } - ts[0] = get_atimespec(&sbuf); /* atime. */ - status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true); + ft.atime = get_atimespec(&sbuf); /* atime. */ + status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { END_PROFILE(SMBcreate); reply_openerror(req, status); @@ -7115,12 +7116,13 @@ void reply_readbs(struct smb_request *req) void reply_setattrE(struct smb_request *req) { connection_struct *conn = req->conn; - struct timespec ts[2]; + struct smb_file_time ft; files_struct *fsp; SMB_STRUCT_STAT sbuf; NTSTATUS status; START_PROFILE(SMBsetattrE); + ZERO_STRUCT(ft); if (req->wct < 7) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -7138,14 +7140,15 @@ void reply_setattrE(struct smb_request *req) /* - * Convert the DOS times into unix times. Ignore create - * time as UNIX can't set this. + * Convert the DOS times into unix times. */ - ts[0] = convert_time_t_to_timespec( - srv_make_unix_date2(req->vwv+3)); /* atime. */ - ts[1] = convert_time_t_to_timespec( - srv_make_unix_date2(req->vwv+5)); /* mtime. */ + ft.atime = convert_time_t_to_timespec( + srv_make_unix_date2(req->vwv+3)); + ft.mtime = convert_time_t_to_timespec( + srv_make_unix_date2(req->vwv+5)); + ft.create_time = convert_time_t_to_timespec( + srv_make_unix_date2(req->vwv+1)); reply_outbuf(req, 0, 0); @@ -7172,17 +7175,20 @@ void reply_setattrE(struct smb_request *req) } status = smb_set_file_time(conn, fsp, fsp->fsp_name, - &sbuf, ts, true); + &sbuf, &ft, true); if (!NT_STATUS_IS_OK(status)) { reply_doserror(req, ERRDOS, ERRnoaccess); END_PROFILE(SMBsetattrE); return; } - DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n", + DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u " + " createtime=%u\n", fsp->fnum, - (unsigned int)ts[0].tv_sec, - (unsigned int)ts[1].tv_sec)); + (unsigned int)ft.atime.tv_sec, + (unsigned int)ft.mtime.tv_sec, + (unsigned int)ft.create_time.tv_sec + )); END_PROFILE(SMBsetattrE); return; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 52340d5370..1b161d5338 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1430,7 +1430,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, mdate_ts = get_mtimespec(&sbuf); adate_ts = get_atimespec(&sbuf); - create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); + create_date_ts = get_create_timespec(&sbuf, + lp_fake_dir_create_times(SNUM(conn))); if (ask_sharemode) { struct timespec write_time_ts; @@ -1453,7 +1454,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, mdate = convert_timespec_to_time_t(mdate_ts); adate = convert_timespec_to_time_t(adate_ts); - DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n",pathreal,fname)); + DEBUG(5,("get_lanman2_dir_entry: found %s fname=%s\n", + pathreal,fname)); found = True; @@ -4892,7 +4894,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, files_struct *fsp, const char *fname, const SMB_STRUCT_STAT *psbuf, - struct timespec ts[2], + struct smb_file_time *ft, bool setting_write_time) { uint32 action = @@ -4904,23 +4906,29 @@ NTSTATUS smb_set_file_time(connection_struct *conn, } /* get some defaults (no modifications) if any info is zero or -1. */ - if (null_timespec(ts[0])) { - ts[0] = get_atimespec(psbuf); + if (null_timespec(ft->atime)) { + ft->atime= get_atimespec(psbuf); action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS; } - if (null_timespec(ts[1])) { - ts[1] = get_mtimespec(psbuf); + if (null_timespec(ft->mtime)) { + ft->mtime = get_mtimespec(psbuf); action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; } if (!setting_write_time) { - /* ts[1] comes from change time, not write time. */ + /* ft->mtime comes from change time, not write time. */ action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; } - DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) )); - DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) )); + DEBUG(5,("smb_set_filetime: actime: %s\n ", + time_to_asc(convert_timespec_to_time_t(ft->atime)))); + DEBUG(5,("smb_set_filetime: modtime: %s\n ", + time_to_asc(convert_timespec_to_time_t(ft->mtime)))); + if (!null_timespec(ft->create_time)) { + DEBUG(5,("smb_set_file_time: createtime: %s\n ", + time_to_asc(convert_timespec_to_time_t(ft->create_time)))); + } /* * Try and set the times of this file if @@ -4930,7 +4938,8 @@ NTSTATUS smb_set_file_time(connection_struct *conn, { struct timespec mts = get_mtimespec(psbuf); struct timespec ats = get_atimespec(psbuf); - if ((timespec_compare(&ts[0], &ats) == 0) && (timespec_compare(&ts[1], &mts) == 0)) { + if ((timespec_compare(&ft->atime, &ats) == 0) && + (timespec_compare(&ft->mtime, &mts) == 0)) { return NT_STATUS_OK; } } @@ -4947,18 +4956,19 @@ NTSTATUS smb_set_file_time(connection_struct *conn, */ DEBUG(10,("smb_set_file_time: setting pending modtime to %s\n", - time_to_asc(convert_timespec_to_time_t(ts[1])) )); + time_to_asc(convert_timespec_to_time_t(ft->mtime)))); if (fsp != NULL) { if (fsp->base_fsp) { - set_sticky_write_time_fsp(fsp->base_fsp, ts[1]); + set_sticky_write_time_fsp(fsp->base_fsp, + ft->mtime); } else { - set_sticky_write_time_fsp(fsp, ts[1]); + set_sticky_write_time_fsp(fsp, ft->mtime); } } else { set_sticky_write_time_path(conn, fname, vfs_file_id_from_sbuf(conn, psbuf), - ts[1]); + ft->mtime); } } @@ -4968,7 +4978,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, fname = fsp->base_fsp->fsp_name; } - if(file_ntimes(conn, fname, ts)!=0) { + if(file_ntimes(conn, fname, ft)!=0) { return map_nt_error_from_unix(errno); } notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname); @@ -5677,16 +5687,21 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf) { - struct timespec ts[2]; + struct smb_file_time ft; + ZERO_STRUCT(ft); if (total_data < 12) { return NT_STATUS_INVALID_PARAMETER; } + /* create time */ + ft.create_time = interpret_long_date(pdata); + /* access time */ - ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastAccess)); + ft.atime = interpret_long_date(pdata + 8); + /* write time */ - ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(pdata+l1_fdateLastWrite)); + ft.mtime = interpret_long_date(pdata + 16); DEBUG(10,("smb_set_info_standard: file %s\n", fname ? fname : fsp->fsp_name )); @@ -5695,7 +5710,7 @@ static NTSTATUS smb_set_info_standard(connection_struct *conn, fsp, fname, psbuf, - ts, + &ft, true); } @@ -5713,47 +5728,49 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Patch to do this correctly from Paul Eggert . */ struct timespec write_time; struct timespec changed_time; + struct smb_file_time ft; uint32 dosmode = 0; - struct timespec ts[2]; NTSTATUS status = NT_STATUS_OK; bool setting_write_time = true; + ZERO_STRUCT(ft); + if (total_data < 36) { return NT_STATUS_INVALID_PARAMETER; } /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, - fname, - psbuf, - dosmode); + status = smb_set_file_dosmode(conn, fname, psbuf, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } - /* Ignore create time at offset pdata. */ /* access time */ - ts[0] = interpret_long_date(pdata+8); + ft.atime = interpret_long_date(pdata+8); write_time = interpret_long_date(pdata+16); changed_time = interpret_long_date(pdata+24); /* mtime */ - ts[1] = timespec_min(&write_time, &changed_time); + ft.mtime = timespec_min(&write_time, &changed_time); - if ((timespec_compare(&write_time, &ts[1]) == 1) && !null_timespec(write_time)) { - ts[1] = write_time; + /* create time */ + ft.create_time = interpret_long_date(pdata); + + if ((timespec_compare(&write_time, &ft.mtime) == 1) && + !null_timespec(write_time)) { + ft.mtime = write_time; } /* Prefer a defined time to an undefined one. */ - if (null_timespec(ts[1])) { + if (null_timespec(ft.mtime)) { if (null_timespec(write_time)) { - ts[1] = changed_time; + ft.mtime = changed_time; setting_write_time = false; } else { - ts[1] = write_time; + ft.mtime = write_time; } } @@ -5764,7 +5781,7 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, fsp, fname, psbuf, - ts, + &ft, setting_write_time); } @@ -6012,7 +6029,7 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { - struct timespec ts[2]; + struct smb_file_time ft; uint32 raw_unixmode; mode_t unixmode; SMB_OFF_T size = 0; @@ -6022,6 +6039,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, bool delete_on_fail = False; enum perm_type ptype; + ZERO_STRUCT(ft); + if (total_data < 100) { return NT_STATUS_INVALID_PARAMETER; } @@ -6039,8 +6058,8 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, #endif /* LARGE_SMB_OFF_T */ } - ts[0] = interpret_long_date(pdata+24); /* access_time */ - ts[1] = interpret_long_date(pdata+32); /* modification_time */ + ft.atime = interpret_long_date(pdata+24); /* access_time */ + ft.mtime = interpret_long_date(pdata+32); /* modification_time */ set_owner = (uid_t)IVAL(pdata,40); set_grp = (gid_t)IVAL(pdata,48); raw_unixmode = IVAL(pdata,84); @@ -6083,8 +6102,8 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", /* Ensure we don't try and change anything else. */ raw_unixmode = SMB_MODE_NO_CHANGE; size = get_file_size(*psbuf); - ts[0] = get_atimespec(psbuf); - ts[1] = get_mtimespec(psbuf); + ft.atime = get_atimespec(psbuf); + ft.mtime = get_mtimespec(psbuf); /* * We continue here as we might want to change the * owner uid/gid. @@ -6172,7 +6191,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", fsp, fname, psbuf, - ts, + &ft, true); } diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index d984dd661c..31eb27b756 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -795,14 +795,17 @@ static NTSTATUS cmd_getwd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, static NTSTATUS cmd_utime(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - struct timespec ts[2]; + struct smb_file_time ft; if (argc != 4) { printf("Usage: utime \n"); return NT_STATUS_OK; } - ts[0] = convert_time_t_to_timespec(atoi(argv[2])); - ts[1] = convert_time_t_to_timespec(atoi(argv[3])); - if (SMB_VFS_NTIMES(vfs->conn, argv[1], ts) != 0) { + + ZERO_STRUCT(ft); + + ft.atime = convert_time_t_to_timespec(atoi(argv[2])); + ft.mtime = convert_time_t_to_timespec(atoi(argv[3])); + if (SMB_VFS_NTIMES(vfs->conn, argv[1], &ft) != 0) { printf("utime: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } -- cgit From c23f0f13b42745a7b9f7c0a5b37f1ad521f886df Mon Sep 17 00:00:00 2001 From: todd stecher Date: Fri, 23 Jan 2009 16:55:18 -0800 Subject: Modify OneFS module to support new NTIMES interfaces --- source3/modules/onefs.h | 3 + source3/modules/onefs_streams.c | 128 +++++++++++++++++++++++++++------------- source3/modules/vfs_onefs.c | 35 +++++++++++ 3 files changed, 124 insertions(+), 42 deletions(-) diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index e189fc4570..9c1c1647ba 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -101,6 +101,9 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, unsigned int *num_streams, struct stream_struct **streams); +int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname, + int flags, struct timespec times[3]); + NTSTATUS onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc); diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 184fe4f0c9..e9543e237f 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -51,6 +51,25 @@ NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, return NT_STATUS_OK; } +int onefs_is_stream(const char *path, char **pbase, char **pstream, + bool *is_stream) +{ + (*is_stream) = is_ntfs_stream_name(path); + + if (!(*is_stream)) { + return 0; + } + + if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path, + pbase, pstream))) { + DEBUG(10, ("onefs_split_ntfs_stream_name failed\n")); + errno = ENOMEM; + return -1; + } + + return 0; +} + int onefs_close(vfs_handle_struct *handle, struct files_struct *fsp) { int ret2, ret = 0; @@ -141,27 +160,18 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, char *nbase = NULL; char *nsname = NULL; - old_is_stream = is_ntfs_stream_name(oldname); - new_is_stream = is_ntfs_stream_name(newname); - - if (!old_is_stream && !new_is_stream) { - return SMB_VFS_NEXT_RENAME(handle, oldname, newname); - } - frame = talloc_stackframe(); - if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), - oldname, &obase, - &osname))) { - errno = ENOMEM; - goto done; - } + ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream); + if (ret) + return ret; - if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), - newname, &nbase, - &nsname))) { - errno = ENOMEM; - goto done; + ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream); + if (ret) + return ret; + + if (!old_is_stream && !new_is_stream) { + return SMB_VFS_NEXT_RENAME(handle, oldname, newname); } dir_fd = get_stream_dir_fd(handle->conn, obase, NULL); @@ -237,18 +247,17 @@ static int stat_stream(vfs_handle_struct *handle, const char *base, int onefs_stat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) { + int ret; + bool is_stream; char *base = NULL; char *stream = NULL; - if (!is_ntfs_stream_name(path)) { - return SMB_VFS_NEXT_STAT(handle, path, sbuf); - } + ret = onefs_is_stream(path, &base, &stream, &is_stream); + if (ret) + return ret; - if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path, - &base, &stream))) { - DEBUG(10, ("onefs_split_ntfs_stream_name failed\n")); - errno = ENOMEM; - return -1; + if (!is_stream) { + return SMB_VFS_NEXT_STAT(handle, path, sbuf); } /* If it's the ::$DATA stream just stat the base file name. */ @@ -285,18 +294,17 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp, int onefs_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf) { + int ret; + bool is_stream; char *base = NULL; char *stream = NULL; - if (!is_ntfs_stream_name(path)) { - return SMB_VFS_NEXT_LSTAT(handle, path, sbuf); - } + ret = onefs_is_stream(path, &base, &stream, &is_stream); + if (ret) + return ret; - if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path, - &base, &stream))) { - DEBUG(10, ("onefs_split_ntfs_stream_name failed\n")); - errno = ENOMEM; - return -1; + if (!is_stream) { + return SMB_VFS_NEXT_LSTAT(handle, path, sbuf); } /* If it's the ::$DATA stream just stat the base file name. */ @@ -309,19 +317,19 @@ int onefs_lstat(vfs_handle_struct *handle, const char *path, int onefs_unlink(vfs_handle_struct *handle, const char *path) { + int ret; + bool is_stream; char *base = NULL; char *stream = NULL; - int dir_fd, ret, saved_errno; + int dir_fd, saved_errno; - if (!is_ntfs_stream_name(path)) { - return SMB_VFS_NEXT_UNLINK(handle, path); + ret = onefs_is_stream(path, &base, &stream, &is_stream); + if (ret) { + return ret; } - if (!NT_STATUS_IS_OK(onefs_split_ntfs_stream_name(talloc_tos(), path, - &base, &stream))) { - DEBUG(10, ("onefs_split_ntfs_stream_name failed\n")); - errno = ENOMEM; - return -1; + if (!is_stream) { + return SMB_VFS_NEXT_UNLINK(handle, path); } /* If it's the ::$DATA stream just unlink the base file name. */ @@ -342,6 +350,42 @@ int onefs_unlink(vfs_handle_struct *handle, const char *path) return ret; } +int onefs_vtimes_streams(vfs_handle_struct *handle, const char *fname, + int flags, struct timespec times[3]) +{ + int ret; + bool is_stream; + char *base; + char *stream; + int dirfd; + int saved_errno; + + START_PROFILE(syscall_ntimes); + + ret = onefs_is_stream(fname, &base, &stream, &is_stream); + if (ret) + return ret; + + if (!is_stream) { + ret = vtimes(fname, times, flags); + return ret; + } + + dirfd = get_stream_dir_fd(handle->conn, base, NULL); + if (dirfd < -1) { + return -1; + } + + ret = enc_vtimesat(dirfd, stream, ENC_DEFAULT, times, flags); + + END_PROFILE(syscall_ntimes); + + saved_errno = errno; + close(dirfd); + errno = saved_errno; + return ret; +} + int onefs_chflags(vfs_handle_struct *handle, const char *path, unsigned int flags) { diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index 6b42c0f373..e048e89589 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -66,6 +66,39 @@ static int onefs_statvfs(vfs_handle_struct *handle, const char *path, return result; } +static int onefs_ntimes(vfs_handle_struct *handle, const char *fname, + struct smb_file_time *ft) +{ + int flags = 0; + struct timespec times[3]; + + if (!null_timespec(ft->atime)) { + flags |= VT_ATIME; + times[0] = ft->atime; + DEBUG(6,("**** onefs_ntimes: actime: %s.%d\n", + time_to_asc(convert_timespec_to_time_t(ft->atime)), + ft->atime.tv_nsec)); + } + + if (!null_timespec(ft->mtime)) { + flags |= VT_MTIME; + times[1] = ft->mtime; + DEBUG(6,("**** onefs_ntimes: modtime: %s.%d\n", + time_to_asc(convert_timespec_to_time_t(ft->mtime)), + ft->mtime.tv_nsec)); + } + + if (!null_timespec(ft->create_time)) { + flags |= VT_BTIME; + times[2] = ft->create_time; + DEBUG(6,("**** onefs_ntimes: createtime: %s.%d\n", + time_to_asc(convert_timespec_to_time_t(ft->create_time)), + ft->create_time.tv_nsec)); + } + + return onefs_vtimes_streams(handle, fname, flags, times); +} + static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle) { return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS; @@ -92,6 +125,8 @@ static vfs_op_tuple onefs_ops[] = { SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(onefs_ntimes), SMB_VFS_OP_NTIMES, + SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(onefs_chflags), SMB_VFS_OP_CHFLAGS, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(onefs_streaminfo), SMB_VFS_OP_STREAMINFO, -- cgit From 8b804077128cd981bf238b2506c589dff3bf8ff4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 24 Jan 2009 15:08:14 +0100 Subject: Fix a segfault in parse_logentry entry->data_record.strings is type smb_ucs2, so the pointer arithmetic increments by two :-) --- source3/rpc_server/srv_eventlog_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c index aa75fb1b46..8cbb319e9b 100644 --- a/source3/rpc_server/srv_eventlog_lib.c +++ b/source3/rpc_server/srv_eventlog_lib.c @@ -715,7 +715,7 @@ bool parse_logentry( char *line, Eventlog_entry * entry, bool * eor ) if (!entry->data_record.strings) { return false; } - memcpy(entry->data_record.strings + old_len, + memcpy(((char *)entry->data_record.strings) + old_len, temp, tmp_len); entry->data_record.strings_len += tmp_len; -- cgit