diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 17 | ||||
-rw-r--r-- | source3/libsmb/clireadwrite.c | 122 | ||||
-rw-r--r-- | source3/libsmb/nterr.c | 1 | ||||
-rw-r--r-- | source3/modules/vfs_aio_fork.c | 3 | ||||
-rw-r--r-- | source3/rpc_client/cli_lsarpc.c | 189 | ||||
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_netlog_nt.c | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 4 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 2 |
9 files changed, 294 insertions, 48 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index abc76e8e02..5da13ca0d7 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5203,6 +5203,14 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, char ***pdomains, char ***pnames, enum lsa_SidType **ptypes); +NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const DOM_SID *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes); NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *pol, int num_names, @@ -5211,6 +5219,15 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, int level, DOM_SID **sids, enum lsa_SidType **types); +NTSTATUS rpccli_lsa_lookup_names4(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, int num_names, + const char **names, + const char ***dom_names, + int level, + DOM_SID **sids, + enum lsa_SidType **types); + bool fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid); /* The following definitions come from rpc_client/cli_netlogon.c */ diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 27f9e4fd98..b6901961d0 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -230,6 +230,120 @@ NTSTATUS cli_read_andx_recv(struct tevent_req *req, ssize_t *received, return NT_STATUS_OK; } +struct cli_readall_state { + struct tevent_context *ev; + struct cli_state *cli; + uint16_t fnum; + off_t start_offset; + size_t size; + size_t received; + uint8_t *buf; +}; + +static void cli_readall_done(struct tevent_req *subreq); + +static struct tevent_req *cli_readall_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + off_t offset, size_t size) +{ + struct tevent_req *req, *subreq; + struct cli_readall_state *state; + + req = tevent_req_create(mem_ctx, &state, struct cli_readall_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->cli = cli; + state->fnum = fnum; + state->start_offset = offset; + state->size = size; + state->received = 0; + state->buf = NULL; + + subreq = cli_read_andx_send(state, ev, cli, fnum, offset, size); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_readall_done, req); + return req; +} + +static void cli_readall_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_readall_state *state = tevent_req_data( + req, struct cli_readall_state); + ssize_t received; + uint8_t *buf; + NTSTATUS status; + + status = cli_read_andx_recv(subreq, &received, &buf); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + + if ((state->received == 0) && (received == state->size)) { + /* Ideal case: Got it all in one run */ + state->buf = buf; + state->received += received; + tevent_req_done(req); + return; + } + + /* + * We got a short read, issue a read for the + * rest. Unfortunately we have to allocate the buffer + * ourselves now, as our caller expects to receive a single + * buffer. cli_read_andx does it from the buffer received from + * the net, but with a short read we have to put it together + * from several reads. + */ + + if (state->buf == NULL) { + state->buf = talloc_array(state, uint8_t, state->size); + if (tevent_req_nomem(state->buf, req)) { + return; + } + } + memcpy(state->buf + state->received, buf, received); + state->received += received; + + TALLOC_FREE(subreq); + + if (state->received >= state->size) { + tevent_req_done(req); + return; + } + + subreq = cli_read_andx_send(state, state->ev, state->cli, state->fnum, + state->start_offset + state->received, + state->size - state->received); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_readall_done, req); +} + +static NTSTATUS cli_readall_recv(struct tevent_req *req, ssize_t *received, + uint8_t **rcvbuf) +{ + struct cli_readall_state *state = tevent_req_data( + req, struct cli_readall_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + *received = state->received; + *rcvbuf = state->buf; + return NT_STATUS_OK; +} + struct cli_pull_subreq { struct tevent_req *req; ssize_t received; @@ -368,7 +482,7 @@ struct tevent_req *cli_pull_send(TALLOC_CTX *mem_ctx, size_left = size - state->requested; request_thistime = MIN(size_left, state->chunk_size); - subreq->req = cli_read_andx_send( + subreq->req = cli_readall_send( state->reqs, ev, cli, fnum, state->start_offset + state->requested, request_thistime); @@ -413,8 +527,8 @@ static void cli_pull_read_done(struct tevent_req *subreq) return; } - status = cli_read_andx_recv(subreq, &pull_subreq->received, - &pull_subreq->buf); + status = cli_readall_recv(subreq, &pull_subreq->received, + &pull_subreq->buf); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(state->req, status); return; @@ -472,7 +586,7 @@ static void cli_pull_read_done(struct tevent_req *subreq) + state->requested), state->top_req)); - new_req = cli_read_andx_send( + new_req = cli_readall_send( state->reqs, state->ev, state->cli, state->fnum, state->start_offset + state->requested, diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e8d6621d1b..197d5bd730 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -543,6 +543,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_RPC_NT_CALL_FAILED", NT_STATUS_RPC_NT_CALL_FAILED }, { "NT_STATUS_RPC_NT_PROTOCOL_ERROR", NT_STATUS_RPC_NT_PROTOCOL_ERROR }, { "NT_STATUS_RPC_NT_PROCNUM_OUT_OF_RANGE", NT_STATUS_RPC_NT_PROCNUM_OUT_OF_RANGE }, + { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, { NULL, NT_STATUS(0) } }; diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c index 4468fe097f..c725fa6b90 100644 --- a/source3/modules/vfs_aio_fork.c +++ b/source3/modules/vfs_aio_fork.c @@ -343,6 +343,9 @@ static void aio_child_loop(int sockfd, struct mmap_area *map) ret_struct.size = sys_pread( fd, (void *)map->ptr, cmd_struct.n, cmd_struct.offset); +#ifdef ENABLE_BUILD_FARM_HACKS + ret_struct.size = MAX(1, ret_struct.size * 0.9); +#endif } else { ret_struct.size = sys_pwrite( diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 68fd96faa8..aa883d3cf1 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -114,7 +114,8 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, const DOM_SID *sids, char **domains, char **names, - enum lsa_SidType *types) + enum lsa_SidType *types, + bool use_lookupsids3) { NTSTATUS result = NT_STATUS_OK; TALLOC_CTX *tmp_ctx = NULL; @@ -147,13 +148,41 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, } } - result = rpccli_lsa_LookupSids(cli, mem_ctx, - pol, - &sid_array, - &ref_domains, - &lsa_names, - level, - &count); + if (use_lookupsids3) { + struct lsa_TransNameArray2 lsa_names2; + uint32_t n; + + result = rpccli_lsa_LookupSids3(cli, mem_ctx, + &sid_array, + &ref_domains, + &lsa_names2, + level, + &count, + 0, + 0); + + if (!NT_STATUS_IS_ERR(result)) { + lsa_names.count = lsa_names2.count; + lsa_names.names = talloc_array(mem_ctx, struct lsa_TranslatedName, lsa_names.count); + if (!lsa_names.names) { + return NT_STATUS_NO_MEMORY; + } + for (n=0; n < lsa_names.count; n++) { + lsa_names.names[n].sid_type = lsa_names2.names[n].sid_type; + lsa_names.names[n].name = lsa_names2.names[n].name; + lsa_names.names[n].sid_index = lsa_names2.names[n].sid_index; + } + } + + } else { + result = rpccli_lsa_LookupSids(cli, mem_ctx, + pol, + &sid_array, + &ref_domains, + &lsa_names, + level, + &count); + } DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n", nt_errstr(result), count)); @@ -233,14 +262,15 @@ done: * at 20480 for win2k3, but we keep it at a save 1000 for now. */ #define LOOKUP_SIDS_HUNK_SIZE 1000 -NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct policy_handle *pol, - int num_sids, - const DOM_SID *sids, - char ***pdomains, - char ***pnames, - enum lsa_SidType **ptypes) +static NTSTATUS rpccli_lsa_lookup_sids_generic(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const DOM_SID *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes, + bool use_lookupsids3) { NTSTATUS result = NT_STATUS_OK; int sids_left = 0; @@ -299,7 +329,8 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, hunk_sids, hunk_domains, hunk_names, - hunk_types); + hunk_types, + use_lookupsids3); if (!NT_STATUS_IS_OK(hunk_result) && !NT_STATUS_EQUAL(hunk_result, STATUS_SOME_UNMAPPED) && @@ -340,25 +371,54 @@ fail: return result; } -/** Lookup a list of names */ +NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const DOM_SID *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes) +{ + return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids, + pdomains, pnames, ptypes, false); +} -NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, +NTSTATUS rpccli_lsa_lookup_sids3(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - struct policy_handle *pol, int num_names, - const char **names, - const char ***dom_names, - int level, - DOM_SID **sids, - enum lsa_SidType **types) + struct policy_handle *pol, + int num_sids, + const DOM_SID *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes) +{ + return rpccli_lsa_lookup_sids_generic(cli, mem_ctx, pol, num_sids, sids, + pdomains, pnames, ptypes, true); +} + +/** Lookup a list of names */ + +static NTSTATUS rpccli_lsa_lookup_names_generic(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, int num_names, + const char **names, + const char ***dom_names, + int level, + DOM_SID **sids, + enum lsa_SidType **types, + bool use_lookupnames4) { NTSTATUS result; int i; struct lsa_String *lsa_names = NULL; struct lsa_RefDomainList *domains = NULL; struct lsa_TransSidArray sid_array; + struct lsa_TransSidArray3 sid_array3; uint32_t count = 0; ZERO_STRUCT(sid_array); + ZERO_STRUCT(sid_array3); lsa_names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names); if (!lsa_names) { @@ -369,14 +429,26 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, init_lsa_String(&lsa_names[i], names[i]); } - result = rpccli_lsa_LookupNames(cli, mem_ctx, - pol, - num_names, - lsa_names, - &domains, - &sid_array, - level, - &count); + if (use_lookupnames4) { + result = rpccli_lsa_LookupNames4(cli, mem_ctx, + num_names, + lsa_names, + &domains, + &sid_array3, + level, + &count, + 0, + 0); + } else { + result = rpccli_lsa_LookupNames(cli, mem_ctx, + pol, + num_names, + lsa_names, + &domains, + &sid_array, + level, + &count); + } if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { @@ -423,10 +495,17 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, } for (i = 0; i < num_names; i++) { - uint32_t dom_idx = sid_array.sids[i].sid_index; - uint32_t dom_rid = sid_array.sids[i].rid; + uint32_t dom_idx; DOM_SID *sid = &(*sids)[i]; + if (use_lookupnames4) { + dom_idx = sid_array3.sids[i].sid_index; + (*types)[i] = sid_array3.sids[i].sid_type; + } else { + dom_idx = sid_array.sids[i].sid_index; + (*types)[i] = sid_array.sids[i].sid_type; + } + /* Translate optimised sid through domain index array */ if (dom_idx == 0xffffffff) { @@ -436,14 +515,16 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, continue; } - sid_copy(sid, domains->domains[dom_idx].sid); + if (use_lookupnames4) { + sid_copy(sid, sid_array3.sids[i].sid); + } else { + sid_copy(sid, domains->domains[dom_idx].sid); - if (dom_rid != 0xffffffff) { - sid_append_rid(sid, dom_rid); + if (sid_array.sids[i].rid != 0xffffffff) { + sid_append_rid(sid, sid_array.sids[i].rid); + } } - (*types)[i] = sid_array.sids[i].sid_type; - if (dom_names == NULL) { continue; } @@ -455,3 +536,31 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, return result; } + +NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, int num_names, + const char **names, + const char ***dom_names, + int level, + DOM_SID **sids, + enum lsa_SidType **types) +{ + return rpccli_lsa_lookup_names_generic(cli, mem_ctx, pol, num_names, + names, dom_names, level, sids, + types, false); +} + +NTSTATUS rpccli_lsa_lookup_names4(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, int num_names, + const char **names, + const char ***dom_names, + int level, + DOM_SID **sids, + enum lsa_SidType **types) +{ + return rpccli_lsa_lookup_names_generic(cli, mem_ctx, pol, num_names, + names, dom_names, level, sids, + types, true); +} diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index d428c3aa9e..c5c0c02090 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1087,7 +1087,7 @@ static void schannel_digest(struct schannel_auth_struct *a, SSVAL(sig,0,verf->SignatureAlgorithm); SSVAL(sig,2,verf->SealAlgorithm); SSVAL(sig,4,verf->Pad); - SSVAL(sig,8,verf->Flags); + SSVAL(sig,6,verf->Flags); /* verfiy the signature on the packet by MD5 over various bits */ MD5Init(&ctx3); diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index f21c80e327..07a0b971a0 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -1150,7 +1150,7 @@ NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p, struct netr_LogonSamLogonEx *r) { NTSTATUS status; - struct netlogon_creds_CredentialState *creds; + struct netlogon_creds_CredentialState *creds = NULL; become_root(); status = schannel_fetch_session_key(p->mem_ctx, r->in.computer_name, &creds); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7be0a0d2d2..ce7df63972 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2199,11 +2199,13 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss return False; } - blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in), data_len); + blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in), auth_len); ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &schannel_chk, (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_SIGNATURE); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("failed to pull NL_AUTH_SIGNATURE\n")); + dump_data(2, blob.data, blob.length); return false; } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 2d50280ac8..058bd12f61 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -773,7 +773,7 @@ NTSTATUS _samr_QuerySecurity(pipes_struct *p, struct samr_alias_info *ainfo; NTSTATUS status; SEC_DESC * psd = NULL; - size_t sd_size; + size_t sd_size = 0; cinfo = policy_handle_find(p, r->in.handle, STD_RIGHT_READ_CONTROL_ACCESS, NULL, |