diff options
54 files changed, 3273 insertions, 771 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 @@ <refsynopsisdiv> <cmdsynopsis> - <command>Browser URL:</command> <para> - smb://[[[domain:]user[:password@]]server[/share[/path[/file]]]] [?options] - </para> + Browser URL: + <command moreinfo="none">smb://[[[domain:]user[:password@]]server[/share[/path[/file]]]] [?options] + </command> + </para> </cmdsynopsis> </refsynopsisdiv> 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/lib/async_req.c b/lib/async_req/async_req.c index 011948a158..011948a158 100644 --- a/source3/lib/async_req.c +++ b/lib/async_req/async_req.c diff --git a/source3/include/async_req.h b/lib/async_req/async_req.h index 3907a08f67..3907a08f67 100644 --- a/source3/include/async_req.h +++ b/lib/async_req/async_req.h 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/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 { @@ -81,6 +85,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_1<r->in.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_1<r->in.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__ */ diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl index 51b3ea706e..ccdca008c5 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( @@ -77,7 +80,9 @@ import "lsa.idl", "security.idl"; /******************/ /* Function: 0x03 */ - [todo] NTSTATUS eventlog_DeregisterEventSource(); + NTSTATUS eventlog_DeregisterEventSource( + [in,out] policy_handle *handle + ); /******************/ /* Function: 0x04 */ @@ -110,11 +115,24 @@ 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 */ - [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 */ @@ -130,7 +148,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 */ @@ -174,11 +207,42 @@ 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 */ 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 + ); } 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/Makefile.in b/source3/Makefile.in index 1924ade8fb..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 \ @@ -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_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 @@ -761,7 +762,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 +845,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) \ diff --git a/source3/configure.in b/source3/configure.in index 44a932c6f5..321924889a 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" @@ -1307,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 @@ -1316,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 <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + ], + [ + struct timespec t; + struct stat s = {0}; + t = s.st_mtimespec; + t = s.st_ctimespec; + t = s.st_atimespec; + ], + samba_cv_stat_timespec_hires=yes, samba_cv_stat_timespec_hires=no) + ]) + +if test x"$samba_cv_stat_timespec_hires" = x"yes" ; then + AC_DEFINE(HAVE_STAT_ST_MTIMESPEC, 1, [whether struct stat contains st_mtimepec]) + AC_DEFINE(HAVE_STAT_ST_ATIMESPEC, 1, [whether struct stat contains st_atimespec]) + AC_DEFINE(HAVE_STAT_ST_CTIMESPEC, 1, [whether struct stat contains st_ctimespec]) + AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1, [whether struct stat has sub-second timestamps]) +fi + + AC_CACHE_CHECK([whether struct stat has sub-second timestamps], samba_cv_stat_hires, [ diff --git a/source3/include/client.h b/source3/include/client.h index 09fdb81462..d62d1c05d2 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -61,21 +61,60 @@ 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; - 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/include/proto.h b/source3/include/proto.h index d55546f94c..1414ba89ec 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,17 @@ 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/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 */ @@ -6678,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); @@ -7414,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/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 */ 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/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); 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 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 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")); diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 6e5eae3085..9c1c1647ba 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 @@ -93,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); @@ -105,7 +116,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_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/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", 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/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_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, 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/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; 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 <http://www.gnu.org/licenses/>. + */ + +#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; +} 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 <http://www.gnu.org/licenses/>. + */ + +#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; +} 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 */ 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; diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 0bf0730d39..a687025ba6 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; @@ -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; @@ -961,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; +} diff --git a/source3/rpcclient/cmd_eventlog.c b/source3/rpcclient/cmd_eventlog.c index a8373f466d..905b147ce6 100644 --- a/source3/rpcclient/cmd_eventlog.c +++ b/source3/rpcclient/cmd_eventlog.c @@ -197,10 +197,274 @@ 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; +} + +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; +} + +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; +} + +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; +} + +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" }, { "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", "" }, + { "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 } }; 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/posix_acls.c b/source3/smbd/posix_acls.c index 951046c562..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); @@ -3426,8 +3429,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 +3452,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 +3470,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 +3495,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; + } + + /* + * Try using the POSIX ACL set first. Fall back to chmod if + * we have no ACL support on this filesystem. + */ - bool acl_set_support = False; - bool ret = False; + 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; } 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 <eggert@twinsun.com>. */ 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 <path> <access> <modify>\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; } 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 # 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 diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index 245dda1978..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 @@ -27,6 +28,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; @@ -180,6 +183,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) { @@ -233,6 +285,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) { @@ -251,6 +350,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; @@ -267,7 +432,10 @@ 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); + torture_rpc_tcase_add_test(tcase, "GetLogIntormation", test_GetLogInformation); + torture_rpc_tcase_add_test(tcase, "BackupLog", test_BackupLog); return suite; } |