diff options
-rw-r--r-- | source3/include/nterr.h | 1 | ||||
-rw-r--r-- | source3/librpc/gen_ndr/ndr_wkssvc.c | 2 | ||||
-rw-r--r-- | source3/libsmb/nterr.c | 1 | ||||
-rw-r--r-- | source3/rpcclient/cmd_wkssvc.c | 82 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 82 | ||||
-rw-r--r-- | source3/smbd/open.c | 70 |
6 files changed, 176 insertions, 62 deletions
diff --git a/source3/include/nterr.h b/source3/include/nterr.h index da9fab3aca..5749c4efbf 100644 --- a/source3/include/nterr.h +++ b/source3/include/nterr.h @@ -563,6 +563,7 @@ #define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) #define NT_STATUS_DS_NO_MORE_RIDS NT_STATUS(0xC0000000 | 0x02a8) #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) +#define NT_STATUS_DOWNGRADE_DETECTED NT_STATUS(0xC0000000 | 0x0388) #define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */ #define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004) diff --git a/source3/librpc/gen_ndr/ndr_wkssvc.c b/source3/librpc/gen_ndr/ndr_wkssvc.c index c3a1f706cd..3599fef352 100644 --- a/source3/librpc/gen_ndr/ndr_wkssvc.c +++ b/source3/librpc/gen_ndr/ndr_wkssvc.c @@ -8606,7 +8606,6 @@ static enum ndr_err_code ndr_pull_wkssvc_NetrGetJoinableOus(struct ndr_pull *ndr TALLOC_CTX *_mem_save_unknown_0; TALLOC_CTX *_mem_save_num_ous_0; TALLOC_CTX *_mem_save_ous_1; - TALLOC_CTX *_mem_save_ous_2; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -9488,7 +9487,6 @@ static enum ndr_err_code ndr_pull_wkssvc_NetrGetJoinableOus2(struct ndr_pull *nd TALLOC_CTX *_mem_save_EncryptedPassword_0; TALLOC_CTX *_mem_save_num_ous_0; TALLOC_CTX *_mem_save_ous_1; - TALLOC_CTX *_mem_save_ous_2; if (flags & NDR_IN) { ZERO_STRUCT(r->out); diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index cf443f2339..608fe9db20 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS }, { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, + { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, diff --git a/source3/rpcclient/cmd_wkssvc.c b/source3/rpcclient/cmd_wkssvc.c index f3ff8113e9..d136cd0d45 100644 --- a/source3/rpcclient/cmd_wkssvc.c +++ b/source3/rpcclient/cmd_wkssvc.c @@ -32,6 +32,15 @@ static WERROR cmd_wkssvc_wkstagetinfo(struct rpc_pipe_client *cli, union wkssvc_NetWkstaInfo info; const char *server_name; + if (argc > 2) { + printf("usage: %s <level>\n", argv[0]); + return WERR_OK; + } + + if (argc > 1) { + level = atoi(argv[1]); + } + server_name = cli->cli->desthost; status = rpccli_wkssvc_NetWkstaGetInfo(cli, mem_ctx, @@ -46,9 +55,80 @@ static WERROR cmd_wkssvc_wkstagetinfo(struct rpc_pipe_client *cli, return werr; } +static WERROR cmd_wkssvc_getjoininformation(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + const char *server_name; + const char *name_buffer; + enum wkssvc_NetJoinStatus name_type; + NTSTATUS status; + WERROR werr; + + server_name = cli->cli->desthost; + name_buffer = ""; + + status = rpccli_wkssvc_NetrGetJoinInformation(cli, mem_ctx, + server_name, + &name_buffer, + &name_type, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(werr)) { + printf("%s (%d)\n", name_buffer, name_type); + } + + return werr; +} + +static WERROR cmd_wkssvc_messagebuffersend(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + const char *server_name = cli->cli->desthost; + const char *message_name = cli->cli->desthost; + const char *message_sender_name = cli->cli->desthost; + smb_ucs2_t *message_buffer = NULL; + size_t message_size = 0; + const char *message = "my message"; + NTSTATUS status; + WERROR werr; + + if (argc > 1) { + message = argv[1]; + } + + message_size = push_ucs2_talloc(mem_ctx, + &message_buffer, + message); + if (message_size == -1) { + return WERR_NOMEM; + } + + status = rpccli_wkssvc_NetrMessageBufferSend(cli, mem_ctx, + server_name, + message_name, + message_sender_name, + (uint8_t *)message_buffer, + message_size, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + return werr; +} + struct cmd_set wkssvc_commands[] = { { "WKSSVC" }, - { "wkstagetinfo", RPC_RTYPE_WERROR, NULL, cmd_wkssvc_wkstagetinfo, PI_WKSSVC, NULL, "Query WKSSVC Workstation Information", "" }, + { "wkssvc_wkstagetinfo", RPC_RTYPE_WERROR, NULL, cmd_wkssvc_wkstagetinfo, PI_WKSSVC, NULL, "Query WKSSVC Workstation Information", "" }, + { "wkssvc_getjoininformation", RPC_RTYPE_WERROR, NULL, cmd_wkssvc_getjoininformation, PI_WKSSVC, NULL, "Query WKSSVC Join Information", "" }, + { "wkssvc_messagebuffersend", RPC_RTYPE_WERROR, NULL, cmd_wkssvc_messagebuffersend, PI_WKSSVC, NULL, "Send WKSSVC message", "" }, { NULL } }; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index fb85a67d0a..99b2bf65bb 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -433,6 +433,7 @@ void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req) struct timespec a_timespec; struct timespec m_timespec; NTSTATUS status; + int oplock_request; uint8_t oplock_granted = NO_OPLOCK_RETURN; TALLOC_CTX *ctx = talloc_tos(); @@ -497,11 +498,16 @@ void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req) } } - status = create_file(conn, req, root_dir_fid, fname, flags, - access_mask, file_attributes, share_access, - create_disposition, create_options, - allocation_size, NULL, NULL, - &fsp, &info, &oplock_granted, &sbuf); + oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; + if (oplock_request) { + oplock_request |= (flags & REQUEST_BATCH_OPLOCK) + ? BATCH_OPLOCK : 0; + } + + status = create_file(conn, req, root_dir_fid, fname, + access_mask, share_access, create_disposition, + create_options, file_attributes, oplock_request, + allocation_size, NULL, NULL, &fsp, &info, &sbuf); if (!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -519,6 +525,31 @@ void reply_ntcreate_and_X(connection_struct *conn, struct smb_request *req) return; } + /* + * If the caller set the extended oplock request bit + * and we granted one (by whatever means) - set the + * correct bit for extended oplock reply. + */ + + if (oplock_request && + (lp_fake_oplocks(SNUM(conn)) + || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) { + + /* + * Exclusive oplock granted + */ + + if (flags & REQUEST_BATCH_OPLOCK) { + oplock_granted = BATCH_OPLOCK_RETURN; + } else { + oplock_granted = EXCLUSIVE_OPLOCK_RETURN; + } + } else if (fsp->oplock_type == LEVEL_II_OPLOCK) { + oplock_granted = LEVEL_II_OPLOCK_RETURN; + } else { + oplock_granted = NO_OPLOCK_RETURN; + } + file_len = sbuf.st_size; fattr = dos_mode(conn,fname,&sbuf); if (fattr == 0) { @@ -834,6 +865,7 @@ static void call_nt_transact_create(connection_struct *conn, NTSTATUS status; size_t param_len; SMB_BIG_UINT allocation_size; + int oplock_request; uint8_t oplock_granted; TALLOC_CTX *ctx = talloc_tos(); @@ -941,11 +973,16 @@ static void call_nt_transact_create(connection_struct *conn, return; } - status = create_file(conn, req, root_dir_fid, fname, flags, - access_mask, file_attributes, share_access, - create_disposition, create_options, - allocation_size, sd, ea_list, - &fsp, &info, &oplock_granted, &sbuf); + oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; + if (oplock_request) { + oplock_request |= (flags & REQUEST_BATCH_OPLOCK) + ? BATCH_OPLOCK : 0; + } + + status = create_file(conn, req, root_dir_fid, fname, + access_mask, share_access, create_disposition, + create_options, file_attributes, oplock_request, + allocation_size, sd, ea_list, &fsp, &info, &sbuf); if(!NT_STATUS_IS_OK(status)) { if (open_was_deferred(req->mid)) { @@ -961,6 +998,31 @@ static void call_nt_transact_create(connection_struct *conn, return; } + /* + * If the caller set the extended oplock request bit + * and we granted one (by whatever means) - set the + * correct bit for extended oplock reply. + */ + + if (oplock_request && + (lp_fake_oplocks(SNUM(conn)) + || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) { + + /* + * Exclusive oplock granted + */ + + if (flags & REQUEST_BATCH_OPLOCK) { + oplock_granted = BATCH_OPLOCK_RETURN; + } else { + oplock_granted = EXCLUSIVE_OPLOCK_RETURN; + } + } else if (fsp->oplock_type == LEVEL_II_OPLOCK) { + oplock_granted = LEVEL_II_OPLOCK_RETURN; + } else { + oplock_granted = NO_OPLOCK_RETURN; + } + file_len = sbuf.st_size; fattr = dos_mode(conn,fname,&sbuf); if (fattr == 0) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 66ceb8dac7..b156dbbce1 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2447,20 +2447,19 @@ static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx NTSTATUS create_file(connection_struct *conn, struct smb_request *req, uint16_t root_dir_fid, - char *fname, - uint32_t flags, + const char *fname, uint32_t access_mask, - uint32_t file_attributes, uint32_t share_access, uint32_t create_disposition, uint32_t create_options, + uint32_t file_attributes, + uint32_t oplock_request, SMB_BIG_UINT allocation_size, struct security_descriptor *sd, struct ea_list *ea_list, files_struct **result, int *pinfo, - uint8_t *poplock_granted, SMB_STRUCT_STAT *psbuf) { TALLOC_CTX *frame = talloc_stackframe(); @@ -2468,21 +2467,20 @@ NTSTATUS create_file(connection_struct *conn, SMB_STRUCT_STAT sbuf; int info = FILE_WAS_OPENED; files_struct *fsp = NULL; - uint8_t oplock_granted = NO_OPLOCK_RETURN; - int oplock_request; NTSTATUS status; - DEBUG(10,("create_file: flags = 0x%x, access_mask = 0x%x " + DEBUG(10,("create_file: access_mask = 0x%x " "file_attributes = 0x%x, share_access = 0x%x, " "create_disposition = 0x%x create_options = 0x%x " + "oplock_request = 0x%x " "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, " "fname = %s\n", - (unsigned int)flags, (unsigned int)access_mask, (unsigned int)file_attributes, (unsigned int)share_access, (unsigned int)create_disposition, (unsigned int)create_options, + (unsigned int)oplock_request, (unsigned int)root_dir_fid, ea_list, sd, fname)); @@ -2613,18 +2611,15 @@ NTSTATUS create_file(connection_struct *conn, } } - oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; - if (oplock_request) { - oplock_request |= (flags & REQUEST_BATCH_OPLOCK) - ? BATCH_OPLOCK : 0; - } - if (req == NULL) { oplock_request |= INTERNAL_OPEN_ONLY; } if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) { - status = resolve_dfspath(talloc_tos(), conn, true, fname, &fname); + char *resolved_fname; + + status = resolve_dfspath(talloc_tos(), conn, true, fname, + &resolved_fname); if (!NT_STATUS_IS_OK(status)) { /* @@ -2635,6 +2630,7 @@ NTSTATUS create_file(connection_struct *conn, */ goto fail; } + fname = resolved_fname; } /* @@ -2646,10 +2642,15 @@ NTSTATUS create_file(connection_struct *conn, file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS; } - status = unix_convert(talloc_tos(), conn, fname, False, &fname, NULL, - &sbuf); - if (!NT_STATUS_IS_OK(status)) { - goto fail; + { + char *converted_fname; + + status = unix_convert(talloc_tos(), conn, fname, False, + &converted_fname, NULL, &sbuf); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + fname = converted_fname; } /* All file access must go through check_name() */ @@ -2826,42 +2827,13 @@ NTSTATUS create_file(connection_struct *conn, } } - /* - * If the caller set the extended oplock request bit - * and we granted one (by whatever means) - set the - * correct bit for extended oplock reply. - */ - - if (oplock_request && - (lp_fake_oplocks(SNUM(conn)) - || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) { - - /* - * Exclusive oplock granted - */ - - if (flags & REQUEST_BATCH_OPLOCK) { - oplock_granted = BATCH_OPLOCK_RETURN; - } else { - oplock_granted = EXCLUSIVE_OPLOCK_RETURN; - } - } else if (fsp->oplock_type == LEVEL_II_OPLOCK) { - oplock_granted = LEVEL_II_OPLOCK_RETURN; - } else { - oplock_granted = NO_OPLOCK_RETURN; - } - done: - DEBUG(10, ("create_file: info=%d, oplock_granted=%d\n", - info, (int)oplock_granted)); + DEBUG(10, ("create_file: info=%d\n", info)); *result = fsp; if (pinfo != NULL) { *pinfo = info; } - if (poplock_granted != NULL) { - *poplock_granted = oplock_granted; - } if (psbuf != NULL) { *psbuf = sbuf; } |