diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-06-24 16:26:23 +1000 |
commit | 6da26870e0ae5acd6ff49a30ec2f6886b44d095e (patch) | |
tree | 850c71039563c16a5d563c47e7ba2ab645baf198 /source3/libsmb | |
parent | 6925a799d04c6fa59dd2ddef1f5510f9bb7d17d1 (diff) | |
parent | 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 (diff) | |
download | samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.gz samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.tar.bz2 samba-6da26870e0ae5acd6ff49a30ec2f6886b44d095e.zip |
Merge 2610c05b5b95cc7036b3d6dfb894c6cfbdb68483 as Samba-4.0alpha16
Diffstat (limited to 'source3/libsmb')
53 files changed, 3913 insertions, 4465 deletions
diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 8af5aa1046..ee15caee7a 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -18,97 +18,14 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "../lib/async_req/async_sock.h" +#include "../lib/util/tevent_ntstatus.h" +#include "../lib/util/tevent_unix.h" #include "async_smb.h" #include "smb_crypt.h" #include "libsmb/nmblib.h" - -/* - * Read an smb packet asynchronously, discard keepalives - */ - -struct read_smb_state { - struct tevent_context *ev; - int fd; - uint8_t *buf; -}; - -static ssize_t read_smb_more(uint8_t *buf, size_t buflen, void *private_data); -static void read_smb_done(struct tevent_req *subreq); - -static struct tevent_req *read_smb_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd) -{ - struct tevent_req *result, *subreq; - struct read_smb_state *state; - - result = tevent_req_create(mem_ctx, &state, struct read_smb_state); - if (result == NULL) { - return NULL; - } - state->ev = ev; - state->fd = fd; - - subreq = read_packet_send(state, ev, fd, 4, read_smb_more, NULL); - if (subreq == NULL) { - goto fail; - } - tevent_req_set_callback(subreq, read_smb_done, result); - return result; - fail: - TALLOC_FREE(result); - return NULL; -} - -static ssize_t read_smb_more(uint8_t *buf, size_t buflen, void *private_data) -{ - if (buflen > 4) { - return 0; /* We've been here, we're done */ - } - return smb_len_large(buf); -} - -static void read_smb_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct read_smb_state *state = tevent_req_data( - req, struct read_smb_state); - ssize_t len; - int err; - - len = read_packet_recv(subreq, state, &state->buf, &err); - TALLOC_FREE(subreq); - if (len == -1) { - tevent_req_error(req, err); - return; - } - - if (CVAL(state->buf, 0) == SMBkeepalive) { - subreq = read_packet_send(state, state->ev, state->fd, 4, - read_smb_more, NULL); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, read_smb_done, req); - return; - } - tevent_req_done(req); -} - -static ssize_t read_smb_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - uint8_t **pbuf, int *perrno) -{ - struct read_smb_state *state = tevent_req_data( - req, struct read_smb_state); - - if (tevent_req_is_unix_error(req, perrno)) { - return -1; - } - *pbuf = talloc_move(mem_ctx, &state->buf); - return talloc_get_size(*pbuf); -} +#include "read_smb.h" /** * Fetch an error out of a NBT packet @@ -236,6 +153,14 @@ void cli_smb_req_unset_pending(struct tevent_req *req) int num_pending = talloc_array_length(cli->pending); int i; + if (state->mid != 0) { + /* + * This is a [nt]trans[2] request which waits + * for more than one reply. + */ + return; + } + if (num_pending == 1) { /* * The pending read_smb tevent_req is a child of @@ -263,9 +188,7 @@ void cli_smb_req_unset_pending(struct tevent_req *req) /* * Remove ourselves from the cli->pending array */ - if (num_pending > 1) { - cli->pending[i] = cli->pending[num_pending-1]; - } + cli->pending[i] = cli->pending[num_pending-1]; /* * No NULL check here, we're shrinking by sizeof(void *), and @@ -278,6 +201,13 @@ void cli_smb_req_unset_pending(struct tevent_req *req) static int cli_smb_req_destructor(struct tevent_req *req) { + struct cli_smb_state *state = tevent_req_data( + req, struct cli_smb_state); + /* + * Make sure we really remove it from + * the pending array on destruction. + */ + state->mid = 0; cli_smb_req_unset_pending(req); return 0; } @@ -340,6 +270,20 @@ void cli_smb_req_set_mid(struct tevent_req *req, uint16_t mid) state->mid = mid; } +uint32_t cli_smb_req_seqnum(struct tevent_req *req) +{ + struct cli_smb_state *state = tevent_req_data( + req, struct cli_smb_state); + return state->seqnum; +} + +void cli_smb_req_set_seqnum(struct tevent_req *req, uint32_t seqnum) +{ + struct cli_smb_state *state = tevent_req_data( + req, struct cli_smb_state); + state->seqnum = seqnum; +} + static size_t iov_len(const struct iovec *iov, int count) { size_t result = 0; @@ -423,9 +367,9 @@ struct tevent_req *cli_smb_req_create(TALLOC_CTX *mem_ctx, state->iov_count = iov_count + 3; if (cli->timeout) { - endtime = timeval_current_ofs(0, cli->timeout * 1000); + endtime = timeval_current_ofs_msec(cli->timeout); if (!tevent_req_set_endtime(result, ev, endtime)) { - tevent_req_nomem(NULL, result); + tevent_req_oom(result); } } return result; @@ -496,8 +440,8 @@ static NTSTATUS cli_smb_req_iov_send(struct tevent_req *req, if (buf == NULL) { return NT_STATUS_NO_MEMORY; } - status = cli_encrypt_message(state->cli, (char *)buf, - &enc_buf); + status = common_encrypt_buffer(state->cli->trans_enc_state, + (char *)buf, &enc_buf); TALLOC_FREE(buf); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Error in encrypting client message: %s\n", @@ -544,7 +488,7 @@ struct tevent_req *cli_smb_send(TALLOC_CTX *mem_ctx, struct iovec iov; NTSTATUS status; - iov.iov_base = CONST_DISCARD(void *, bytes); + iov.iov_base = discard_const_p(void, bytes); iov.iov_len = num_bytes; req = cli_smb_req_create(mem_ctx, ev, cli, smb_command, @@ -712,7 +656,7 @@ static void cli_smb_received(struct tevent_req *subreq) if (state->chained_requests == NULL) { state->inbuf = talloc_move(state, &inbuf); talloc_set_destructor(req, NULL); - cli_smb_req_destructor(req); + cli_smb_req_unset_pending(req); state->chain_num = 0; state->chain_length = 1; tevent_req_done(req); @@ -756,7 +700,7 @@ static void cli_smb_received(struct tevent_req *subreq) while (talloc_array_length(cli->pending) > 0) { req = cli->pending[0]; talloc_set_destructor(req, NULL); - cli_smb_req_destructor(req); + cli_smb_req_unset_pending(req); tevent_req_nterror(req, status); } } @@ -779,6 +723,24 @@ NTSTATUS cli_smb_recv(struct tevent_req *req, } if (state->inbuf == NULL) { + if (min_wct != 0) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + if (pinbuf) { + *pinbuf = NULL; + } + if (pwct) { + *pwct = 0; + } + if (pvwv) { + *pvwv = NULL; + } + if (pnum_bytes) { + *pnum_bytes = 0; + } + if (pbytes) { + *pbytes = NULL; + } /* This was a request without a reply */ return NT_STATUS_OK; } @@ -821,6 +783,8 @@ NTSTATUS cli_smb_recv(struct tevent_req *req, status = cli_pull_error((char *)state->inbuf); + cli_set_error(state->cli, status); + if (!have_andx_command((char *)state->inbuf, wct_ofs)) { if ((cmd == SMBsesssetupX) diff --git a/source3/libsmb/cli_np_tstream.c b/source3/libsmb/cli_np_tstream.c index 1f9e5ffd36..7521181ec8 100644 --- a/source3/libsmb/cli_np_tstream.c +++ b/source3/libsmb/cli_np_tstream.c @@ -19,7 +19,8 @@ #include "includes.h" #include "system/network.h" -#include "../util/tevent_unix.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "../lib/tsocket/tsocket.h" #include "../lib/tsocket/tsocket_internal.h" #include "cli_np_tstream.h" @@ -27,9 +28,24 @@ static const struct tstream_context_ops tstream_cli_np_ops; /* - * Window uses 1024 hardcoded for read size and trans max data + * Windows uses 4280 (the max xmit/recv size negotiated on DCERPC). + * This is fits into the max_xmit negotiated at the SMB layer. + * + * On the sending side they may use SMBtranss if the request does not + * fit into a single SMBtrans call. + * + * Windows uses 1024 as max data size of a SMBtrans request and then + * possibly reads the rest of the DCERPC fragment (up to 3256 bytes) + * via a SMBreadX. + * + * For now we just ask for the full 4280 bytes (max data size) in the SMBtrans + * request to get the whole fragment at once (like samba 3.5.x and below did. + * + * It is important that we use do SMBwriteX with the size of a full fragment, + * otherwise we may get NT_STATUS_PIPE_BUSY on the SMBtrans request + * from NT4 servers. (See bug #8195) */ -#define TSTREAM_CLI_NP_BUF_SIZE 1024 +#define TSTREAM_CLI_NP_MAX_BUF_SIZE 4280 struct tstream_cli_np { struct cli_state *cli; @@ -47,7 +63,7 @@ struct tstream_cli_np { struct { off_t ofs; size_t left; - uint8_t buf[TSTREAM_CLI_NP_BUF_SIZE]; + uint8_t *buf; } read, write; }; @@ -347,9 +363,26 @@ static void tstream_cli_np_writev_write_next(struct tevent_req *req) tstream_context_data(state->stream, struct tstream_cli_np); struct tevent_req *subreq; + size_t i; + size_t left = 0; + + for (i=0; i < state->count; i++) { + left += state->vector[i].iov_len; + } + + if (left == 0) { + TALLOC_FREE(cli_nps->write.buf); + tevent_req_done(req); + return; + } cli_nps->write.ofs = 0; - cli_nps->write.left = TSTREAM_CLI_NP_BUF_SIZE; + cli_nps->write.left = MIN(left, TSTREAM_CLI_NP_MAX_BUF_SIZE); + cli_nps->write.buf = talloc_realloc(cli_nps, cli_nps->write.buf, + uint8_t, cli_nps->write.left); + if (tevent_req_nomem(cli_nps->write.buf, req)) { + return; + } /* * copy the pending buffer first @@ -375,11 +408,6 @@ static void tstream_cli_np_writev_write_next(struct tevent_req *req) state->ret += len; } - if (cli_nps->write.ofs == 0) { - tevent_req_done(req); - return; - } - if (cli_nps->trans.active && state->count == 0) { cli_nps->trans.active = false; cli_nps->trans.write_req = req; @@ -478,9 +506,8 @@ static void tstream_cli_np_writev_disconnect_done(struct tevent_req *subreq) tevent_req_data(req, struct tstream_cli_np_writev_state); struct tstream_cli_np *cli_nps = tstream_context_data(state->stream, struct tstream_cli_np); - NTSTATUS status; - status = cli_close_recv(subreq); + cli_close_recv(subreq); TALLOC_FREE(subreq); cli_nps->cli = NULL; @@ -619,6 +646,10 @@ static void tstream_cli_np_readv_read_next(struct tevent_req *req) state->ret += len; } + if (cli_nps->read.left == 0) { + TALLOC_FREE(cli_nps->read.buf); + } + if (state->count == 0) { tevent_req_done(req); return; @@ -637,7 +668,7 @@ static void tstream_cli_np_readv_read_next(struct tevent_req *req) } subreq = cli_read_andx_send(state, state->ev, cli_nps->cli, - cli_nps->fnum, 0, TSTREAM_CLI_NP_BUF_SIZE); + cli_nps->fnum, 0, TSTREAM_CLI_NP_MAX_BUF_SIZE); if (tevent_req_nomem(subreq, req)) { return; } @@ -673,7 +704,7 @@ static void tstream_cli_np_readv_trans_start(struct tevent_req *req) NULL, 0, 0, cli_nps->write.buf, cli_nps->write.ofs, - TSTREAM_CLI_NP_BUF_SIZE); + TSTREAM_CLI_NP_MAX_BUF_SIZE); if (tevent_req_nomem(subreq, req)) { return; } @@ -713,7 +744,7 @@ static void tstream_cli_np_readv_trans_done(struct tevent_req *subreq) return; } - if (received > TSTREAM_CLI_NP_BUF_SIZE) { + if (received > TSTREAM_CLI_NP_MAX_BUF_SIZE) { tstream_cli_np_readv_disconnect_now(req, EIO, __location__); return; } @@ -725,8 +756,7 @@ static void tstream_cli_np_readv_trans_done(struct tevent_req *subreq) cli_nps->read.ofs = 0; cli_nps->read.left = received; - memcpy(cli_nps->read.buf, rcvbuf, received); - TALLOC_FREE(rcvbuf); + cli_nps->read.buf = talloc_move(cli_nps, &rcvbuf); if (cli_nps->trans.write_req == NULL) { tstream_cli_np_readv_read_next(req); @@ -788,7 +818,7 @@ static void tstream_cli_np_readv_read_done(struct tevent_req *subreq) return; } - if (received > TSTREAM_CLI_NP_BUF_SIZE) { + if (received > TSTREAM_CLI_NP_MAX_BUF_SIZE) { TALLOC_FREE(subreq); tstream_cli_np_readv_disconnect_now(req, EIO, __location__); return; @@ -802,6 +832,12 @@ static void tstream_cli_np_readv_read_done(struct tevent_req *subreq) cli_nps->read.ofs = 0; cli_nps->read.left = received; + cli_nps->read.buf = talloc_array(cli_nps, uint8_t, received); + if (cli_nps->read.buf == NULL) { + TALLOC_FREE(subreq); + tevent_req_nomem(cli_nps->read.buf, req); + return; + } memcpy(cli_nps->read.buf, rcvbuf, received); TALLOC_FREE(subreq); @@ -852,9 +888,8 @@ static void tstream_cli_np_readv_disconnect_done(struct tevent_req *subreq) tevent_req_data(req, struct tstream_cli_np_readv_state); struct tstream_cli_np *cli_nps = tstream_context_data(state->stream, struct tstream_cli_np); - NTSTATUS status; - status = cli_close_recv(subreq); + cli_close_recv(subreq); TALLOC_FREE(subreq); cli_nps->cli = NULL; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e3d97b60fa..62e3a35a36 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3,6 +3,8 @@ client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Volker Lendecke 2011 + Copyright (C) Jeremy Allison 2011 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 @@ -19,6 +21,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "popt_common.h" #include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/spnego.h" @@ -26,8 +29,10 @@ #include "../libcli/auth/ntlmssp.h" #include "libads/kerberos_proto.h" #include "krb5_env.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" #include "libsmb/nmblib.h" +#include "read_smb.h" static const struct { int prot; @@ -47,6 +52,40 @@ static const struct { #define STAR_SMBSERVER "*SMBSERVER" +/******************************************************** + Utility function to ensure we always return at least + a valid char * pointer to an empty string for the + cli->server_os, cli->server_type and cli->server_domain + strings. +*******************************************************/ + +static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli, + char *inbuf, + char **dest, + uint8_t *src, + size_t srclen, + ssize_t *destlen) +{ + *destlen = clistr_pull_talloc(cli, + inbuf, + SVAL(inbuf, smb_flg2), + dest, + (char *)src, + srclen, + STR_TERMINATE); + if (*destlen == -1) { + return NT_STATUS_NO_MEMORY; + } + + if (*dest == NULL) { + *dest = talloc_strdup(cli, ""); + if (*dest == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; +} + /** * Set the user session key for a connection * @param cli The cli structure to add it too @@ -63,86 +102,267 @@ static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_ Do an old lanman2 style session setup. ****************************************************************************/ -static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, - const char *user, - const char *pass, size_t passlen, - const char *workgroup) +struct cli_session_setup_lanman2_state { + struct cli_state *cli; + uint16_t vwv[10]; + const char *user; +}; + +static void cli_session_setup_lanman2_done(struct tevent_req *subreq); + +static struct tevent_req *cli_session_setup_lanman2_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *workgroup) { + struct tevent_req *req, *subreq; + struct cli_session_setup_lanman2_state *state; DATA_BLOB lm_response = data_blob_null; - NTSTATUS status; - fstring pword; - char *p; + uint16_t *vwv; + uint8_t *bytes; + char *tmp; - if (passlen > sizeof(pword)-1) { - return NT_STATUS_INVALID_PARAMETER; + req = tevent_req_create(mem_ctx, &state, + struct cli_session_setup_lanman2_state); + if (req == NULL) { + return NULL; } + state->cli = cli; + state->user = user; + vwv = state->vwv; - /* LANMAN servers predate NT status codes and Unicode and ignore those - smb flags so we must disable the corresponding default capabilities - that would otherwise cause the Unicode and NT Status flags to be - set (and even returned by the server) */ + /* + * LANMAN servers predate NT status codes and Unicode and + * ignore those smb flags so we must disable the corresponding + * default capabilities that would otherwise cause the Unicode + * and NT Status flags to be set (and even returned by the + * server) + */ cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) + /* + * if in share level security then don't send a password now + */ + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; + } - if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { - /* Encrypted mode needed, and non encrypted password supplied. */ + if (passlen > 0 + && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) + && passlen != 24) { + /* + * Encrypted mode needed, and non encrypted password + * supplied. + */ lm_response = data_blob(NULL, 24); - if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { - DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); - return NT_STATUS_ACCESS_DENIED; + if (tevent_req_nomem(lm_response.data, req)) { + return tevent_req_post(req, ev); + } + + if (!SMBencrypt(pass, cli->secblob.data, + (uint8_t *)lm_response.data)) { + DEBUG(1, ("Password is > 14 chars in length, and is " + "therefore incompatible with Lanman " + "authentication\n")); + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return tevent_req_post(req, ev); } - } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { - /* Encrypted mode needed, and encrypted password supplied. */ + } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) + && passlen == 24) { + /* + * Encrypted mode needed, and encrypted password + * supplied. + */ lm_response = data_blob(pass, passlen); + if (tevent_req_nomem(lm_response.data, req)) { + return tevent_req_post(req, ev); + } } else if (passlen > 0) { - /* Plaintext mode needed, assume plaintext supplied. */ - passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + uint8_t *buf; + size_t converted_size; + /* + * Plaintext mode needed, assume plaintext supplied. + */ + buf = talloc_array(talloc_tos(), uint8_t, 0); + buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1, + &converted_size); + if (tevent_req_nomem(buf, req)) { + return tevent_req_post(req, ev); + } lm_response = data_blob(pass, passlen); + TALLOC_FREE(buf); + if (tevent_req_nomem(lm_response.data, req)) { + return tevent_req_post(req, ev); + } } - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); - cli_set_message(cli->outbuf,10, 0, True); - SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - cli_setup_packet(cli); + SCVAL(vwv+0, 0, 0xff); + SCVAL(vwv+0, 1, 0); + SSVAL(vwv+1, 0, 0); + SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); + SSVAL(vwv+3, 0, 2); + SSVAL(vwv+4, 0, 1); + SIVAL(vwv+5, 0, cli->sesskey); + SSVAL(vwv+7, 0, lm_response.length); - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,1); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,lm_response.length); + bytes = talloc_array(state, uint8_t, lm_response.length); + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } + if (lm_response.length != 0) { + memcpy(bytes, lm_response.data, lm_response.length); + } + data_blob_free(&lm_response); - p = smb_buf(cli->outbuf); - memcpy(p,lm_response.data,lm_response.length); - p += lm_response.length; - p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); - cli_setup_bcc(cli, p); + tmp = talloc_strdup_upper(talloc_tos(), user); + if (tevent_req_nomem(tmp, req)) { + return tevent_req_post(req, ev); + } + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1, + NULL); + TALLOC_FREE(tmp); - if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - return cli_nt_error(cli); + tmp = talloc_strdup_upper(talloc_tos(), workgroup); + if (tevent_req_nomem(tmp, req)) { + return tevent_req_post(req, ev); } + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1, + NULL); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL); - show_msg(cli->inbuf); + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } - if (cli_is_error(cli)) { - return cli_nt_error(cli); + subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv, + talloc_get_size(bytes), bytes); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req); + return req; +} - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - status = cli_set_username(cli, user); +static void cli_session_setup_lanman2_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_session_setup_lanman2_state *state = tevent_req_data( + req, struct cli_session_setup_lanman2_state); + struct cli_state *cli = state->cli; + uint32_t num_bytes; + uint8_t *in; + char *inbuf; + uint8_t *bytes; + uint8_t *p; + NTSTATUS status; + ssize_t ret; + uint8_t wct; + uint16_t *vwv; + + status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, + &num_bytes, &bytes); + TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - return status; + tevent_req_nterror(req, status); + return; } - return NT_STATUS_OK; + + inbuf = (char *)in; + p = bytes; + + cli->vuid = SVAL(inbuf, smb_uid); + cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_os, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_type, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_domain, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + if (strstr(cli->server_type, "Samba")) { + cli->is_samba = True; + } + status = cli_set_username(cli, state->user); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + +static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *workgroup) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen, + workgroup); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_session_setup_lanman2_recv(req); + fail: + TALLOC_FREE(frame); + return status; } /**************************************************************************** @@ -267,8 +487,11 @@ static void cli_session_setup_guest_done(struct tevent_req *subreq) uint8_t *bytes; uint8_t *p; NTSTATUS status; + ssize_t ret; + uint8_t wct; + uint16_t *vwv; - status = cli_smb_recv(subreq, state, &in, 0, NULL, NULL, + status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, &num_bytes, &bytes); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { @@ -280,13 +503,46 @@ static void cli_session_setup_guest_done(struct tevent_req *subreq) p = bytes; cli->vuid = SVAL(inbuf, smb_uid); + cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_os, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_type, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; - p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring), - bytes+num_bytes-p, STR_TERMINATE); - p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring), - bytes+num_bytes-p, STR_TERMINATE); - p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring), - bytes+num_bytes-p, STR_TERMINATE); + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_domain, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; if (strstr(cli->server_type, "Samba")) { cli->is_samba = True; @@ -340,9 +596,6 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli) status = cli_session_setup_guest_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -350,82 +603,201 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli) Do a NT1 plaintext session setup. ****************************************************************************/ -static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, - const char *user, const char *pass, - const char *workgroup) +struct cli_session_setup_plain_state { + struct cli_state *cli; + uint16_t vwv[13]; + const char *user; +}; + +static void cli_session_setup_plain_done(struct tevent_req *subreq); + +static struct tevent_req *cli_session_setup_plain_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct cli_state *cli, + const char *user, const char *pass, const char *workgroup) { - uint32 capabilities = cli_session_setup_capabilities(cli); - char *p; + struct tevent_req *req, *subreq; + struct cli_session_setup_plain_state *state; + uint16_t *vwv; + uint8_t *bytes; + size_t passlen; + char *version; + + req = tevent_req_create(mem_ctx, &state, + struct cli_session_setup_plain_state); + if (req == NULL) { + return NULL; + } + state->cli = cli; + state->user = user; + vwv = state->vwv; + + SCVAL(vwv+0, 0, 0xff); + SCVAL(vwv+0, 1, 0); + SSVAL(vwv+1, 0, 0); + SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); + SSVAL(vwv+3, 0, 2); + SSVAL(vwv+4, 0, cli->pid); + SIVAL(vwv+5, 0, cli->sesskey); + SSVAL(vwv+7, 0, 0); + SSVAL(vwv+8, 0, 0); + SSVAL(vwv+9, 0, 0); + SSVAL(vwv+10, 0, 0); + SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli)); + + bytes = talloc_array(state, uint8_t, 0); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1, + &passlen); + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } + SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen); + + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), + user, strlen(user)+1, NULL); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), + workgroup, strlen(workgroup)+1, NULL); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), + "Unix", 5, NULL); + + version = talloc_asprintf(talloc_tos(), "Samba %s", + samba_version_string()); + if (tevent_req_nomem(version, req)){ + return tevent_req_post(req, ev); + } + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), + version, strlen(version)+1, NULL); + TALLOC_FREE(version); + + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } + + subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv, + talloc_get_size(bytes), bytes); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_session_setup_plain_done, req); + return req; +} + +static void cli_session_setup_plain_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_session_setup_plain_state *state = tevent_req_data( + req, struct cli_session_setup_plain_state); + struct cli_state *cli = state->cli; + uint32_t num_bytes; + uint8_t *in; + char *inbuf; + uint8_t *bytes; + uint8_t *p; NTSTATUS status; - fstring lanman; - - fstr_sprintf( lanman, "Samba %s", samba_version_string()); - - memset(cli->outbuf, '\0', smb_size); - cli_set_message(cli->outbuf,13,0,True); - SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - cli_setup_packet(cli); - - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv8,0); - SIVAL(cli->outbuf,smb_vwv11,capabilities); - p = smb_buf(cli->outbuf); - - /* check wether to send the ASCII or UNICODE version of the password */ - - if ( (capabilities & CAP_UNICODE) == 0 ) { - p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ - SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); - } - else { - /* For ucs2 passwords clistr_push calls ucs2_align, which causes - * the space taken by the unicode password to be one byte too - * long (as we're on an odd byte boundary here). Reduce the - * count by 1 to cope with this. Fixes smbclient against NetApp - * servers which can't cope. Fix from - * bryan.kolodziej@allenlund.com in bug #3840. - */ - p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */ - SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1); + ssize_t ret; + uint8_t wct; + uint16_t *vwv; + + status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, + &num_bytes, &bytes); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; } - p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ - p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); - cli_setup_bcc(cli, p); + inbuf = (char *)in; + p = bytes; + + cli->vuid = SVAL(inbuf, smb_uid); + cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_os, + p, + bytes+num_bytes-p, + &ret); - if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - return cli_nt_error(cli); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + p += ret; - show_msg(cli->inbuf); + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_type, + p, + bytes+num_bytes-p, + &ret); - if (cli_is_error(cli)) { - return cli_nt_error(cli); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + p += ret; + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_domain, + p, + bytes+num_bytes-p, + &ret); - cli->vuid = SVAL(cli->inbuf,smb_uid); - p = smb_buf(cli->inbuf); - p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), - -1, STR_TERMINATE); - p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), - -1, STR_TERMINATE); - p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), - -1, STR_TERMINATE); - status = cli_set_username(cli, user); if (!NT_STATUS_IS_OK(status)) { - return status; + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = cli_set_username(cli, state->user); + if (tevent_req_nterror(req, status)) { + return; } if (strstr(cli->server_type, "Samba")) { cli->is_samba = True; } + tevent_req_done(req); +} - return NT_STATUS_OK; +static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +static NTSTATUS cli_session_setup_plain(struct cli_state *cli, + const char *user, const char *pass, + const char *workgroup) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_session_setup_plain_send(frame, ev, cli, user, pass, + workgroup); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_session_setup_plain_recv(req); + fail: + TALLOC_FREE(frame); + return status; } /**************************************************************************** @@ -438,18 +810,40 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, @param workgroup The user's domain. ****************************************************************************/ -static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, - const char *ntpass, size_t ntpasslen, - const char *workgroup) +struct cli_session_setup_nt1_state { + struct cli_state *cli; + uint16_t vwv[13]; + DATA_BLOB response; + DATA_BLOB session_key; + const char *user; +}; + +static void cli_session_setup_nt1_done(struct tevent_req *subreq); + +static struct tevent_req *cli_session_setup_nt1_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, + const char *workgroup) { - uint32 capabilities = cli_session_setup_capabilities(cli); + struct tevent_req *req, *subreq; + struct cli_session_setup_nt1_state *state; DATA_BLOB lm_response = data_blob_null; DATA_BLOB nt_response = data_blob_null; DATA_BLOB session_key = data_blob_null; - NTSTATUS result; - char *p; - bool ok; + uint16_t *vwv; + uint8_t *bytes; + char *workgroup_upper; + + req = tevent_req_create(mem_ctx, &state, + struct cli_session_setup_nt1_state); + if (req == NULL) { + return NULL; + } + state->cli = cli; + state->user = user; + vwv = state->vwv; if (passlen == 0) { /* do nothing - guest login */ @@ -457,20 +851,35 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; - server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); - /* note that the 'workgroup' here is a best guess - we don't know - the server's domain at this point. The 'server name' is also - dodgy... - */ - names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup); + server_chal = data_blob(cli->secblob.data, + MIN(cli->secblob.length, 8)); + if (tevent_req_nomem(server_chal.data, req)) { + return tevent_req_post(req, ev); + } + + /* + * note that the 'workgroup' here is a best + * guess - we don't know the server's domain + * at this point. The 'server name' is also + * dodgy... + */ + names_blob = NTLMv2_generate_names_blob( + NULL, cli->called.name, workgroup); + + if (tevent_req_nomem(names_blob.data, req)) { + return tevent_req_post(req, ev); + } - if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal, - &names_blob, - &lm_response, &nt_response, NULL, &session_key)) { + if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, + &server_chal, &names_blob, + &lm_response, &nt_response, + NULL, &session_key)) { data_blob_free(&names_blob); data_blob_free(&server_chal); - return NT_STATUS_ACCESS_DENIED; + tevent_req_nterror( + req, NT_STATUS_ACCESS_DENIED); + return tevent_req_post(req, ev); } data_blob_free(&names_blob); data_blob_free(&server_chal); @@ -483,23 +892,50 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, nt_response = data_blob_null; #else nt_response = data_blob(NULL, 24); - SMBNTencrypt(pass,cli->secblob.data,nt_response.data); + if (tevent_req_nomem(nt_response.data, req)) { + return tevent_req_post(req, ev); + } + + SMBNTencrypt(pass, cli->secblob.data, + nt_response.data); #endif /* non encrypted password supplied. Ignore ntpass. */ if (lp_client_lanman_auth()) { + lm_response = data_blob(NULL, 24); - if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) { - /* Oops, the LM response is invalid, just put - the NT response there instead */ + if (tevent_req_nomem(lm_response.data, req)) { + return tevent_req_post(req, ev); + } + + if (!SMBencrypt(pass,cli->secblob.data, + lm_response.data)) { + /* + * Oops, the LM response is + * invalid, just put the NT + * response there instead + */ data_blob_free(&lm_response); - lm_response = data_blob(nt_response.data, nt_response.length); + lm_response = data_blob( + nt_response.data, + nt_response.length); } } else { - /* LM disabled, place NT# in LM field instead */ - lm_response = data_blob(nt_response.data, nt_response.length); + /* + * LM disabled, place NT# in LM field + * instead + */ + lm_response = data_blob( + nt_response.data, nt_response.length); + } + + if (tevent_req_nomem(lm_response.data, req)) { + return tevent_req_post(req, ev); } session_key = data_blob(NULL, 16); + if (tevent_req_nomem(session_key.data, req)) { + return tevent_req_post(req, ev); + } #ifdef LANMAN_ONLY E_deshash(pass, session_key.data); memset(&session_key.data[8], '\0', 8); @@ -514,94 +950,219 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, signing because we don't have original key */ lm_response = data_blob(pass, passlen); + if (tevent_req_nomem(lm_response.data, req)) { + return tevent_req_post(req, ev); + } + nt_response = data_blob(ntpass, ntpasslen); + if (tevent_req_nomem(nt_response.data, req)) { + return tevent_req_post(req, ev); + } } - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); +#ifdef LANMAN_ONLY + state->response = data_blob_talloc( + state, lm_response.data, lm_response.length); +#else + state->response = data_blob_talloc( + state, nt_response.data, nt_response.length); +#endif + if (tevent_req_nomem(state->response.data, req)) { + return tevent_req_post(req, ev); + } - cli_set_message(cli->outbuf,13,0,True); - SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - cli_setup_packet(cli); + if (session_key.data) { + state->session_key = data_blob_talloc( + state, session_key.data, session_key.length); + if (tevent_req_nomem(state->session_key.data, req)) { + return tevent_req_post(req, ev); + } + } + data_blob_free(&session_key); + + SCVAL(vwv+0, 0, 0xff); + SCVAL(vwv+0, 1, 0); + SSVAL(vwv+1, 0, 0); + SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); + SSVAL(vwv+3, 0, 2); + SSVAL(vwv+4, 0, cli->pid); + SIVAL(vwv+5, 0, cli->sesskey); + SSVAL(vwv+7, 0, lm_response.length); + SSVAL(vwv+8, 0, nt_response.length); + SSVAL(vwv+9, 0, 0); + SSVAL(vwv+10, 0, 0); + SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli)); - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,lm_response.length); - SSVAL(cli->outbuf,smb_vwv8,nt_response.length); - SIVAL(cli->outbuf,smb_vwv11,capabilities); - p = smb_buf(cli->outbuf); - if (lm_response.length) { - memcpy(p,lm_response.data, lm_response.length); p += lm_response.length; + bytes = talloc_array(state, uint8_t, + lm_response.length + nt_response.length); + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } + if (lm_response.length != 0) { + memcpy(bytes, lm_response.data, lm_response.length); } - if (nt_response.length) { - memcpy(p,nt_response.data, nt_response.length); p += nt_response.length; + if (nt_response.length != 0) { + memcpy(bytes + lm_response.length, + nt_response.data, nt_response.length); } - p += clistr_push(cli, p, user, -1, STR_TERMINATE); + data_blob_free(&lm_response); + data_blob_free(&nt_response); - /* Upper case here might help some NTLMv2 implementations */ - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); - cli_setup_bcc(cli, p); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), + user, strlen(user)+1, NULL); - if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - result = cli_nt_error(cli); - goto end; + /* + * Upper case here might help some NTLMv2 implementations + */ + workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup); + if (tevent_req_nomem(workgroup_upper, req)) { + return tevent_req_post(req, ev); } + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), + workgroup_upper, strlen(workgroup_upper)+1, + NULL); + TALLOC_FREE(workgroup_upper); - /* show_msg(cli->inbuf); */ + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL); + bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL); + if (tevent_req_nomem(bytes, req)) { + return tevent_req_post(req, ev); + } - if (cli_is_error(cli)) { - result = cli_nt_error(cli); - goto end; + subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv, + talloc_get_size(bytes), bytes); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req); + return req; +} -#ifdef LANMAN_ONLY - ok = cli_simple_set_signing(cli, session_key, lm_response); -#else - ok = cli_simple_set_signing(cli, session_key, nt_response); -#endif - if (ok) { - if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { - result = NT_STATUS_ACCESS_DENIED; - goto end; - } +static void cli_session_setup_nt1_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_session_setup_nt1_state *state = tevent_req_data( + req, struct cli_session_setup_nt1_state); + struct cli_state *cli = state->cli; + uint32_t num_bytes; + uint8_t *in; + char *inbuf; + uint8_t *bytes; + uint8_t *p; + NTSTATUS status; + ssize_t ret; + uint8_t wct; + uint16_t *vwv; + + status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, + &num_bytes, &bytes); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); + inbuf = (char *)in; + p = bytes; - p = smb_buf(cli->inbuf); - p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), - -1, STR_TERMINATE); - p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), - -1, STR_TERMINATE); - p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), - -1, STR_TERMINATE); + cli->vuid = SVAL(inbuf, smb_uid); + cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_os, + p, + bytes+num_bytes-p, + &ret); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_type, + p, + bytes+num_bytes-p, + &ret); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + inbuf, + &cli->server_domain, + p, + bytes+num_bytes-p, + &ret); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; if (strstr(cli->server_type, "Samba")) { cli->is_samba = True; } - result = cli_set_username(cli, user); - if (!NT_STATUS_IS_OK(result)) { - goto end; + status = cli_set_username(cli, state->user); + if (tevent_req_nterror(req, status)) { + return; } - - if (session_key.data) { + if (cli_simple_set_signing(cli, state->session_key, state->response) + && !cli_check_sign_mac(cli, (char *)in, 1)) { + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return; + } + if (state->session_key.data) { /* Have plaintext orginal */ - cli_set_session_key(cli, session_key); + cli_set_session_key(cli, state->session_key); } + tevent_req_done(req); +} - result = NT_STATUS_OK; -end: - data_blob_free(&lm_response); - data_blob_free(&nt_response); - data_blob_free(&session_key); - return result; +static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, + const char *workgroup) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen, + ntpass, ntpasslen, workgroup); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_session_setup_nt1_recv(req); + fail: + TALLOC_FREE(frame); + return status; } /* The following is calculated from : @@ -729,8 +1290,9 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq) uint8_t *p; uint16_t blob_length; uint8_t *inbuf; + ssize_t ret; - status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv, + status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, &num_bytes, &bytes); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status) @@ -744,6 +1306,7 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq) state->inbuf = (char *)inbuf; cli->vuid = SVAL(state->inbuf, smb_uid); + cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); blob_length = SVAL(vwv+3, 0); if (blob_length > num_bytes) { @@ -754,15 +1317,44 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq) p = bytes + blob_length; - p += clistr_pull(state->inbuf, cli->server_os, - (char *)p, sizeof(fstring), - bytes+num_bytes-p, STR_TERMINATE); - p += clistr_pull(state->inbuf, cli->server_type, - (char *)p, sizeof(fstring), - bytes+num_bytes-p, STR_TERMINATE); - p += clistr_pull(state->inbuf, cli->server_domain, - (char *)p, sizeof(fstring), - bytes+num_bytes-p, STR_TERMINATE); + status = smb_bytes_talloc_string(cli, + (char *)inbuf, + &cli->server_os, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + (char *)inbuf, + &cli->server_type, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; + + status = smb_bytes_talloc_string(cli, + (char *)inbuf, + &cli->server_domain, + p, + bytes+num_bytes-p, + &ret); + + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + p += ret; if (strstr(cli->server_type, "Samba")) { cli->is_samba = True; @@ -773,7 +1365,7 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq) * More to send */ if (!cli_sesssetup_blob_next(state, &subreq)) { - tevent_req_nomem(NULL, req); + tevent_req_oom(req); return; } tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); @@ -833,7 +1425,7 @@ static void cli_session_setup_kerberos_done(struct tevent_req *subreq); static struct tevent_req *cli_session_setup_kerberos_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, - const char *principal, const char *workgroup) + const char *principal) { struct tevent_req *req, *subreq; struct cli_session_setup_kerberos_state *state; @@ -921,8 +1513,7 @@ static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) } static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, - const char *principal, - const char *workgroup) + const char *principal) { struct tevent_context *ev; struct tevent_req *req; @@ -935,8 +1526,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, if (ev == NULL) { goto fail; } - req = cli_session_setup_kerberos_send(ev, ev, cli, principal, - workgroup); + req = cli_session_setup_kerberos_send(ev, ev, cli, principal); if (req == NULL) { goto fail; } @@ -1000,7 +1590,7 @@ static struct tevent_req *cli_session_setup_ntlmssp_send( cli_temp_set_signing(cli); status = ntlmssp_client_start(state, - global_myname(), + lp_netbios_name(), lp_workgroup(), lp_client_ntlmv2_auth(), &state->ntlmssp_state); @@ -1063,8 +1653,14 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) if (NT_STATUS_IS_OK(status)) { if (state->cli->server_domain[0] == '\0') { - fstrcpy(state->cli->server_domain, - state->ntlmssp_state->server.netbios_domain); + TALLOC_FREE(state->cli->server_domain); + state->cli->server_domain = talloc_strdup(state->cli, + state->ntlmssp_state->server.netbios_domain); + if (state->cli->server_domain == NULL) { + TALLOC_FREE(subreq); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; + } } cli_set_session_key( state->cli, state->ntlmssp_state->session_key); @@ -1179,9 +1775,6 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, status = cli_session_setup_ntlmssp_recv(req); fail: TALLOC_FREE(ev); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1291,6 +1884,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, host = strchr_m(cli->desthost, '.'); if (dest_realm) { realm = SMB_STRDUP(dest_realm); + if (!realm) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } strupper_m(realm); } else { if (host) { @@ -1302,25 +1898,38 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } } - if (realm && *realm) { - principal = talloc_asprintf(talloc_tos(), - "cifs/%s@%s", - cli->desthost, - realm); - if (!principal) { - SAFE_FREE(realm); + if (realm == NULL || *realm == '\0') { + realm = SMB_STRDUP(lp_realm()); + if (!realm) { return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - DEBUG(3,("cli_session_setup_spnego: guessed " - "server principal=%s\n", - principal ? principal : "<null>")); + strupper_m(realm); + DEBUG(3,("cli_session_setup_spnego: cannot " + "get realm from dest_realm %s, " + "desthost %s. Using default " + "smb.conf realm %s\n", + dest_realm ? dest_realm : "<null>", + cli->desthost, + realm)); } + + principal = talloc_asprintf(talloc_tos(), + "cifs/%s@%s", + cli->desthost, + realm); + if (!principal) { + SAFE_FREE(realm); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + DEBUG(3,("cli_session_setup_spnego: guessed " + "server principal=%s\n", + principal ? principal : "<null>")); + SAFE_FREE(realm); } if (principal) { - rc = cli_session_setup_kerberos(cli, principal, - dest_realm); + rc = cli_session_setup_kerberos(cli, principal); if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { TALLOC_FREE(principal); return rc; @@ -1361,12 +1970,15 @@ NTSTATUS cli_session_setup(struct cli_state *cli, const char *workgroup) { char *p; - fstring user2; + char *user2; if (user) { - fstrcpy(user2, user); + user2 = talloc_strdup(talloc_tos(), user); } else { - user2[0] ='\0'; + user2 = talloc_strdup(talloc_tos(), ""); + } + if (user2 == NULL) { + return NT_STATUS_NO_MEMORY; } if (!workgroup) { @@ -1378,6 +1990,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, (p=strchr_m(user2,*lp_winbind_separator()))) { *p = 0; user = p+1; + strupper_m(user2); workgroup = user2; } @@ -1420,7 +2033,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, connect */ if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) - return cli_session_setup_plaintext(cli, user, "", workgroup); + return cli_session_setup_plain(cli, user, "", workgroup); /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ @@ -1431,7 +2044,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, " or 'client ntlmv2 auth = yes'\n")); return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_plaintext(cli, user, pass, workgroup); + return cli_session_setup_plain(cli, user, pass, workgroup); } /* if the server supports extended security then use SPNEGO */ @@ -1545,9 +2158,6 @@ NTSTATUS cli_ulogoff(struct cli_state *cli) status = cli_ulogoff_recv(req); fail: TALLOC_FREE(ev); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1572,7 +2182,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct cli_tcon_andx_state *state; - fstring pword; + uint8_t p24[24]; uint16_t *vwv; char *tmp = NULL; uint8_t *bytes; @@ -1586,7 +2196,10 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, state->cli = cli; vwv = state->vwv; - fstrcpy(cli->share, share); + cli->share = talloc_strdup(cli, share); + if (!cli->share) { + return NULL; + } /* in user level security don't send a password now */ if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { @@ -1611,12 +2224,15 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, * Non-encrypted passwords - convert to DOS codepage before * encryption. */ + SMBencrypt(pass, cli->secblob.data, p24); passlen = 24; - SMBencrypt(pass, cli->secblob.data, (uchar *)pword); + pass = (const char *)p24; } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { + char *tmp_pass; + if (!lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext " "password but " @@ -1628,16 +2244,21 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, * Non-encrypted passwords - convert to DOS codepage * before using. */ - passlen = clistr_push(cli, pword, pass, sizeof(pword), - STR_TERMINATE); - if (passlen == -1) { - DEBUG(1, ("clistr_push(pword) failed\n")); - goto access_denied; + tmp_pass = talloc_array(talloc_tos(), char, 128); + if (tmp_pass == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return tevent_req_post(req, ev); } - } else { - if (passlen) { - memcpy(pword, pass, passlen); + passlen = clistr_push(cli, + tmp_pass, + pass, + talloc_get_size(tmp_pass), + STR_TERMINATE); + if (passlen == -1) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return tevent_req_post(req, ev); } + pass = tmp_pass; } } @@ -1647,8 +2268,8 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE); SSVAL(vwv+3, 0, passlen); - if (passlen) { - bytes = (uint8_t *)talloc_memdup(state, pword, passlen); + if (passlen && pass) { + bytes = (uint8_t *)talloc_memdup(state, pass, passlen); } else { bytes = talloc_array(state, uint8_t, 0); } @@ -1750,8 +2371,24 @@ static void cli_tcon_andx_done(struct tevent_req *subreq) inbuf = (char *)in; - clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes, - STR_TERMINATE|STR_ASCII); + if (num_bytes) { + if (clistr_pull_talloc(cli, + inbuf, + SVAL(inbuf, smb_flg2), + &cli->dev, + bytes, + num_bytes, + STR_TERMINATE|STR_ASCII) == -1) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + } else { + cli->dev = talloc_strdup(cli, ""); + if (cli->dev == NULL) { + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + } if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) { /* almost certainly win95 - enable bug fixes */ @@ -1814,9 +2451,6 @@ NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share, status = cli_tcon_andx_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1897,9 +2531,6 @@ NTSTATUS cli_tdis(struct cli_state *cli) status = cli_tdis_recv(req); fail: TALLOC_FREE(ev); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -2028,11 +2659,14 @@ static void cli_negprot_done(struct tevent_req *subreq) } /* work out if they sent us a workgroup */ if (!(cli->capabilities & CAP_EXTENDED_SECURITY) && - smb_buflen(cli->inbuf) > 8) { - clistr_pull(cli->inbuf, cli->server_domain, - bytes+8, sizeof(cli->server_domain), - num_bytes-8, - STR_UNICODE|STR_NOALIGN); + smb_buflen(inbuf) > 8) { + ssize_t ret; + status = smb_bytes_talloc_string( + cli, (char *)inbuf, &cli->server_domain, + bytes + 8, num_bytes - 8, &ret); + if (tevent_req_nterror(req, status)) { + return; + } } /* @@ -2149,306 +2783,141 @@ NTSTATUS cli_negprot(struct cli_state *cli) status = cli_negprot_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } -/**************************************************************************** - Send a session request. See rfc1002.txt 4.3 and 4.3.2. -****************************************************************************/ - -bool cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called) +static NTSTATUS cli_connect_sock(const char *host, int name_type, + const struct sockaddr_storage *pss, + const char *myname, uint16_t port, + int sec_timeout, int *pfd, uint16_t *pport) { - char *p; - int len = 4; - int namelen = 0; - char *tmp; - - /* 445 doesn't have session request */ - if (cli->port == 445) - return True; - - memcpy(&(cli->calling), calling, sizeof(*calling)); - memcpy(&(cli->called ), called , sizeof(*called )); - - /* put in the destination name */ - - tmp = name_mangle(talloc_tos(), cli->called.name, - cli->called.name_type); - if (tmp == NULL) { - return false; - } - - p = cli->outbuf+len; - namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp)); - if (namelen > 0) { - memcpy(p, tmp, namelen); - len += namelen; - } - TALLOC_FREE(tmp); - - /* and my name */ - - tmp = name_mangle(talloc_tos(), cli->calling.name, - cli->calling.name_type); - if (tmp == NULL) { - return false; - } - - p = cli->outbuf+len; - namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp)); - if (namelen > 0) { - memcpy(p, tmp, namelen); - len += namelen; - } - TALLOC_FREE(tmp); - - /* send a session request (RFC 1002) */ - /* setup the packet length - * Remove four bytes from the length count, since the length - * field in the NBT Session Service header counts the number - * of bytes which follow. The cli_send_smb() function knows - * about this and accounts for those four bytes. - * CRH. - */ - len -= 4; - _smb_setlen(cli->outbuf,len); - SCVAL(cli->outbuf,0,0x81); - - cli_send_smb(cli); - DEBUG(5,("Sent session request\n")); - - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,0) == 0x84) { - /* C. Hoch 9/14/95 Start */ - /* For information, here is the response structure. - * We do the byte-twiddling to for portability. - struct RetargetResponse{ - unsigned char type; - unsigned char flags; - int16 length; - int32 ip_addr; - int16 port; - }; - */ - uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); - struct in_addr dest_ip; - NTSTATUS status; - - /* SESSION RETARGET */ - putip((char *)&dest_ip,cli->inbuf+4); - in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip); - - status = open_socket_out(&cli->dest_ss, port, - LONG_CONNECT_TIMEOUT, &cli->fd); - if (!NT_STATUS_IS_OK(status)) { - return False; - } - - DEBUG(3,("Retargeted\n")); - - set_socket_options(cli->fd, lp_socket_options()); - - /* Try again */ - { - static int depth; - bool ret; - if (depth > 4) { - DEBUG(0,("Retarget recursion - failing\n")); - return False; - } - depth++; - ret = cli_session_request(cli, calling, called); - depth--; - return ret; - } - } /* C. Hoch 9/14/95 End */ - - if (CVAL(cli->inbuf,0) != 0x82) { - /* This is the wrong place to put the error... JRA. */ - cli->rap_error = CVAL(cli->inbuf,4); - return False; - } - return(True); -} - -struct fd_struct { - int fd; -}; - -static void smb_sock_connected(struct tevent_req *req) -{ - struct fd_struct *pfd = tevent_req_callback_data( - req, struct fd_struct); - int fd; + TALLOC_CTX *frame = talloc_stackframe(); + const char *prog; + unsigned int i, num_addrs; + const char **called_names; + const char **calling_names; + int *called_types; NTSTATUS status; + int fd; - status = open_socket_out_defer_recv(req, &fd); - if (NT_STATUS_IS_OK(status)) { - pfd->fd = fd; - } -} - -static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss, - uint16_t *port, int timeout, int *pfd) -{ - struct event_context *ev; - struct tevent_req *r139, *r445; - struct fd_struct *fd139, *fd445; - NTSTATUS status = NT_STATUS_NO_MEMORY; - - if (*port != 0) { - return open_socket_out(pss, *port, timeout, pfd); - } - - ev = event_context_init(talloc_tos()); - if (ev == NULL) { - return NT_STATUS_NO_MEMORY; - } - - fd139 = talloc(ev, struct fd_struct); - if (fd139 == NULL) { + prog = getenv("LIBSMB_PROG"); + if (prog != NULL) { + fd = sock_exec(prog); + if (fd == -1) { + return map_nt_error_from_unix(errno); + } + port = 0; goto done; } - fd139->fd = -1; - fd445 = talloc(ev, struct fd_struct); - if (fd445 == NULL) { - goto done; + if ((pss == NULL) || is_zero_addr(pss)) { + struct sockaddr_storage *addrs; + status = resolve_name_list(talloc_tos(), host, name_type, + &addrs, &num_addrs); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + pss = addrs; + } else { + num_addrs = 1; } - fd445->fd = -1; - r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0), - pss, 445, timeout); - r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000), - pss, 139, timeout); - if ((r445 == NULL) || (r139 == NULL)) { - goto done; + called_names = talloc_array(talloc_tos(), const char *, num_addrs); + if (called_names == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - tevent_req_set_callback(r445, smb_sock_connected, fd445); - tevent_req_set_callback(r139, smb_sock_connected, fd139); - - while ((fd445->fd == -1) && (fd139->fd == -1) - && (tevent_req_is_in_progress(r139) - || tevent_req_is_in_progress(r445))) { - event_loop_once(ev); + called_types = talloc_array(talloc_tos(), int, num_addrs); + if (called_types == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - - if ((fd139->fd != -1) && (fd445->fd != -1)) { - close(fd139->fd); - fd139->fd = -1; + calling_names = talloc_array(talloc_tos(), const char *, num_addrs); + if (calling_names == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; } - - if (fd445->fd != -1) { - *port = 445; - *pfd = fd445->fd; - status = NT_STATUS_OK; - goto done; + for (i=0; i<num_addrs; i++) { + called_names[i] = host; + called_types[i] = name_type; + calling_names[i] = myname; } - if (fd139->fd != -1) { - *port = 139; - *pfd = fd139->fd; - status = NT_STATUS_OK; - goto done; + status = smbsock_any_connect(pss, called_names, called_types, + calling_names, NULL, num_addrs, port, + sec_timeout, &fd, NULL, &port); + if (!NT_STATUS_IS_OK(status)) { + goto fail; } - - status = open_socket_out_defer_recv(r445, &fd445->fd); - done: - TALLOC_FREE(ev); + set_socket_options(fd, lp_socket_options()); +done: + *pfd = fd; + *pport = port; + status = NT_STATUS_OK; +fail: + TALLOC_FREE(frame); return status; } -/**************************************************************************** - Open the client sockets. -****************************************************************************/ - -NTSTATUS cli_connect(struct cli_state *cli, - const char *host, - struct sockaddr_storage *dest_ss) - +NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss, + uint16_t port, int name_type, const char *myname, + int signing_state, struct cli_state **pcli) { - int name_type = 0x20; TALLOC_CTX *frame = talloc_stackframe(); - unsigned int num_addrs = 0; - unsigned int i = 0; - struct sockaddr_storage *ss_arr = NULL; - char *p = NULL; + struct cli_state *cli; + NTSTATUS status = NT_STATUS_NO_MEMORY; + int fd = -1; + char *desthost; + char *p; + socklen_t length; + int ret; - /* reasonable default hostname */ - if (!host) { - host = STAR_SMBSERVER; + desthost = talloc_strdup(talloc_tos(), host); + if (desthost == NULL) { + goto fail; } - fstrcpy(cli->desthost, host); - - /* allow hostnames of the form NAME#xx and do a netbios lookup */ - if ((p = strchr(cli->desthost, '#'))) { + p = strchr(host, '#'); + if (p != NULL) { name_type = strtol(p+1, NULL, 16); - *p = 0; - } - - if (!dest_ss || is_zero_addr(dest_ss)) { - NTSTATUS status =resolve_name_list(frame, - cli->desthost, - name_type, - &ss_arr, - &num_addrs); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return NT_STATUS_BAD_NETWORK_NAME; - } - } else { - num_addrs = 1; - ss_arr = TALLOC_P(frame, struct sockaddr_storage); - if (!ss_arr) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; + host = talloc_strndup(talloc_tos(), host, p - host); + if (host == NULL) { + goto fail; } - *ss_arr = *dest_ss; } - for (i = 0; i < num_addrs; i++) { - cli->dest_ss = ss_arr[i]; - if (getenv("LIBSMB_PROG")) { - cli->fd = sock_exec(getenv("LIBSMB_PROG")); - } else { - uint16_t port = cli->port; - NTSTATUS status; - status = open_smb_socket(&cli->dest_ss, &port, - cli->timeout, &cli->fd); - if (NT_STATUS_IS_OK(status)) { - cli->port = port; - } - } - if (cli->fd == -1) { - char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &ss_arr[i]); - DEBUG(2,("Error connecting to %s (%s)\n", - dest_ss?addr:host,strerror(errno))); - } else { - /* Exit from loop on first connection. */ - break; - } + cli = cli_initialise_ex(signing_state); + if (cli == NULL) { + goto fail; } + cli->desthost = talloc_move(cli, &desthost); - if (cli->fd == -1) { - TALLOC_FREE(frame); - return map_nt_error_from_unix(errno); + status = cli_connect_sock(host, name_type, pss, myname, port, 20, &fd, + &port); + if (!NT_STATUS_IS_OK(status)) { + cli_shutdown(cli); + goto fail; } + cli->fd = fd; + cli->port = port; - if (dest_ss) { - *dest_ss = cli->dest_ss; + length = sizeof(cli->dest_ss); + ret = getpeername(fd, (struct sockaddr *)(void *)&cli->dest_ss, + &length); + if (ret == -1) { + status = map_nt_error_from_unix(errno); + cli_shutdown(cli); + goto fail; } - set_socket_options(cli->fd, lp_socket_options()); + if (pss != NULL) { + *pss = cli->dest_ss; + } + *pcli = cli; + status = NT_STATUS_OK; +fail: TALLOC_FREE(frame); - return NT_STATUS_OK; + return status; } /** @@ -2465,59 +2934,16 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, int signing_state, int flags) { NTSTATUS nt_status; - struct nmb_name calling; - struct nmb_name called; struct cli_state *cli; - struct sockaddr_storage ss; - - if (!my_name) - my_name = global_myname(); - - if (!(cli = cli_initialise_ex(signing_state))) { - return NT_STATUS_NO_MEMORY; - } - - make_nmb_name(&calling, my_name, 0x0); - make_nmb_name(&called , dest_host, 0x20); - - cli_set_port(cli, port); - cli_set_timeout(cli, 10000); /* 10 seconds. */ - if (dest_ss) { - ss = *dest_ss; - } else { - zero_sockaddr(&ss); - } - -again: - - DEBUG(3,("Connecting to host=%s\n", dest_host)); - - nt_status = cli_connect(cli, dest_host, &ss); + nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name, + signing_state, &cli); if (!NT_STATUS_IS_OK(nt_status)) { - char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &ss); - DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n", - nmb_namestr(&called), addr, nt_errstr(nt_status) )); - cli_shutdown(cli); + DEBUG(10, ("cli_connect_nb failed: %s\n", + nt_errstr(nt_status))); return nt_status; } - if (!cli_session_request(cli, &calling, &called)) { - char *p; - DEBUG(1,("session request to %s failed (%s)\n", - called.name, cli_errstr(cli))); - if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { - *p = 0; - goto again; - } - if (strcmp(called.name, STAR_SMBSERVER)) { - make_nmb_name(&called , STAR_SMBSERVER, 0x20); - goto again; - } - return NT_STATUS_BAD_NETWORK_NAME; - } - if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) @@ -2631,71 +3057,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, } /**************************************************************************** - Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. -****************************************************************************/ - -bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, - struct sockaddr_storage *pdest_ss) -{ - struct nmb_name calling, called; - - make_nmb_name(&calling, srchost, 0x0); - - /* - * If the called name is an IP address - * then use *SMBSERVER immediately. - */ - - if(is_ipaddress(desthost)) { - make_nmb_name(&called, STAR_SMBSERVER, 0x20); - } else { - make_nmb_name(&called, desthost, 0x20); - } - - if (!cli_session_request(*ppcli, &calling, &called)) { - NTSTATUS status; - struct nmb_name smbservername; - - make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20); - - /* - * If the name wasn't *SMBSERVER then - * try with *SMBSERVER if the first name fails. - */ - - if (nmb_name_equal(&called, &smbservername)) { - - /* - * The name used was *SMBSERVER, don't bother with another name. - */ - - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ -with error %s.\n", desthost, cli_errstr(*ppcli) )); - return False; - } - - /* Try again... */ - cli_shutdown(*ppcli); - - *ppcli = cli_initialise(); - if (!*ppcli) { - /* Out of memory... */ - return False; - } - - status = cli_connect(*ppcli, desthost, pdest_ss); - if (!NT_STATUS_IS_OK(status) || - !cli_session_request(*ppcli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ -name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); - return False; - } - } - - return True; -} - -/**************************************************************************** Send an old style tcon. ****************************************************************************/ NTSTATUS cli_raw_tcon(struct cli_state *cli, @@ -2786,7 +3147,7 @@ struct cli_state *get_ipc_connect(char *server, */ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, - struct ip_service *mb_ip, + struct sockaddr_storage *mb_ip, const struct user_auth_info *user_info, char **pp_workgroup_out) { @@ -2797,7 +3158,7 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, *pp_workgroup_out = NULL; - print_sockaddr(addr, sizeof(addr), &mb_ip->ss); + print_sockaddr(addr, sizeof(addr), mb_ip); DEBUG(99, ("Looking up name of master browser %s\n", addr)); @@ -2812,8 +3173,8 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, * the original wildcard query as the first choice and fall back to * MSBROWSE if the wildcard query fails. */ - if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) && - !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) { + if (!name_status_find("*", 0, 0x1d, mb_ip, name) && + !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) { DEBUG(99, ("Could not retrieve name status for %s\n", addr)); @@ -2844,9 +3205,10 @@ struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx, const struct user_auth_info *user_info, char **pp_workgroup_out) { - struct ip_service *ip_list; + struct sockaddr_storage *ip_list; struct cli_state *cli; int i, count; + NTSTATUS status; *pp_workgroup_out = NULL; @@ -2854,15 +3216,17 @@ struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx, /* Go looking for workgroups by broadcasting on the local network */ - if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, - &count))) { - DEBUG(99, ("No master browsers responded\n")); + status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(), + &ip_list, &count); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(99, ("No master browsers responded: %s\n", + nt_errstr(status))); return False; } for (i = 0; i < count; i++) { char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); + print_sockaddr(addr, sizeof(addr), &ip_list[i]); DEBUG(99, ("Found master browser %s\n", addr)); cli = get_ipc_connect_master_ip(ctx, &ip_list[i], diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index a0d60482ee..5c5257fb6f 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmb/clirap.h" #include "msdfs.h" #include "trans2.h" @@ -87,10 +88,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, int name_type) { struct cli_state *c = NULL; - struct nmb_name called, calling; - const char *called_str; - const char *server_n; - struct sockaddr_storage ss; char *servicename; char *sharename; char *newserver, *newshare; @@ -106,7 +103,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, sharename = servicename; if (*sharename == '\\') { sharename += 2; - called_str = sharename; if (server == NULL) { server = sharename; } @@ -116,36 +112,19 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, } *sharename = 0; sharename++; - } else { - called_str = server; } - - server_n = server; - - zero_sockaddr(&ss); - - make_nmb_name(&calling, global_myname(), 0x0); - make_nmb_name(&called , called_str, name_type); - - again: - zero_sockaddr(&ss); - - /* have to open a new connection */ - c = cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); - if (c == NULL) { - d_printf("Connection to %s failed\n", server_n); + if (server == NULL) { return NULL; } - if (port) { - cli_set_port(c, port); - } - status = cli_connect(c, server_n, &ss); + status = cli_connect_nb( + server, NULL, port, name_type, NULL, + get_cmdline_auth_info_signing_state(auth_info), &c); + if (!NT_STATUS_IS_OK(status)) { d_printf("Connection to %s failed (Error %s)\n", - server_n, + server, nt_errstr(status)); - cli_shutdown(c); return NULL; } @@ -158,23 +137,6 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, get_cmdline_auth_info_fallback_after_kerberos(auth_info); c->use_ccache = get_cmdline_auth_info_use_ccache(auth_info); - if (!cli_session_request(c, &calling, &called)) { - char *p; - d_printf("session request to %s failed (%s)\n", - called.name, cli_errstr(c)); - cli_shutdown(c); - c = NULL; - if ((p=strchr_m(called.name, '.'))) { - *p = 0; - goto again; - } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - return NULL; - } - DEBUG(4,(" session request ok\n")); status = cli_negprot(c); diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 92f381e87b..90f06fd535 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -20,6 +20,8 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "libsmb/clidgram.h" #include "libsmb/nmblib.h" #include "messages.h" @@ -138,7 +140,7 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, my_sid = *sid; } - my_acct_name = talloc_asprintf(talloc_tos(), "%s$", global_myname()); + my_acct_name = talloc_asprintf(talloc_tos(), "%s$", lp_netbios_name()); if (my_acct_name == NULL) { goto fail; } @@ -147,7 +149,7 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, s = &packet.req.logon; s->request_count = 0; - s->computer_name = global_myname(); + s->computer_name = lp_netbios_name(); s->user_name = my_acct_name; s->mailslot_name = my_mailslot; s->acct_control = ACB_WSTRUST; @@ -168,7 +170,7 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, ret = cli_prep_mailslot(false, NBT_MAILSLOT_NTLOGON, 0, (char *)blob.data, blob.length, - global_myname(), 0, domain_name, 0x1c, + lp_netbios_name(), 0, domain_name, 0x1c, dc_ss, dgm_id, p); fail: TALLOC_FREE(frame); @@ -225,7 +227,7 @@ static bool parse_getdc_response( blob = p.smb.body.trans.data; - r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); + r = talloc_zero(mem_ctx, struct netlogon_samlogon_response); if (!r) { return false; } @@ -320,7 +322,7 @@ struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } state->my_mailslot = mailslot_name( - state, ((struct sockaddr_in *)dc_addr)->sin_addr); + state, ((const struct sockaddr_in *)dc_addr)->sin_addr); if (tevent_req_nomem(state->my_mailslot, req)) { return tevent_req_post(req, ev); } diff --git a/source3/libsmb/clidgram.h b/source3/libsmb/clidgram.h index 01a8a6a404..a449724a41 100644 --- a/source3/libsmb/clidgram.h +++ b/source3/libsmb/clidgram.h @@ -1,3 +1,27 @@ +/* + Unix SMB/CIFS implementation. + client dgram calls + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Richard Sharpe 2001 + Copyright (C) John Terpstra 2001 + + 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/>. +*/ + +#ifndef _LIBSMB_CLIDGRAM_H_ +#define _LIBSMB_CLIDGRAM_H_ + #include "../libcli/netlogon/netlogon.h" /* The following definitions come from libsmb/clidgram.c */ @@ -21,3 +45,5 @@ NTSTATUS nbt_getdc(struct messaging_context *msg_ctx, uint32_t *pnt_version, const char **dc_name, struct netlogon_samlogon_response **samlogon_response); + +#endif /* _LIBSMB_CLIDGRAM_H_ */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7eb10c4f1d..d3b66b67e1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -19,6 +19,8 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "smb_signing.h" #include "async_smb.h" @@ -66,364 +68,6 @@ bool cli_ucs2(struct cli_state *cli) return ((cli->capabilities & CAP_UNICODE) != 0); } - -/**************************************************************************** - Read an smb from a fd ignoring all keepalive packets. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. -****************************************************************************/ - -static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) -{ - size_t len; - - for(;;) { - NTSTATUS status; - - set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); - - status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize, - cli->timeout, maxlen, &len); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(cli->inbuf); - - if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { - set_smb_read_error(&cli->smb_rw_error, - SMB_READ_EOF); - return -1; - } - - if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - set_smb_read_error(&cli->smb_rw_error, - SMB_READ_TIMEOUT); - return -1; - } - - set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); - return -1; - } - - /* - * I don't believe len can be < 0 with NT_STATUS_OK - * returned above, but this check doesn't hurt. JRA. - */ - - if ((ssize_t)len < 0) { - return len; - } - - /* Ignore session keepalive packets. */ - if(CVAL(cli->inbuf,0) != SMBkeepalive) { - break; - } - } - - if (cli_encryption_on(cli)) { - NTSTATUS status = cli_decrypt_message(cli); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status))); - cli->smb_rw_error = SMB_READ_BAD_DECRYPT; - return -1; - } - } - - show_msg(cli->inbuf); - return len; -} - -static bool cli_state_set_seqnum(struct cli_state *cli, uint16_t mid, uint32_t seqnum) -{ - struct cli_state_seqnum *c; - - for (c = cli->seqnum; c; c = c->next) { - if (c->mid == mid) { - c->seqnum = seqnum; - return true; - } - } - - c = talloc_zero(cli, struct cli_state_seqnum); - if (!c) { - return false; - } - - c->mid = mid; - c->seqnum = seqnum; - c->persistent = false; - DLIST_ADD_END(cli->seqnum, c, struct cli_state_seqnum *); - - return true; -} - -bool cli_state_seqnum_persistent(struct cli_state *cli, - uint16_t mid) -{ - struct cli_state_seqnum *c; - - for (c = cli->seqnum; c; c = c->next) { - if (c->mid == mid) { - c->persistent = true; - return true; - } - } - - return false; -} - -bool cli_state_seqnum_remove(struct cli_state *cli, - uint16_t mid) -{ - struct cli_state_seqnum *c; - - for (c = cli->seqnum; c; c = c->next) { - if (c->mid == mid) { - DLIST_REMOVE(cli->seqnum, c); - TALLOC_FREE(c); - return true; - } - } - - return false; -} - -static uint32_t cli_state_get_seqnum(struct cli_state *cli, uint16_t mid) -{ - struct cli_state_seqnum *c; - - for (c = cli->seqnum; c; c = c->next) { - if (c->mid == mid) { - uint32_t seqnum = c->seqnum; - if (!c->persistent) { - DLIST_REMOVE(cli->seqnum, c); - TALLOC_FREE(c); - } - return seqnum; - } - } - - return 0; -} - -/**************************************************************************** - Recv an smb. -****************************************************************************/ - -bool cli_receive_smb(struct cli_state *cli) -{ - ssize_t len; - uint16_t mid; - uint32_t seqnum; - - /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) - return false; - - again: - len = client_receive_smb(cli, 0); - - if (len > 0) { - /* it might be an oplock break request */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && - CVAL(cli->inbuf,smb_com) == SMBlockingX && - SVAL(cli->inbuf,smb_vwv6) == 0 && - SVAL(cli->inbuf,smb_vwv7) == 0) { - if (cli->oplock_handler) { - int fnum = SVAL(cli->inbuf,smb_vwv2); - unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!NT_STATUS_IS_OK(cli->oplock_handler(cli, fnum, level))) { - return false; - } - } - /* try to prevent loops */ - SCVAL(cli->inbuf,smb_com,0xFF); - goto again; - } - } - - /* If the server is not responding, note that now */ - if (len < 0) { - /* - * only log if the connection should still be open and not when - * the connection was closed due to a dropped ip message - */ - if (cli->fd != -1) { - char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &cli->dest_ss); - DEBUG(0, ("Receiving SMB: Server %s stopped responding\n", - addr)); - close(cli->fd); - cli->fd = -1; - } - return false; - } - - mid = SVAL(cli->inbuf,smb_mid); - seqnum = cli_state_get_seqnum(cli, mid); - - if (!cli_check_sign_mac(cli, cli->inbuf, seqnum+1)) { - /* - * If we get a signature failure in sessionsetup, then - * the server sometimes just reflects the sent signature - * back to us. Detect this and allow the upper layer to - * retrieve the correct Windows error message. - */ - if (CVAL(cli->outbuf,smb_com) == SMBsesssetupX && - (smb_len(cli->inbuf) > (smb_ss_field + 8 - 4)) && - (SVAL(cli->inbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) && - memcmp(&cli->outbuf[smb_ss_field],&cli->inbuf[smb_ss_field],8) == 0 && - cli_is_error(cli)) { - - /* - * Reflected signature on login error. - * Set bad sig but don't close fd. - */ - cli->smb_rw_error = SMB_READ_BAD_SIG; - return true; - } - - DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = SMB_READ_BAD_SIG; - close(cli->fd); - cli->fd = -1; - return false; - }; - return true; -} - -static ssize_t write_socket(int fd, const char *buf, size_t len) -{ - ssize_t ret=0; - - DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); - ret = write_data(fd,buf,len); - - DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); - if(ret <= 0) - DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", - (int)len, fd, strerror(errno) )); - - return(ret); -} - -/**************************************************************************** - Send an smb to a fd. -****************************************************************************/ - -bool cli_send_smb(struct cli_state *cli) -{ - size_t len; - size_t nwritten=0; - ssize_t ret; - char *buf_out = cli->outbuf; - bool enc_on = cli_encryption_on(cli); - uint32_t seqnum; - - /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) - return false; - - cli_calculate_sign_mac(cli, cli->outbuf, &seqnum); - - if (!cli_state_set_seqnum(cli, cli->mid, seqnum)) { - DEBUG(0,("Failed to store mid[%u]/seqnum[%u]\n", - (unsigned int)cli->mid, - (unsigned int)seqnum)); - return false; - } - - if (enc_on) { - NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, - &buf_out); - if (!NT_STATUS_IS_OK(status)) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = SMB_WRITE_ERROR; - DEBUG(0,("Error in encrypting client message. Error %s\n", - nt_errstr(status) )); - return false; - } - } - - len = smb_len(buf_out) + 4; - - while (nwritten < len) { - ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); - if (ret <= 0) { - if (enc_on) { - cli_free_enc_buffer(cli, buf_out); - } - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = SMB_WRITE_ERROR; - DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", - (int)len,(int)ret, strerror(errno) )); - return false; - } - nwritten += ret; - } - - if (enc_on) { - cli_free_enc_buffer(cli, buf_out); - } - - /* Increment the mid so we can tell between responses. */ - cli->mid++; - if (!cli->mid) - cli->mid++; - return true; -} - -/**************************************************************************** - Send a "direct" writeX smb to a fd. -****************************************************************************/ - -bool cli_send_smb_direct_writeX(struct cli_state *cli, - const char *p, - size_t extradata) -{ - /* First length to send is the offset to the data. */ - size_t len = SVAL(cli->outbuf,smb_vwv11) + 4; - size_t nwritten=0; - struct iovec iov[2]; - - /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) { - return false; - } - - if (client_is_signing_on(cli)) { - DEBUG(0,("cli_send_smb_large: cannot send signed packet.\n")); - return false; - } - - iov[0].iov_base = (void *)cli->outbuf; - iov[0].iov_len = len; - iov[1].iov_base = CONST_DISCARD(void *, p); - iov[1].iov_len = extradata; - - nwritten = write_data_iov(cli->fd, iov, 2); - if (nwritten < (len + extradata)) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = SMB_WRITE_ERROR; - DEBUG(0,("Error writing %d bytes to client. (%s)\n", - (int)(len+extradata), strerror(errno))); - return false; - } - - /* Increment the mid so we can tell between responses. */ - cli->mid++; - if (!cli->mid) - cli->mid++; - return true; -} - /**************************************************************************** Setup basics in a outgoing packet. ****************************************************************************/ @@ -460,20 +104,6 @@ void cli_setup_packet_buf(struct cli_state *cli, char *buf) SSVAL(buf,smb_flg2, flags2); } -void cli_setup_packet(struct cli_state *cli) -{ - cli_setup_packet_buf(cli, cli->outbuf); -} - -/**************************************************************************** - Setup the bcc length of the packet from a pointer to the end of the data. -****************************************************************************/ - -void cli_setup_bcc(struct cli_state *cli, void *p) -{ - set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); -} - /**************************************************************************** Initialize Domain, user or password. ****************************************************************************/ @@ -552,7 +182,7 @@ struct cli_state *cli_initialise_ex(int signing_state) return NULL; } - cli = TALLOC_ZERO_P(NULL, struct cli_state); + cli = talloc_zero(NULL, struct cli_state); if (!cli) { return NULL; } @@ -572,7 +202,6 @@ struct cli_state *cli_initialise_ex(int signing_state) cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); - cli->seqnum = 0; cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = false; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 015afb18aa..d5ac8937ed 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" /***************************************************** RAP error codes - a small start but will be extended. @@ -322,44 +323,6 @@ bool cli_is_dos_error(struct cli_state *cli) return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); } -/* Return the last error always as an NTSTATUS. */ - -NTSTATUS cli_get_nt_error(struct cli_state *cli) -{ - if (cli_is_nt_error(cli)) { - return cli_nt_error(cli); - } else if (cli_is_dos_error(cli)) { - uint32 ecode; - uint8 eclass; - cli_dos_error(cli, &eclass, &ecode); - return dos_to_ntstatus(eclass, ecode); - } else { - /* Something went wrong, we don't know what. */ - return NT_STATUS_UNSUCCESSFUL; - } -} - -/* Push an error code into the inbuf to be returned on the next - * query. */ - -void cli_set_nt_error(struct cli_state *cli, NTSTATUS status) -{ - SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); - SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); -} - -/* Reset an error. */ - -void cli_reset_error(struct cli_state *cli) -{ - if (SVAL(cli->inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) { - SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(NT_STATUS_OK)); - } else { - SCVAL(cli->inbuf,smb_rcls,0); - SSVAL(cli->inbuf,smb_err,0); - } -} - bool cli_state_is_connected(struct cli_state *cli) { if (cli == NULL) { diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 28f59f0d88..88cecd505c 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -20,10 +20,13 @@ #include "includes.h" #include "system/filesys.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" #include "libsmb/clirap.h" #include "trans2.h" #include "ntioctl.h" +#include "libcli/security/secdesc.h" /*********************************************************** Common function for pushing stings, used by smb_bytes_push_str() @@ -46,11 +49,13 @@ static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2, buflen = talloc_get_size(buf); - if (align_odd && ucs2 && (buflen % 2 == 0)) { + if (ucs2 && + ((align_odd && (buflen % 2 == 0)) || + (!align_odd && (buflen % 2 == 1)))) { /* * We're pushing into an SMB buffer, align odd */ - buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1); + buf = talloc_realloc(NULL, buf, uint8_t, buflen + 1); if (buf == NULL) { return NULL; } @@ -65,7 +70,7 @@ static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2, return NULL; } - buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, + buf = talloc_realloc(NULL, buf, uint8_t, buflen + converted_size); if (buf == NULL) { TALLOC_FREE(converted); @@ -106,7 +111,7 @@ uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, } buflen = talloc_get_size(buf); - buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, + buf = talloc_realloc(NULL, buf, uint8_t, buflen + 1 + num_bytes); if (buf == NULL) { return NULL; @@ -159,7 +164,7 @@ struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx, SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO); /* Setup param array. */ - state->param = TALLOC_ZERO_ARRAY(state, uint8_t, 6); + state->param = talloc_zero_array(state, uint8_t, 6); if (tevent_req_nomem(state->param, req)) { return tevent_req_post(req, ev); } @@ -356,9 +361,6 @@ NTSTATUS cli_posix_symlink(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -416,8 +418,7 @@ static void cli_posix_readlink_done(struct tevent_req *subreq) status = cli_qpathinfo_recv(subreq, state, &state->data, &state->num_data); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } /* @@ -501,9 +502,6 @@ NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -568,107 +566,10 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } /**************************************************************************** - Map standard UNIX permissions onto wire representations. -****************************************************************************/ - -uint32_t unix_perms_to_wire(mode_t perms) -{ - unsigned int ret = 0; - - ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); - ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); - ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0); - ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0); - ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0); - ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0); - ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0); - ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0); - ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0); -#ifdef S_ISVTX - ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0); -#endif -#ifdef S_ISGID - ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); -#endif -#ifdef S_ISUID - ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0); -#endif - return ret; -} - -/**************************************************************************** - Map wire permissions to standard UNIX. -****************************************************************************/ - -mode_t wire_perms_to_unix(uint32_t perms) -{ - mode_t ret = (mode_t)0; - - ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0); - ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0); - ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0); - ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0); - ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0); - ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0); - ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0); - ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0); - ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0); -#ifdef S_ISVTX - ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0); -#endif -#ifdef S_ISGID - ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0); -#endif -#ifdef S_ISUID - ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0); -#endif - return ret; -} - -/**************************************************************************** - Return the file type from the wire filetype for UNIX extensions. -****************************************************************************/ - -static mode_t unix_filetype_from_wire(uint32_t wire_type) -{ - switch (wire_type) { - case UNIX_TYPE_FILE: - return S_IFREG; - case UNIX_TYPE_DIR: - return S_IFDIR; -#ifdef S_IFLNK - case UNIX_TYPE_SYMLINK: - return S_IFLNK; -#endif -#ifdef S_IFCHR - case UNIX_TYPE_CHARDEV: - return S_IFCHR; -#endif -#ifdef S_IFBLK - case UNIX_TYPE_BLKDEV: - return S_IFBLK; -#endif -#ifdef S_IFIFO - case UNIX_TYPE_FIFO: - return S_IFIFO; -#endif -#ifdef S_IFSOCK - case UNIX_TYPE_SOCKET: - return S_IFSOCK; -#endif - default: - return (mode_t)0; - } -} - -/**************************************************************************** Do a POSIX getfacl (UNIX extensions). ****************************************************************************/ @@ -711,8 +612,7 @@ static void cli_posix_getfacl_done(struct tevent_req *subreq) status = cli_qpathinfo_recv(subreq, state, &state->data, &state->num_data); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -777,9 +677,6 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -825,8 +722,7 @@ static void cli_posix_stat_done(struct tevent_req *subreq) status = cli_qpathinfo_recv(subreq, state, &state->data, &state->num_data); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -912,9 +808,6 @@ NTSTATUS cli_posix_stat(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1029,9 +922,6 @@ NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1102,9 +992,6 @@ NTSTATUS cli_posix_chown(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1134,7 +1021,7 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, return NULL; } - SSVAL(state->vwv+0, 0, aSYSTEM | aHIDDEN | aDIR); + SSVAL(state->vwv+0, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); bytes = talloc_array(state, uint8_t, 1); if (tevent_req_nomem(bytes, req)) { @@ -1147,7 +1034,7 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - bytes = TALLOC_REALLOC_ARRAY(state, bytes, uint8_t, + bytes = talloc_realloc(state, bytes, uint8_t, talloc_get_size(bytes)+1); if (tevent_req_nomem(bytes, req)) { return tevent_req_post(req, ev); @@ -1177,8 +1064,7 @@ static void cli_rename_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -1225,9 +1111,6 @@ NTSTATUS cli_rename(struct cli_state *cli, const char *fname_src, const char *fn fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1259,7 +1142,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx, return NULL; } - SSVAL(state->vwv+0, 0 ,aSYSTEM | aHIDDEN | aDIR); + SSVAL(state->vwv+0, 0 ,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); SSVAL(state->vwv+1, 0, rename_flag); bytes = talloc_array(state, uint8_t, 1); @@ -1273,7 +1156,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - bytes = TALLOC_REALLOC_ARRAY(state, bytes, uint8_t, + bytes = talloc_realloc(state, bytes, uint8_t, talloc_get_size(bytes)+1); if (tevent_req_nomem(bytes, req)) { return tevent_req_post(req, ev); @@ -1303,8 +1186,7 @@ static void cli_ntrename_internal_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -1370,9 +1252,6 @@ NTSTATUS cli_ntrename(struct cli_state *cli, const char *fname_src, const char * fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1435,9 +1314,6 @@ NTSTATUS cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const cha fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1498,8 +1374,7 @@ static void cli_unlink_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -1546,9 +1421,6 @@ NTSTATUS cli_unlink(struct cli_state *cli, const char *fname, uint16_t mayhave_a fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1606,8 +1478,7 @@ static void cli_mkdir_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -1654,9 +1525,6 @@ NTSTATUS cli_mkdir(struct cli_state *cli, const char *dname) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1714,8 +1582,7 @@ static void cli_rmdir_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -1762,9 +1629,6 @@ NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1879,9 +1743,6 @@ NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1976,8 +1837,7 @@ static void cli_ntcreate_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, &num_bytes, &bytes); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } state->fnum = SVAL(vwv+2, 1); @@ -2044,9 +1904,184 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, status = cli_ntcreate_recv(req, pfid); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); + return status; +} + +struct cli_nttrans_create_state { + uint16_t fnum; +}; + +static void cli_nttrans_create_done(struct tevent_req *subreq); + +struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas) +{ + struct tevent_req *req, *subreq; + struct cli_nttrans_create_state *state; + uint8_t *param; + uint8_t *secdesc_buf; + size_t secdesc_len; + NTSTATUS status; + size_t converted_len; + + req = tevent_req_create(mem_ctx, + &state, struct cli_nttrans_create_state); + if (req == NULL) { + return NULL; + } + + if (secdesc != NULL) { + status = marshall_sec_desc(talloc_tos(), secdesc, + &secdesc_buf, &secdesc_len); + if (tevent_req_nterror(req, status)) { + DEBUG(10, ("marshall_sec_desc failed: %s\n", + nt_errstr(status))); + return tevent_req_post(req, ev); + } + } else { + secdesc_buf = NULL; + secdesc_len = 0; + } + + if (num_eas != 0) { + /* + * TODO ;-) + */ + tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED); + return tevent_req_post(req, ev); } + + param = talloc_array(state, uint8_t, 53); + if (tevent_req_nomem(param, req)) { + return tevent_req_post(req, ev); + } + + param = trans2_bytes_push_str(param, cli_ucs2(cli), + fname, strlen(fname), + &converted_len); + if (tevent_req_nomem(param, req)) { + return tevent_req_post(req, ev); + } + + SIVAL(param, 0, CreatFlags); + SIVAL(param, 4, 0x0); /* RootDirectoryFid */ + SIVAL(param, 8, DesiredAccess); + SIVAL(param, 12, 0x0); /* AllocationSize */ + SIVAL(param, 16, 0x0); /* AllocationSize */ + SIVAL(param, 20, FileAttributes); + SIVAL(param, 24, ShareAccess); + SIVAL(param, 28, CreateDisposition); + SIVAL(param, 32, CreateOptions); + SIVAL(param, 36, secdesc_len); + SIVAL(param, 40, 0); /* EA length*/ + SIVAL(param, 44, converted_len); + SIVAL(param, 48, 0x02); /* ImpersonationLevel */ + SCVAL(param, 52, SecurityFlags); + + subreq = cli_trans_send(state, ev, cli, SMBnttrans, + NULL, -1, /* name, fid */ + NT_TRANSACT_CREATE, 0, + NULL, 0, 0, /* setup */ + param, talloc_get_size(param), 128, /* param */ + secdesc_buf, secdesc_len, 0); /* data */ + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_nttrans_create_done, req); + return req; +} + +static void cli_nttrans_create_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_nttrans_create_state *state = tevent_req_data( + req, struct cli_nttrans_create_state); + uint8_t *param; + uint32_t num_param; + NTSTATUS status; + + status = cli_trans_recv(subreq, talloc_tos(), NULL, + NULL, 0, NULL, /* rsetup */ + ¶m, 69, &num_param, + NULL, 0, NULL); + if (tevent_req_nterror(req, status)) { + return; + } + state->fnum = SVAL(param, 2); + TALLOC_FREE(param); + tevent_req_done(req); +} + +NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum) +{ + struct cli_nttrans_create_state *state = tevent_req_data( + req, struct cli_nttrans_create_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + *fnum = state->fnum; + return NT_STATUS_OK; +} + +NTSTATUS cli_nttrans_create(struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas, + uint16_t *pfid) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_nttrans_create_send(frame, ev, cli, fname, CreatFlags, + DesiredAccess, FileAttributes, + ShareAccess, CreateDisposition, + CreateOptions, SecurityFlags, + secdesc, eas, num_eas); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_nttrans_create_recv(req, pfid); + fail: + TALLOC_FREE(frame); return status; } @@ -2115,7 +2150,7 @@ struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx, SSVAL(state->vwv + 1, 0, 0); SSVAL(state->vwv + 2, 0, 0); /* no additional info */ SSVAL(state->vwv + 3, 0, accessmode); - SSVAL(state->vwv + 4, 0, aSYSTEM | aHIDDEN); + SSVAL(state->vwv + 4, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); SSVAL(state->vwv + 5, 0, 0); SIVAL(state->vwv + 6, 0, 0); SSVAL(state->vwv + 8, 0, openfn); @@ -2169,8 +2204,7 @@ struct tevent_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev, } status = cli_smb_req_send(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } return req; @@ -2190,8 +2224,7 @@ static void cli_open_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } state->fnum = SVAL(vwv+2, 0); @@ -2247,9 +2280,6 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, status = cli_open_recv(req, pfnum); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -2305,8 +2335,7 @@ struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx, } status = cli_smb_req_send(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); } return req; @@ -2320,8 +2349,7 @@ static void cli_close_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -2367,9 +2395,6 @@ NTSTATUS cli_close(struct cli_state *cli, uint16_t fnum) status = cli_close_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -2485,9 +2510,6 @@ NTSTATUS cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -2547,7 +2569,6 @@ bool cli_lock(struct cli_state *cli, uint16_t fnum, status = cli_locktype(cli, fnum, offset, len, timeout, (lock_type == READ_LOCK? 1 : 0)); - cli_set_error(cli, status); return NT_STATUS_IS_OK(status); } @@ -2607,8 +2628,7 @@ static void cli_unlock_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -2659,9 +2679,6 @@ NTSTATUS cli_unlock(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -2712,7 +2729,6 @@ bool cli_lock64(struct cli_state *cli, uint16_t fnum, cli->timeout = saved_timeout; - cli_set_error(cli, status); return NT_STATUS_IS_OK(status); } @@ -2772,8 +2788,7 @@ static void cli_unlock64_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -2828,9 +2843,6 @@ NTSTATUS cli_unlock64(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3002,9 +3014,6 @@ NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3069,9 +3078,6 @@ NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3131,8 +3137,7 @@ static void cli_getattrE_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, state, &inbuf, 11, &wct, &vwv, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } @@ -3224,9 +3229,6 @@ NTSTATUS cli_getattrE(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3295,8 +3297,7 @@ static void cli_getatr_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } @@ -3374,9 +3375,6 @@ NTSTATUS cli_getatr(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3432,8 +3430,7 @@ static void cli_setattrE_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -3490,9 +3487,6 @@ NTSTATUS cli_setattrE(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3536,7 +3530,7 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(bytes, req)) { return tevent_req_post(req, ev); } - bytes = TALLOC_REALLOC_ARRAY(state, bytes, uint8_t, + bytes = talloc_realloc(state, bytes, uint8_t, talloc_get_size(bytes)+1); if (tevent_req_nomem(bytes, req)) { return tevent_req_post(req, ev); @@ -3566,8 +3560,7 @@ static void cli_setatr_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -3617,9 +3610,6 @@ NTSTATUS cli_setatr(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3677,8 +3667,7 @@ static void cli_chkpath_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -3740,9 +3729,6 @@ NTSTATUS cli_chkpath(struct cli_state *cli, const char *path) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3794,8 +3780,7 @@ static void cli_dskattr_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } state->bsize = SVAL(vwv+1, 0)*SVAL(vwv+2,0); @@ -3855,9 +3840,6 @@ NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -3927,8 +3909,7 @@ static void cli_ctemp_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, state, &inbuf, 1, &wcnt, &vwv, &num_bytes, &bytes); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } @@ -4013,9 +3994,6 @@ NTSTATUS cli_ctemp(struct cli_state *cli, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -4201,7 +4179,7 @@ static bool parse_ea_blob(TALLOC_CTX *ctx, const uint8_t *rdata, return true; } - ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); + ea_list = talloc_array(ctx, struct ea_struct, num_eas); if (!ea_list) { return false; } @@ -4288,8 +4266,7 @@ static void cli_get_ea_list_path_done(struct tevent_req *subreq) status = cli_qpathinfo_recv(subreq, state, &state->data, &state->num_data); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -4343,9 +4320,6 @@ NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path, status = cli_get_ea_list_path_recv(req, ctx, pnum_eas, pea_list); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -4395,7 +4369,6 @@ static uint32_t open_flags_to_wire(int flags) #endif #if defined(O_DIRECTORY) if (flags & O_DIRECTORY) { - ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY); ret |= SMB_O_DIRECTORY; } #endif @@ -4425,8 +4398,7 @@ static void cli_posix_open_internal_done(struct tevent_req *subreq) status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, NULL, 0, NULL, &data, 12, &num_data); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } state->fnum = SVAL(data,2); @@ -4470,7 +4442,6 @@ static struct tevent_req *cli_posix_open_internal_send(TALLOC_CTX *mem_ctx, /* Setup data words. */ if (is_dir) { - wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY); wire_flags |= SMB_O_DIRECTORY; } @@ -4575,9 +4546,6 @@ NTSTATUS cli_posix_open(struct cli_state *cli, const char *fname, fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -4636,9 +4604,6 @@ NTSTATUS cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -4744,9 +4709,6 @@ NTSTATUS cli_posix_unlink(struct cli_state *cli, const char *fname) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -4808,9 +4770,6 @@ NTSTATUS cli_posix_rmdir(struct cli_state *cli, const char *fname) fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -4884,9 +4843,8 @@ static void cli_notify_done(struct tevent_req *subreq) status = cli_trans_recv(subreq, talloc_tos(), &flags2, NULL, 0, NULL, ¶ms, 0, &num_params, NULL, 0, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { + if (tevent_req_nterror(req, status)) { DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status))); - tevent_req_nterror(req, status); return; } @@ -5035,8 +4993,7 @@ static void cli_qpathinfo_done(struct tevent_req *subreq) NULL, 0, NULL, &state->rdata, state->min_rdata, &state->num_rdata); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -5095,9 +5052,6 @@ NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, status = cli_qpathinfo_recv(req, mem_ctx, rdata, num_rdata); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -5168,8 +5122,7 @@ static void cli_qfileinfo_done(struct tevent_req *subreq) NULL, 0, NULL, &state->rdata, state->min_rdata, &state->num_rdata); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -5228,9 +5181,6 @@ NTSTATUS cli_qfileinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, status = cli_qfileinfo_recv(req, mem_ctx, rdata, num_rdata); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -5271,8 +5221,7 @@ static void cli_flush_done(struct tevent_req *subreq) status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -5311,9 +5260,6 @@ NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum) status = cli_flush_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -5374,8 +5320,7 @@ static void cli_shadow_copy_data_done(struct tevent_req *subreq) NULL, 0, NULL, /* param */ &state->data, 12, &state->num_data); TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); + if (tevent_req_nterror(req, status)) { return; } tevent_req_done(req); @@ -5460,8 +5405,5 @@ NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli, status = cli_shadow_copy_data_recv(req, mem_ctx, pnames, pnum_names); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index ebd04e6d2b..78024c8f98 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -19,8 +19,10 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "../libcli/auth/spnego.h" #include "../libcli/auth/ntlmssp.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" #include "smb_crypt.h" #include "trans2.h" @@ -151,9 +153,6 @@ NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, pcaphigh); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -256,9 +255,6 @@ NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, status = cli_set_unix_extensions_capabilities_recv(req); fail: TALLOC_FREE(ev); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -355,9 +351,6 @@ NTSTATUS cli_get_fs_attr_info(struct cli_state *cli, uint32_t *fs_attr) status = cli_get_fs_attr_info_recv(req, fs_attr); fail: TALLOC_FREE(ev); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -599,7 +592,7 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, return NT_STATUS_NO_MEMORY; } status = ntlmssp_client_start(NULL, - global_myname(), + lp_netbios_name(), lp_workgroup(), lp_client_ntlmv2_auth(), &es->s.ntlmssp_state); @@ -692,7 +685,7 @@ static NTSTATUS make_cli_gss_blob(TALLOC_CTX *ctx, NTSTATUS status = NT_STATUS_OK; gss_OID_desc nt_hostbased_service = - {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; + {10, discard_const_p(char, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; memset(&tok_out, '\0', sizeof(tok_out)); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index a872d2df61..b11aed8c7b 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -538,6 +538,7 @@ static krb5_error_code setup_auth_context(krb5_context context, return retval; } +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) static krb5_error_code create_gss_checksum(krb5_data *in_data, /* [inout] */ uint32_t gss_flags) { @@ -589,6 +590,7 @@ static krb5_error_code create_gss_checksum(krb5_data *in_data, /* [inout] */ in_data->length = base_cksum_size + orig_length; return 0; } +#endif /* we can't use krb5_mk_req because w2k wants the service to be in a particular format @@ -610,7 +612,6 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_data in_data; bool creds_ready = False; int i = 0, maxtries = 3; - uint32_t gss_flags = 0; ZERO_STRUCT(in_data); @@ -690,80 +691,84 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, } #if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) - if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) { - /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket - as part of the kerberos exchange. */ + { + uint32_t gss_flags = 0; - DEBUG( 3, ("ads_krb5_mk_req: server marked as OK to delegate to, building forwardable TGT\n") ); + if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) { + /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket + as part of the kerberos exchange. */ - retval = krb5_auth_con_setuseruserkey(context, + DEBUG( 3, ("ads_krb5_mk_req: server marked as OK to delegate to, building forwardable TGT\n") ); + + retval = krb5_auth_con_setuseruserkey(context, *auth_context, &credsp->keyblock ); - if (retval) { - DEBUG(1,("krb5_auth_con_setuseruserkey failed (%s)\n", - error_message(retval))); - goto cleanup_creds; - } + if (retval) { + DEBUG(1,("krb5_auth_con_setuseruserkey failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } - /* Must use a subkey for forwarded tickets. */ - retval = krb5_auth_con_setflags(context, + /* Must use a subkey for forwarded tickets. */ + retval = krb5_auth_con_setflags(context, *auth_context, KRB5_AUTH_CONTEXT_USE_SUBKEY); - if (retval) { - DEBUG(1,("krb5_auth_con_setflags failed (%s)\n", - error_message(retval))); - goto cleanup_creds; - } + if (retval) { + DEBUG(1,("krb5_auth_con_setflags failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } - retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */ + retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */ *auth_context, /* Authentication context [in] */ - CONST_DISCARD(char *, KRB5_TGS_NAME), /* Ticket service name ("krbtgt") [in] */ + discard_const_p(char, KRB5_TGS_NAME), /* Ticket service name ("krbtgt") [in] */ credsp->client, /* Client principal for the tgt [in] */ credsp->server, /* Server principal for the tgt [in] */ ccache, /* Credential cache to use for storage [in] */ 1, /* Turn on for "Forwardable ticket" [in] */ &in_data ); /* Resulting response [out] */ - if (retval) { - DEBUG( 3, ("krb5_fwd_tgt_creds failed (%s)\n", - error_message( retval ) ) ); - - /* - * This is not fatal. Delete the *auth_context and continue - * with krb5_mk_req_extended to get a non-forwardable ticket. - */ - - if (in_data.data) { - free( in_data.data ); - in_data.data = NULL; - in_data.length = 0; - } - krb5_auth_con_free(context, *auth_context); - *auth_context = NULL; - retval = setup_auth_context(context, auth_context); if (retval) { - DEBUG(1,("setup_auth_context failed (%s)\n", - error_message(retval))); - goto cleanup_creds; + DEBUG( 3, ("krb5_fwd_tgt_creds failed (%s)\n", + error_message( retval ) ) ); + + /* + * This is not fatal. Delete the *auth_context and continue + * with krb5_mk_req_extended to get a non-forwardable ticket. + */ + + if (in_data.data) { + free( in_data.data ); + in_data.data = NULL; + in_data.length = 0; + } + krb5_auth_con_free(context, *auth_context); + *auth_context = NULL; + retval = setup_auth_context(context, auth_context); + if (retval) { + DEBUG(1,("setup_auth_context failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } + } else { + /* We got a delegated ticket. */ + gss_flags |= GSS_C_DELEG_FLAG; } - } else { - /* We got a delegated ticket. */ - gss_flags |= GSS_C_DELEG_FLAG; } - } - /* Frees and reallocates in_data into a GSS checksum blob. */ - retval = create_gss_checksum(&in_data, gss_flags); - if (retval) { - goto cleanup_data; - } + /* Frees and reallocates in_data into a GSS checksum blob. */ + retval = create_gss_checksum(&in_data, gss_flags); + if (retval) { + goto cleanup_data; + } - /* We always want GSS-checksum types. */ - retval = krb5_auth_con_set_req_cksumtype(context, *auth_context, GSSAPI_CHECKSUM ); - if (retval) { - DEBUG(1,("krb5_auth_con_set_req_cksumtype failed (%s)\n", - error_message(retval))); - goto cleanup_data; + /* We always want GSS-checksum types. */ + retval = krb5_auth_con_set_req_cksumtype(context, *auth_context, GSSAPI_CHECKSUM ); + if (retval) { + DEBUG(1,("krb5_auth_con_set_req_cksumtype failed (%s)\n", + error_message(retval))); + goto cleanup_data; + } } #endif @@ -774,7 +779,10 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, error_message(retval))); } +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) cleanup_data: +#endif + if (in_data.data) { free( in_data.data ); in_data.length = 0; @@ -919,7 +927,7 @@ done: { static krb5_data kdata; - kdata.data = (char *)krb5_principal_get_comp_string(context, principal, i); + kdata.data = discard_const_p(char, krb5_principal_get_comp_string(context, principal, i)); kdata.length = strlen((const char *)kdata.data); return &kdata; } @@ -1131,7 +1139,7 @@ out: DEBUG(10,("smb_krb5_renew_ticket: using %s as ccache\n", ccache_string)); /* FIXME: we should not fall back to defaults */ - ret = krb5_cc_resolve(context, CONST_DISCARD(char *, ccache_string), &ccache); + ret = krb5_cc_resolve(context, discard_const_p(char, ccache_string), &ccache); if (ret) { goto done; } @@ -1150,7 +1158,7 @@ out: #ifdef HAVE_KRB5_GET_RENEWED_CREDS /* MIT */ { - ret = krb5_get_renewed_creds(context, &creds, client, ccache, CONST_DISCARD(char *, service_string)); + ret = krb5_get_renewed_creds(context, &creds, client, ccache, discard_const_p(char, service_string)); if (ret) { DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); goto done; @@ -1265,7 +1273,7 @@ done: return ENOMEM; } - put_name(buf, global_myname(), ' ', 0x20); + put_name(buf, lp_netbios_name(), ' ', 0x20); #if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ { @@ -1956,11 +1964,11 @@ char *smb_krb5_principal_get_realm(krb5_context context, krb5_principal principal) { #ifdef HAVE_KRB5_PRINCIPAL_GET_REALM /* Heimdal */ - return krb5_principal_get_realm(context, principal); + return discard_const_p(char, krb5_principal_get_realm(context, principal)); #elif defined(krb5_princ_realm) /* MIT */ krb5_data *realm; realm = krb5_princ_realm(context, principal); - return (char *)realm->data; + return discard_const_p(char, realm->data); #else return NULL; #endif diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 552de00242..9eec97fbeb 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -18,6 +18,8 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" #include "trans2.h" @@ -319,7 +321,7 @@ static struct tevent_req *cli_list_old_send(TALLOC_CTX *mem_ctx, bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), mask, strlen(mask)+1, NULL); - bytes = smb_bytes_push_bytes(bytes, 5, (uint8_t *)&zero, 2); + bytes = smb_bytes_push_bytes(bytes, 5, (const uint8_t *)&zero, 2); if (tevent_req_nomem(bytes, req)) { return tevent_req_post(req, ev); } @@ -385,7 +387,7 @@ static void cli_list_old_done(struct tevent_req *subreq) dirlist_len = talloc_get_size(state->dirlist); - tmp = TALLOC_REALLOC_ARRAY( + tmp = talloc_realloc( state, state->dirlist, uint8_t, dirlist_len + received * DIR_STRUCT_SIZE); if (tevent_req_nomem(tmp, req)) { @@ -450,7 +452,7 @@ static NTSTATUS cli_list_old_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, num_received = talloc_array_length(state->dirlist) / DIR_STRUCT_SIZE; - finfo = TALLOC_ARRAY(mem_ctx, struct file_info, num_received); + finfo = talloc_array(mem_ctx, struct file_info, num_received); if (finfo == NULL) { return NT_STATUS_NO_MEMORY; } @@ -512,9 +514,6 @@ NTSTATUS cli_list_old(struct cli_state *cli, const char *mask, } fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -574,7 +573,7 @@ static struct tevent_req *cli_list_trans_send(TALLOC_CTX *mem_ctx, state->setup[0] = TRANSACT2_FINDFIRST; nlen = 2*(strlen(mask)+1); - state->param = TALLOC_ARRAY(state, uint8_t, 12+nlen+2); + state->param = talloc_array(state, uint8_t, 12+nlen+2); if (tevent_req_nomem(state->param, req)) { return tevent_req_post(req, ev); } @@ -655,7 +654,7 @@ static void cli_list_trans_done(struct tevent_req *subreq) old_num_finfo = talloc_array_length(state->finfo); - tmp = TALLOC_REALLOC_ARRAY(state, state->finfo, struct file_info, + tmp = talloc_realloc(state, state->finfo, struct file_info, old_num_finfo + ff_searchcount); if (tevent_req_nomem(tmp, req)) { return; @@ -712,7 +711,7 @@ static void cli_list_trans_done(struct tevent_req *subreq) /* * Shrink state->finfo to the real length we received */ - tmp = TALLOC_REALLOC_ARRAY(state, state->finfo, struct file_info, + tmp = talloc_realloc(state, state->finfo, struct file_info, old_num_finfo + i); if (tevent_req_nomem(tmp, req)) { return; @@ -737,7 +736,7 @@ static void cli_list_trans_done(struct tevent_req *subreq) nlen = 2*(strlen(state->mask) + 1); - param = TALLOC_REALLOC_ARRAY(state, state->param, uint8_t, + param = talloc_realloc(state, state->param, uint8_t, 12 + nlen + last_name_raw.length + 2); if (tevent_req_nomem(param, req)) { return; @@ -841,9 +840,6 @@ NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask, } fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -966,8 +962,5 @@ NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16 attribute, } fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 2c2921aa0c..55ffd8d9a5 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -18,7 +18,9 @@ */ #include "includes.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" +#include "libsmb/libsmb.h" struct cli_message_start_state { uint16_t grp; diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 78e93a4f31..da55f971a8 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -18,7 +18,9 @@ */ #include "includes.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" +#include "libsmb/libsmb.h" /**************************************************************************** send an ack for an oplock break request @@ -116,9 +118,6 @@ NTSTATUS cli_oplock_ack(struct cli_state *cli, uint16_t fnum, unsigned char leve status = cli_oplock_ack_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 10d1759de8..06cb02521f 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmb/clirap.h" /***************************************************************************** @@ -65,16 +66,16 @@ int cli_print_queue(struct cli_state *cli, p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; - safe_strcpy_base(p,"zWrLeh", param, sizeof(param)); /* parameter description? */ + strlcpy_base(p,"zWrLeh", param, sizeof(param)); /* parameter description? */ p = skip_string(param,sizeof(param),p); - safe_strcpy_base(p,"WWzWWDDzz", param, sizeof(param)); /* returned data format */ + strlcpy_base(p,"WWzWWDDzz", param, sizeof(param)); /* returned data format */ p = skip_string(param,sizeof(param),p); - safe_strcpy_base(p,cli->share, param, sizeof(param)); /* name of queue */ + strlcpy_base(p,cli->share, param, sizeof(param)); /* name of queue */ p = skip_string(param,sizeof(param),p); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; - safe_strcpy_base(p,"", param,sizeof(param)); /* subformat */ + strlcpy_base(p,"", param,sizeof(param)); /* subformat */ p = skip_string(param,sizeof(param),p); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); @@ -136,9 +137,9 @@ int cli_printjob_del(struct cli_state *cli, int job) p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; - safe_strcpy_base(p,"W", param,sizeof(param)); + strlcpy_base(p,"W", param,sizeof(param)); p = skip_string(param,sizeof(param),p); - safe_strcpy_base(p,"", param,sizeof(param)); + strlcpy_base(p,"", param,sizeof(param)); p = skip_string(param,sizeof(param),p); SSVAL(p,0,job); p += 2; diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index e5c8c831b7..9136506e48 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "../librpc/gen_ndr/ndr_security.h" #include "fake_file.h" #include "../libcli/security/security.h" @@ -88,7 +89,7 @@ static bool parse_user_quota_record(const uint8_t *rdata, /* the hard quotas 8 bytes (uint64_t)*/ qt.hardlim = BVAL(rdata,32); - if (!sid_parse((char *)rdata+40,sid_len,&qt.sid)) { + if (!sid_parse((const char *)rdata+40,sid_len,&qt.sid)) { return false; } @@ -262,19 +263,19 @@ NTSTATUS cli_list_user_quota(struct cli_state *cli, int quota_fnum, ((curdata)&&(curdata_count>=8)&&(offset>0)); curdata +=offset,curdata_count -= offset) { ZERO_STRUCT(qt); - if (!parse_user_quota_record((uint8_t *)curdata, curdata_count, + if (!parse_user_quota_record((const uint8_t *)curdata, curdata_count, &offset, &qt)) { DEBUG(1,("Failed to parse the quota record\n")); goto cleanup; } - if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { + if ((tmp_list_ent=talloc_zero(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } - if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { + if ((tmp_list_ent->quotas=talloc_zero(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; @@ -318,20 +319,20 @@ NTSTATUS cli_list_user_quota(struct cli_state *cli, int quota_fnum, ((curdata)&&(curdata_count>=8)&&(offset>0)); curdata +=offset,curdata_count -= offset) { ZERO_STRUCT(qt); - if (!parse_user_quota_record((uint8_t *)curdata, + if (!parse_user_quota_record((const uint8_t *)curdata, curdata_count, &offset, &qt)) { DEBUG(1,("Failed to parse the quota record\n")); goto cleanup; } - if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { + if ((tmp_list_ent=talloc_zero(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); goto cleanup; } - if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { + if ((tmp_list_ent->quotas=talloc_zero(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); goto cleanup; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 8d1be2d66e..e5ff1abc18 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -23,7 +23,9 @@ #include "../libcli/auth/libcli_auth.h" #include "../librpc/gen_ndr/rap.h" #include "../lib/crypto/arcfour.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" +#include "libsmb/libsmb.h" #include "libsmb/clirap.h" #include "trans2.h" @@ -687,9 +689,6 @@ NTSTATUS cli_qpathinfo1(struct cli_state *cli, write_time, size, mode); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -865,9 +864,6 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname, write_time, change_time, size, mode, ino); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -979,9 +975,6 @@ NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname, pstreams); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -1005,7 +998,7 @@ static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata, struct stream_struct *tmp; uint8_t *tmp_buf; - tmp = TALLOC_REALLOC_ARRAY(mem_ctx, streams, + tmp = talloc_realloc(mem_ctx, streams, struct stream_struct, num_streams+1); @@ -1030,7 +1023,7 @@ static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata, * convert_string_talloc?? */ - tmp_buf = TALLOC_ARRAY(streams, uint8_t, nlen+2); + tmp_buf = talloc_array(streams, uint8_t, nlen+2); if (tmp_buf == NULL) { goto fail; } @@ -1086,7 +1079,7 @@ NTSTATUS cli_qfilename(struct cli_state *cli, uint16_t fnum, char *name, return status; } - clistr_pull(cli->inbuf, name, rdata+4, namelen, IVAL(rdata, 0), + clistr_pull((const char *)rdata, name, rdata+4, namelen, IVAL(rdata, 0), STR_UNICODE); TALLOC_FREE(rdata); return NT_STATUS_OK; @@ -1247,9 +1240,6 @@ NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name, status = cli_qpathinfo_basic_recv(req, sbuf, attributes); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } diff --git a/source3/libsmb/clirap.h b/source3/libsmb/clirap.h index 6ea6978c04..26265dec50 100644 --- a/source3/libsmb/clirap.h +++ b/source3/libsmb/clirap.h @@ -25,6 +25,8 @@ #ifndef _LIBSMB_CLIRAP_H #define _LIBSMB_CLIRAP_H +struct cli_state; + /* The following definitions come from libsmb/clirap.c */ bool cli_api(struct cli_state *cli, diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 44a9d7c8c4..03b4ca7541 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -76,6 +76,7 @@ /*****************************************************/ #include "includes.h" +#include "libsmb/libsmb.h" #include "../librpc/gen_ndr/rap.h" #include "../librpc/gen_ndr/svcctl.h" #include "libsmb/clirap.h" diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index e243f8a0fc..14b6401051 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -18,6 +18,8 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" #include "trans2.h" @@ -26,6 +28,11 @@ ****************************************************************************/ static size_t cli_read_max_bufsize(struct cli_state *cli) { + size_t data_offset = smb_size - 4; + size_t wct = 12; + + size_t useable_space; + if (!client_is_signing_on(cli) && !cli_encryption_on(cli) && (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; @@ -35,13 +42,21 @@ static size_t cli_read_max_bufsize(struct cli_state *cli) ? CLI_SAMBA_MAX_LARGE_READX_SIZE : CLI_WINDOWS_MAX_LARGE_READX_SIZE; } - return (cli->max_xmit - (smb_size+32)) & ~1023; + + data_offset += wct * sizeof(uint16_t); + data_offset += 1; /* pad */ + + useable_space = cli->max_xmit - data_offset; + + return useable_space; } /**************************************************************************** Calculate the recommended write buffer size ****************************************************************************/ -static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode) +static size_t cli_write_max_bufsize(struct cli_state *cli, + uint16_t write_mode, + uint8_t wct) { if (write_mode == 0 && !client_is_signing_on(cli) && @@ -60,13 +75,15 @@ static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode) if (((cli->capabilities & CAP_LARGE_WRITEX) == 0) || client_is_signing_on(cli) || strequal(cli->dev, "LPT1:")) { + size_t data_offset = smb_size - 4; + size_t useable_space; - /* - * Printer devices are restricted to max_xmit writesize in - * Vista and XPSP3 as are signing connections. - */ + data_offset += wct * sizeof(uint16_t); + data_offset += 1; /* pad */ - return (cli->max_xmit - (smb_size+32)) & ~1023; + useable_space = cli->max_xmit - data_offset; + + return useable_space; } return CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE; @@ -196,7 +213,7 @@ static void cli_read_andx_done(struct tevent_req *subreq) return; } - state->buf = (uint8_t *)smb_base(inbuf) + SVAL(vwv+6, 0); + state->buf = discard_const_p(uint8_t, smb_base(inbuf)) + SVAL(vwv+6, 0); if (trans_oob(smb_len(inbuf), SVAL(vwv+6, 0), state->received) || ((state->received != 0) && (state->buf < bytes))) { @@ -465,7 +482,7 @@ struct tevent_req *cli_pull_send(TALLOC_CTX *mem_ctx, state->num_reqs = MAX(window_size/state->chunk_size, 1); state->num_reqs = MIN(state->num_reqs, cli->max_mux); - state->reqs = TALLOC_ZERO_ARRAY(state, struct cli_pull_subreq, + state->reqs = talloc_zero_array(state, struct cli_pull_subreq, state->num_reqs); if (state->reqs == NULL) { goto failed; @@ -663,9 +680,6 @@ NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, status = cli_pull_recv(req, received); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } @@ -686,171 +700,12 @@ ssize_t cli_read(struct cli_state *cli, uint16_t fnum, char *buf, status = cli_pull(cli, fnum, offset, size, size, cli_read_sink, &buf, &ret); if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); return -1; } return ret; } /**************************************************************************** - Issue a single SMBwrite and don't wait for a reply. -****************************************************************************/ - -static bool cli_issue_write(struct cli_state *cli, - uint16_t fnum, - off_t offset, - uint16 mode, - const char *buf, - size_t size) -{ - char *p; - bool large_writex = false; - /* We can only do direct writes if not signing and not encrypting. */ - bool direct_writes = !client_is_signing_on(cli) && !cli_encryption_on(cli); - - if (!direct_writes && size + 1 > cli->bufsize) { - cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024); - if (!cli->outbuf) { - return False; - } - cli->inbuf = (char *)SMB_REALLOC(cli->inbuf, size + 1024); - if (cli->inbuf == NULL) { - SAFE_FREE(cli->outbuf); - return False; - } - cli->bufsize = size + 1024; - } - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - if (cli->capabilities & CAP_LARGE_FILES) { - large_writex = True; - } - - if (large_writex) { - cli_set_message(cli->outbuf,14,0,True); - } else { - cli_set_message(cli->outbuf,12,0,True); - } - - SCVAL(cli->outbuf,smb_com,SMBwriteX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - - SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv7,mode); - - SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); - /* - * According to CIFS-TR-1p00, this following field should only - * be set if CAP_LARGE_WRITEX is set. We should check this - * locally. However, this check might already have been - * done by our callers. - */ - SSVAL(cli->outbuf,smb_vwv9,(size>>16)); - SSVAL(cli->outbuf,smb_vwv10,size); - /* +1 is pad byte. */ - SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf) + 1); - - if (large_writex) { - SIVAL(cli->outbuf,smb_vwv12,(((uint64_t)offset)>>32) & 0xffffffff); - } - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11) -1; - *p++ = '\0'; /* pad byte. */ - if (!direct_writes) { - memcpy(p, buf, size); - } - if (size > 0x1FFFF) { - /* This is a POSIX 14 word large write. */ - set_message_bcc(cli->outbuf, 0); /* Set bcc to zero. */ - _smb_setlen_large(cli->outbuf,smb_size + 28 + 1 /* pad */ + size - 4); - } else { - cli_setup_bcc(cli, p+size); - } - - show_msg(cli->outbuf); - if (direct_writes) { - /* For direct writes we now need to write the data - * directly out of buf. */ - return cli_send_smb_direct_writeX(cli, buf, size); - } else { - return cli_send_smb(cli); - } -} - -/**************************************************************************** - write to a file - write_mode: 0x0001 disallow write cacheing - 0x0002 return bytes remaining - 0x0004 use raw named pipe protocol - 0x0008 start of message mode named pipe protocol -****************************************************************************/ - -ssize_t cli_write(struct cli_state *cli, - uint16_t fnum, uint16 write_mode, - const char *buf, off_t offset, size_t size) -{ - ssize_t bwritten = 0; - unsigned int issued = 0; - unsigned int received = 0; - int mpx = 1; - size_t writesize; - int blocks; - - if(cli->max_mux > 1) { - mpx = cli->max_mux-1; - } else { - mpx = 1; - } - - writesize = cli_write_max_bufsize(cli, write_mode); - - blocks = (size + (writesize-1)) / writesize; - - while (received < blocks) { - - while ((issued - received < mpx) && (issued < blocks)) { - ssize_t bsent = issued * writesize; - ssize_t size1 = MIN(writesize, size - bsent); - - if (!cli_issue_write(cli, fnum, offset + bsent, - write_mode, - buf + bsent, - size1)) - return -1; - issued++; - } - - if (!cli_receive_smb(cli)) { - return bwritten; - } - - received++; - - if (cli_is_error(cli)) - break; - - bwritten += SVAL(cli->inbuf, smb_vwv2); - if (writesize > 0xFFFF) { - bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16); - } - } - - while (received < issued && cli_receive_smb(cli)) { - received++; - } - - return bwritten; -} - -/**************************************************************************** write to a file using a SMBwrite and not bypassing 0 byte writes ****************************************************************************/ @@ -864,7 +719,7 @@ NTSTATUS cli_smbwrite(struct cli_state *cli, uint16_t fnum, char *buf, * 3 bytes prefix */ - bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 3); + bytes = talloc_array(talloc_tos(), uint8_t, 3); if (bytes == NULL) { return NT_STATUS_NO_MEMORY; } @@ -882,7 +737,7 @@ NTSTATUS cli_smbwrite(struct cli_state *cli, uint16_t fnum, char *buf, SIVAL(vwv+2, 0, offset); SSVAL(vwv+4, 0, 0); - bytes = TALLOC_REALLOC_ARRAY(talloc_tos(), bytes, uint8_t, + bytes = talloc_realloc(talloc_tos(), bytes, uint8_t, size+3); if (bytes == NULL) { return NT_STATUS_NO_MEMORY; @@ -944,7 +799,7 @@ struct tevent_req *cli_write_andx_create(TALLOC_CTX *mem_ctx, struct cli_write_andx_state *state; bool bigoffset = ((cli->capabilities & CAP_LARGE_FILES) != 0); uint8_t wct = bigoffset ? 14 : 12; - size_t max_write = cli_write_max_bufsize(cli, mode); + size_t max_write = cli_write_max_bufsize(cli, mode, wct); uint16_t *vwv; req = tevent_req_create(mem_ctx, &state, struct cli_write_andx_state); @@ -981,7 +836,7 @@ struct tevent_req *cli_write_andx_create(TALLOC_CTX *mem_ctx, state->pad = 0; state->iov[0].iov_base = (void *)&state->pad; state->iov[0].iov_len = 1; - state->iov[1].iov_base = CONST_DISCARD(void *, buf); + state->iov[1].iov_base = discard_const_p(void, buf); state->iov[1].iov_len = size; subreq = cli_smb_req_create(state, ev, cli, SMBwriteX, 0, wct, vwv, @@ -1138,9 +993,54 @@ static void cli_writeall_written(struct tevent_req *subreq) tevent_req_set_callback(subreq, cli_writeall_written, req); } -static NTSTATUS cli_writeall_recv(struct tevent_req *req) +static NTSTATUS cli_writeall_recv(struct tevent_req *req, + size_t *pwritten) { - return tevent_req_simple_recv_ntstatus(req); + struct cli_writeall_state *state = tevent_req_data( + req, struct cli_writeall_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + if (pwritten != NULL) { + *pwritten = state->written; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_writeall(struct cli_state *cli, uint16_t fnum, uint16_t mode, + const uint8_t *buf, off_t offset, size_t size, + size_t *pwritten) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_writeall_send(frame, ev, cli, fnum, mode, buf, offset, size); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + status = cli_writeall_recv(req, pwritten); + fail: + TALLOC_FREE(frame); + return status; } struct cli_push_write_state { @@ -1252,7 +1152,7 @@ struct tevent_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->pending = 0; state->next_offset = start_offset; - state->chunk_size = cli_write_max_bufsize(cli, mode); + state->chunk_size = cli_write_max_bufsize(cli, mode, 14); if (window_size == 0) { window_size = cli->max_mux * state->chunk_size; @@ -1264,7 +1164,7 @@ struct tevent_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, state->num_reqs = MIN(state->num_reqs, cli->max_mux); state->num_reqs = MAX(state->num_reqs, 1); - state->reqs = TALLOC_ZERO_ARRAY(state, struct cli_push_write_state *, + state->reqs = talloc_zero_array(state, struct cli_push_write_state *, state->num_reqs); if (state->reqs == NULL) { goto failed; @@ -1305,7 +1205,7 @@ static void cli_push_written(struct tevent_req *subreq) state->reqs[idx] = NULL; state->pending -= 1; - status = cli_writeall_recv(subreq); + status = cli_writeall_recv(subreq, NULL); TALLOC_FREE(subreq); TALLOC_FREE(substate); if (tevent_req_nterror(req, status)) { @@ -1369,8 +1269,5 @@ NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode, status = cli_push_recv(req); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 5543ce5033..d703b1f774 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -18,6 +18,8 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" +#include "../libcli/security/secdesc.h" /**************************************************************************** query the security descriptor for a open file diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c index 1752edb023..ac4db7626f 100644 --- a/source3/libsmb/clisigning.c +++ b/source3/libsmb/clisigning.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "smb_signing.h" bool cli_simple_set_signing(struct cli_state *cli, diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 944479c2a8..ff18ef6bcf 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" size_t clistr_push_fn(struct cli_state *cli, void *dest, @@ -74,8 +75,3 @@ size_t clistr_pull_talloc(TALLOC_CTX *ctx, src_len, flags); } - -size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) -{ - return align_string(cli->outbuf, (const char *)p, flags); -} diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index dab8c10c84..dd8063bf1e 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -18,6 +18,8 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" +#include "../lib/util/tevent_ntstatus.h" #include "async_smb.h" struct trans_recvblob { @@ -30,7 +32,6 @@ struct cli_trans_state { struct event_context *ev; uint8_t cmd; uint16_t mid; - uint32_t seqnum; const char *pipe_name; uint8_t *pipe_name_conv; size_t pipe_name_conv_len; @@ -50,13 +51,29 @@ struct cli_trans_state { struct trans_recvblob rdata; uint16_t recv_flags2; - TALLOC_CTX *secondary_request_ctx; - - struct iovec iov[4]; + struct iovec iov[6]; uint8_t pad[4]; + uint8_t zero_pad[4]; uint16_t vwv[32]; + + struct tevent_req *primary_subreq; }; +static void cli_trans_cleanup_primary(struct cli_trans_state *state) +{ + if (state->primary_subreq) { + cli_smb_req_set_mid(state->primary_subreq, 0); + cli_smb_req_unset_pending(state->primary_subreq); + TALLOC_FREE(state->primary_subreq); + } +} + +static int cli_trans_state_destructor(struct cli_trans_state *state) +{ + cli_trans_cleanup_primary(state); + return 0; +} + static NTSTATUS cli_pull_trans(uint8_t *inbuf, uint8_t wct, uint16_t *vwv, uint16_t num_bytes, uint8_t *bytes, @@ -146,7 +163,7 @@ static NTSTATUS cli_trans_pull_blob(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_NETWORK_RESPONSE; } blob->total = total; - blob->data = TALLOC_ARRAY(mem_ctx, uint8_t, total); + blob->data = talloc_array(mem_ctx, uint8_t, total); if (blob->data == NULL) { return NT_STATUS_NO_MEMORY; } @@ -171,9 +188,12 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, struct iovec *iov = state->iov; uint8_t *pad = state->pad; uint16_t *vwv = state->vwv; - uint16_t param_offset; - uint16_t this_param = 0; - uint16_t this_data = 0; + uint32_t param_offset; + uint32_t this_param = 0; + uint32_t param_pad; + uint32_t data_offset; + uint32_t this_data = 0; + uint32_t data_pad; uint32_t useable_space; uint8_t cmd; @@ -221,7 +241,18 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, break; } - useable_space = state->cli->max_xmit - smb_size - sizeof(uint16_t)*wct; + param_offset += wct * sizeof(uint16_t); + useable_space = state->cli->max_xmit - param_offset; + + param_pad = param_offset % 4; + if (param_pad > 0) { + param_pad = MIN(param_pad, useable_space); + iov[0].iov_base = (void *)state->zero_pad; + iov[0].iov_len = param_pad; + iov += 1; + param_offset += param_pad; + } + useable_space = state->cli->max_xmit - param_offset; if (state->param_sent < state->num_param) { this_param = MIN(state->num_param - state->param_sent, @@ -231,27 +262,41 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, iov += 1; } + data_offset = param_offset + this_param; + useable_space = state->cli->max_xmit - data_offset; + + data_pad = data_offset % 4; + if (data_pad > 0) { + data_pad = MIN(data_pad, useable_space); + iov[0].iov_base = (void *)state->zero_pad; + iov[0].iov_len = data_pad; + iov += 1; + data_offset += data_pad; + } + useable_space = state->cli->max_xmit - data_offset; + if (state->data_sent < state->num_data) { this_data = MIN(state->num_data - state->data_sent, - useable_space - this_param); + useable_space); iov[0].iov_base = (void *)(state->data + state->data_sent); iov[0].iov_len = this_data; iov += 1; } - param_offset += wct * sizeof(uint16_t); - DEBUG(10, ("num_setup=%u, max_setup=%u, " "param_total=%u, this_param=%u, max_param=%u, " "data_total=%u, this_data=%u, max_data=%u, " - "param_offset=%u, param_disp=%u, data_disp=%u\n", + "param_offset=%u, param_pad=%u, param_disp=%u, " + "data_offset=%u, data_pad=%u, data_disp=%u\n", (unsigned)state->num_setup, (unsigned)state->max_setup, (unsigned)state->num_param, (unsigned)this_param, (unsigned)state->rparam.max, (unsigned)state->num_data, (unsigned)this_data, (unsigned)state->rdata.max, - (unsigned)param_offset, - (unsigned)state->param_sent, (unsigned)state->data_sent)); + (unsigned)param_offset, (unsigned)param_pad, + (unsigned)state->param_sent, + (unsigned)data_offset, (unsigned)data_pad, + (unsigned)state->data_sent)); switch (cmd) { case SMBtrans: @@ -268,7 +313,7 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, SSVAL(vwv + 9, 0, this_param); SSVAL(vwv +10, 0, param_offset); SSVAL(vwv +11, 0, this_data); - SSVAL(vwv +12, 0, param_offset + this_param); + SSVAL(vwv +12, 0, data_offset); SCVAL(vwv +13, 0, state->num_setup); SCVAL(vwv +13, 1, 0); /* reserved */ memcpy(vwv + 14, state->setup, @@ -282,40 +327,40 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, SSVAL(vwv + 3, 0, param_offset); SSVAL(vwv + 4, 0, state->param_sent); SSVAL(vwv + 5, 0, this_data); - SSVAL(vwv + 6, 0, param_offset + this_param); + SSVAL(vwv + 6, 0, data_offset); SSVAL(vwv + 7, 0, state->data_sent); if (cmd == SMBtranss2) { SSVAL(vwv + 8, 0, state->fid); } break; case SMBnttrans: - SCVAL(vwv, 0, state->max_setup); - SSVAL(vwv, 1, 0); /* reserved */ - SIVAL(vwv, 3, state->num_param); - SIVAL(vwv, 7, state->num_data); - SIVAL(vwv, 11, state->rparam.max); - SIVAL(vwv, 15, state->rdata.max); - SIVAL(vwv, 19, this_param); - SIVAL(vwv, 23, param_offset); - SIVAL(vwv, 27, this_data); - SIVAL(vwv, 31, param_offset + this_param); - SCVAL(vwv, 35, state->num_setup); - SSVAL(vwv, 36, state->function); + SCVAL(vwv + 0, 0, state->max_setup); + SSVAL(vwv + 0, 1, 0); /* reserved */ + SIVAL(vwv + 1, 1, state->num_param); + SIVAL(vwv + 3, 1, state->num_data); + SIVAL(vwv + 5, 1, state->rparam.max); + SIVAL(vwv + 7, 1, state->rdata.max); + SIVAL(vwv + 9, 1, this_param); + SIVAL(vwv +11, 1, param_offset); + SIVAL(vwv +13, 1, this_data); + SIVAL(vwv +15, 1, data_offset); + SCVAL(vwv +17, 1, state->num_setup); + SSVAL(vwv +18, 0, state->function); memcpy(vwv + 19, state->setup, sizeof(uint16_t) * state->num_setup); break; case SMBnttranss: - SSVAL(vwv, 0, 0); /* reserved */ - SCVAL(vwv, 2, 0); /* reserved */ - SIVAL(vwv, 3, state->num_param); - SIVAL(vwv, 7, state->num_data); - SIVAL(vwv, 11, this_param); - SIVAL(vwv, 15, param_offset); - SIVAL(vwv, 19, state->param_sent); - SIVAL(vwv, 23, this_data); - SIVAL(vwv, 27, param_offset + this_param); - SIVAL(vwv, 31, state->data_sent); - SCVAL(vwv, 35, 0); /* reserved */ + SSVAL(vwv + 0, 0, 0); /* reserved */ + SCVAL(vwv + 1, 0, 0); /* reserved */ + SIVAL(vwv + 1, 1, state->num_param); + SIVAL(vwv + 3, 1, state->num_data); + SIVAL(vwv + 5, 1, this_param); + SIVAL(vwv + 7, 1, param_offset); + SIVAL(vwv + 9, 1, state->param_sent); + SIVAL(vwv +11, 1, this_data); + SIVAL(vwv +13, 1, data_offset); + SIVAL(vwv +15, 1, state->data_sent); + SCVAL(vwv +17, 1, 0); /* reserved */ break; } @@ -412,17 +457,30 @@ struct tevent_req *cli_trans_send( if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - state->mid = cli_smb_req_mid(subreq); status = cli_smb_req_send(subreq); if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return tevent_req_post(req, state->ev); } - cli_state_seqnum_persistent(cli, state->mid); tevent_req_set_callback(subreq, cli_trans_done, req); + + /* + * Now get the MID of the primary request + * and mark it as persistent. This means + * we will able to send and receive multiple + * SMB pdus using this MID in both directions + * (including correct SMB signing). + */ + state->mid = cli_smb_req_mid(subreq); + cli_smb_req_set_mid(subreq, state->mid); + state->primary_subreq = subreq; + talloc_set_destructor(state, cli_trans_state_destructor); + return req; } +static void cli_trans_done2(struct tevent_req *subreq); + static void cli_trans_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( @@ -478,25 +536,25 @@ static void cli_trans_done(struct tevent_req *subreq) if (!sent_all) { int iov_count; - - TALLOC_FREE(subreq); + struct tevent_req *subreq2; cli_trans_format(state, &wct, &iov_count); - subreq = cli_smb_req_create(state, state->ev, state->cli, - state->cmd + 1, 0, wct, state->vwv, - iov_count, state->iov); - if (tevent_req_nomem(subreq, req)) { + subreq2 = cli_smb_req_create(state, state->ev, state->cli, + state->cmd + 1, 0, wct, state->vwv, + iov_count, state->iov); + if (tevent_req_nomem(subreq2, req)) { return; } - cli_smb_req_set_mid(subreq, state->mid); + cli_smb_req_set_mid(subreq2, state->mid); - status = cli_smb_req_send(subreq); + status = cli_smb_req_send(subreq2); if (!NT_STATUS_IS_OK(status)) { goto fail; } - tevent_req_set_callback(subreq, cli_trans_done, req); + tevent_req_set_callback(subreq2, cli_trans_done2, req); + return; } @@ -521,23 +579,80 @@ static void cli_trans_done(struct tevent_req *subreq) if ((state->rparam.total == state->rparam.received) && (state->rdata.total == state->rdata.received)) { state->recv_flags2 = SVAL(inbuf, smb_flg2); - TALLOC_FREE(subreq); - cli_state_seqnum_remove(state->cli, state->mid); + cli_trans_cleanup_primary(state); tevent_req_done(req); return; } TALLOC_FREE(inbuf); - if (!cli_smb_req_set_pending(subreq)) { - status = NT_STATUS_NO_MEMORY; + return; + + fail: + cli_trans_cleanup_primary(state); + tevent_req_nterror(req, status); +} + +static void cli_trans_done2(struct tevent_req *subreq2) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq2, struct tevent_req); + struct cli_trans_state *state = tevent_req_data( + req, struct cli_trans_state); + NTSTATUS status; + bool sent_all; + uint8_t wct; + uint32_t seqnum; + + /* + * First backup the seqnum of the secondary request + * and attach it to the primary request. + */ + seqnum = cli_smb_req_seqnum(subreq2); + cli_smb_req_set_seqnum(state->primary_subreq, seqnum); + + status = cli_smb_recv(subreq2, state, NULL, 0, &wct, NULL, + NULL, NULL); + TALLOC_FREE(subreq2); + + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + if (wct != 0) { + status = NT_STATUS_INVALID_NETWORK_RESPONSE; goto fail; } + + sent_all = ((state->param_sent == state->num_param) + && (state->data_sent == state->num_data)); + + if (!sent_all) { + int iov_count; + + cli_trans_format(state, &wct, &iov_count); + + subreq2 = cli_smb_req_create(state, state->ev, state->cli, + state->cmd + 1, 0, wct, state->vwv, + iov_count, state->iov); + if (tevent_req_nomem(subreq2, req)) { + return; + } + cli_smb_req_set_mid(subreq2, state->mid); + + status = cli_smb_req_send(subreq2); + + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + tevent_req_set_callback(subreq2, cli_trans_done2, req); + return; + } + return; fail: - cli_state_seqnum_remove(state->cli, state->mid); - TALLOC_FREE(subreq); + cli_trans_cleanup_primary(state); tevent_req_nterror(req, status); } @@ -554,6 +669,8 @@ NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, req, struct cli_trans_state); NTSTATUS status; + cli_trans_cleanup_primary(state); + if (tevent_req_is_nterror(req, &status)) { return status; } @@ -644,8 +761,5 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, rdata, min_rdata, num_rdata); fail: TALLOC_FREE(frame); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - } return status; } diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index e062818dda..5df833f40f 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -32,7 +32,6 @@ struct ip_service_name { struct sockaddr_storage ss; - unsigned port; const char *hostname; }; @@ -340,7 +339,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_NOT_FOUND; } - info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); + info = talloc_zero(mem_ctx, struct netr_DsRGetDCNameInfo); if (!info) { return NT_STATUS_NO_MEMORY; } @@ -499,7 +498,7 @@ static NTSTATUS discover_dc_netbios(TALLOC_CTX *mem_ctx, return status; } - dclist = TALLOC_ZERO_ARRAY(mem_ctx, struct ip_service_name, count); + dclist = talloc_zero_array(mem_ctx, struct ip_service_name, count); if (!dclist) { SAFE_FREE(iplist); return NT_STATUS_NO_MEMORY; @@ -514,7 +513,6 @@ static NTSTATUS discover_dc_netbios(TALLOC_CTX *mem_ctx, &iplist[i].ss); r->ss = iplist[i].ss; - r->port = iplist[i].port; r->hostname = talloc_strdup(mem_ctx, addr); if (!r->hostname) { SAFE_FREE(iplist); @@ -581,7 +579,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, numaddrs += MAX(dcs[i].num_ips,1); } - dclist = TALLOC_ZERO_ARRAY(mem_ctx, + dclist = talloc_zero_array(mem_ctx, struct ip_service_name, numaddrs); if (!dclist) { @@ -598,7 +596,6 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, struct ip_service_name *r = &dclist[count]; - r->port = dcs[i].port; r->hostname = dcs[i].hostname; /* If we don't have an IP list for a name, lookup it up */ @@ -609,7 +606,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, i++; j = 0; } else { - /* use the IP addresses from the SRV sresponse */ + /* use the IP addresses from the SRV response */ if (j >= dcs[i].num_ips) { i++; @@ -623,8 +620,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, /* make sure it is a valid IP. I considered checking the * negative connection cache, but this is the wrong place for - * it. Maybe only as a hac. After think about it, if all of - * the IP addresses retuend from DNS are dead, what hope does a + * it. Maybe only as a hack. After think about it, if all of + * the IP addresses returned from DNS are dead, what hope does a * netbios name lookup have? The standard reason for falling * back to netbios lookups is that our DNS server doesn't know * anything about the DC's -- jerry */ @@ -662,7 +659,7 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, { struct netr_DsRGetDCNameInfo *info; - info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); + info = talloc_zero(mem_ctx, struct netr_DsRGetDCNameInfo); NT_STATUS_HAVE_NO_MEMORY(info); if (dc_unc) { @@ -864,9 +861,10 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, for (i=0; i<num_dcs; i++) { + DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname)); - if (ads_cldap_netlogon(mem_ctx, dclist[i].hostname, + if (ads_cldap_netlogon(mem_ctx, &dclist[i].ss, domain_name, nt_version, &r)) @@ -938,10 +936,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, for (i=0; i<num_dcs; i++) { uint16_t val; - int dgm_id; generate_random_buffer((uint8_t *)&val, 2); - dgm_id = val; ip_list.ss = dclist[i].ss; ip_list.port = 0; @@ -967,7 +963,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, { struct NETLOGON_SAM_LOGON_RESPONSE_NT40 logon1; - r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); + r = talloc_zero(mem_ctx, struct netlogon_samlogon_response); NT_STATUS_HAVE_NO_MEMORY(r); ZERO_STRUCT(logon1); diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index bc9676bbff..35b4137ec3 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -29,600 +29,6 @@ #include <gssapi.h> #endif -/* This map was extracted by the ERRMAPEXTRACT smbtorture command. - The setup was a Samba HEAD (2002-01-03) PDC and an Win2k member - workstation. The PDC was modified (by using the 'name_to_nt_status' - authentication module) to convert the username (in hex) into the - corresponding NTSTATUS error return. - - By opening two nbt sessions to the Win2k workstation, one negotiating - DOS and one negotiating NT errors it was possible to extract the - error mapping. (Because the server only supplies NT errors, the - NT4 workstation had to use its own error tables to convert these - to dos errors). - - Some errors show up as 'squashed' because the NT error connection - got back a different error to the one it sent, so a mapping could - not be determined (a guess has been made in this case, to map the - error as squashed). This is done mainly to prevent users from getting - NT_STATUS_WRONG_PASSWORD and NT_STATUS_NO_SUCH_USER errors (they get - NT_STATUS_LOGON_FAILURE instead. - - -- abartlet (2002-01-03) -*/ - -/* NT status -> dos error map */ -static const struct { - uint8 dos_class; - uint32 dos_code; - NTSTATUS ntstatus; -} ntstatus_to_dos_map[] = { - {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, - {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, - {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, - {ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, - {ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, - {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, - {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, - {ERRDOS, 87, NT_STATUS_INVALID_CID}, - {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, - {ERRDOS, ERRinvalidparam, NT_STATUS_INVALID_PARAMETER}, - {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, - {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, - {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, - {ERRDOS, 38, NT_STATUS_END_OF_FILE}, - {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, - {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, - {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, - {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, -/** Session setup succeeded. This shouldn't happen...*/ -/** Session setup succeeded. This shouldn't happen...*/ -/** NT error on DOS connection! (NT_STATUS_OK) */ -/* { This NT error code was 'sqashed' - from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK - during the session setup } -*/ -#if 0 - {SUCCESS, 0, NT_STATUS_OK}, -#endif - {ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, - {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, - {ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, - {ERRDOS, 87, NT_STATUS_UNABLE_TO_FREE_VM}, - {ERRDOS, 87, NT_STATUS_UNABLE_TO_DELETE_SECTION}, - {ERRDOS, 2142, NT_STATUS_INVALID_SYSTEM_SERVICE}, - {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, - {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, - {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, - {ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, - {ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, -/* { This NT error code was 'sqashed' - from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, - {ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, -/* - * Not an official error, as only bit 0x80000000, not bits 0xC0000000 are set. - */ - {ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW}, - {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, - {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, - {ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, - {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, - {ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, - {ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, - {ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, - {ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, - {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, - {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, - {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, - {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, - {ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_INVALID}, - {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, - {ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, - {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, - {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, - {ERRDOS, 23, NT_STATUS_DATA_ERROR}, - {ERRDOS, 23, NT_STATUS_CRC_ERROR}, - {ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, - {ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, - {ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, - {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, - {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, - {ERRDOS, 87, NT_STATUS_INVALID_PAGE_PROTECTION}, - {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, - {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, - {ERRDOS, 87, NT_STATUS_PORT_ALREADY_SET}, - {ERRDOS, 87, NT_STATUS_SECTION_NOT_IMAGE}, - {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, - {ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, - {ERRDOS, 87, NT_STATUS_BAD_WORKING_SET_LIMIT}, - {ERRDOS, 87, NT_STATUS_INCOMPATIBLE_FILE_MAP}, - {ERRDOS, 87, NT_STATUS_SECTION_PROTECTION}, - {ERRDOS, ERReasnotsupported, NT_STATUS_EAS_NOT_SUPPORTED}, - {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, - {ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, - {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, - {ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, - {ERRDOS, ERRnoaccess, NT_STATUS_DELETE_PENDING}, - {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, - {ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, - {ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, - {ERRDOS, 2215, NT_STATUS_NO_LOGON_SERVERS}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, - {ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, - {ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, -/* { This NT error code was 'sqashed' - from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, - {ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, -/* { This NT error code was 'sqashed' - from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE - during the session setup } -*/ - {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, - {ERRSRV, ERRbaduid, NT_STATUS_USER_SESSION_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, - {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, - {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, - {ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, - {ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, - {ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, - {ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, - {ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, - {ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, - {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, - {ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, - {ERRDOS, 112, NT_STATUS_DISK_FULL}, - {ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, - {ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, - {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, - {ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, - {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, - {ERRDOS, ERRres, NT_STATUS_SECTION_NOT_EXTENDED}, - {ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, - {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, - {ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, - {ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, - {ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, -/* { This NT error code was 'sqashed' - from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES - during the session setup } -*/ - {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, - {ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, - {ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, - {ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, - {ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, - {ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, - {ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, - {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, - {ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, - {ERRDOS, 87, NT_STATUS_BAD_MASTER_BOOT_RECORD}, - {ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, - {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, - {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, - {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, - {ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, - {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, - {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, - {ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, - {ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, - {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, - {ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, - {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, - {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, - {ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, - {ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, - {ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, - {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, - {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, - {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, - {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, - {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, - {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, - {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, - {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, - {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, - {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, - {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, - {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, - {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, - {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, - {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, - {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, - {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, - {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, - {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, - {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, - {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, - {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, - {ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, - {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, - {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, - {ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, - {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, - {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, - {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, - {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_1}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_2}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_3}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_4}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_5}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_6}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_7}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_8}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_9}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_10}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_11}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_12}, - {ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, - {ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, - {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, - {ERRDOS, 203, NT_STATUS(0xc0000100)}, - {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, - {ERRDOS, ERRbaddirectory, NT_STATUS_NOT_A_DIRECTORY}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, - {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, - {ERRDOS, 2401, NT_STATUS_FILES_OPEN}, - {ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, - {ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, - {ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, - {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, - {ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_PRESENT}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_NOT_EXIST}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_ALREADY_OWNED}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_LID_OWNER}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_COMMAND}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_LID}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_SELECTOR}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, - {ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, - {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, - {ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, - {ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, - {ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, - {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, - {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, - {ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, - {ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, - {ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, - {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, - {ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, - {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, - {ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, - {ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, - {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, - {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, - {ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, - {ERRDOS, 64, NT_STATUS_LOCAL_DISCONNECT}, - {ERRDOS, 64, NT_STATUS_REMOTE_DISCONNECT}, - {ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, - {ERRDOS, 59, NT_STATUS_LINK_FAILED}, - {ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, - {ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, - {ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, - {ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, - {ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, - {ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, - {ERRDOS, ERRunknownlevel, NT_STATUS_INVALID_LEVEL}, - {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, - {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, - {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, - {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, - {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, - {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, - {ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, - {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, - {ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, - {ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, - {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, - {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, - {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, - {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, - {ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, - {ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, - {ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000016e)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000016f)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc0000170)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc0000171)}, - {ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, - {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, - {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, - {ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc0000179)}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, - {ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, - {ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, - {ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, - {ERRDOS, 87, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, - {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, - {ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, - {ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, - {ERRDOS, 19, NT_STATUS_TOO_LATE}, - {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, -/* { This NT error code was 'sqashed' - from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, - {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, - {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, - {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, - {ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, - {ERRDOS, ERRinvgroup, NT_STATUS_NETLOGON_NOT_STARTED}, - {ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, - {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, - {ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, - {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, - {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, - {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, - {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, -/* { This NT error code was 'sqashed' - from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE - during the session setup } -*/ - {ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, - {ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, - {ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, - {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, - {ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, - {ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, - {ERRDOS, 64, NT_STATUS_ADDRESS_CLOSED}, - {ERRDOS, 64, NT_STATUS_CONNECTION_DISCONNECTED}, - {ERRDOS, 64, NT_STATUS_CONNECTION_RESET}, - {ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_RELEASE}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_MATCH}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_RESPONDED}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_ID}, - {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, - {ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, - {ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, - {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, - {ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, - {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, - {ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, - {ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, - {ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, - {ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, - {ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, - {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, - {ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, - {ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, - {ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, - {ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, - {ERRHRD, ERRgeneral, NT_STATUS_RETRY}, - {ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, - {ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, - {ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, - {ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, - {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, - {ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, - {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, - {ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, - {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, - {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, - {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, - {ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, - {ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, - {ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, - {ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, - {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, - {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, - {ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024a)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024b)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024c)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024d)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024e)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000024f)}, - {ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, - {ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, - {ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, - {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, - {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, - {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, - {ERRSRV, ERRbadtype, NT_STATUS_PATH_NOT_COVERED}, - {ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, - {ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, - {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, - {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, - {ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000025d)}, - {ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, - {ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, - {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, - {ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, - {ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, - {ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, - {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LINKS}, - {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, - {ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, - {ERRDOS, 21, NT_STATUS(0xc000026e)}, - {ERRDOS, 161, NT_STATUS(0xc0000281)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028a)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028b)}, - {ERRHRD, ERRgeneral, NT_STATUS(0xc000028c)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028d)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028e)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028f)}, - {ERRDOS, ERRnoaccess, NT_STATUS(0xc0000290)}, - {ERRDOS, ERRbadfunc, NT_STATUS(0xc000029c)}, -}; - - /* dos -> nt status error map */ static const struct { uint8 dos_class; @@ -879,555 +285,6 @@ static const struct { {ERRHRD, 1022, NT_STATUS(0x0000010c)}, }; -/* errmap NTSTATUS->Win32 */ -static const struct { - NTSTATUS ntstatus; - WERROR werror; -} ntstatus_to_werror_map[] = { - {NT_STATUS(0x103), W_ERROR(0x3e5)}, - {NT_STATUS(0x105), W_ERROR(0xea)}, - {NT_STATUS(0x106), W_ERROR(0x514)}, - {NT_STATUS(0x107), W_ERROR(0x515)}, - {NT_STATUS(0x10c), W_ERROR(0x3fe)}, - {NT_STATUS(0x10d), W_ERROR(0x516)}, - {NT_STATUS(0x121), W_ERROR(0x2009)}, - {NT_STATUS(0xc0000001), W_ERROR(0x1f)}, - {NT_STATUS(0xc0000002), W_ERROR(0x1)}, - {NT_STATUS(0xc0000003), W_ERROR(0x57)}, - {NT_STATUS(0xc0000004), W_ERROR(0x18)}, - {NT_STATUS(0xc0000005), W_ERROR(0x3e6)}, - {NT_STATUS(0xc0000006), W_ERROR(0x3e7)}, - {NT_STATUS(0xc0000007), W_ERROR(0x5ae)}, - {NT_STATUS(0xc0000008), W_ERROR(0x6)}, - {NT_STATUS(0xc0000009), W_ERROR(0x3e9)}, - {NT_STATUS(0xc000000a), W_ERROR(0xc1)}, - {NT_STATUS(0xc000000b), W_ERROR(0x57)}, - {NT_STATUS(0xc000000d), W_ERROR(0x57)}, - {NT_STATUS(0xc000000e), W_ERROR(0x2)}, - {NT_STATUS(0xc000000f), W_ERROR(0x2)}, - {NT_STATUS(0xc0000010), W_ERROR(0x1)}, - {NT_STATUS(0xc0000011), W_ERROR(0x26)}, - {NT_STATUS(0xc0000012), W_ERROR(0x22)}, - {NT_STATUS(0xc0000013), W_ERROR(0x15)}, - {NT_STATUS(0xc0000014), W_ERROR(0x6f9)}, - {NT_STATUS(0xc0000015), W_ERROR(0x1b)}, - {NT_STATUS(0xc0000016), W_ERROR(0xea)}, - {NT_STATUS(0xc0000017), W_ERROR(0x8)}, - {NT_STATUS(0xc0000018), W_ERROR(0x1e7)}, - {NT_STATUS(0xc0000019), W_ERROR(0x1e7)}, - {NT_STATUS(0xc000001a), W_ERROR(0x57)}, - {NT_STATUS(0xc000001b), W_ERROR(0x57)}, - {NT_STATUS(0xc000001c), W_ERROR(0x1)}, - {NT_STATUS(0xc000001d), W_ERROR(0xc000001d)}, - {NT_STATUS(0xc000001e), W_ERROR(0x5)}, - {NT_STATUS(0xc000001f), W_ERROR(0x5)}, - {NT_STATUS(0xc0000020), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000021), W_ERROR(0x5)}, - {NT_STATUS(0xc0000022), W_ERROR(0x5)}, - {NT_STATUS(0xc0000023), W_ERROR(0x7a)}, - {NT_STATUS(0xc0000024), W_ERROR(0x6)}, - {NT_STATUS(0xc0000025), W_ERROR(0xc0000025)}, - {NT_STATUS(0xc0000026), W_ERROR(0xc0000026)}, - {NT_STATUS(0xc000002a), W_ERROR(0x9e)}, - {NT_STATUS(0xc000002b), W_ERROR(0xc000002b)}, - {NT_STATUS(0xc000002c), W_ERROR(0x1e7)}, - {NT_STATUS(0xc000002d), W_ERROR(0x1e7)}, - {NT_STATUS(0xc0000030), W_ERROR(0x57)}, - {NT_STATUS(0xc0000032), W_ERROR(0x571)}, - {NT_STATUS(0xc0000033), W_ERROR(0x7b)}, - {NT_STATUS(0xc0000034), W_ERROR(0x2)}, - {NT_STATUS(0xc0000035), W_ERROR(0xb7)}, - {NT_STATUS(0xc0000037), W_ERROR(0x6)}, - {NT_STATUS(0xc0000039), W_ERROR(0xa1)}, - {NT_STATUS(0xc000003a), W_ERROR(0x3)}, - {NT_STATUS(0xc000003b), W_ERROR(0xa1)}, - {NT_STATUS(0xc000003c), W_ERROR(0x45d)}, - {NT_STATUS(0xc000003d), W_ERROR(0x45d)}, - {NT_STATUS(0xc000003e), W_ERROR(0x17)}, - {NT_STATUS(0xc000003f), W_ERROR(0x17)}, - {NT_STATUS(0xc0000040), W_ERROR(0x8)}, - {NT_STATUS(0xc0000041), W_ERROR(0x5)}, - {NT_STATUS(0xc0000042), W_ERROR(0x6)}, - {NT_STATUS(0xc0000043), W_ERROR(0x20)}, - {NT_STATUS(0xc0000044), W_ERROR(0x718)}, - {NT_STATUS(0xc0000045), W_ERROR(0x57)}, - {NT_STATUS(0xc0000046), W_ERROR(0x120)}, - {NT_STATUS(0xc0000047), W_ERROR(0x12a)}, - {NT_STATUS(0xc0000048), W_ERROR(0x57)}, - {NT_STATUS(0xc0000049), W_ERROR(0x57)}, - {NT_STATUS(0xc000004a), W_ERROR(0x9c)}, - {NT_STATUS(0xc000004b), W_ERROR(0x5)}, - {NT_STATUS(0xc000004c), W_ERROR(0x57)}, - {NT_STATUS(0xc000004d), W_ERROR(0x57)}, - {NT_STATUS(0xc000004e), W_ERROR(0x57)}, - {NT_STATUS(0xc000004f), W_ERROR(0x11a)}, - {NT_STATUS(0xc0000050), W_ERROR(0xff)}, - {NT_STATUS(0xc0000051), W_ERROR(0x570)}, - {NT_STATUS(0xc0000052), W_ERROR(0x570)}, - {NT_STATUS(0xc0000053), W_ERROR(0x570)}, - {NT_STATUS(0xc0000054), W_ERROR(0x21)}, - {NT_STATUS(0xc0000055), W_ERROR(0x21)}, - {NT_STATUS(0xc0000056), W_ERROR(0x5)}, - {NT_STATUS(0xc0000057), W_ERROR(0x32)}, - {NT_STATUS(0xc0000058), W_ERROR(0x519)}, - {NT_STATUS(0xc0000059), W_ERROR(0x51a)}, - {NT_STATUS(0xc000005a), W_ERROR(0x51b)}, - {NT_STATUS(0xc000005b), W_ERROR(0x51c)}, - {NT_STATUS(0xc000005c), W_ERROR(0x51d)}, - {NT_STATUS(0xc000005d), W_ERROR(0x51e)}, - {NT_STATUS(0xc000005e), W_ERROR(0x51f)}, - {NT_STATUS(0xc000005f), W_ERROR(0x520)}, - {NT_STATUS(0xc0000060), W_ERROR(0x521)}, - {NT_STATUS(0xc0000061), W_ERROR(0x522)}, - {NT_STATUS(0xc0000062), W_ERROR(0x523)}, - {NT_STATUS(0xc0000063), W_ERROR(0x524)}, - {NT_STATUS(0xc0000064), W_ERROR(0x525)}, - {NT_STATUS(0xc0000065), W_ERROR(0x526)}, - {NT_STATUS(0xc0000066), W_ERROR(0x527)}, - {NT_STATUS(0xc0000067), W_ERROR(0x528)}, - {NT_STATUS(0xc0000068), W_ERROR(0x529)}, - {NT_STATUS(0xc0000069), W_ERROR(0x52a)}, - {NT_STATUS(0xc000006a), W_ERROR(0x56)}, - {NT_STATUS(0xc000006b), W_ERROR(0x52c)}, - {NT_STATUS(0xc000006c), W_ERROR(0x52d)}, - {NT_STATUS(0xc000006d), W_ERROR(0x52e)}, - {NT_STATUS(0xc000006e), W_ERROR(0x52f)}, - {NT_STATUS(0xc000006f), W_ERROR(0x530)}, - {NT_STATUS(0xc0000070), W_ERROR(0x531)}, - {NT_STATUS(0xc0000071), W_ERROR(0x532)}, - {NT_STATUS(0xc0000072), W_ERROR(0x533)}, - {NT_STATUS(0xc0000073), W_ERROR(0x534)}, - {NT_STATUS(0xc0000074), W_ERROR(0x535)}, - {NT_STATUS(0xc0000075), W_ERROR(0x536)}, - {NT_STATUS(0xc0000076), W_ERROR(0x537)}, - {NT_STATUS(0xc0000077), W_ERROR(0x538)}, - {NT_STATUS(0xc0000078), W_ERROR(0x539)}, - {NT_STATUS(0xc0000079), W_ERROR(0x53a)}, - {NT_STATUS(0xc000007a), W_ERROR(0x7f)}, - {NT_STATUS(0xc000007b), W_ERROR(0xc1)}, - {NT_STATUS(0xc000007c), W_ERROR(0x3f0)}, - {NT_STATUS(0xc000007d), W_ERROR(0x53c)}, - {NT_STATUS(0xc000007e), W_ERROR(0x9e)}, - {NT_STATUS(0xc000007f), W_ERROR(0x70)}, - {NT_STATUS(0xc0000080), W_ERROR(0x53d)}, - {NT_STATUS(0xc0000081), W_ERROR(0x53e)}, - {NT_STATUS(0xc0000082), W_ERROR(0x44)}, - {NT_STATUS(0xc0000083), W_ERROR(0x103)}, - {NT_STATUS(0xc0000084), W_ERROR(0x53f)}, - {NT_STATUS(0xc0000085), W_ERROR(0x103)}, - {NT_STATUS(0xc0000086), W_ERROR(0x9a)}, - {NT_STATUS(0xc0000087), W_ERROR(0xe)}, - {NT_STATUS(0xc0000088), W_ERROR(0x1e7)}, - {NT_STATUS(0xc0000089), W_ERROR(0x714)}, - {NT_STATUS(0xc000008a), W_ERROR(0x715)}, - {NT_STATUS(0xc000008b), W_ERROR(0x716)}, - {NT_STATUS(0xc000008c), W_ERROR(0xc000008c)}, - {NT_STATUS(0xc000008d), W_ERROR(0xc000008d)}, - {NT_STATUS(0xc000008e), W_ERROR(0xc000008e)}, - {NT_STATUS(0xc000008f), W_ERROR(0xc000008f)}, - {NT_STATUS(0xc0000090), W_ERROR(0xc0000090)}, - {NT_STATUS(0xc0000091), W_ERROR(0xc0000091)}, - {NT_STATUS(0xc0000092), W_ERROR(0xc0000092)}, - {NT_STATUS(0xc0000093), W_ERROR(0xc0000093)}, - {NT_STATUS(0xc0000094), W_ERROR(0xc0000094)}, - {NT_STATUS(0xc0000095), W_ERROR(0x216)}, - {NT_STATUS(0xc0000096), W_ERROR(0xc0000096)}, - {NT_STATUS(0xc0000097), W_ERROR(0x8)}, - {NT_STATUS(0xc0000098), W_ERROR(0x3ee)}, - {NT_STATUS(0xc0000099), W_ERROR(0x540)}, - {NT_STATUS(0xc000009a), W_ERROR(0x5aa)}, - {NT_STATUS(0xc000009b), W_ERROR(0x3)}, - {NT_STATUS(0xc000009c), W_ERROR(0x17)}, - {NT_STATUS(0xc000009d), W_ERROR(0x48f)}, - {NT_STATUS(0xc000009e), W_ERROR(0x15)}, - {NT_STATUS(0xc000009f), W_ERROR(0x1e7)}, - {NT_STATUS(0xc00000a0), W_ERROR(0x1e7)}, - {NT_STATUS(0xc00000a1), W_ERROR(0x5ad)}, - {NT_STATUS(0xc00000a2), W_ERROR(0x13)}, - {NT_STATUS(0xc00000a3), W_ERROR(0x15)}, - {NT_STATUS(0xc00000a4), W_ERROR(0x541)}, - {NT_STATUS(0xc00000a5), W_ERROR(0x542)}, - {NT_STATUS(0xc00000a6), W_ERROR(0x543)}, - {NT_STATUS(0xc00000a7), W_ERROR(0x544)}, - {NT_STATUS(0xc00000a8), W_ERROR(0x545)}, - {NT_STATUS(0xc00000a9), W_ERROR(0x57)}, - {NT_STATUS(0xc00000ab), W_ERROR(0xe7)}, - {NT_STATUS(0xc00000ac), W_ERROR(0xe7)}, - {NT_STATUS(0xc00000ad), W_ERROR(0xe6)}, - {NT_STATUS(0xc00000ae), W_ERROR(0xe7)}, - {NT_STATUS(0xc00000af), W_ERROR(0x1)}, - {NT_STATUS(0xc00000b0), W_ERROR(0xe9)}, - {NT_STATUS(0xc00000b1), W_ERROR(0xe8)}, - {NT_STATUS(0xc00000b2), W_ERROR(0x217)}, - {NT_STATUS(0xc00000b3), W_ERROR(0x218)}, - {NT_STATUS(0xc00000b4), W_ERROR(0xe6)}, - {NT_STATUS(0xc00000b5), W_ERROR(0x79)}, - {NT_STATUS(0xc00000b6), W_ERROR(0x26)}, - {NT_STATUS(0xc00000ba), W_ERROR(0x5)}, - {NT_STATUS(0xc00000bb), W_ERROR(0x32)}, - {NT_STATUS(0xc00000bc), W_ERROR(0x33)}, - {NT_STATUS(0xc00000bd), W_ERROR(0x34)}, - {NT_STATUS(0xc00000be), W_ERROR(0x35)}, - {NT_STATUS(0xc00000bf), W_ERROR(0x36)}, - {NT_STATUS(0xc00000c0), W_ERROR(0x37)}, - {NT_STATUS(0xc00000c1), W_ERROR(0x38)}, - {NT_STATUS(0xc00000c2), W_ERROR(0x39)}, - {NT_STATUS(0xc00000c3), W_ERROR(0x3a)}, - {NT_STATUS(0xc00000c4), W_ERROR(0x3b)}, - {NT_STATUS(0xc00000c5), W_ERROR(0x3c)}, - {NT_STATUS(0xc00000c6), W_ERROR(0x3d)}, - {NT_STATUS(0xc00000c7), W_ERROR(0x3e)}, - {NT_STATUS(0xc00000c8), W_ERROR(0x3f)}, - {NT_STATUS(0xc00000c9), W_ERROR(0x40)}, - {NT_STATUS(0xc00000ca), W_ERROR(0x41)}, - {NT_STATUS(0xc00000cb), W_ERROR(0x42)}, - {NT_STATUS(0xc00000cc), W_ERROR(0x43)}, - {NT_STATUS(0xc00000cd), W_ERROR(0x44)}, - {NT_STATUS(0xc00000ce), W_ERROR(0x45)}, - {NT_STATUS(0xc00000cf), W_ERROR(0x46)}, - {NT_STATUS(0xc00000d0), W_ERROR(0x47)}, - {NT_STATUS(0xc00000d1), W_ERROR(0x48)}, - {NT_STATUS(0xc00000d2), W_ERROR(0x58)}, - {NT_STATUS(0xc00000d4), W_ERROR(0x11)}, - {NT_STATUS(0xc00000d5), W_ERROR(0x5)}, - {NT_STATUS(0xc00000d6), W_ERROR(0xf0)}, - {NT_STATUS(0xc00000d7), W_ERROR(0x546)}, - {NT_STATUS(0xc00000d9), W_ERROR(0xe8)}, - {NT_STATUS(0xc00000da), W_ERROR(0x547)}, - {NT_STATUS(0xc00000dc), W_ERROR(0x548)}, - {NT_STATUS(0xc00000dd), W_ERROR(0x549)}, - {NT_STATUS(0xc00000de), W_ERROR(0x54a)}, - {NT_STATUS(0xc00000df), W_ERROR(0x54b)}, - {NT_STATUS(0xc00000e0), W_ERROR(0x54c)}, - {NT_STATUS(0xc00000e1), W_ERROR(0x54d)}, - {NT_STATUS(0xc00000e2), W_ERROR(0x12c)}, - {NT_STATUS(0xc00000e3), W_ERROR(0x12d)}, - {NT_STATUS(0xc00000e4), W_ERROR(0x54e)}, - {NT_STATUS(0xc00000e5), W_ERROR(0x54f)}, - {NT_STATUS(0xc00000e6), W_ERROR(0x550)}, - {NT_STATUS(0xc00000e7), W_ERROR(0x551)}, - {NT_STATUS(0xc00000e8), W_ERROR(0x6f8)}, - {NT_STATUS(0xc00000ed), W_ERROR(0x552)}, - {NT_STATUS(0xc00000ee), W_ERROR(0x553)}, - {NT_STATUS(0xc00000ef), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f0), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f1), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f2), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f3), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f4), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f5), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f6), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f7), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f8), W_ERROR(0x57)}, - {NT_STATUS(0xc00000f9), W_ERROR(0x57)}, - {NT_STATUS(0xc00000fa), W_ERROR(0x57)}, - {NT_STATUS(0xc00000fb), W_ERROR(0x3)}, - {NT_STATUS(0xc00000fd), W_ERROR(0x3e9)}, - {NT_STATUS(0xc00000fe), W_ERROR(0x554)}, - {NT_STATUS(0xc0000100), W_ERROR(0xcb)}, - {NT_STATUS(0xc0000101), W_ERROR(0x91)}, - {NT_STATUS(0xc0000102), W_ERROR(0x570)}, - {NT_STATUS(0xc0000103), W_ERROR(0x10b)}, - {NT_STATUS(0xc0000104), W_ERROR(0x555)}, - {NT_STATUS(0xc0000105), W_ERROR(0x556)}, - {NT_STATUS(0xc0000106), W_ERROR(0xce)}, - {NT_STATUS(0xc0000107), W_ERROR(0x961)}, - {NT_STATUS(0xc0000108), W_ERROR(0x964)}, - {NT_STATUS(0xc000010a), W_ERROR(0x5)}, - {NT_STATUS(0xc000010b), W_ERROR(0x557)}, - {NT_STATUS(0xc000010d), W_ERROR(0x558)}, - {NT_STATUS(0xc000010e), W_ERROR(0x420)}, - {NT_STATUS(0xc0000117), W_ERROR(0x5a4)}, - {NT_STATUS(0xc000011b), W_ERROR(0xc1)}, - {NT_STATUS(0xc000011c), W_ERROR(0x559)}, - {NT_STATUS(0xc000011d), W_ERROR(0x55a)}, - {NT_STATUS(0xc000011e), W_ERROR(0x3ee)}, - {NT_STATUS(0xc000011f), W_ERROR(0x4)}, - {NT_STATUS(0xc0000120), W_ERROR(0x3e3)}, - {NT_STATUS(0xc0000121), W_ERROR(0x5)}, - {NT_STATUS(0xc0000122), W_ERROR(0x4ba)}, - {NT_STATUS(0xc0000123), W_ERROR(0x5)}, - {NT_STATUS(0xc0000124), W_ERROR(0x55b)}, - {NT_STATUS(0xc0000125), W_ERROR(0x55c)}, - {NT_STATUS(0xc0000126), W_ERROR(0x55d)}, - {NT_STATUS(0xc0000127), W_ERROR(0x55e)}, - {NT_STATUS(0xc0000128), W_ERROR(0x6)}, - {NT_STATUS(0xc000012b), W_ERROR(0x55f)}, - {NT_STATUS(0xc000012d), W_ERROR(0x5af)}, - {NT_STATUS(0xc000012e), W_ERROR(0xc1)}, - {NT_STATUS(0xc000012f), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000130), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000131), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000133), W_ERROR(0x576)}, - {NT_STATUS(0xc0000135), W_ERROR(0x7e)}, - {NT_STATUS(0xc0000138), W_ERROR(0xb6)}, - {NT_STATUS(0xc0000139), W_ERROR(0x7f)}, - {NT_STATUS(0xc000013b), W_ERROR(0x40)}, - {NT_STATUS(0xc000013c), W_ERROR(0x40)}, - {NT_STATUS(0xc000013d), W_ERROR(0x33)}, - {NT_STATUS(0xc000013e), W_ERROR(0x3b)}, - {NT_STATUS(0xc000013f), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000140), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000141), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000142), W_ERROR(0x45a)}, - {NT_STATUS(0xc0000148), W_ERROR(0x7c)}, - {NT_STATUS(0xc0000149), W_ERROR(0x56)}, - {NT_STATUS(0xc000014b), W_ERROR(0x6d)}, - {NT_STATUS(0xc000014c), W_ERROR(0x3f1)}, - {NT_STATUS(0xc000014d), W_ERROR(0x3f8)}, - {NT_STATUS(0xc000014f), W_ERROR(0x3ed)}, - {NT_STATUS(0xc0000150), W_ERROR(0x45e)}, - {NT_STATUS(0xc0000151), W_ERROR(0x560)}, - {NT_STATUS(0xc0000152), W_ERROR(0x561)}, - {NT_STATUS(0xc0000153), W_ERROR(0x562)}, - {NT_STATUS(0xc0000154), W_ERROR(0x563)}, - {NT_STATUS(0xc0000155), W_ERROR(0x564)}, - {NT_STATUS(0xc0000156), W_ERROR(0x565)}, - {NT_STATUS(0xc0000157), W_ERROR(0x566)}, - {NT_STATUS(0xc0000158), W_ERROR(0x567)}, - {NT_STATUS(0xc0000159), W_ERROR(0x3ef)}, - {NT_STATUS(0xc000015a), W_ERROR(0x568)}, - {NT_STATUS(0xc000015b), W_ERROR(0x569)}, - {NT_STATUS(0xc000015c), W_ERROR(0x3f9)}, - {NT_STATUS(0xc000015d), W_ERROR(0x56a)}, - {NT_STATUS(0xc000015f), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000162), W_ERROR(0x459)}, - {NT_STATUS(0xc0000165), W_ERROR(0x462)}, - {NT_STATUS(0xc0000166), W_ERROR(0x463)}, - {NT_STATUS(0xc0000167), W_ERROR(0x464)}, - {NT_STATUS(0xc0000168), W_ERROR(0x465)}, - {NT_STATUS(0xc0000169), W_ERROR(0x466)}, - {NT_STATUS(0xc000016a), W_ERROR(0x467)}, - {NT_STATUS(0xc000016b), W_ERROR(0x468)}, - {NT_STATUS(0xc000016c), W_ERROR(0x45f)}, - {NT_STATUS(0xc000016d), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000172), W_ERROR(0x451)}, - {NT_STATUS(0xc0000173), W_ERROR(0x452)}, - {NT_STATUS(0xc0000174), W_ERROR(0x453)}, - {NT_STATUS(0xc0000175), W_ERROR(0x454)}, - {NT_STATUS(0xc0000176), W_ERROR(0x455)}, - {NT_STATUS(0xc0000177), W_ERROR(0x469)}, - {NT_STATUS(0xc0000178), W_ERROR(0x458)}, - {NT_STATUS(0xc000017a), W_ERROR(0x56b)}, - {NT_STATUS(0xc000017b), W_ERROR(0x56c)}, - {NT_STATUS(0xc000017c), W_ERROR(0x3fa)}, - {NT_STATUS(0xc000017d), W_ERROR(0x3fb)}, - {NT_STATUS(0xc000017e), W_ERROR(0x56d)}, - {NT_STATUS(0xc000017f), W_ERROR(0x56e)}, - {NT_STATUS(0xc0000180), W_ERROR(0x3fc)}, - {NT_STATUS(0xc0000181), W_ERROR(0x3fd)}, - {NT_STATUS(0xc0000182), W_ERROR(0x57)}, - {NT_STATUS(0xc0000183), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000184), W_ERROR(0x16)}, - {NT_STATUS(0xc0000185), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000186), W_ERROR(0x45d)}, - {NT_STATUS(0xc0000188), W_ERROR(0x5de)}, - {NT_STATUS(0xc0000189), W_ERROR(0x13)}, - {NT_STATUS(0xc000018a), W_ERROR(0x6fa)}, - {NT_STATUS(0xc000018b), W_ERROR(0x6fb)}, - {NT_STATUS(0xc000018c), W_ERROR(0x6fc)}, - {NT_STATUS(0xc000018d), W_ERROR(0x6fd)}, - {NT_STATUS(0xc000018e), W_ERROR(0x5dc)}, - {NT_STATUS(0xc000018f), W_ERROR(0x5dd)}, - {NT_STATUS(0xc0000190), W_ERROR(0x6fe)}, - {NT_STATUS(0xc0000192), W_ERROR(0x700)}, - {NT_STATUS(0xc0000193), W_ERROR(0x701)}, - {NT_STATUS(0xc0000194), W_ERROR(0x46b)}, - {NT_STATUS(0xc0000195), W_ERROR(0x4c3)}, - {NT_STATUS(0xc0000196), W_ERROR(0x4c4)}, - {NT_STATUS(0xc0000197), W_ERROR(0x5df)}, - {NT_STATUS(0xc0000198), W_ERROR(0x70f)}, - {NT_STATUS(0xc0000199), W_ERROR(0x710)}, - {NT_STATUS(0xc000019a), W_ERROR(0x711)}, - {NT_STATUS(0xc000019b), W_ERROR(0x712)}, - {NT_STATUS(0xc0000202), W_ERROR(0x572)}, - {NT_STATUS(0xc0000203), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000204), W_ERROR(0x717)}, - {NT_STATUS(0xc0000205), W_ERROR(0x46a)}, - {NT_STATUS(0xc0000206), W_ERROR(0x6f8)}, - {NT_STATUS(0xc0000207), W_ERROR(0x4be)}, - {NT_STATUS(0xc0000208), W_ERROR(0x4be)}, - {NT_STATUS(0xc0000209), W_ERROR(0x44)}, - {NT_STATUS(0xc000020a), W_ERROR(0x34)}, - {NT_STATUS(0xc000020b), W_ERROR(0x40)}, - {NT_STATUS(0xc000020c), W_ERROR(0x40)}, - {NT_STATUS(0xc000020d), W_ERROR(0x40)}, - {NT_STATUS(0xc000020e), W_ERROR(0x44)}, - {NT_STATUS(0xc000020f), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000210), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000211), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000212), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000213), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000214), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000215), W_ERROR(0x3b)}, - {NT_STATUS(0xc0000216), W_ERROR(0x32)}, - {NT_STATUS(0xc0000217), W_ERROR(0x32)}, - {NT_STATUS(0xc000021c), W_ERROR(0x17e6)}, - {NT_STATUS(0xc0000220), W_ERROR(0x46c)}, - {NT_STATUS(0xc0000221), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000224), W_ERROR(0x773)}, - {NT_STATUS(0xc0000225), W_ERROR(0x490)}, - {NT_STATUS(0xc000022a), W_ERROR(0xc000022a)}, - {NT_STATUS(0xc000022b), W_ERROR(0xc000022b)}, - {NT_STATUS(0xc000022d), W_ERROR(0x4d5)}, - {NT_STATUS(0xc0000230), W_ERROR(0x492)}, - {NT_STATUS(0xc0000233), W_ERROR(0x774)}, - {NT_STATUS(0xc0000234), W_ERROR(0x775)}, - {NT_STATUS(0xc0000235), W_ERROR(0x6)}, - {NT_STATUS(0xc0000236), W_ERROR(0x4c9)}, - {NT_STATUS(0xc0000237), W_ERROR(0x4ca)}, - {NT_STATUS(0xc0000238), W_ERROR(0x4cb)}, - {NT_STATUS(0xc0000239), W_ERROR(0x4cc)}, - {NT_STATUS(0xc000023a), W_ERROR(0x4cd)}, - {NT_STATUS(0xc000023b), W_ERROR(0x4ce)}, - {NT_STATUS(0xc000023c), W_ERROR(0x4cf)}, - {NT_STATUS(0xc000023d), W_ERROR(0x4d0)}, - {NT_STATUS(0xc000023e), W_ERROR(0x4d1)}, - {NT_STATUS(0xc000023f), W_ERROR(0x4d2)}, - {NT_STATUS(0xc0000240), W_ERROR(0x4d3)}, - {NT_STATUS(0xc0000241), W_ERROR(0x4d4)}, - {NT_STATUS(0xc0000243), W_ERROR(0x4c8)}, - {NT_STATUS(0xc0000246), W_ERROR(0x4d6)}, - {NT_STATUS(0xc0000247), W_ERROR(0x4d7)}, - {NT_STATUS(0xc0000248), W_ERROR(0x4d8)}, - {NT_STATUS(0xc0000249), W_ERROR(0xc1)}, - {NT_STATUS(0xc0000253), W_ERROR(0x54f)}, - {NT_STATUS(0xc0000257), W_ERROR(0x4d0)}, - {NT_STATUS(0xc0000259), W_ERROR(0x573)}, - {NT_STATUS(0xc000025e), W_ERROR(0x422)}, - {NT_STATUS(0xc0000262), W_ERROR(0xb6)}, - {NT_STATUS(0xc0000263), W_ERROR(0x7f)}, - {NT_STATUS(0xc0000264), W_ERROR(0x120)}, - {NT_STATUS(0xc0000265), W_ERROR(0x476)}, - {NT_STATUS(0xc0000267), W_ERROR(0x10fe)}, - {NT_STATUS(0xc000026c), W_ERROR(0x7d1)}, - {NT_STATUS(0xc000026d), W_ERROR(0x4b1)}, - {NT_STATUS(0xc000026e), W_ERROR(0x15)}, - {NT_STATUS(0xc0000272), W_ERROR(0x491)}, - {NT_STATUS(0xc0000275), W_ERROR(0x1126)}, - {NT_STATUS(0xc0000276), W_ERROR(0x1129)}, - {NT_STATUS(0xc0000277), W_ERROR(0x112a)}, - {NT_STATUS(0xc0000278), W_ERROR(0x1128)}, - {NT_STATUS(0xc0000279), W_ERROR(0x780)}, - {NT_STATUS(0xc0000280), W_ERROR(0x781)}, - {NT_STATUS(0xc0000281), W_ERROR(0xa1)}, - {NT_STATUS(0xc0000283), W_ERROR(0x488)}, - {NT_STATUS(0xc0000284), W_ERROR(0x489)}, - {NT_STATUS(0xc0000285), W_ERROR(0x48a)}, - {NT_STATUS(0xc0000286), W_ERROR(0x48b)}, - {NT_STATUS(0xc0000287), W_ERROR(0x48c)}, - {NT_STATUS(0xc000028a), W_ERROR(0x5)}, - {NT_STATUS(0xc000028b), W_ERROR(0x5)}, - {NT_STATUS(0xc000028d), W_ERROR(0x5)}, - {NT_STATUS(0xc000028e), W_ERROR(0x5)}, - {NT_STATUS(0xc000028f), W_ERROR(0x5)}, - {NT_STATUS(0xc0000290), W_ERROR(0x5)}, - {NT_STATUS(0xc0000291), W_ERROR(0x1777)}, - {NT_STATUS(0xc0000292), W_ERROR(0x1778)}, - {NT_STATUS(0xc0000293), W_ERROR(0x1772)}, - {NT_STATUS(0xc0000295), W_ERROR(0x1068)}, - {NT_STATUS(0xc0000296), W_ERROR(0x1069)}, - {NT_STATUS(0xc0000297), W_ERROR(0x106a)}, - {NT_STATUS(0xc0000298), W_ERROR(0x106b)}, - {NT_STATUS(0xc0000299), W_ERROR(0x201a)}, - {NT_STATUS(0xc000029a), W_ERROR(0x201b)}, - {NT_STATUS(0xc000029b), W_ERROR(0x201c)}, - {NT_STATUS(0xc000029c), W_ERROR(0x1)}, - {NT_STATUS(0xc000029d), W_ERROR(0x10ff)}, - {NT_STATUS(0xc000029e), W_ERROR(0x1100)}, - {NT_STATUS(0xc000029f), W_ERROR(0x494)}, - {NT_STATUS(0xc00002a1), W_ERROR(0x200a)}, - {NT_STATUS(0xc00002a2), W_ERROR(0x200b)}, - {NT_STATUS(0xc00002a3), W_ERROR(0x200c)}, - {NT_STATUS(0xc00002a4), W_ERROR(0x200d)}, - {NT_STATUS(0xc00002a5), W_ERROR(0x200e)}, - {NT_STATUS(0xc00002a6), W_ERROR(0x200f)}, - {NT_STATUS(0xc00002a7), W_ERROR(0x2010)}, - {NT_STATUS(0xc00002a8), W_ERROR(0x2011)}, - {NT_STATUS(0xc00002a9), W_ERROR(0x2012)}, - {NT_STATUS(0xc00002aa), W_ERROR(0x2013)}, - {NT_STATUS(0xc00002ab), W_ERROR(0x2014)}, - {NT_STATUS(0xc00002ac), W_ERROR(0x2015)}, - {NT_STATUS(0xc00002ad), W_ERROR(0x2016)}, - {NT_STATUS(0xc00002ae), W_ERROR(0x2017)}, - {NT_STATUS(0xc00002af), W_ERROR(0x2018)}, - {NT_STATUS(0xc00002b0), W_ERROR(0x2019)}, - {NT_STATUS(0xc00002b1), W_ERROR(0x211e)}, - {NT_STATUS(0xc00002b2), W_ERROR(0x1127)}, - {NT_STATUS(0xc00002b6), W_ERROR(0x651)}, - {NT_STATUS(0xc00002b7), W_ERROR(0x49a)}, - {NT_STATUS(0xc00002b8), W_ERROR(0x49b)}, - {NT_STATUS(0xc00002c1), W_ERROR(0x2024)}, - {NT_STATUS(0xc00002c3), W_ERROR(0x575)}, - {NT_STATUS(0xc00002c5), W_ERROR(0x3e6)}, - {NT_STATUS(0xc00002c6), W_ERROR(0x1075)}, - {NT_STATUS(0xc00002c7), W_ERROR(0x1076)}, - {NT_STATUS(0xc00002ca), W_ERROR(0x10e8)}, - {NT_STATUS(0xc00002cb), W_ERROR(0x2138)}, - {NT_STATUS(0xc00002cc), W_ERROR(0x4e3)}, - {NT_STATUS(0xc00002cd), W_ERROR(0x2139)}, - {NT_STATUS(0xc00002cf), W_ERROR(0x49d)}, - {NT_STATUS(0xc00002d0), W_ERROR(0x213a)}, - {NT_STATUS(0xc00002d4), W_ERROR(0x2141)}, - {NT_STATUS(0xc00002d5), W_ERROR(0x2142)}, - {NT_STATUS(0xc00002d6), W_ERROR(0x2143)}, - {NT_STATUS(0xc00002d7), W_ERROR(0x2144)}, - {NT_STATUS(0xc00002d8), W_ERROR(0x2145)}, - {NT_STATUS(0xc00002d9), W_ERROR(0x2146)}, - {NT_STATUS(0xc00002da), W_ERROR(0x2147)}, - {NT_STATUS(0xc00002db), W_ERROR(0x2148)}, - {NT_STATUS(0xc00002dc), W_ERROR(0x2149)}, - {NT_STATUS(0xc00002dd), W_ERROR(0x32)}, - {NT_STATUS(0xc00002df), W_ERROR(0x2151)}, - {NT_STATUS(0xc00002e0), W_ERROR(0x2152)}, - {NT_STATUS(0xc00002e1), W_ERROR(0x2153)}, - {NT_STATUS(0xc00002e2), W_ERROR(0x2154)}, - {NT_STATUS(0xc00002e3), W_ERROR(0x215d)}, - {NT_STATUS(0xc00002e4), W_ERROR(0x2163)}, - {NT_STATUS(0xc00002e5), W_ERROR(0x2164)}, - {NT_STATUS(0xc00002e6), W_ERROR(0x2165)}, - {NT_STATUS(0xc00002e7), W_ERROR(0x216d)}, - {NT_STATUS(0xc00002fe), W_ERROR(0x45b)}, - {NT_STATUS(0xc00002ff), W_ERROR(0x4e7)}, - {NT_STATUS(0xc0000300), W_ERROR(0x4e6)}, - {NT_STATUS(0x80000001), W_ERROR(0x80000001)}, - {NT_STATUS(0x80000002), W_ERROR(0x3e6)}, - {NT_STATUS(0x80000003), W_ERROR(0x80000003)}, - {NT_STATUS(0x80000004), W_ERROR(0x80000004)}, - {NT_STATUS(0x80000005), W_ERROR(0xea)}, - {NT_STATUS(0x80000006), W_ERROR(0x12)}, - {NT_STATUS(0x8000000b), W_ERROR(0x56f)}, - {NT_STATUS(0x8000000d), W_ERROR(0x12b)}, - {NT_STATUS(0x8000000e), W_ERROR(0x1c)}, - {NT_STATUS(0x8000000f), W_ERROR(0x15)}, - {NT_STATUS(0x80000010), W_ERROR(0x15)}, - {NT_STATUS(0x80000011), W_ERROR(0xaa)}, - {NT_STATUS(0x80000012), W_ERROR(0x103)}, - {NT_STATUS(0x80000013), W_ERROR(0xfe)}, - {NT_STATUS(0x80000014), W_ERROR(0xff)}, - {NT_STATUS(0x80000015), W_ERROR(0xff)}, - {NT_STATUS(0x80000016), W_ERROR(0x456)}, - {NT_STATUS(0x8000001a), W_ERROR(0x103)}, - {NT_STATUS(0x8000001b), W_ERROR(0x44d)}, - {NT_STATUS(0x8000001c), W_ERROR(0x456)}, - {NT_STATUS(0x8000001d), W_ERROR(0x457)}, - {NT_STATUS(0x8000001e), W_ERROR(0x44c)}, - {NT_STATUS(0x8000001f), W_ERROR(0x44e)}, - {NT_STATUS(0x80000021), W_ERROR(0x44f)}, - {NT_STATUS(0x80000022), W_ERROR(0x450)}, - {NT_STATUS(0x80000025), W_ERROR(0x962)}, - {NT_STATUS(0x80000288), W_ERROR(0x48d)}, - {NT_STATUS(0x80000289), W_ERROR(0x48e)}, - {NT_STATUS_OK, WERR_OK}}; - -static const struct { - WERROR werror; - NTSTATUS ntstatus; -} werror_to_ntstatus_map[] = { - { W_ERROR(0x5), NT_STATUS_ACCESS_DENIED }, - { WERR_OK, NT_STATUS_OK } -}; - /***************************************************************************** convert a dos eclas/ecode to a NT status32 code *****************************************************************************/ @@ -1444,76 +301,6 @@ NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode) return NT_STATUS_UNSUCCESSFUL; } - -/***************************************************************************** -convert a NT status code to a dos class/code - *****************************************************************************/ -void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) -{ - int i; - if (NT_STATUS_IS_OK(ntstatus)) { - *eclass = 0; - *ecode = 0; - return; - } - for (i=0; NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus); i++) { - if (NT_STATUS_V(ntstatus) == - NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus)) { - *eclass = ntstatus_to_dos_map[i].dos_class; - *ecode = ntstatus_to_dos_map[i].dos_code; - return; - } - } - *eclass = ERRHRD; - *ecode = ERRgeneral; -} - - -/***************************************************************************** -convert a WERROR to a NT status32 code - *****************************************************************************/ -NTSTATUS werror_to_ntstatus(WERROR error) -{ - int i; - if (W_ERROR_IS_OK(error)) return NT_STATUS_OK; - - for (i=0; !W_ERROR_IS_OK(werror_to_ntstatus_map[i].werror); i++) { - if (W_ERROR_V(error) == - W_ERROR_V(werror_to_ntstatus_map[i].werror)) { - return werror_to_ntstatus_map[i].ntstatus; - } - } - - for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { - if (W_ERROR_V(error) == - W_ERROR_V(ntstatus_to_werror_map[i].werror)) { - return ntstatus_to_werror_map[i].ntstatus; - } - } - - /* just guess ... */ - return NT_STATUS(W_ERROR_V(error) | 0xc0000000); -} - -/***************************************************************************** -convert a NTSTATUS to a WERROR - *****************************************************************************/ -WERROR ntstatus_to_werror(NTSTATUS error) -{ - int i; - if (NT_STATUS_IS_OK(error)) return WERR_OK; - for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { - if (NT_STATUS_V(error) == - NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus)) { - return ntstatus_to_werror_map[i].werror; - } - } - - /* a lame guess */ - return W_ERROR(NT_STATUS_V(error) & 0xffff); -} - - #if defined(HAVE_GSSAPI) /******************************************************************************* Map between gssapi errors and NT status. I made these up :-(. JRA. diff --git a/source3/libsmb/errormap_wbc.h b/source3/libsmb/errormap_wbc.h index 2042da4efc..6323deec1d 100644 --- a/source3/libsmb/errormap_wbc.h +++ b/source3/libsmb/errormap_wbc.h @@ -1,3 +1,29 @@ +/* + * Unix SMB/CIFS implementation. + * error mapping functions + * Copyright (C) Andrew Tridgell 2001 + * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Tim Potter 2000 + * + * 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/>. + */ + +#ifndef _LIBSMB_ERRORMAP_WBC_H_ +#define _LIBSMB_ERRORMAP_WBC_H_ + /* The following definitions come from libsmb/errormap_wbc.c */ NTSTATUS map_nt_error_from_wbcErr(wbcErr wbc_err); + +#endif /* _LIBSMB_ERRORMAP_WBC_H_ */ diff --git a/source3/libsmb/libsmb.h b/source3/libsmb/libsmb.h new file mode 100644 index 0000000000..061f317e1e --- /dev/null +++ b/source3/libsmb/libsmb.h @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 1992-1998,2001 + Copyright (C) Jeremy Allison 1998 + Copyright (C) Remus Koos 2001 + Copyright (C) Andrew Bartlett 2001 + + 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/>. +*/ + +#ifndef _LIBSMB_LIBSMB_H +#define _LIBSMB_LIBSMB_H + +#include "client.h" +#include "libads/ads_status.h" +#include "libsmb/proto.h" + +#endif /* _LIBSMB_LIBSMB_H */ diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index f9770d363c..598fa81376 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 9c8429aab4..dbf70e02c8 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" #include "secrets.h" @@ -456,11 +457,11 @@ smbc_option_get(SMBCCTX *context, switch(smbc_getOptionSmbEncryptionLevel(context)) { case 0: - return (void *) "none"; + return discard_const_p(void, "none"); case 1: - return (void *) "request"; + return discard_const_p(void, "request"); case 2: - return (void *) "require"; + return discard_const_p(void, "require"); } } else if (strcmp(option_name, "smb_encrypt_on") == 0) { @@ -598,8 +599,8 @@ smbc_init_context(SMBCCTX *context) * our hostname etc */ char *netbios_name; - if (global_myname()) { - netbios_name = SMB_STRDUP(global_myname()); + if (lp_netbios_name()) { + netbios_name = SMB_STRDUP(lp_netbios_name()); } else { /* * Hmmm, I want to get hostname as well, but I am too @@ -749,6 +750,7 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, } set_cmdline_auth_info_username(auth_info, user); + set_cmdline_auth_info_domain(auth_info, workgroup); set_cmdline_auth_info_password(auth_info, password); set_cmdline_auth_info_use_kerberos(auth_info, use_kerberos); set_cmdline_auth_info_signing_state(auth_info, signing_state); @@ -756,7 +758,6 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, smbc_getOptionFallbackAfterKerberos(context)); set_cmdline_auth_info_use_ccache( auth_info, smbc_getOptionUseCCache(context)); - set_global_myworkgroup(workgroup); TALLOC_FREE(context->internal->auth_info); diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index c0c6e83bb6..ea75dbf264 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "popt_common.h" #include "libsmbclient.h" #include "libsmb_internal.h" @@ -245,7 +246,7 @@ dir_list_fn(const char *mnt, { if (add_dirent((SMBCFILE *)state, finfo->name, "", - (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { + (finfo->mode&FILE_ATTRIBUTE_DIRECTORY?SMBC_DIR:SMBC_FILE)) < 0) { SMBCFILE *dir = (SMBCFILE *)state; return map_nt_error_from_unix(dir->dir_error); } @@ -456,9 +457,10 @@ SMBC_opendir_ctx(SMBCCTX *context, int i; int count; int max_lmb_count; - struct ip_service *ip_list; - struct ip_service server_addr; + struct sockaddr_storage *ip_list; + struct sockaddr_storage server_addr; struct user_auth_info u_info; + NTSTATUS status; if (share[0] != (char)0 || path[0] != (char)0) { @@ -498,13 +500,14 @@ SMBC_opendir_ctx(SMBCCTX *context, */ ip_list = NULL; - if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, - &count))) + status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(), + &ip_list, &count); + if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(ip_list); + TALLOC_FREE(ip_list); - if (!find_master_ip(workgroup, &server_addr.ss)) { + if (!find_master_ip(workgroup, &server_addr)) { if (dir) { SAFE_FREE(dir->fname); @@ -515,8 +518,9 @@ SMBC_opendir_ctx(SMBCCTX *context, return NULL; } - ip_list = (struct ip_service *)memdup( - &server_addr, sizeof(server_addr)); + ip_list = (struct sockaddr_storage *)talloc_memdup( + talloc_tos(), &server_addr, + sizeof(server_addr)); if (ip_list == NULL) { if (dir) { SAFE_FREE(dir->fname); @@ -534,7 +538,7 @@ SMBC_opendir_ctx(SMBCCTX *context, char *wg_ptr = NULL; struct cli_state *cli = NULL; - print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); + print_sockaddr(addr, sizeof(addr), &ip_list[i]); DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), addr)); @@ -594,7 +598,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } } - SAFE_FREE(ip_list); + TALLOC_FREE(ip_list); } else { /* * Server not an empty string ... Check the rest and see what @@ -816,7 +820,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } status = cli_list(targetcli, targetpath, - aDIR | aSYSTEM | aHIDDEN, + FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, dir_list_fn, (void *)dir); if (!NT_STATUS_IS_OK(status)) { if (dir) { @@ -1345,7 +1349,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, } status = cli_list(targetcli, lpath, - aDIR | aSYSTEM | aHIDDEN, + FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, rmdir_list_fn, &smbc_rmdir_dirempty); @@ -1611,10 +1615,10 @@ SMBC_chmod_ctx(SMBCCTX *context, mode = 0; - if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; - if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; - if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; - if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; + if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= FILE_ATTRIBUTE_READONLY; + if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= FILE_ATTRIBUTE_ARCHIVE; + if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= FILE_ATTRIBUTE_SYSTEM; + if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= FILE_ATTRIBUTE_HIDDEN; if (!NT_STATUS_IS_OK(cli_setatr(targetcli, targetpath, mode, 0))) { errno = SMBC_errno(context, targetcli); @@ -1803,7 +1807,7 @@ SMBC_unlink_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ - if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetpath, aSYSTEM | aHIDDEN))) { + if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetpath, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) { errno = SMBC_errno(context, targetcli); @@ -2009,7 +2013,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, int eno = SMBC_errno(ocontext, targetcli1); if (eno != EEXIST || - !NT_STATUS_IS_OK(cli_unlink(targetcli1, targetpath2, aSYSTEM | aHIDDEN)) || + !NT_STATUS_IS_OK(cli_unlink(targetcli1, targetpath2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) || !NT_STATUS_IS_OK(cli_rename(targetcli1, targetpath1, targetpath2))) { errno = eno; diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 58403dfbb3..c822eab798 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" @@ -318,13 +319,13 @@ SMBC_write_ctx(SMBCCTX *context, const void *buf, size_t count) { - int ret; off_t offset; char *server = NULL, *share = NULL, *user = NULL, *password = NULL; char *path = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; /* First check all pointers before dereferencing them */ @@ -377,18 +378,18 @@ SMBC_write_ctx(SMBCCTX *context, } /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - ret = cli_write(targetcli, file->cli_fd, - 0, (char *)buf, offset, count); - if (ret <= 0) { - errno = SMBC_errno(context, targetcli); + status = cli_writeall(targetcli, file->cli_fd, + 0, (const uint8_t *)buf, offset, count, NULL); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); TALLOC_FREE(frame); return -1; } - file->offset += ret; + file->offset += count; TALLOC_FREE(frame); - return ret; /* Success, 0 bytes of data ... */ + return count; /* Success, 0 bytes of data ... */ } /* @@ -480,7 +481,7 @@ SMBC_close_ctx(SMBCCTX *context, bool SMBC_getatr(SMBCCTX * context, SMBCSRV *srv, - char *path, + const char *path, uint16 *mode, SMB_OFF_T *size, struct timespec *create_time_ts, diff --git a/source3/libsmb/libsmb_misc.c b/source3/libsmb/libsmb_misc.c index a6e96350f5..7808d8e4f0 100644 --- a/source3/libsmb/libsmb_misc.c +++ b/source3/libsmb/libsmb_misc.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 64a956d9ee..1dcf2dd516 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -88,7 +88,7 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) newlen++; } - dest = TALLOC_ARRAY(ctx, char, newlen); + dest = talloc_array(ctx, char, newlen); if (!dest) { return err_count; } diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c index ea0cb37a14..db46ceee9c 100644 --- a/source3/libsmb/libsmb_printjob.c +++ b/source3/libsmb/libsmb_printjob.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 961c9cde83..755ef2d32b 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" #include "../librpc/gen_ndr/ndr_lsa.h" @@ -245,20 +246,14 @@ SMBC_server_internal(TALLOC_CTX *ctx, { SMBCSRV *srv=NULL; char *workgroup = NULL; - struct cli_state *c; - struct nmb_name called, calling; + struct cli_state *c = NULL; const char *server_n = server; - struct sockaddr_storage ss; - int tried_reverse = 0; - int port_try_first; - int port_try_next; int is_ipc = (share != NULL && strcmp(share, "IPC$") == 0); uint32 fs_attrs = 0; const char *username_used; NTSTATUS status; char *newserver, *newshare; - zero_sockaddr(&ss); ZERO_STRUCT(c); *in_cache = false; @@ -392,20 +387,32 @@ SMBC_server_internal(TALLOC_CTX *ctx, return NULL; } - make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0); - make_nmb_name(&called , server, 0x20); - DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); -again: + status = NT_STATUS_UNSUCCESSFUL; - zero_sockaddr(&ss); + if (share == NULL || *share == '\0' || is_ipc) { + /* + * Try 139 first for IPC$ + */ + status = cli_connect_nb(server_n, NULL, 139, 0x20, + smbc_getNetbiosName(context), + Undefined, &c); + } - /* have to open a new connection */ - if ((c = cli_initialise()) == NULL) { - errno = ENOMEM; + if (!NT_STATUS_IS_OK(status)) { + /* + * No IPC$ or 139 did not work + */ + status = cli_connect_nb(server_n, NULL, 0, 0x20, + smbc_getNetbiosName(context), + Undefined, &c); + } + + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); return NULL; } @@ -423,73 +430,6 @@ again: c->timeout = smbc_getTimeout(context); - /* - * Force use of port 139 for first try if share is $IPC, empty, or - * null, so browse lists can work - */ - if (share == NULL || *share == '\0' || is_ipc) { - port_try_first = 139; - port_try_next = 445; - } else { - port_try_first = 445; - port_try_next = 139; - } - - c->port = port_try_first; - - status = cli_connect(c, server_n, &ss); - if (!NT_STATUS_IS_OK(status)) { - - /* First connection attempt failed. Try alternate port. */ - c->port = port_try_next; - - status = cli_connect(c, server_n, &ss); - if (!NT_STATUS_IS_OK(status)) { - cli_shutdown(c); - errno = ETIMEDOUT; - return NULL; - } - } - - if (!cli_session_request(c, &calling, &called)) { - cli_shutdown(c); - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } else { /* Try one more time, but ensure we don't loop */ - - /* Only try this if server is an IP address ... */ - - if (is_ipaddress(server) && !tried_reverse) { - fstring remote_name; - struct sockaddr_storage rem_ss; - - if (!interpret_string_addr(&rem_ss, server, - NI_NUMERICHOST)) { - DEBUG(4, ("Could not convert IP address " - "%s to struct sockaddr_storage\n", - server)); - errno = ETIMEDOUT; - return NULL; - } - - tried_reverse++; /* Yuck */ - - if (name_status_find("*", 0, 0, - &rem_ss, remote_name)) { - make_nmb_name(&called, - remote_name, - 0x20); - goto again; - } - } - } - errno = ETIMEDOUT; - return NULL; - } - - DEBUG(4,(" session request ok\n")); - status = cli_negprot(c); if (!NT_STATUS_IS_OK(status)) { @@ -646,6 +586,10 @@ done: workgroup = *pp_workgroup; } if(!workgroup) { + if (c != NULL) { + cli_shutdown(c); + } + SAFE_FREE(srv); return NULL; } @@ -773,7 +717,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, zero_sockaddr(&ss); nt_status = cli_full_connection(&ipc_cli, - global_myname(), server, + lp_netbios_name(), server, &ss, 0, "IPC$", "?????", *pp_username, *pp_workgroup, diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 9c613508eb..b579a5f5c1 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" @@ -52,7 +53,7 @@ generate_inode(SMBCCTX *context, static int setup_stat(SMBCCTX *context, struct stat *st, - char *fname, + const char *fname, SMB_OFF_T size, int mode) { @@ -180,7 +181,7 @@ SMBC_stat_ctx(SMBCCTX *context, st->st_ino = ino; - setup_stat(context, st, (char *) fname, size, mode); + setup_stat(context, st, fname, size, mode); st->st_atime = convert_timespec_to_time_t(access_time_ts); st->st_ctime = convert_timespec_to_time_t(change_time_ts); diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index af2c56ad40..eeff9a9030 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "libsmb/libsmb.h" #include "libsmbclient.h" #include "libsmb_internal.h" #include "../librpc/gen_ndr/ndr_lsa.h" @@ -320,9 +321,9 @@ parse_ace(struct cli_state *ipc_cli, return false; } - if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { + if (strncasecmp_m(tok, "ALLOWED", strlen("ALLOWED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_ALLOWED; - } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { + } else if (strncasecmp_m(tok, "DENIED", strlen("DENIED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_DENIED; } else { TALLOC_FREE(frame); @@ -435,12 +436,12 @@ sec_desc_parse(TALLOC_CTX *ctx, while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { - if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { + if (strncasecmp_m(tok,"REVISION:", 9) == 0) { revision = strtol(tok+9, NULL, 16); continue; } - if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { + if (strncasecmp_m(tok,"OWNER:", 6) == 0) { if (owner_sid) { DEBUG(5,("OWNER specified more than once!\n")); goto done; @@ -456,7 +457,7 @@ sec_desc_parse(TALLOC_CTX *ctx, continue; } - if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { + if (strncasecmp_m(tok,"OWNER+:", 7) == 0) { if (owner_sid) { DEBUG(5,("OWNER specified more than once!\n")); goto done; @@ -472,7 +473,7 @@ sec_desc_parse(TALLOC_CTX *ctx, continue; } - if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { + if (strncasecmp_m(tok,"GROUP:", 6) == 0) { if (group_sid) { DEBUG(5,("GROUP specified more than once!\n")); goto done; @@ -488,7 +489,7 @@ sec_desc_parse(TALLOC_CTX *ctx, continue; } - if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { + if (strncasecmp_m(tok,"GROUP+:", 7) == 0) { if (group_sid) { DEBUG(5,("GROUP specified more than once!\n")); goto done; @@ -504,7 +505,7 @@ sec_desc_parse(TALLOC_CTX *ctx, continue; } - if (StrnCaseCmp(tok,"ACL:", 4) == 0) { + if (strncasecmp_m(tok,"ACL:", 4) == 0) { struct security_ace ace; if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { DEBUG(5, ("Failed to parse ACL %s\n", tok)); @@ -517,7 +518,7 @@ sec_desc_parse(TALLOC_CTX *ctx, continue; } - if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { + if (strncasecmp_m(tok,"ACL+:", 5) == 0) { struct security_ace ace; if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { DEBUG(5, ("Failed to parse ACL %s\n", tok)); @@ -560,14 +561,14 @@ dos_attr_query(SMBCCTX *context, SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; - ret = TALLOC_P(ctx, DOS_ATTR_DESC); + ret = talloc(ctx, DOS_ATTR_DESC); if (!ret) { errno = ENOMEM; return NULL; } /* Obtain the DOS attributes */ - if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), + if (!SMBC_getatr(context, srv, filename, &mode, &size, &create_time_ts, &access_time_ts, @@ -636,7 +637,7 @@ dos_attr_parse(SMBCCTX *context, frame = talloc_stackframe(); while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { - if (StrnCaseCmp(tok, "MODE:", 5) == 0) { + if (strncasecmp_m(tok, "MODE:", 5) == 0) { long request = strtol(tok+5, NULL, 16); if (request == 0) { dad->mode = (request | @@ -649,32 +650,32 @@ dos_attr_parse(SMBCCTX *context, continue; } - if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { + if (strncasecmp_m(tok, "SIZE:", 5) == 0) { dad->size = (SMB_OFF_T)atof(tok+5); continue; } n = strlen(attr_strings.access_time_attr); - if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { + if (strncasecmp_m(tok, attr_strings.access_time_attr, n) == 0) { dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } n = strlen(attr_strings.change_time_attr); - if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { + if (strncasecmp_m(tok, attr_strings.change_time_attr, n) == 0) { dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } n = strlen(attr_strings.write_time_attr); - if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { + if (strncasecmp_m(tok, attr_strings.write_time_attr, n) == 0) { dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } if (attr_strings.create_time_attr != NULL) { n = strlen(attr_strings.create_time_attr); - if (StrnCaseCmp(tok, attr_strings.create_time_attr, + if (strncasecmp_m(tok, attr_strings.create_time_attr, n) == 0) { dad->create_time = (time_t)strtol(tok+n+1, NULL, 10); @@ -682,7 +683,7 @@ dos_attr_parse(SMBCCTX *context, } } - if (StrnCaseCmp(tok, "INODE:", 6) == 0) { + if (strncasecmp_m(tok, "INODE:", 6) == 0) { dad->inode = (SMB_INO_T)atof(tok+6); continue; } @@ -700,8 +701,8 @@ cacl_get(SMBCCTX *context, SMBCSRV *srv, struct cli_state *ipc_cli, struct policy_handle *pol, - char *filename, - char *attr_name, + const char *filename, + const char *attr_name, char *buf, int bufsize) { @@ -799,12 +800,12 @@ cacl_get(SMBCCTX *context, *pExclude++ = '\0'; } - all = (StrnCaseCmp(name, "system.*", 8) == 0); - all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); - all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); - all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); - some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); - some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); + all = (strncasecmp_m(name, "system.*", 8) == 0); + all_nt = (strncasecmp_m(name, "system.nt_sec_desc.*", 20) == 0); + all_nt_acls = (strncasecmp_m(name, "system.nt_sec_desc.acl.*", 24) == 0); + all_dos = (strncasecmp_m(name, "system.dos_attr.*", 17) == 0); + some_nt = (strncasecmp_m(name, "system.nt_sec_desc.", 19) == 0); + some_dos = (strncasecmp_m(name, "system.dos_attr.", 16) == 0); numeric = (* (name + strlen(name) - 1) != '+'); /* Look for exclusions from "all" requests */ @@ -821,48 +822,48 @@ cacl_get(SMBCCTX *context, } /* Which exclusion name is this? */ - if (StrCaseCmp(pExclude, + if (strcasecmp_m(pExclude, "nt_sec_desc.revision") == 0) { exclude_nt_revision = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, "nt_sec_desc.owner") == 0) { exclude_nt_owner = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, "nt_sec_desc.group") == 0) { exclude_nt_group = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, "nt_sec_desc.acl") == 0) { exclude_nt_acl = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, "dos_attr.mode") == 0) { exclude_dos_mode = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, "dos_attr.size") == 0) { exclude_dos_size = True; } else if (excl_attr_strings.create_time_attr != NULL && - StrCaseCmp(pExclude, + strcasecmp_m(pExclude, excl_attr_strings.change_time_attr) == 0) { exclude_dos_create_time = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, excl_attr_strings.access_time_attr) == 0) { exclude_dos_access_time = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, excl_attr_strings.write_time_attr) == 0) { exclude_dos_write_time = True; } - else if (StrCaseCmp(pExclude, + else if (strcasecmp_m(pExclude, excl_attr_strings.change_time_attr) == 0) { exclude_dos_change_time = True; } - else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { + else if (strcasecmp_m(pExclude, "dos_attr.inode") == 0) { exclude_dos_inode = True; } else { @@ -932,7 +933,7 @@ cacl_get(SMBCCTX *context, "REVISION:%d", sd->revision); } - } else if (StrCaseCmp(name, "revision") == 0) { + } else if (strcasecmp_m(name, "revision") == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%d", sd->revision); @@ -981,7 +982,7 @@ cacl_get(SMBCCTX *context, n = snprintf(buf, bufsize, ",OWNER:%s", sidstr); } - } else if (StrnCaseCmp(name, "owner", 5) == 0) { + } else if (strncasecmp_m(name, "owner", 5) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%s", sidstr); if (!p) { @@ -1027,7 +1028,7 @@ cacl_get(SMBCCTX *context, n = snprintf(buf, bufsize, ",GROUP:%s", sidstr); } - } else if (StrnCaseCmp(name, "group", 5) == 0) { + } else if (strncasecmp_m(name, "group", 5) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%s", sidstr); if (!p) { @@ -1084,10 +1085,10 @@ cacl_get(SMBCCTX *context, ace->flags, ace->access_mask); } - } else if ((StrnCaseCmp(name, "acl", 3) == 0 && - StrCaseCmp(name+3, sidstr) == 0) || - (StrnCaseCmp(name, "acl+", 4) == 0 && - StrCaseCmp(name+4, sidstr) == 0)) { + } else if ((strncasecmp_m(name, "acl", 3) == 0 && + strcasecmp_m(name+3, sidstr) == 0) || + (strncasecmp_m(name, "acl+", 4) == 0 && + strcasecmp_m(name+4, sidstr) == 0)) { if (determine_size) { p = talloc_asprintf( ctx, @@ -1192,7 +1193,7 @@ cacl_get(SMBCCTX *context, : ""), mode); } - } else if (StrCaseCmp(name, "mode") == 0) { + } else if (strcasecmp_m(name, "mode") == 0) { if (determine_size) { p = talloc_asprintf(ctx, "0x%x", mode); if (!p) { @@ -1233,7 +1234,7 @@ cacl_get(SMBCCTX *context, ",SIZE:%.0f", (double)size); } - } else if (StrCaseCmp(name, "size") == 0) { + } else if (strcasecmp_m(name, "size") == 0) { if (determine_size) { p = talloc_asprintf( ctx, @@ -1280,7 +1281,7 @@ cacl_get(SMBCCTX *context, attr_strings.create_time_attr, (unsigned long) create_time); } - } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { + } else if (strcasecmp_m(name, attr_strings.create_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", (unsigned long) create_time); if (!p) { @@ -1322,7 +1323,7 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr, (unsigned long) access_time); } - } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { + } else if (strcasecmp_m(name, attr_strings.access_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", (unsigned long) access_time); if (!p) { @@ -1364,7 +1365,7 @@ cacl_get(SMBCCTX *context, attr_strings.write_time_attr, (unsigned long) write_time); } - } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { + } else if (strcasecmp_m(name, attr_strings.write_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", (unsigned long) write_time); if (!p) { @@ -1406,7 +1407,7 @@ cacl_get(SMBCCTX *context, attr_strings.change_time_attr, (unsigned long) change_time); } - } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { + } else if (strcasecmp_m(name, attr_strings.change_time_attr) == 0) { if (determine_size) { p = talloc_asprintf(ctx, "%lu", (unsigned long) change_time); if (!p) { @@ -1447,7 +1448,7 @@ cacl_get(SMBCCTX *context, ",INODE:%.0f", (double) ino); } - } else if (StrCaseCmp(name, "inode") == 0) { + } else if (strcasecmp_m(name, "inode") == 0) { if (determine_size) { p = talloc_asprintf( ctx, @@ -1774,8 +1775,8 @@ SMBC_setxattr_ctx(SMBCCTX *context, /* * Are they asking to set the entire set of known attributes? */ - if (StrCaseCmp(name, "system.*") == 0 || - StrCaseCmp(name, "system.*+") == 0) { + if (strcasecmp_m(name, "system.*") == 0 || + strcasecmp_m(name, "system.*+") == 0) { /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", @@ -1834,11 +1835,11 @@ SMBC_setxattr_ctx(SMBCCTX *context, * Are they asking to set an access control element or to set * the entire access control list? */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + if (strcasecmp_m(name, "system.nt_sec_desc.*") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.*+") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.revision") == 0 || + strncasecmp_m(name, "system.nt_sec_desc.acl", 22) == 0 || + strncasecmp_m(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ char *namevalue = @@ -1867,8 +1868,8 @@ SMBC_setxattr_ctx(SMBCCTX *context, /* * Are they asking to set the owner? */ - if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { + if (strcasecmp_m(name, "system.nt_sec_desc.owner") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.owner+") == 0) { /* Yup. */ char *namevalue = @@ -1893,8 +1894,8 @@ SMBC_setxattr_ctx(SMBCCTX *context, /* * Are they asking to set the group? */ - if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { + if (strcasecmp_m(name, "system.nt_sec_desc.group") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.group+") == 0) { /* Yup. */ char *namevalue = @@ -1935,13 +1936,13 @@ SMBC_setxattr_ctx(SMBCCTX *context, /* * Are they asking to set a DOS attribute? */ - if (StrCaseCmp(name, "system.dos_attr.*") == 0 || - StrCaseCmp(name, "system.dos_attr.mode") == 0 || + if (strcasecmp_m(name, "system.dos_attr.*") == 0 || + strcasecmp_m(name, "system.dos_attr.mode") == 0 || (attr_strings.create_time_attr != NULL && - StrCaseCmp(name, attr_strings.create_time_attr) == 0) || - StrCaseCmp(name, attr_strings.access_time_attr) == 0 || - StrCaseCmp(name, attr_strings.write_time_attr) == 0 || - StrCaseCmp(name, attr_strings.change_time_attr) == 0) { + strcasecmp_m(name, attr_strings.create_time_attr) == 0) || + strcasecmp_m(name, attr_strings.access_time_attr) == 0 || + strcasecmp_m(name, attr_strings.write_time_attr) == 0 || + strcasecmp_m(name, attr_strings.change_time_attr) == 0) { /* get a DOS Attribute Descriptor with current attributes */ dad = dos_attr_query(context, talloc_tos(), path, srv); @@ -2080,39 +2081,39 @@ SMBC_getxattr_ctx(SMBCCTX *context, } /* Are they requesting a supported attribute? */ - if (StrCaseCmp(name, "system.*") == 0 || - StrnCaseCmp(name, "system.*!", 9) == 0 || - StrCaseCmp(name, "system.*+") == 0 || - StrnCaseCmp(name, "system.*+!", 10) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || - StrCaseCmp(name, "system.dos_attr.*") == 0 || - StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || - StrCaseCmp(name, "system.dos_attr.mode") == 0 || - StrCaseCmp(name, "system.dos_attr.size") == 0 || + if (strcasecmp_m(name, "system.*") == 0 || + strncasecmp_m(name, "system.*!", 9) == 0 || + strcasecmp_m(name, "system.*+") == 0 || + strncasecmp_m(name, "system.*+!", 10) == 0 || + strcasecmp_m(name, "system.nt_sec_desc.*") == 0 || + strncasecmp_m(name, "system.nt_sec_desc.*!", 21) == 0 || + strcasecmp_m(name, "system.nt_sec_desc.*+") == 0 || + strncasecmp_m(name, "system.nt_sec_desc.*+!", 22) == 0 || + strcasecmp_m(name, "system.nt_sec_desc.revision") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.owner") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.owner+") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.group") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.group+") == 0 || + strncasecmp_m(name, "system.nt_sec_desc.acl", 22) == 0 || + strncasecmp_m(name, "system.nt_sec_desc.acl+", 23) == 0 || + strcasecmp_m(name, "system.dos_attr.*") == 0 || + strncasecmp_m(name, "system.dos_attr.*!", 18) == 0 || + strcasecmp_m(name, "system.dos_attr.mode") == 0 || + strcasecmp_m(name, "system.dos_attr.size") == 0 || (attr_strings.create_time_attr != NULL && - StrCaseCmp(name, attr_strings.create_time_attr) == 0) || - StrCaseCmp(name, attr_strings.access_time_attr) == 0 || - StrCaseCmp(name, attr_strings.write_time_attr) == 0 || - StrCaseCmp(name, attr_strings.change_time_attr) == 0 || - StrCaseCmp(name, "system.dos_attr.inode") == 0) { + strcasecmp_m(name, attr_strings.create_time_attr) == 0) || + strcasecmp_m(name, attr_strings.access_time_attr) == 0 || + strcasecmp_m(name, attr_strings.write_time_attr) == 0 || + strcasecmp_m(name, attr_strings.change_time_attr) == 0 || + strcasecmp_m(name, "system.dos_attr.inode") == 0) { /* Yup. */ - char *filename = (char *) name; + const char *filename = name; ret = cacl_get(context, talloc_tos(), srv, ipc_srv == NULL ? NULL : ipc_srv->cli, &ipc_srv->pol, path, filename, - CONST_DISCARD(char *, value), + discard_const_p(char, value), size); if (ret < 0 && errno == 0) { errno = SMBC_errno(context, srv->cli); @@ -2205,8 +2206,8 @@ SMBC_removexattr_ctx(SMBCCTX *context, } /* Are they asking to set the entire ACL? */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { + if (strcasecmp_m(name, "system.nt_sec_desc.*") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.*+") == 0) { /* Yup. */ ret = cacl_set(context, talloc_tos(), srv->cli, @@ -2220,18 +2221,18 @@ SMBC_removexattr_ctx(SMBCCTX *context, * Are they asking to remove one or more spceific security descriptor * attributes? */ - if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + if (strcasecmp_m(name, "system.nt_sec_desc.revision") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.owner") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.owner+") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.group") == 0 || + strcasecmp_m(name, "system.nt_sec_desc.group+") == 0 || + strncasecmp_m(name, "system.nt_sec_desc.acl", 22) == 0 || + strncasecmp_m(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ ret = cacl_set(context, talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, - CONST_DISCARD(char *, name) + 19, + discard_const_p(char, name) + 19, SMBC_XATTR_MODE_REMOVE, 0); TALLOC_FREE(frame); return ret; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index ef7aab6a6a..dca740d3e6 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "../lib/util/tevent_ntstatus.h" #include "libads/sitename_cache.h" #include "libads/dns.h" #include "../libcli/netlogon/netlogon.h" @@ -196,6 +197,26 @@ char *saf_fetch( const char *domain ) return server; } +static void set_socket_addr_v4(struct sockaddr_storage *addr) +{ + if (!interpret_string_addr(addr, lp_socket_address(), + AI_NUMERICHOST|AI_PASSIVE)) { + zero_sockaddr(addr); + } + if (addr->ss_family != AF_INET) { + zero_sockaddr(addr); + } +} + +static struct in_addr my_socket_addr_v4(void) +{ + struct sockaddr_storage my_addr; + struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr); + + set_socket_addr_v4(&my_addr); + return in_addr->sin_addr; +} + /**************************************************************************** Generate a random trn_id. ****************************************************************************/ @@ -225,7 +246,7 @@ static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p, if (*num_names == 0) return NULL; - ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names); + ret = talloc_array(mem_ctx, struct node_status,*num_names); if (!ret) return NULL; @@ -704,10 +725,7 @@ struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx, in_addr = (struct sockaddr_in *)(void *)&state->addr; in_addr->sin_port = htons(NMB_PORT); - if (!interpret_string_addr(&state->my_addr, lp_socket_address(), - AI_NUMERICHOST|AI_PASSIVE)) { - zero_sockaddr(&state->my_addr); - } + set_socket_addr_v4(&state->my_addr); ZERO_STRUCT(p); nmb->header.name_trn_id = generate_trn_id(); @@ -891,10 +909,7 @@ bool name_status_find(const char *q_name, return false; } - if (!interpret_string_addr(&ss, lp_socket_address(), - AI_NUMERICHOST|AI_PASSIVE)) { - zero_sockaddr(&ss); - } + set_socket_addr_v4(&ss); /* W2K PDC's seem not to respond to '*'#0. JRA */ make_nmb_name(&nname, q_name, q_type); @@ -962,9 +977,9 @@ static int addr_compare(const struct sockaddr_storage *ss1, for (i=0;i<num_interfaces;i++) { const struct sockaddr_storage *pss = iface_n_bcast(i); - unsigned char *p_ss1 = NULL; - unsigned char *p_ss2 = NULL; - unsigned char *p_if = NULL; + const unsigned char *p_ss1 = NULL; + const unsigned char *p_ss2 = NULL; + const unsigned char *p_if = NULL; size_t len = 0; int bits1, bits2; @@ -973,21 +988,21 @@ static int addr_compare(const struct sockaddr_storage *ss1, continue; } if (pss->ss_family == AF_INET) { - p_if = (unsigned char *) + p_if = (const unsigned char *) &((const struct sockaddr_in *)pss)->sin_addr; - p_ss1 = (unsigned char *) + p_ss1 = (const unsigned char *) &((const struct sockaddr_in *)ss1)->sin_addr; - p_ss2 = (unsigned char *) + p_ss2 = (const unsigned char *) &((const struct sockaddr_in *)ss2)->sin_addr; len = 4; } #if defined(HAVE_IPV6) if (pss->ss_family == AF_INET6) { - p_if = (unsigned char *) + p_if = (const unsigned char *) &((const struct sockaddr_in6 *)pss)->sin6_addr; - p_ss1 = (unsigned char *) + p_ss1 = (const unsigned char *) &((const struct sockaddr_in6 *)ss1)->sin6_addr; - p_ss2 = (unsigned char *) + p_ss2 = (const unsigned char *) &((const struct sockaddr_in6 *)ss2)->sin6_addr; len = 16; } @@ -1002,14 +1017,14 @@ static int addr_compare(const struct sockaddr_storage *ss1, } /* Bias towards directly reachable IPs */ - if (iface_local((struct sockaddr *)ss1)) { + if (iface_local((const struct sockaddr *)ss1)) { if (ss1->ss_family == AF_INET) { max_bits1 += 32; } else { max_bits1 += 128; } } - if (iface_local((struct sockaddr *)ss2)) { + if (iface_local((const struct sockaddr *)ss2)) { if (ss2->ss_family == AF_INET) { max_bits2 += 32; } else { @@ -1084,7 +1099,8 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count ) } for ( j=i+1; j<count; j++ ) { - if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) && + if (sockaddr_equal((struct sockaddr *)(void *)&iplist[i].ss, + (struct sockaddr *)(void *)&iplist[j].ss) && iplist[i].port == iplist[j].port) { zero_sockaddr(&iplist[j].ss); } @@ -1111,7 +1127,7 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count ) static bool prioritize_ipv4_list(struct ip_service *iplist, int count) { TALLOC_CTX *frame = talloc_stackframe(); - struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count); + struct ip_service *iplist_new = talloc_array(frame, struct ip_service, count); int i, j; if (iplist_new == NULL) { @@ -1177,7 +1193,6 @@ struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, struct packet_struct p; struct nmb_packet *nmb = &p.packet.nmb; struct sockaddr_in *in_addr; - struct timeval timeout; req = tevent_req_create(mem_ctx, &state, struct name_query_state); if (req == NULL) { @@ -1202,10 +1217,7 @@ struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, in_addr = (struct sockaddr_in *)(void *)&state->addr; in_addr->sin_port = htons(NMB_PORT); - if (!interpret_string_addr(&state->my_addr, lp_socket_address(), - AI_NUMERICHOST|AI_PASSIVE)) { - zero_sockaddr(&state->my_addr); - } + set_socket_addr_v4(&state->my_addr); ZERO_STRUCT(p); nmb->header.name_trn_id = generate_trn_id(); @@ -1243,14 +1255,6 @@ struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, DEBUG(10, ("nb_trans_send failed\n")); return tevent_req_post(req, ev); } - if (bcast) { - timeout = timeval_current_ofs(0, 250000); - } else { - timeout = timeval_current_ofs(2, 0); - } - if (!tevent_req_set_endtime(req, ev, timeout)) { - return tevent_req_post(req, ev); - } tevent_req_set_callback(subreq, name_query_done, req); return req; } @@ -1261,6 +1265,7 @@ static bool name_query_validator(struct packet_struct *p, void *private_data) private_data, struct name_query_state); struct nmb_packet *nmb = &p->packet.nmb; struct sockaddr_storage *tmp_addrs; + bool got_unique_netbios_name = false; int i; debug_nmb_packet(p); @@ -1322,7 +1327,7 @@ static bool name_query_validator(struct packet_struct *p, void *private_data) return false; } - tmp_addrs = TALLOC_REALLOC_ARRAY( + tmp_addrs = talloc_realloc( state, state->addrs, struct sockaddr_storage, state->num_addrs + nmb->answers->rdlength/6); if (tmp_addrs == NULL) { @@ -1335,11 +1340,32 @@ static bool name_query_validator(struct packet_struct *p, void *private_data) "from %s ( ", inet_ntoa(p->ip))); for (i=0; i<nmb->answers->rdlength/6; i++) { + uint16_t flags; struct in_addr ip; + struct sockaddr_storage addr; + int j; + + flags = RSVAL(&nmb->answers->rdata[i*6], 0); + got_unique_netbios_name |= ((flags & 0x8000) == 0); + putip((char *)&ip,&nmb->answers->rdata[2+i*6]); - in_addr_to_sockaddr_storage( - &state->addrs[state->num_addrs], ip); + in_addr_to_sockaddr_storage(&addr, ip); + + for (j=0; j<state->num_addrs; j++) { + if (sockaddr_equal( + (struct sockaddr *)(void *)&addr, + (struct sockaddr *)(void *)&state->addrs[j])) { + break; + } + } + if (j < state->num_addrs) { + /* Already got it */ + continue; + } + DEBUGADD(2,("%s ",inet_ntoa(ip))); + + state->addrs[state->num_addrs] = addr; state->num_addrs += 1; } DEBUGADD(2,(")\n")); @@ -1360,10 +1386,10 @@ static bool name_query_validator(struct packet_struct *p, void *private_data) if (state->bcast) { /* - * We have to collect all entries coming in from - * broadcast queries + * We have to collect all entries coming in from broadcast + * queries. If we got a unique name, we're done. */ - return false; + return got_unique_netbios_name; } /* * WINS responses are accepted when they are received @@ -1407,9 +1433,18 @@ NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, req, struct name_query_state); NTSTATUS status; - if (tevent_req_is_nterror(req, &status) - && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - return status; + if (tevent_req_is_nterror(req, &status)) { + if (state->bcast && + NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + /* + * In the broadcast case we collect replies until the + * timeout. + */ + status = NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } } if (state->num_addrs == 0) { return NT_STATUS_NOT_FOUND; @@ -1433,6 +1468,7 @@ NTSTATUS name_query(const char *name, int name_type, TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; struct tevent_req *req; + struct timeval timeout; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = tevent_context_init(frame); @@ -1443,6 +1479,14 @@ NTSTATUS name_query(const char *name, int name_type, if (req == NULL) { goto fail; } + if (bcast) { + timeout = timeval_current_ofs(0, 250000); + } else { + timeout = timeval_current_ofs(2, 0); + } + if (!tevent_req_set_endtime(req, ev, timeout)) { + goto fail; + } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } @@ -1482,113 +1526,507 @@ static bool convert_ss2service(struct ip_service **return_iplist, return true; } +struct name_queries_state { + struct tevent_context *ev; + const char *name; + int name_type; + bool bcast; + bool recurse; + const struct sockaddr_storage *addrs; + int num_addrs; + int wait_msec; + int timeout_msec; + + struct tevent_req **subreqs; + int num_received; + int num_sent; + + int received_index; + struct sockaddr_storage *result_addrs; + int num_result_addrs; + uint8_t flags; +}; + +static void name_queries_done(struct tevent_req *subreq); +static void name_queries_next(struct tevent_req *subreq); + +/* + * Send a name query to multiple destinations with a wait time in between + */ + +static struct tevent_req *name_queries_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + const char *name, int name_type, + bool bcast, bool recurse, + const struct sockaddr_storage *addrs, + int num_addrs, int wait_msec, int timeout_msec) +{ + struct tevent_req *req, *subreq; + struct name_queries_state *state; + + req = tevent_req_create(mem_ctx, &state, + struct name_queries_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->name = name; + state->name_type = name_type; + state->bcast = bcast; + state->recurse = recurse; + state->addrs = addrs; + state->num_addrs = num_addrs; + state->wait_msec = wait_msec; + state->timeout_msec = timeout_msec; + + state->subreqs = talloc_zero_array( + state, struct tevent_req *, num_addrs); + if (tevent_req_nomem(state->subreqs, req)) { + return tevent_req_post(req, ev); + } + state->num_sent = 0; + + subreq = name_query_send( + state->subreqs, state->ev, name, name_type, bcast, recurse, + &state->addrs[state->num_sent]); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + if (!tevent_req_set_endtime( + subreq, state->ev, + timeval_current_ofs(0, state->timeout_msec * 1000))) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, name_queries_done, req); + + state->subreqs[state->num_sent] = subreq; + state->num_sent += 1; + + if (state->num_sent < state->num_addrs) { + subreq = tevent_wakeup_send( + state, state->ev, + timeval_current_ofs(0, state->wait_msec * 1000)); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, name_queries_next, req); + } + return req; +} + +static void name_queries_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct name_queries_state *state = tevent_req_data( + req, struct name_queries_state); + int i; + NTSTATUS status; + + status = name_query_recv(subreq, state, &state->result_addrs, + &state->num_result_addrs, &state->flags); + + for (i=0; i<state->num_sent; i++) { + if (state->subreqs[i] == subreq) { + break; + } + } + if (i == state->num_sent) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + TALLOC_FREE(state->subreqs[i]); + + state->num_received += 1; + + if (!NT_STATUS_IS_OK(status)) { + + if (state->num_received >= state->num_addrs) { + tevent_req_nterror(req, status); + return; + } + /* + * Still outstanding requests, just wait + */ + return; + } + state->received_index = i; + tevent_req_done(req); +} + +static void name_queries_next(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct name_queries_state *state = tevent_req_data( + req, struct name_queries_state); + + if (!tevent_wakeup_recv(subreq)) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + subreq = name_query_send( + state->subreqs, state->ev, + state->name, state->name_type, state->bcast, state->recurse, + &state->addrs[state->num_sent]); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, name_queries_done, req); + if (!tevent_req_set_endtime( + subreq, state->ev, + timeval_current_ofs(0, state->timeout_msec * 1000))) { + tevent_req_oom(req); + return; + } + state->subreqs[state->num_sent] = subreq; + state->num_sent += 1; + + if (state->num_sent < state->num_addrs) { + subreq = tevent_wakeup_send( + state, state->ev, + timeval_current_ofs(0, state->wait_msec * 1000)); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, name_queries_next, req); + } +} + +static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct sockaddr_storage **result_addrs, + int *num_result_addrs, uint8_t *flags, + int *received_index) +{ + struct name_queries_state *state = tevent_req_data( + req, struct name_queries_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + + if (result_addrs != NULL) { + *result_addrs = talloc_move(mem_ctx, &state->result_addrs); + } + if (num_result_addrs != NULL) { + *num_result_addrs = state->num_result_addrs; + } + if (flags != NULL) { + *flags = state->flags; + } + if (received_index != NULL) { + *received_index = state->received_index; + } + return NT_STATUS_OK; +} + /******************************************************** Resolve via "bcast" method. *********************************************************/ -NTSTATUS name_resolve_bcast(const char *name, - int name_type, - struct ip_service **return_iplist, - int *return_count) +struct name_resolve_bcast_state { + struct sockaddr_storage *addrs; + int num_addrs; +}; + +static void name_resolve_bcast_done(struct tevent_req *subreq); + +struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *name, + int name_type) { - int i; - int num_interfaces = iface_count(); - struct sockaddr_storage *ss_list; - struct sockaddr_storage ss; - NTSTATUS status = NT_STATUS_NOT_FOUND; + struct tevent_req *req, *subreq; + struct name_resolve_bcast_state *state; + struct sockaddr_storage *bcast_addrs; + int i, num_addrs, num_bcast_addrs; - if (lp_disable_netbios()) { - DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", - name, name_type)); - return NT_STATUS_INVALID_PARAMETER; + req = tevent_req_create(mem_ctx, &state, + struct name_resolve_bcast_state); + if (req == NULL) { + return NULL; } - *return_iplist = NULL; - *return_count = 0; + if (lp_disable_netbios()) { + DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n", + name, name_type)); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } /* * "bcast" means do a broadcast lookup on all the local interfaces. */ - DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup " - "for name %s<0x%x>\n", name, name_type)); + DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup " + "for name %s<0x%x>\n", name, name_type)); - if (!interpret_string_addr(&ss, lp_socket_address(), - AI_NUMERICHOST|AI_PASSIVE)) { - zero_sockaddr(&ss); + num_addrs = iface_count(); + bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs); + if (tevent_req_nomem(bcast_addrs, req)) { + return tevent_req_post(req, ev); } /* * Lookup the name on all the interfaces, return on * the first successful match. */ - for( i = num_interfaces-1; i >= 0; i--) { + num_bcast_addrs = 0; + + for (i=0; i<num_addrs; i++) { const struct sockaddr_storage *pss = iface_n_bcast(i); - /* Done this way to fix compiler error on IRIX 5.x */ - if (!pss) { + if (pss->ss_family != AF_INET) { continue; } - status = name_query(name, name_type, true, true, pss, - talloc_tos(), &ss_list, return_count, - NULL); - if (NT_STATUS_IS_OK(status)) { - goto success; - } + bcast_addrs[num_bcast_addrs] = *pss; + num_bcast_addrs += 1; } - /* failed - no response */ + subreq = name_queries_send(state, ev, name, name_type, true, true, + bcast_addrs, num_bcast_addrs, 0, 1000); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, name_resolve_bcast_done, req); + return req; +} - return status; +static void name_resolve_bcast_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct name_resolve_bcast_state *state = tevent_req_data( + req, struct name_resolve_bcast_state); + NTSTATUS status; -success: + status = name_queries_recv(subreq, state, + &state->addrs, &state->num_addrs, + NULL, NULL); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} - if (!convert_ss2service(return_iplist, ss_list, *return_count) ) - status = NT_STATUS_NO_MEMORY; +NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct sockaddr_storage **addrs, + int *num_addrs) +{ + struct name_resolve_bcast_state *state = tevent_req_data( + req, struct name_resolve_bcast_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + *addrs = talloc_move(mem_ctx, &state->addrs); + *num_addrs = state->num_addrs; + return NT_STATUS_OK; +} - TALLOC_FREE(ss_list); +NTSTATUS name_resolve_bcast(const char *name, + int name_type, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = name_resolve_bcast_send(frame, ev, name, name_type); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = name_resolve_bcast_recv(req, mem_ctx, return_iplist, + return_count); + fail: + TALLOC_FREE(frame); return status; } -/******************************************************** - Resolve via "wins" method. -*********************************************************/ +struct query_wins_list_state { + struct tevent_context *ev; + const char *name; + uint8_t name_type; + struct in_addr *servers; + uint32_t num_servers; + struct sockaddr_storage server; + uint32_t num_sent; -NTSTATUS resolve_wins(const char *name, - int name_type, - struct ip_service **return_iplist, - int *return_count) + struct sockaddr_storage *addrs; + int num_addrs; + uint8_t flags; +}; + +static void query_wins_list_done(struct tevent_req *subreq); + +/* + * Query a list of (replicating) wins servers in sequence, call them + * dead if they don't reply + */ + +static struct tevent_req *query_wins_list_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, + struct in_addr src_ip, const char *name, uint8_t name_type, + struct in_addr *servers, int num_servers) { - int t, i; - char **wins_tags; - struct sockaddr_storage src_ss, *ss_list = NULL; - struct in_addr src_ip; + struct tevent_req *req, *subreq; + struct query_wins_list_state *state; + + req = tevent_req_create(mem_ctx, &state, + struct query_wins_list_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->name = name; + state->name_type = name_type; + state->servers = servers; + state->num_servers = num_servers; + + if (state->num_servers == 0) { + tevent_req_nterror(req, NT_STATUS_NOT_FOUND); + return tevent_req_post(req, ev); + } + + in_addr_to_sockaddr_storage( + &state->server, state->servers[state->num_sent]); + + subreq = name_query_send(state, state->ev, + state->name, state->name_type, + false, true, &state->server); + state->num_sent += 1; + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + if (!tevent_req_set_endtime(subreq, state->ev, + timeval_current_ofs(2, 0))) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, query_wins_list_done, req); + return req; +} + +static void query_wins_list_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct query_wins_list_state *state = tevent_req_data( + req, struct query_wins_list_state); NTSTATUS status; - if (lp_disable_netbios()) { - DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", - name, name_type)); - return NT_STATUS_INVALID_PARAMETER; + status = name_query_recv(subreq, state, + &state->addrs, &state->num_addrs, + &state->flags); + TALLOC_FREE(subreq); + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + return; + } + if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + tevent_req_nterror(req, status); + return; } + wins_srv_died(state->servers[state->num_sent-1], + my_socket_addr_v4()); - *return_iplist = NULL; - *return_count = 0; + if (state->num_sent == state->num_servers) { + tevent_req_nterror(req, NT_STATUS_NOT_FOUND); + return; + } - DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", - name, name_type)); + in_addr_to_sockaddr_storage( + &state->server, state->servers[state->num_sent]); - if (wins_srv_count() < 1) { - DEBUG(3,("resolve_wins: WINS server resolution selected " - "and no WINS servers listed.\n")); - return NT_STATUS_INVALID_PARAMETER; + subreq = name_query_send(state, state->ev, + state->name, state->name_type, + false, true, &state->server); + state->num_sent += 1; + if (tevent_req_nomem(subreq, req)) { + return; } + if (!tevent_req_set_endtime(subreq, state->ev, + timeval_current_ofs(2, 0))) { + tevent_req_oom(req); + return; + } + tevent_req_set_callback(subreq, query_wins_list_done, req); +} - /* we try a lookup on each of the WINS tags in turn */ - wins_tags = wins_srv_tags(); +static NTSTATUS query_wins_list_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **addrs, + int *num_addrs, + uint8_t *flags) +{ + struct query_wins_list_state *state = tevent_req_data( + req, struct query_wins_list_state); + NTSTATUS status; - if (!wins_tags) { - /* huh? no tags?? give up in disgust */ - return NT_STATUS_INVALID_PARAMETER; + if (tevent_req_is_nterror(req, &status)) { + return status; + } + if (addrs != NULL) { + *addrs = talloc_move(mem_ctx, &state->addrs); + } + if (num_addrs != NULL) { + *num_addrs = state->num_addrs; + } + if (flags != NULL) { + *flags = state->flags; + } + return NT_STATUS_OK; +} + +struct resolve_wins_state { + int num_sent; + int num_received; + + struct sockaddr_storage *addrs; + int num_addrs; + uint8_t flags; +}; + +static void resolve_wins_done(struct tevent_req *subreq); + +struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *name, + int name_type) +{ + struct tevent_req *req, *subreq; + struct resolve_wins_state *state; + char **wins_tags = NULL; + struct sockaddr_storage src_ss; + struct in_addr src_ip; + int i, num_wins_tags; + + req = tevent_req_create(mem_ctx, &state, + struct resolve_wins_state); + if (req == NULL) { + return NULL; + } + + if (wins_srv_count() < 1) { + DEBUG(3,("resolve_wins: WINS server resolution selected " + "and no WINS servers listed.\n")); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + goto fail; } /* the address we will be sending from */ @@ -1603,80 +2041,164 @@ NTSTATUS resolve_wins(const char *name, DEBUG(3,("resolve_wins: cannot receive WINS replies " "on IPv6 address %s\n", addr)); - wins_srv_tags_free(wins_tags); - return NT_STATUS_INVALID_PARAMETER; + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + goto fail; } - src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr; + src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr; - /* in the worst case we will try every wins server with every - tag! */ - for (t=0; wins_tags && wins_tags[t]; t++) { - int srv_count = wins_srv_count_tag(wins_tags[t]); - for (i=0; i<srv_count; i++) { - struct sockaddr_storage wins_ss; - struct in_addr wins_ip; + wins_tags = wins_srv_tags(); + if (wins_tags == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + goto fail; + } + + num_wins_tags = 0; + while (wins_tags[num_wins_tags] != NULL) { + num_wins_tags += 1; + } + + for (i=0; i<num_wins_tags; i++) { + int num_servers, num_alive; + struct in_addr *servers, *alive; + int j; + + if (!wins_server_tag_ips(wins_tags[i], talloc_tos(), + &servers, &num_servers)) { + DEBUG(10, ("wins_server_tag_ips failed for tag %s\n", + wins_tags[i])); + continue; + } + + alive = talloc_array(state, struct in_addr, num_servers); + if (tevent_req_nomem(alive, req)) { + goto fail; + } - wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip); + num_alive = 0; + for (j=0; j<num_servers; j++) { + struct in_addr wins_ip = servers[j]; if (global_in_nmbd && ismyip_v4(wins_ip)) { /* yikes! we'll loop forever */ continue; } - /* skip any that have been unresponsive lately */ if (wins_srv_is_dead(wins_ip, src_ip)) { continue; } + DEBUG(3, ("resolve_wins: using WINS server %s " + "and tag '%s'\n", + inet_ntoa(wins_ip), wins_tags[i])); + alive[num_alive] = wins_ip; + num_alive += 1; + } + TALLOC_FREE(servers); - DEBUG(3,("resolve_wins: using WINS server %s " - "and tag '%s'\n", - inet_ntoa(wins_ip), wins_tags[t])); + if (num_alive == 0) { + continue; + } - in_addr_to_sockaddr_storage(&wins_ss, wins_ip); - status = name_query(name, - name_type, - false, - true, - &wins_ss, - talloc_tos(), - &ss_list, - return_count, - NULL); + subreq = query_wins_list_send( + state, ev, src_ip, name, name_type, + alive, num_alive); + if (tevent_req_nomem(subreq, req)) { + goto fail; + } + tevent_req_set_callback(subreq, resolve_wins_done, req); + state->num_sent += 1; + } - /* exit loop if we got a list of addresses */ + if (state->num_sent == 0) { + tevent_req_nterror(req, NT_STATUS_NOT_FOUND); + goto fail; + } - if (NT_STATUS_IS_OK(status)) { - goto success; - } + wins_srv_tags_free(wins_tags); + return req; +fail: + wins_srv_tags_free(wins_tags); + return tevent_req_post(req, ev); +} - if (NT_STATUS_EQUAL(status, - NT_STATUS_IO_TIMEOUT)) { - /* Timed out waiting for WINS server to - * respond. - * Mark it dead. */ - wins_srv_died(wins_ip, src_ip); - } else { - /* The name definitely isn't in this - group of WINS servers. - goto the next group */ - break; - } - } +static void resolve_wins_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct resolve_wins_state *state = tevent_req_data( + req, struct resolve_wins_state); + NTSTATUS status; + + status = query_wins_list_recv(subreq, state, &state->addrs, + &state->num_addrs, &state->flags); + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + return; } - wins_srv_tags_free(wins_tags); - return NT_STATUS_NO_LOGON_SERVERS; + state->num_received += 1; -success: + if (state->num_received < state->num_sent) { + /* + * Wait for the others + */ + return; + } + tevent_req_nterror(req, status); +} - status = NT_STATUS_OK; - if (!convert_ss2service(return_iplist, ss_list, *return_count)) - status = NT_STATUS_INVALID_PARAMETER; +NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct sockaddr_storage **addrs, + int *num_addrs, uint8_t *flags) +{ + struct resolve_wins_state *state = tevent_req_data( + req, struct resolve_wins_state); + NTSTATUS status; - TALLOC_FREE(ss_list); - wins_srv_tags_free(wins_tags); + if (tevent_req_is_nterror(req, &status)) { + return status; + } + if (addrs != NULL) { + *addrs = talloc_move(mem_ctx, &state->addrs); + } + if (num_addrs != NULL) { + *num_addrs = state->num_addrs; + } + if (flags != NULL) { + *flags = state->flags; + } + return NT_STATUS_OK; +} +/******************************************************** + Resolve via "wins" method. +*********************************************************/ + +NTSTATUS resolve_wins(const char *name, + int name_type, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **return_iplist, + int *return_count) +{ + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = tevent_context_init(talloc_tos()); + if (ev == NULL) { + goto fail; + } + req = resolve_wins_send(ev, ev, name, name_type); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count, + NULL); +fail: + TALLOC_FREE(ev); return status; } @@ -1744,6 +2266,7 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, struct addrinfo *res = NULL; int ret = -1; int i = 0; + const char *dns_hosts_file; if ( name_type != 0x20 && name_type != 0x0) { DEBUG(5, ("resolve_hosts: not appropriate " @@ -1768,6 +2291,32 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, hints.ai_family = AF_INET; #endif + dns_hosts_file = lp_parm_const_string(-1, "resolv", "host file", NULL); + if (dns_hosts_file) { + struct sockaddr_storage *ss_list; + NTSTATUS status; + TALLOC_CTX *ctx = talloc_stackframe(); + if (!ctx) { + return NT_STATUS_NO_MEMORY; + } + + status = resolve_dns_hosts_file_as_sockaddr(dns_hosts_file, name, false, + ctx, &ss_list, return_count); + if (NT_STATUS_IS_OK(status)) { + if (convert_ss2service(return_iplist, + ss_list, + *return_count)) { + talloc_free(ctx); + return NT_STATUS_OK; + } else { + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + } + talloc_free(ctx); + return NT_STATUS_UNSUCCESSFUL; + } + ret = getaddrinfo(name, NULL, &hints, @@ -2044,19 +2593,32 @@ NTSTATUS internal_resolve_name(const char *name, } } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ + struct sockaddr_storage *ss_list; if (name_type != 0x1D) { status = resolve_wins(name, name_type, - return_iplist, + talloc_tos(), + &ss_list, return_count); if (NT_STATUS_IS_OK(status)) { + if (!convert_ss2service(return_iplist, + ss_list, + *return_count)) { + status = NT_STATUS_NO_MEMORY; + } goto done; } } } else if(strequal( tok, "bcast")) { - status = name_resolve_bcast(name, name_type, - return_iplist, - return_count); + struct sockaddr_storage *ss_list; + status = name_resolve_bcast( + name, name_type, talloc_tos(), + &ss_list, return_count); if (NT_STATUS_IS_OK(status)) { + if (!convert_ss2service(return_iplist, + ss_list, + *return_count)) { + status = NT_STATUS_NO_MEMORY; + } goto done; } } else { @@ -2152,7 +2714,7 @@ bool resolve_name(const char *name, if (prefer_ipv4) { for (i=0; i<count; i++) { if (!is_zero_addr(&ss_list[i].ss) && - !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) && + !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) && (ss_list[i].ss.ss_family == AF_INET)) { *return_ss = ss_list[i].ss; SAFE_FREE(ss_list); @@ -2165,7 +2727,7 @@ bool resolve_name(const char *name, /* only return valid addresses for TCP connections */ for (i=0; i<count; i++) { if (!is_zero_addr(&ss_list[i].ss) && - !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { + !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) { *return_ss = ss_list[i].ss; SAFE_FREE(ss_list); SAFE_FREE(sitename); @@ -2203,7 +2765,7 @@ NTSTATUS resolve_name_list(TALLOC_CTX *ctx, *return_ss_arr = NULL; if (is_ipaddress(name)) { - *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage); + *return_ss_arr = talloc(ctx, struct sockaddr_storage); if (!*return_ss_arr) { return NT_STATUS_NO_MEMORY; } @@ -2229,7 +2791,7 @@ NTSTATUS resolve_name_list(TALLOC_CTX *ctx, /* only return valid addresses for TCP connections */ for (i=0, num_entries = 0; i<count; i++) { if (!is_zero_addr(&ss_list[i].ss) && - !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { + !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) { num_entries++; } } @@ -2238,7 +2800,7 @@ NTSTATUS resolve_name_list(TALLOC_CTX *ctx, return NT_STATUS_BAD_NETWORK_NAME; } - *return_ss_arr = TALLOC_ARRAY(ctx, + *return_ss_arr = talloc_array(ctx, struct sockaddr_storage, num_entries); if (!(*return_ss_arr)) { @@ -2248,7 +2810,7 @@ NTSTATUS resolve_name_list(TALLOC_CTX *ctx, for (i=0, num_entries = 0; i<count; i++) { if (!is_zero_addr(&ss_list[i].ss) && - !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { + !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) { (*return_ss_arr)[num_entries++] = ss_list[i].ss; } } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index dbf996ee5e..767ff81476 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -288,7 +288,7 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type) If buf == NULL this is a length calculation. ******************************************************************/ -static int put_nmb_name(char *buf,int offset,struct nmb_name *name) +static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name) { int ret,m; nstring buf1; @@ -302,6 +302,9 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) } if (buf) { + if (offset >= buflen) { + return 0; + } buf[offset] = 0x20; } @@ -309,6 +312,9 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) for (m=0;m<MAX_NETBIOSNAME_LEN;m++) { if (buf) { + if (offset+2+2*m >= buflen) { + return 0; + } buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); } @@ -316,20 +322,30 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) offset += 33; if (buf) { + if (offset >= buflen) { + return 0; + } buf[offset] = 0; } if (name->scope[0]) { /* XXXX this scope handling needs testing */ - ret += strlen(name->scope) + 1; + size_t scopenamelen = strlen(name->scope) + 1; + ret += scopenamelen; if (buf) { - safe_strcpy(&buf[offset+1],name->scope, - sizeof(name->scope)); + if (offset+1+scopenamelen >= buflen) { + return 0; + } + strlcpy(&buf[offset+1],name->scope, + buflen - (offset+1)); p = &buf[offset+1]; while ((p = strchr_m(p,'.'))) { buf[offset] = PTR_DIFF(p,&buf[offset+1]); offset += (buf[offset] + 1); + if (offset+1 >= buflen) { + return 0; + } p = &buf[offset+1]; } buf[offset] = strlen(&buf[offset+1]); @@ -404,13 +420,13 @@ static bool parse_alloc_res_rec(char *inbuf,int *offset,int length, If buf == NULL this is a length calculation. ******************************************************************/ -static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) +static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count) { int ret=0; int i; for (i=0;i<count;i++) { - int l = put_nmb_name(buf,offset,&recs[i].rr_name); + int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name); offset += l; ret += l; if (buf) { @@ -887,8 +903,8 @@ static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram) if (dgram->header.msg_type == 0x10 || dgram->header.msg_type == 0x11 || dgram->header.msg_type == 0x12) { - offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); - offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name); } if (buf) { @@ -920,7 +936,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) strupper_m(unix_name); push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE); n->name_type = (unsigned int)type & 0xFF; - push_ascii(n->scope, global_scope(), 64, STR_TERMINATE); + push_ascii(n->scope, lp_netbios_scope(), 64, STR_TERMINATE); } /******************************************************************* @@ -979,13 +995,13 @@ static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb) /* XXXX this doesn't handle a qdcount of > 1 */ if (len) { /* Length check. */ - int extra = put_nmb_name(NULL,offset, + int extra = put_nmb_name(NULL,0,offset, &nmb->question.question_name); if (offset + extra > len) { return 0; } } - offset += put_nmb_name((char *)ubuf,offset, + offset += put_nmb_name((char *)ubuf,len,offset, &nmb->question.question_name); if (buf) { RSSVAL(ubuf,offset,nmb->question.question_type); @@ -997,26 +1013,26 @@ static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb) if (nmb->header.ancount) { if (len) { /* Length check. */ - int extra = put_res_rec(NULL,offset,nmb->answers, + int extra = put_res_rec(NULL,0,offset,nmb->answers, nmb->header.ancount); if (offset + extra > len) { return 0; } } - offset += put_res_rec((char *)ubuf,offset,nmb->answers, + offset += put_res_rec((char *)ubuf,len,offset,nmb->answers, nmb->header.ancount); } if (nmb->header.nscount) { if (len) { /* Length check. */ - int extra = put_res_rec(NULL,offset,nmb->nsrecs, + int extra = put_res_rec(NULL,0,offset,nmb->nsrecs, nmb->header.nscount); if (offset + extra > len) { return 0; } } - offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs, nmb->header.nscount); } @@ -1048,13 +1064,13 @@ static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb) } else if (nmb->header.arcount) { if (len) { /* Length check. */ - int extra = put_res_rec(NULL,offset,nmb->additional, + int extra = put_res_rec(NULL,0,offset,nmb->additional, nmb->header.arcount); if (offset + extra > len) { return 0; } } - offset += put_res_rec((char *)ubuf,offset,nmb->additional, + offset += put_res_rec((char *)ubuf,len,offset,nmb->additional, nmb->header.arcount); } return offset; @@ -1131,7 +1147,7 @@ bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name) Return the number of bits that match between two len character buffers ***************************************************************************/ -int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len) +int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len) { size_t i, j; int ret = 0; @@ -1245,7 +1261,7 @@ char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type) char *result; char *p; - result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2); + result = talloc_array(mem_ctx, char, 33 + strlen(lp_netbios_scope()) + 2); if (result == NULL) { return NULL; } @@ -1280,8 +1296,8 @@ char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { - switch( (global_scope())[i] ) { + for( i = 0, len = 0; *(lp_netbios_scope()) != '\0'; i++, len++ ) { + switch( (lp_netbios_scope())[i] ) { case '\0': p[0] = len; if( len > 0 ) @@ -1293,7 +1309,7 @@ char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type) len = -1; break; default: - p[len+1] = (global_scope())[i]; + p[len+1] = (lp_netbios_scope())[i]; break; } } diff --git a/source3/libsmb/nmblib.h b/source3/libsmb/nmblib.h index a6666a84c6..d8290dc076 100644 --- a/source3/libsmb/nmblib.h +++ b/source3/libsmb/nmblib.h @@ -1,3 +1,28 @@ +/* + Unix SMB/CIFS implementation. + handle unexpected packets + NBT netbios library routines + Copyright (C) Andrew Tridgell 1994-1998, 2000 + Copyright (C) Jeremy Allison 2007 + + 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/>. + +*/ + +#ifndef _LIBSMB_NMBLIB_H_ +#define _LIBSMB_NMBLIB_H_ + /* The following definitions come from libsmb/unexpected.c */ #include "nameserv.h" @@ -42,8 +67,10 @@ bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); int build_packet(char *buf, size_t buflen, struct packet_struct *p); bool send_packet(struct packet_struct *p); bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name); -int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len); +int matching_len_bits(const unsigned char *p1, const unsigned char *p2, size_t len); void sort_query_replies(char *data, int n, struct in_addr ip); char *name_mangle(TALLOC_CTX *mem_ctx, const char *In, char name_type); int name_extract(unsigned char *buf,size_t buf_len, unsigned int ofs, fstring name); int name_len(unsigned char *s1, size_t buf_len); + +#endif /* _LIBSMB_NMBLIB_H_ */ diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c deleted file mode 100644 index 321965878d..0000000000 --- a/source3/libsmb/nterr.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. - * - * 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/>. - */ - -/* NT error codes. please read nterr.h */ - -#include "includes.h" -#include "smb_ldap.h" -#undef strcasecmp - -#if !defined(N_) -#define N_(string) string -#endif - -typedef struct -{ - const char *nt_errstr; - NTSTATUS nt_errcode; -} nt_err_code_struct; - -static const nt_err_code_struct nt_errs[] = -{ - { "NT_STATUS_OK", NT_STATUS_OK }, - { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, - { "STATUS_NO_MORE_EAS", STATUS_NO_MORE_EAS }, - { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME }, - { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT }, - { "STATUS_INVALID_EA_FLAG", STATUS_INVALID_EA_FLAG }, - { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, - { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, - { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, - { "NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH }, - { "NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION }, - { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW }, - { "NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR }, - { "NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA }, - { "NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE }, - { "NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK }, - { "NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC }, - { "NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID }, - { "NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED }, - { "NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER }, - { "NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE }, - { "NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE }, - { "NT_STATUS_INVALID_DEVICE_REQUEST", NT_STATUS_INVALID_DEVICE_REQUEST }, - { "NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE }, - { "NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME }, - { "NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE }, - { "NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA }, - { "NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR }, - { "NT_STATUS_MORE_PROCESSING_REQUIRED", NT_STATUS_MORE_PROCESSING_REQUIRED }, - { "NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY }, - { "NT_STATUS_CONFLICTING_ADDRESSES", NT_STATUS_CONFLICTING_ADDRESSES }, - { "NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW }, - { "NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM }, - { "NT_STATUS_UNABLE_TO_DELETE_SECTION", NT_STATUS_UNABLE_TO_DELETE_SECTION }, - { "NT_STATUS_INVALID_SYSTEM_SERVICE", NT_STATUS_INVALID_SYSTEM_SERVICE }, - { "NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION }, - { "NT_STATUS_INVALID_LOCK_SEQUENCE", NT_STATUS_INVALID_LOCK_SEQUENCE }, - { "NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE }, - { "NT_STATUS_INVALID_FILE_FOR_SECTION", NT_STATUS_INVALID_FILE_FOR_SECTION }, - { "NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED }, - { "NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED }, - { "NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL }, - { "NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH }, - { "NT_STATUS_NONCONTINUABLE_EXCEPTION", NT_STATUS_NONCONTINUABLE_EXCEPTION }, - { "NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION }, - { "NT_STATUS_UNWIND", NT_STATUS_UNWIND }, - { "NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK }, - { "NT_STATUS_INVALID_UNWIND_TARGET", NT_STATUS_INVALID_UNWIND_TARGET }, - { "NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED }, - { "NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR }, - { "NT_STATUS_UNABLE_TO_DECOMMIT_VM", NT_STATUS_UNABLE_TO_DECOMMIT_VM }, - { "NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED }, - { "NT_STATUS_INVALID_PORT_ATTRIBUTES", NT_STATUS_INVALID_PORT_ATTRIBUTES }, - { "NT_STATUS_PORT_MESSAGE_TOO_LONG", NT_STATUS_PORT_MESSAGE_TOO_LONG }, - { "NT_STATUS_INVALID_PARAMETER_MIX", NT_STATUS_INVALID_PARAMETER_MIX }, - { "NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER }, - { "NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR }, - { "NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID }, - { "NT_STATUS_OBJECT_NAME_NOT_FOUND", NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { "NT_STATUS_OBJECT_NAME_COLLISION", NT_STATUS_OBJECT_NAME_COLLISION }, - { "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE }, - { "NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED }, - { "NT_STATUS_DEVICE_ALREADY_ATTACHED", NT_STATUS_DEVICE_ALREADY_ATTACHED }, - { "NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID }, - { "NT_STATUS_OBJECT_PATH_NOT_FOUND", NT_STATUS_OBJECT_PATH_NOT_FOUND }, - { "NT_STATUS_OBJECT_PATH_SYNTAX_BAD", NT_STATUS_OBJECT_PATH_SYNTAX_BAD }, - { "NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN }, - { "NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR }, - { "NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR }, - { "NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR }, - { "NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG }, - { "NT_STATUS_PORT_CONNECTION_REFUSED", NT_STATUS_PORT_CONNECTION_REFUSED }, - { "NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE }, - { "NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION }, - { "NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED }, - { "NT_STATUS_INVALID_PAGE_PROTECTION", NT_STATUS_INVALID_PAGE_PROTECTION }, - { "NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED }, - { "NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED }, - { "NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET }, - { "NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE }, - { "NT_STATUS_SUSPEND_COUNT_EXCEEDED", NT_STATUS_SUSPEND_COUNT_EXCEEDED }, - { "NT_STATUS_THREAD_IS_TERMINATING", NT_STATUS_THREAD_IS_TERMINATING }, - { "NT_STATUS_BAD_WORKING_SET_LIMIT", NT_STATUS_BAD_WORKING_SET_LIMIT }, - { "NT_STATUS_INCOMPATIBLE_FILE_MAP", NT_STATUS_INCOMPATIBLE_FILE_MAP }, - { "NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION }, - { "NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED }, - { "NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE }, - { "NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY }, - { "NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE }, - { "NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR }, - { "NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT }, - { "NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED }, - { "NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING }, - { "NT_STATUS_CTL_FILE_NOT_SUPPORTED", NT_STATUS_CTL_FILE_NOT_SUPPORTED }, - { "NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION }, - { "NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH }, - { "NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER }, - { "NT_STATUS_INVALID_PRIMARY_GROUP", NT_STATUS_INVALID_PRIMARY_GROUP }, - { "NT_STATUS_NO_IMPERSONATION_TOKEN", NT_STATUS_NO_IMPERSONATION_TOKEN }, - { "NT_STATUS_CANT_DISABLE_MANDATORY", NT_STATUS_CANT_DISABLE_MANDATORY }, - { "NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS }, - { "NT_STATUS_NO_SUCH_LOGON_SESSION", NT_STATUS_NO_SUCH_LOGON_SESSION }, - { "NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE }, - { "NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD }, - { "NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME }, - { "NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS }, - { "NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER }, - { "NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS }, - { "NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP }, - { "NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP }, - { "NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP }, - { "NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN }, - { "NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD }, - { "NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD }, - { "NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION }, - { "NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE }, - { "NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION }, - { "NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS }, - { "NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION }, - { "NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED }, - { "NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED }, - { "NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED }, - { "NT_STATUS_TOO_MANY_LUIDS_REQUESTED", NT_STATUS_TOO_MANY_LUIDS_REQUESTED }, - { "NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED }, - { "NT_STATUS_INVALID_SUB_AUTHORITY", NT_STATUS_INVALID_SUB_AUTHORITY }, - { "NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL }, - { "NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID }, - { "NT_STATUS_INVALID_SECURITY_DESCR", NT_STATUS_INVALID_SECURITY_DESCR }, - { "NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND }, - { "NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT }, - { "NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN }, - { "NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL }, - { "NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED }, - { "NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL }, - { "NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED }, - { "NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED }, - { "NT_STATUS_TOO_MANY_GUIDS_REQUESTED", NT_STATUS_TOO_MANY_GUIDS_REQUESTED }, - { "NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED }, - { "NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY }, - { "NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED }, - { "NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL }, - { "NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED }, - { "NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA }, - { "NT_STATUS_RESOURCE_DATA_NOT_FOUND", NT_STATUS_RESOURCE_DATA_NOT_FOUND }, - { "NT_STATUS_RESOURCE_TYPE_NOT_FOUND", NT_STATUS_RESOURCE_TYPE_NOT_FOUND }, - { "NT_STATUS_RESOURCE_NAME_NOT_FOUND", NT_STATUS_RESOURCE_NAME_NOT_FOUND }, - { "NT_STATUS_ARRAY_BOUNDS_EXCEEDED", NT_STATUS_ARRAY_BOUNDS_EXCEEDED }, - { "NT_STATUS_FLOAT_DENORMAL_OPERAND", NT_STATUS_FLOAT_DENORMAL_OPERAND }, - { "NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO }, - { "NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT }, - { "NT_STATUS_FLOAT_INVALID_OPERATION", NT_STATUS_FLOAT_INVALID_OPERATION }, - { "NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW }, - { "NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK }, - { "NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW }, - { "NT_STATUS_INTEGER_DIVIDE_BY_ZERO", NT_STATUS_INTEGER_DIVIDE_BY_ZERO }, - { "NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW }, - { "NT_STATUS_PRIVILEGED_INSTRUCTION", NT_STATUS_PRIVILEGED_INSTRUCTION }, - { "NT_STATUS_TOO_MANY_PAGING_FILES", NT_STATUS_TOO_MANY_PAGING_FILES }, - { "NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID }, - { "NT_STATUS_ALLOTTED_SPACE_EXCEEDED", NT_STATUS_ALLOTTED_SPACE_EXCEEDED }, - { "NT_STATUS_INSUFFICIENT_RESOURCES", NT_STATUS_INSUFFICIENT_RESOURCES }, - { "NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND }, - { "NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR }, - { "NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED }, - { "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE }, - { "NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE }, - { "NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED }, - { "NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA }, - { "NT_STATUS_MEDIA_WRITE_PROTECTED", NT_STATUS_MEDIA_WRITE_PROTECTED }, - { "NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY }, - { "NT_STATUS_INVALID_GROUP_ATTRIBUTES", NT_STATUS_INVALID_GROUP_ATTRIBUTES }, - { "NT_STATUS_BAD_IMPERSONATION_LEVEL", NT_STATUS_BAD_IMPERSONATION_LEVEL }, - { "NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS }, - { "NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS }, - { "NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE }, - { "NT_STATUS_BAD_MASTER_BOOT_RECORD", NT_STATUS_BAD_MASTER_BOOT_RECORD }, - { "NT_STATUS_INSTRUCTION_MISALIGNMENT", NT_STATUS_INSTRUCTION_MISALIGNMENT }, - { "NT_STATUS_INSTANCE_NOT_AVAILABLE", NT_STATUS_INSTANCE_NOT_AVAILABLE }, - { "NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE }, - { "NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE }, - { "NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY }, - { "NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION }, - { "NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED }, - { "NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING }, - { "NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED }, - { "NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING }, - { "NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE }, - { "NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT }, - { "NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED }, - { "NT_STATUS_PROFILING_NOT_STARTED", NT_STATUS_PROFILING_NOT_STARTED }, - { "NT_STATUS_PROFILING_NOT_STOPPED", NT_STATUS_PROFILING_NOT_STOPPED }, - { "NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET }, - { "NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY }, - { "NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED }, - { "NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING }, - { "NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME }, - { "NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH }, - { "NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY }, - { "NT_STATUS_DEVICE_DOES_NOT_EXIST", NT_STATUS_DEVICE_DOES_NOT_EXIST }, - { "NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS }, - { "NT_STATUS_ADAPTER_HARDWARE_ERROR", NT_STATUS_ADAPTER_HARDWARE_ERROR }, - { "NT_STATUS_INVALID_NETWORK_RESPONSE", NT_STATUS_INVALID_NETWORK_RESPONSE }, - { "NT_STATUS_UNEXPECTED_NETWORK_ERROR", NT_STATUS_UNEXPECTED_NETWORK_ERROR }, - { "NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER }, - { "NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL }, - { "NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE }, - { "NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED }, - { "NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED }, - { "NT_STATUS_NETWORK_ACCESS_DENIED", NT_STATUS_NETWORK_ACCESS_DENIED }, - { "NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE }, - { "NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME }, - { "NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES }, - { "NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS }, - { "NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED }, - { "NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED }, - { "NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED }, - { "NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT }, - { "NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT }, - { "NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE }, - { "NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED }, - { "NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", NT_STATUS_VIRTUAL_CIRCUIT_CLOSED }, - { "NT_STATUS_NO_SECURITY_ON_OBJECT", NT_STATUS_NO_SECURITY_ON_OBJECT }, - { "NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT }, - { "NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY }, - { "NT_STATUS_CANT_ACCESS_DOMAIN_INFO", NT_STATUS_CANT_ACCESS_DOMAIN_INFO }, - { "NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF }, - { "NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE }, - { "NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE }, - { "NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE }, - { "NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN }, - { "NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS }, - { "NT_STATUS_DOMAIN_LIMIT_EXCEEDED", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, - { "NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED }, - { "NT_STATUS_INVALID_OPLOCK_PROTOCOL", NT_STATUS_INVALID_OPLOCK_PROTOCOL }, - { "NT_STATUS_INTERNAL_DB_CORRUPTION", NT_STATUS_INTERNAL_DB_CORRUPTION }, - { "NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR }, - { "NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED }, - { "NT_STATUS_BAD_DESCRIPTOR_FORMAT", NT_STATUS_BAD_DESCRIPTOR_FORMAT }, - { "NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER }, - { "NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR }, - { "NT_STATUS_UNEXPECTED_MM_CREATE_ERR", NT_STATUS_UNEXPECTED_MM_CREATE_ERR }, - { "NT_STATUS_UNEXPECTED_MM_MAP_ERROR", NT_STATUS_UNEXPECTED_MM_MAP_ERROR }, - { "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", NT_STATUS_UNEXPECTED_MM_EXTEND_ERR }, - { "NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS }, - { "NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS }, - { "NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1 }, - { "NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2 }, - { "NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3 }, - { "NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4 }, - { "NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5 }, - { "NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6 }, - { "NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7 }, - { "NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8 }, - { "NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9 }, - { "NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10 }, - { "NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11 }, - { "NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12 }, - { "NT_STATUS_REDIRECTOR_NOT_STARTED", NT_STATUS_REDIRECTOR_NOT_STARTED }, - { "NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED }, - { "NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW }, - { "NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE }, - { "NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE }, - { "NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY }, - { "NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR }, - { "NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY }, - { "NT_STATUS_BAD_LOGON_SESSION_STATE", NT_STATUS_BAD_LOGON_SESSION_STATE }, - { "NT_STATUS_LOGON_SESSION_COLLISION", NT_STATUS_LOGON_SESSION_COLLISION }, - { "NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG }, - { "NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN }, - { "NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE }, - { "NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND }, - { "NT_STATUS_PROCESS_IS_TERMINATING", NT_STATUS_PROCESS_IS_TERMINATING }, - { "NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE }, - { "NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION }, - { "NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE }, - { "NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED }, - { "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT }, - { "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST }, - { "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED }, - { "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER }, - { "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND }, - { "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID }, - { "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE }, - { "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR }, - { "NT_STATUS_NO_LDT", NT_STATUS_NO_LDT }, - { "NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE }, - { "NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET }, - { "NT_STATUS_INVALID_LDT_DESCRIPTOR", NT_STATUS_INVALID_LDT_DESCRIPTOR }, - { "NT_STATUS_INVALID_IMAGE_NE_FORMAT", NT_STATUS_INVALID_IMAGE_NE_FORMAT }, - { "NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE }, - { "NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE }, - { "NT_STATUS_MAPPED_FILE_SIZE_ZERO", NT_STATUS_MAPPED_FILE_SIZE_ZERO }, - { "NT_STATUS_TOO_MANY_OPENED_FILES", NT_STATUS_TOO_MANY_OPENED_FILES }, - { "NT_STATUS_CANCELLED", NT_STATUS_CANCELLED }, - { "NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE }, - { "NT_STATUS_INVALID_COMPUTER_NAME", NT_STATUS_INVALID_COMPUTER_NAME }, - { "NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED }, - { "NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT }, - { "NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP }, - { "NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER }, - { "NT_STATUS_MEMBERS_PRIMARY_GROUP", NT_STATUS_MEMBERS_PRIMARY_GROUP }, - { "NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED }, - { "NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS }, - { "NT_STATUS_THREAD_NOT_IN_PROCESS", NT_STATUS_THREAD_NOT_IN_PROCESS }, - { "NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE }, - { "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", NT_STATUS_PAGEFILE_QUOTA_EXCEEDED }, - { "NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT }, - { "NT_STATUS_INVALID_IMAGE_LE_FORMAT", NT_STATUS_INVALID_IMAGE_LE_FORMAT }, - { "NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ }, - { "NT_STATUS_INVALID_IMAGE_PROTECT", NT_STATUS_INVALID_IMAGE_PROTECT }, - { "NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16 }, - { "NT_STATUS_LOGON_SERVER_CONFLICT", NT_STATUS_LOGON_SERVER_CONFLICT }, - { "NT_STATUS_TIME_DIFFERENCE_AT_DC", NT_STATUS_TIME_DIFFERENCE_AT_DC }, - { "NT_STATUS_SYNCHRONIZATION_REQUIRED", NT_STATUS_SYNCHRONIZATION_REQUIRED }, - { "NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND }, - { "NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED }, - { "NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED }, - { "NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND }, - { "NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND }, - { "NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT }, - { "NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT }, - { "NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT }, - { "NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES }, - { "NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED }, - { "NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT }, - { "NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION }, - { "NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS }, - { "NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED }, - { "NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE }, - { "NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION }, - { "NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE }, - { "NT_STATUS_PAGEFILE_CREATE_FAILED", NT_STATUS_PAGEFILE_CREATE_FAILED }, - { "NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE }, - { "NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL }, - { "NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE }, - { "NT_STATUS_ILLEGAL_FLOAT_CONTEXT", NT_STATUS_ILLEGAL_FLOAT_CONTEXT }, - { "NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN }, - { "NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT }, - { "NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED }, - { "NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR }, - { "NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME }, - { "NT_STATUS_SERIAL_NO_DEVICE_INITED", NT_STATUS_SERIAL_NO_DEVICE_INITED }, - { "NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS }, - { "NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS }, - { "NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS }, - { "NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS }, - { "NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED }, - { "NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS }, - { "NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG }, - { "NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR }, - { "NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE }, - { "NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS }, - { "NT_STATUS_LOGON_TYPE_NOT_GRANTED", NT_STATUS_LOGON_TYPE_NOT_GRANTED }, - { "NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE }, - { "NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED }, - { "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR }, - { "NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER }, - { "NT_STATUS_ILL_FORMED_SERVICE_ENTRY", NT_STATUS_ILL_FORMED_SERVICE_ENTRY }, - { "NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER }, - { "NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER }, - { "NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER }, - { "NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME }, - { "NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND }, - { "NT_STATUS_FLOPPY_WRONG_CYLINDER", NT_STATUS_FLOPPY_WRONG_CYLINDER }, - { "NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR }, - { "NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS }, - { "NT_STATUS_DISK_RECALIBRATE_FAILED", NT_STATUS_DISK_RECALIBRATE_FAILED }, - { "NT_STATUS_DISK_OPERATION_FAILED", NT_STATUS_DISK_OPERATION_FAILED }, - { "NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED }, - { "NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY }, - { "NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING }, - { "NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE }, - { "NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH }, - { "NT_STATUS_DEVICE_NOT_PARTITIONED", NT_STATUS_DEVICE_NOT_PARTITIONED }, - { "NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA }, - { "NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", NT_STATUS_UNABLE_TO_UNLOAD_MEDIA }, - { "NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW }, - { "NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA }, - { "NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER }, - { "NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER }, - { "NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED }, - { "NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE }, - { "NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS }, - { "NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, - { "NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN }, - { "NT_STATUS_CHILD_MUST_BE_VOLATILE", NT_STATUS_CHILD_MUST_BE_VOLATILE }, - { "NT_STATUS_DEVICE_CONFIGURATION_ERROR", NT_STATUS_DEVICE_CONFIGURATION_ERROR }, - { "NT_STATUS_DRIVER_INTERNAL_ERROR", NT_STATUS_DRIVER_INTERNAL_ERROR }, - { "NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE }, - { "NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR }, - { "NT_STATUS_DEVICE_PROTOCOL_ERROR", NT_STATUS_DEVICE_PROTOCOL_ERROR }, - { "NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER }, - { "NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL }, - { "NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE }, - { "NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET }, - { "NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, - { "NT_STATUS_TRUSTED_DOMAIN_FAILURE", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, - { "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, - { "NT_STATUS_EVENTLOG_FILE_CORRUPT", NT_STATUS_EVENTLOG_FILE_CORRUPT }, - { "NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START }, - { "NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE }, - { "NT_STATUS_MUTANT_LIMIT_EXCEEDED", NT_STATUS_MUTANT_LIMIT_EXCEEDED }, - { "NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED }, - { "NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED }, - { "NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK }, - { "NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, - { "NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT }, - { "NT_STATUS_EVENTLOG_FILE_CHANGED", NT_STATUS_EVENTLOG_FILE_CHANGED }, - { "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, - { "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, - { "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, - { "NT_STATUS_DOMAIN_TRUST_INCONSISTENT", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, - { "NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED }, - { "NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY }, - { "NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED }, - { "NT_STATUS_RESOURCE_LANG_NOT_FOUND", NT_STATUS_RESOURCE_LANG_NOT_FOUND }, - { "NT_STATUS_INSUFF_SERVER_RESOURCES", NT_STATUS_INSUFF_SERVER_RESOURCES }, - { "NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE }, - { "NT_STATUS_INVALID_ADDRESS_COMPONENT", NT_STATUS_INVALID_ADDRESS_COMPONENT }, - { "NT_STATUS_INVALID_ADDRESS_WILDCARD", NT_STATUS_INVALID_ADDRESS_WILDCARD }, - { "NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES }, - { "NT_STATUS_ADDRESS_ALREADY_EXISTS", NT_STATUS_ADDRESS_ALREADY_EXISTS }, - { "NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED }, - { "NT_STATUS_CONNECTION_DISCONNECTED", NT_STATUS_CONNECTION_DISCONNECTED }, - { "NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET }, - { "NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES }, - { "NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED }, - { "NT_STATUS_TRANSACTION_TIMED_OUT", NT_STATUS_TRANSACTION_TIMED_OUT }, - { "NT_STATUS_TRANSACTION_NO_RELEASE", NT_STATUS_TRANSACTION_NO_RELEASE }, - { "NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH }, - { "NT_STATUS_TRANSACTION_RESPONDED", NT_STATUS_TRANSACTION_RESPONDED }, - { "NT_STATUS_TRANSACTION_INVALID_ID", NT_STATUS_TRANSACTION_INVALID_ID }, - { "NT_STATUS_TRANSACTION_INVALID_TYPE", NT_STATUS_TRANSACTION_INVALID_TYPE }, - { "NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION }, - { "NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION }, - { "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", NT_STATUS_CANNOT_LOAD_REGISTRY_FILE }, - { "NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED }, - { "NT_STATUS_SYSTEM_PROCESS_TERMINATED", NT_STATUS_SYSTEM_PROCESS_TERMINATED }, - { "NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED }, - { "NT_STATUS_NO_BROWSER_SERVERS_FOUND", NT_STATUS_NO_BROWSER_SERVERS_FOUND }, - { "NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR }, - { "NT_STATUS_DRIVER_CANCEL_TIMEOUT", NT_STATUS_DRIVER_CANCEL_TIMEOUT }, - { "NT_STATUS_REPLY_MESSAGE_MISMATCH", NT_STATUS_REPLY_MESSAGE_MISMATCH }, - { "NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT }, - { "NT_STATUS_IMAGE_CHECKSUM_MISMATCH", NT_STATUS_IMAGE_CHECKSUM_MISMATCH }, - { "NT_STATUS_LOST_WRITEBEHIND_DATA", NT_STATUS_LOST_WRITEBEHIND_DATA }, - { "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID }, - { "NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE }, - { "NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND }, - { "NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM }, - { "NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE }, - { "NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ }, - { "NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK }, - { "NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID }, - { "NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS }, - { "NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE }, - { "NT_STATUS_RETRY", NT_STATUS_RETRY }, - { "NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE }, - { "NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET }, - { "NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND }, - { "NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW }, - { "NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT }, - { "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, - { "NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE }, - { "NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED }, - { "NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT }, - { "NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, - { "NT_STATUS_ADDRESS_NOT_ASSOCIATED", NT_STATUS_ADDRESS_NOT_ASSOCIATED }, - { "NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID }, - { "NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE }, - { "NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE }, - { "NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE }, - { "NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE }, - { "NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE }, - { "NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED }, - { "NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED }, - { "NT_STATUS_BAD_COMPRESSION_BUFFER", NT_STATUS_BAD_COMPRESSION_BUFFER }, - { "NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE }, - { "NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED }, - { "NT_STATUS_TIMER_RESOLUTION_NOT_SET", NT_STATUS_TIMER_RESOLUTION_NOT_SET }, - { "NT_STATUS_CONNECTION_COUNT_LIMIT", NT_STATUS_CONNECTION_COUNT_LIMIT }, - { "NT_STATUS_LOGIN_TIME_RESTRICTION", NT_STATUS_LOGIN_TIME_RESTRICTION }, - { "NT_STATUS_LOGIN_WKSTA_RESTRICTION", NT_STATUS_LOGIN_WKSTA_RESTRICTION }, - { "NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH }, - { "NT_STATUS_INSUFFICIENT_LOGON_INFO", NT_STATUS_INSUFFICIENT_LOGON_INFO }, - { "NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT }, - { "NT_STATUS_BAD_SERVICE_ENTRYPOINT", NT_STATUS_BAD_SERVICE_ENTRYPOINT }, - { "NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST }, - { "NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1 }, - { "NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2 }, - { "NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT }, - { "NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED }, - { "NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE }, - { "NT_STATUS_LICENSE_QUOTA_EXCEEDED", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, - { "NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT }, - { "NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT }, - { "NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT }, - { "NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE }, - { "NT_STATUS_UNSUPPORTED_COMPRESSION", NT_STATUS_UNSUPPORTED_COMPRESSION }, - { "NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE }, - { "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH }, - { "NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", NT_STATUS_DRIVER_ORDINAL_NOT_FOUND }, - { "NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND }, - { "NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED }, - { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, - { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, - { "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_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, - { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, - { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, - { "NT_STATUS_RPC_UNKNOWN_IF", NT_STATUS_RPC_UNKNOWN_IF }, - { "NT_STATUS_RPC_CALL_FAILED", NT_STATUS_RPC_CALL_FAILED }, - { "NT_STATUS_RPC_PROTOCOL_ERROR", NT_STATUS_RPC_PROTOCOL_ERROR }, - { "NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE", NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE }, - { "NT_STATUS_RPC_CANNOT_SUPPORT", NT_STATUS_RPC_CANNOT_SUPPORT }, - { "NT_STATUS_RPC_SEC_PKG_ERROR", NT_STATUS_RPC_SEC_PKG_ERROR }, - { "NT_STATUS_RPC_SS_CONTEXT_MISMATCH", NT_STATUS_RPC_SS_CONTEXT_MISMATCH }, - { "NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE", NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE }, - { "NT_STATUS_RPC_BAD_STUB_DATA", NT_STATUS_RPC_BAD_STUB_DATA }, - { "NT_STATUS_RPC_INVALID_PIPE_OBJECT", NT_STATUS_RPC_INVALID_PIPE_OBJECT }, - { "NT_STATUS_RPC_INVALID_PIPE_OPERATION", NT_STATUS_RPC_INVALID_PIPE_OPERATION }, - { "NT_STATUS_RPC_WRONG_PIPE_VERSION", NT_STATUS_RPC_WRONG_PIPE_VERSION }, - { "NT_STATUS_RPC_PIPE_CLOSED", NT_STATUS_RPC_PIPE_CLOSED }, - { "NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR", NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR }, - { "NT_STATUS_RPC_PIPE_EMPTY", NT_STATUS_RPC_PIPE_EMPTY }, - { "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED }, - { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, - { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, - { "NT_STATUS_INVALID_LOCK_RANGE", NT_STATUS_INVALID_LOCK_RANGE }, - { "NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS", NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS }, - { "NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION", NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION }, - { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, - { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, - { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP }, - { "STATUS_NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR }, - - { NULL, NT_STATUS(0) } -}; - -/* These need sorting..... */ - -static const nt_err_code_struct nt_err_desc[] = -{ - { N_("Success"), NT_STATUS_OK }, - { N_("Undetermined error"), NT_STATUS_UNSUCCESSFUL }, - { N_("Access denied"), NT_STATUS_ACCESS_DENIED }, - { N_("Account locked out"), NT_STATUS_ACCOUNT_LOCKED_OUT }, - { N_("Must change password"), NT_STATUS_PASSWORD_MUST_CHANGE }, - { N_("Password is too short"), NT_STATUS_PWD_TOO_SHORT }, - { N_("Password is too recent"), NT_STATUS_PWD_TOO_RECENT }, - { N_("Password history conflict"), NT_STATUS_PWD_HISTORY_CONFLICT }, - { N_("No logon servers"), NT_STATUS_NO_LOGON_SERVERS }, - { N_("Improperly formed account name"), NT_STATUS_INVALID_ACCOUNT_NAME }, - { N_("User exists"), NT_STATUS_USER_EXISTS }, - { N_("No such user"), NT_STATUS_NO_SUCH_USER }, - { N_("Group exists"), NT_STATUS_GROUP_EXISTS }, - { N_("No such group"), NT_STATUS_NO_SUCH_GROUP }, - { N_("Member not in group"), NT_STATUS_MEMBER_NOT_IN_GROUP }, - { N_("Wrong Password"), NT_STATUS_WRONG_PASSWORD }, - { N_("Ill formed password"), NT_STATUS_ILL_FORMED_PASSWORD }, - { N_("Password restriction"), NT_STATUS_PASSWORD_RESTRICTION }, - { N_("Logon failure"), NT_STATUS_LOGON_FAILURE }, - { N_("Account restriction"), NT_STATUS_ACCOUNT_RESTRICTION }, - { N_("Invalid logon hours"), NT_STATUS_INVALID_LOGON_HOURS }, - { N_("Invalid workstation"), NT_STATUS_INVALID_WORKSTATION }, - { N_("Password expired"), NT_STATUS_PASSWORD_EXPIRED }, - { N_("Account disabled"), NT_STATUS_ACCOUNT_DISABLED }, - { N_("Unexpected information received"), NT_STATUS_INVALID_PARAMETER }, - { N_("Memory allocation error"), NT_STATUS_NO_MEMORY }, - { N_("No domain controllers located"), NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, - { N_("Account locked out"), NT_STATUS_ACCOUNT_LOCKED_OUT }, - { N_("Named pipe not available"), NT_STATUS_PIPE_NOT_AVAILABLE }, - { N_("Not implemented"), NT_STATUS_NOT_IMPLEMENTED }, - { N_("Invalid information class"), NT_STATUS_INVALID_INFO_CLASS }, - { N_("Information length mismatch"), NT_STATUS_INFO_LENGTH_MISMATCH }, - { N_("Access violation"), NT_STATUS_ACCESS_VIOLATION }, - { N_("Invalid handle"), NT_STATUS_INVALID_HANDLE }, - { N_("Invalid parameter"), NT_STATUS_INVALID_PARAMETER }, - { N_("No memory"), NT_STATUS_NO_MEMORY }, - { N_("Buffer too small"), NT_STATUS_BUFFER_TOO_SMALL }, - { N_("Revision mismatch"), NT_STATUS_REVISION_MISMATCH }, - { N_("No logon servers"), NT_STATUS_NO_LOGON_SERVERS }, - { N_("No such logon session"), NT_STATUS_NO_SUCH_LOGON_SESSION }, - { N_("No such privilege"), NT_STATUS_NO_SUCH_PRIVILEGE }, - { N_("Procedure not found"), NT_STATUS_PROCEDURE_NOT_FOUND }, - { N_("Server disabled"), NT_STATUS_SERVER_DISABLED }, - { N_("Invalid pipe state"), NT_STATUS_INVALID_PIPE_STATE }, - { N_("Named pipe busy"), NT_STATUS_PIPE_BUSY }, - { N_("Illegal function"), NT_STATUS_ILLEGAL_FUNCTION }, - { N_("Named pipe disconnected"), NT_STATUS_PIPE_DISCONNECTED }, - { N_("Named pipe closing"), NT_STATUS_PIPE_CLOSING }, - { N_("Remote host not listening"), NT_STATUS_REMOTE_NOT_LISTENING }, - { N_("Duplicate name on network"), NT_STATUS_DUPLICATE_NAME }, - { N_("Print queue is full"), NT_STATUS_PRINT_QUEUE_FULL }, - { N_("No print spool space available"), NT_STATUS_NO_SPOOL_SPACE }, - { N_("The network name cannot be found"), NT_STATUS_BAD_NETWORK_NAME }, - { N_("The connection was refused"), NT_STATUS_CONNECTION_REFUSED }, - { N_("Too many names"), NT_STATUS_TOO_MANY_NAMES }, - { N_("Too many sessions"), NT_STATUS_TOO_MANY_SESSIONS }, - { N_("Invalid server state"), NT_STATUS_INVALID_SERVER_STATE }, - { N_("Invalid domain state"), NT_STATUS_INVALID_DOMAIN_STATE }, - { N_("Invalid domain role"), NT_STATUS_INVALID_DOMAIN_ROLE }, - { N_("No such domain"), NT_STATUS_NO_SUCH_DOMAIN }, - { N_("Domain exists"), NT_STATUS_DOMAIN_EXISTS }, - { N_("Domain limit exceeded"), NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, - { N_("Bad logon session state"), NT_STATUS_BAD_LOGON_SESSION_STATE }, - { N_("Logon session collision"), NT_STATUS_LOGON_SESSION_COLLISION }, - { N_("Invalid logon type"), NT_STATUS_INVALID_LOGON_TYPE }, - { N_("Cancelled"), NT_STATUS_CANCELLED }, - { N_("Invalid computer name"), NT_STATUS_INVALID_COMPUTER_NAME }, - { N_("Logon server conflict"), NT_STATUS_LOGON_SERVER_CONFLICT }, - { N_("Time difference at domain controller"), NT_STATUS_TIME_DIFFERENCE_AT_DC }, - { N_("Pipe broken"), NT_STATUS_PIPE_BROKEN }, - { N_("Registry corrupt"), NT_STATUS_REGISTRY_CORRUPT }, - { N_("Too many secrets"), NT_STATUS_TOO_MANY_SECRETS }, - { N_("Too many SIDs"), NT_STATUS_TOO_MANY_SIDS }, - { N_("Lanmanager cross encryption required"), NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, - { N_("Log file full"), NT_STATUS_LOG_FILE_FULL }, - { N_("No trusted LSA secret"), NT_STATUS_NO_TRUST_LSA_SECRET }, - { N_("No trusted SAM account"), NT_STATUS_NO_TRUST_SAM_ACCOUNT }, - { N_("Trusted domain failure"), NT_STATUS_TRUSTED_DOMAIN_FAILURE }, - { N_("Trust relationship failure"), NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, - { N_("Trust failure"), NT_STATUS_TRUST_FAILURE }, - { N_("Netlogon service not started"), NT_STATUS_NETLOGON_NOT_STARTED }, - { N_("Account expired"), NT_STATUS_ACCOUNT_EXPIRED }, - { N_("Network credential conflict"), NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, - { N_("Remote session limit"), NT_STATUS_REMOTE_SESSION_LIMIT }, - { N_("No logon interdomain trust account"), NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, - { N_("No logon workstation trust account"), NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, - { N_("No logon server trust account"), NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, - { N_("Domain trust inconsistent"), NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, - { N_("No user session key available"), NT_STATUS_NO_USER_SESSION_KEY }, - { N_("User session deleted"), NT_STATUS_USER_SESSION_DELETED }, - { N_("Insufficient server resources"), NT_STATUS_INSUFF_SERVER_RESOURCES }, - { N_("Insufficient logon information"), NT_STATUS_INSUFFICIENT_LOGON_INFO }, - - { N_("License quota exceeded"), NT_STATUS_LICENSE_QUOTA_EXCEEDED }, - { N_("No more files"), STATUS_NO_MORE_FILES }, - - { NULL, NT_STATUS(0) } -}; - -/***************************************************************************** - Returns an NT error message. not amazingly helpful, but better than a number. - *****************************************************************************/ - -const char *nt_errstr(NTSTATUS nt_code) -{ - int idx = 0; - char *result; - -#ifdef HAVE_LDAP - if (NT_STATUS_IS_LDAP(nt_code)) { - return ldap_err2string(NT_STATUS_LDAP_CODE(nt_code)); - } -#endif - - if (NT_STATUS_IS_DOS(nt_code)) { - return smb_dos_err_name(NT_STATUS_DOS_CLASS(nt_code), - NT_STATUS_DOS_CODE(nt_code)); - } - - while (nt_errs[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == - NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; - } - idx++; - } - - result = talloc_asprintf(talloc_tos(), "NT code 0x%08x", - NT_STATUS_V(nt_code)); - SMB_ASSERT(result != NULL); - return result; -} - -/************************************************************************ - Print friendler version fo NT error code - ***********************************************************************/ - -const char *get_friendly_nt_error_msg(NTSTATUS nt_code) -{ - int idx = 0; - - while (nt_err_desc[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { - return nt_err_desc[idx].nt_errstr; - } - idx++; - } - - /* fall back to NT_STATUS_XXX string */ - - return nt_errstr(nt_code); -} - -/***************************************************************************** - Returns an NT_STATUS constant as a string for inclusion in autogen C code. - *****************************************************************************/ - -const char *get_nt_error_c_code(NTSTATUS nt_code) -{ - char *result; - int idx = 0; - - while (nt_errs[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == - NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; - } - idx++; - } - - result = talloc_asprintf(talloc_tos(), "NT_STATUS(0x%08x)", - NT_STATUS_V(nt_code)); - SMB_ASSERT(result); - return result; -} - -/***************************************************************************** - Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) - *****************************************************************************/ - -NTSTATUS nt_status_string_to_code(const char *nt_status_str) -{ - int idx = 0; - - while (nt_errs[idx].nt_errstr != NULL) { - if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { - return nt_errs[idx].nt_errcode; - } - idx++; - } - return NT_STATUS_UNSUCCESSFUL; -} - -/** - * Squash an NT_STATUS in line with security requirements. - * In an attempt to avoid giving the whole game away when users - * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and - * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations - * (session setups in particular). - * - * @param nt_status NTSTATUS input for squashing. - * @return the 'squashed' nt_status - **/ - -NTSTATUS nt_status_squash(NTSTATUS nt_status) -{ - if NT_STATUS_IS_OK(nt_status) { - return nt_status; - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { - /* Match WinXP and don't give the game away */ - return NT_STATUS_LOGON_FAILURE; - - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { - /* Match WinXP and don't give the game away */ - return NT_STATUS_LOGON_FAILURE; - } else { - return nt_status; - } -} diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index d000ed59c0..fe2fb663ba 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -117,9 +117,9 @@ NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state, const uint8_t nt_hash[16]) { ntlmssp_state->lm_hash = (uint8_t *) - TALLOC_MEMDUP(ntlmssp_state, lm_hash, 16); + talloc_memdup(ntlmssp_state, lm_hash, 16); ntlmssp_state->nt_hash = (uint8_t *) - TALLOC_MEMDUP(ntlmssp_state, nt_hash, 16); + talloc_memdup(ntlmssp_state, nt_hash, 16); if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) { TALLOC_FREE(ntlmssp_state->lm_hash); TALLOC_FREE(ntlmssp_state->nt_hash); diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index d37389a485..bf2103db68 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. SMB client password change routine Copyright (C) Andrew Tridgell 1994-1998 - + 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/>. */ @@ -21,6 +21,7 @@ #include "../librpc/gen_ndr/ndr_samr.h" #include "rpc_client/cli_pipe.h" #include "rpc_client/cli_samr.h" +#include "libsmb/libsmb.h" #include "libsmb/clirap.h" #include "libsmb/nmblib.h" @@ -32,10 +33,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam const char *old_passwd, const char *new_passwd, char **err_str) { - struct nmb_name calling, called; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_hnd = NULL; - struct sockaddr_storage ss; char *user, *domain, *p; NTSTATUS result; @@ -56,41 +55,14 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam *err_str = NULL; - if(!resolve_name( remote_machine, &ss, 0x20, false)) { - if (asprintf(err_str, "Unable to find an IP address for machine " - "%s.\n", remote_machine) == -1) { - *err_str = NULL; - } - return NT_STATUS_UNSUCCESSFUL; - } - - cli = cli_initialise(); - if (!cli) { - return NT_STATUS_NO_MEMORY; - } - - result = cli_connect(cli, remote_machine, &ss); + result = cli_connect_nb(remote_machine, NULL, 0, 0x20, NULL, + Undefined, &cli); if (!NT_STATUS_IS_OK(result)) { if (asprintf(err_str, "Unable to connect to SMB server on " "machine %s. Error was : %s.\n", remote_machine, nt_errstr(result))==-1) { *err_str = NULL; } - cli_shutdown(cli); - return result; - } - - make_nmb_name(&calling, global_myname() , 0x0); - make_nmb_name(&called , remote_machine, 0x20); - - if (!cli_session_request(cli, &calling, &called)) { - if (asprintf(err_str, "machine %s rejected the session setup. " - "Error was : %s.\n", - remote_machine, cli_errstr(cli)) == -1) { - *err_str = NULL; - } - result = cli_nt_error(cli); - cli_shutdown(cli); return result; } @@ -125,7 +97,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { if (asprintf(err_str, "Could not connect to machine %s: " - "%s\n", remote_machine, cli_errstr(cli)) == -1) { + "%s\n", remote_machine, nt_errstr(result)) == -1) { *err_str = NULL; } cli_shutdown(cli); @@ -145,7 +117,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (!NT_STATUS_IS_OK(result)) { if (asprintf(err_str, "machine %s rejected the session " "setup. Error was : %s.\n", - remote_machine, cli_errstr(cli)) == -1) { + remote_machine, nt_errstr(result)) == -1) { *err_str = NULL; } cli_shutdown(cli); @@ -203,12 +175,12 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (lp_client_lanman_auth()) { /* Use the old RAP method. */ if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { + result = cli_nt_error(cli); if (asprintf(err_str, "machine %s rejected the " "password change: Error was : %s.\n", - remote_machine, cli_errstr(cli)) == -1) { + remote_machine, nt_errstr(result)) == -1) { *err_str = NULL; } - result = cli_nt_error(cli); cli_shutdown(cli); return result; } @@ -294,12 +266,13 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_shutdown(cli); return NT_STATUS_OK; } + + result = cli_nt_error(cli); if (asprintf(err_str, "machine %s rejected the password " "change: Error was : %s.\n", - remote_machine, cli_errstr(cli)) == -1) { + remote_machine, nt_errstr(result)) == -1) { *err_str = NULL; } - result = cli_nt_error(cli); cli_shutdown(cli); return result; } else { diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h new file mode 100644 index 0000000000..f88a891d58 --- /dev/null +++ b/source3/libsmb/proto.h @@ -0,0 +1,854 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Andrew Tridgell 1994-1998,2000-2001 + Copyright (C) Gerald (Jerry) Carter 2004 + Copyright (C) Jelmer Vernooij 2003 + Copyright (C) Jeremy Allison 2001-2009,2011 + Copyright (C) Stefan Metzmacher 2003,2009 + Copyright (C) Volker Lendecke 2011 + + 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/>. +*/ + +#ifndef _LIBSMB_PROTO_H_ +#define _LIBSMB_PROTO_H_ + +#include "ads.h" + +/* The following definitions come from libsmb/cliconnect.c */ + +ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, + const char *pass, const char *user_domain, + const char * dest_realm); + +NTSTATUS cli_session_setup(struct cli_state *cli, + const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup); +struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + struct tevent_req **psmbreq); +struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli); +NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req); +struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS cli_ulogoff_recv(struct tevent_req *req); +NTSTATUS cli_ulogoff(struct cli_state *cli); +struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *share, const char *dev, + const char *pass, int passlen, + struct tevent_req **psmbreq); +struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *share, const char *dev, + const char *pass, int passlen); +NTSTATUS cli_tcon_andx_recv(struct tevent_req *req); +NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share, + const char *dev, const char *pass, int passlen); +struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS cli_tdis_recv(struct tevent_req *req); +NTSTATUS cli_tdis(struct cli_state *cli); +NTSTATUS cli_negprot(struct cli_state *cli); +struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli); +NTSTATUS cli_negprot_recv(struct tevent_req *req); +NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss, + uint16_t port, int name_type, const char *myname, + int signing_state, struct cli_state **pcli); +NTSTATUS cli_start_connection(struct cli_state **output_cli, + const char *my_name, + const char *dest_host, + struct sockaddr_storage *dest_ss, int port, + int signing_state, int flags); +NTSTATUS cli_full_connection(struct cli_state **output_cli, + const char *my_name, + const char *dest_host, + struct sockaddr_storage *dest_ss, int port, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password, int flags, + int signing_state); +NTSTATUS cli_raw_tcon(struct cli_state *cli, + const char *service, const char *pass, const char *dev, + uint16 *max_xmit, uint16 *tid); +struct cli_state *get_ipc_connect(char *server, + struct sockaddr_storage *server_ss, + const struct user_auth_info *user_info); +struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, + struct sockaddr_storage *mb_ip, + const struct user_auth_info *user_info, + char **pp_workgroup_out); +struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx, + const struct user_auth_info *user_info, + char **pp_workgroup_out); + +/* The following definitions come from libsmb/clidfs.c */ + +NTSTATUS cli_cm_force_encryption(struct cli_state *c, + const char *username, + const char *password, + const char *domain, + const char *sharename); +struct cli_state *cli_cm_open(TALLOC_CTX *ctx, + struct cli_state *referring_cli, + const char *server, + const char *share, + const struct user_auth_info *auth_info, + bool show_hdr, + bool force_encrypt, + int max_protocol, + int port, + int name_type); +void cli_cm_display(const struct cli_state *c); +struct client_dfs_referral; +NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx, + struct cli_state *cli, + const char *path, + struct client_dfs_referral **refs, + size_t *num_refs, + size_t *consumed); +bool cli_resolve_path(TALLOC_CTX *ctx, + const char *mountpt, + const struct user_auth_info *dfs_auth_info, + struct cli_state *rootcli, + const char *path, + struct cli_state **targetcli, + char **pp_targetpath); + +bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, + struct cli_state *cli, + const char *sharename, + char **pp_newserver, + char **pp_newshare, + bool force_encrypt, + const char *username, + const char *password, + const char *domain); + +/* The following definitions come from libsmb/clientgen.c */ + +int cli_set_message(char *buf,int num_words,int num_bytes,bool zero); +unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout); +void cli_set_port(struct cli_state *cli, int port); +void cli_setup_packet_buf(struct cli_state *cli, char *buf); +NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain); +NTSTATUS cli_set_username(struct cli_state *cli, const char *username); +NTSTATUS cli_set_password(struct cli_state *cli, const char *password); +NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password); +struct cli_state *cli_initialise(void); +struct cli_state *cli_initialise_ex(int signing_state); +void cli_nt_pipes_close(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); +void cli_sockopt(struct cli_state *cli, const char *options); +uint16 cli_setpid(struct cli_state *cli, uint16 pid); +bool cli_set_case_sensitive(struct cli_state *cli, bool case_sensitive); +struct tevent_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, uint16_t num_echos, + DATA_BLOB data); +NTSTATUS cli_echo_recv(struct tevent_req *req); +NTSTATUS cli_echo(struct cli_state *cli, uint16_t num_echos, DATA_BLOB data); +bool cli_ucs2(struct cli_state *cli); +bool is_andx_req(uint8_t cmd); +NTSTATUS cli_smb(TALLOC_CTX *mem_ctx, struct cli_state *cli, + uint8_t smb_command, uint8_t additional_flags, + uint8_t wct, uint16_t *vwv, + uint32_t num_bytes, const uint8_t *bytes, + struct tevent_req **result_parent, + uint8_t min_wct, uint8_t *pwct, uint16_t **pvwv, + uint32_t *pnum_bytes, uint8_t **pbytes); + +/* The following definitions come from libsmb/clierror.c */ + +const char *cli_errstr(struct cli_state *cli); +NTSTATUS cli_nt_error(struct cli_state *cli); +void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode); +int cli_errno(struct cli_state *cli); +bool cli_is_error(struct cli_state *cli); +bool cli_is_nt_error(struct cli_state *cli); +bool cli_is_dos_error(struct cli_state *cli); +bool cli_state_is_connected(struct cli_state *cli); + +/* The following definitions come from libsmb/clifile.c */ + +struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t level, + const char *path, + uint8_t *data, + size_t data_len); +NTSTATUS cli_setpathinfo_recv(struct tevent_req *req); +NTSTATUS cli_setpathinfo(struct cli_state *cli, + uint16_t level, + const char *path, + uint8_t *data, + size_t data_len); + +struct tevent_req *cli_posix_symlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname); +NTSTATUS cli_posix_symlink_recv(struct tevent_req *req); +NTSTATUS cli_posix_symlink(struct cli_state *cli, + const char *oldname, + const char *newname); +struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + size_t len); +NTSTATUS cli_posix_readlink_recv(struct tevent_req *req, struct cli_state *cli, + char *retpath, size_t len); +NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname, + char *linkpath, size_t len); +struct tevent_req *cli_posix_hardlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *oldname, + const char *newname); +NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req); +NTSTATUS cli_posix_hardlink(struct cli_state *cli, + const char *oldname, + const char *newname); +uint32_t unix_perms_to_wire(mode_t perms); +mode_t wire_perms_to_unix(uint32_t perms); +struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf); +NTSTATUS cli_posix_getfacl(struct cli_state *cli, + const char *fname, + TALLOC_CTX *mem_ctx, + size_t *prb_size, + char **retbuf); +struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_posix_stat_recv(struct tevent_req *req, + SMB_STRUCT_STAT *sbuf); +NTSTATUS cli_posix_stat(struct cli_state *cli, + const char *fname, + SMB_STRUCT_STAT *sbuf); +struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + mode_t mode); +NTSTATUS cli_posix_chmod_recv(struct tevent_req *req); +NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode); +struct tevent_req *cli_posix_chown_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uid_t uid, + gid_t gid); +NTSTATUS cli_posix_chown_recv(struct tevent_req *req); +NTSTATUS cli_posix_chown(struct cli_state *cli, + const char *fname, + uid_t uid, + gid_t gid); +struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname_src, + const char *fname_dst); +NTSTATUS cli_rename_recv(struct tevent_req *req); +NTSTATUS cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst); +struct tevent_req *cli_ntrename_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname_src, + const char *fname_dst); +NTSTATUS cli_ntrename_recv(struct tevent_req *req); +NTSTATUS cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst); + +struct tevent_req *cli_nt_hardlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname_src, + const char *fname_dst); +NTSTATUS cli_nt_hardlink_recv(struct tevent_req *req); +NTSTATUS cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst); + +struct tevent_req *cli_unlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint16_t mayhave_attrs); +NTSTATUS cli_unlink_recv(struct tevent_req *req); +NTSTATUS cli_unlink(struct cli_state *cli, const char *fname, uint16_t mayhave_attrs); + +struct tevent_req *cli_mkdir_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *dname); +NTSTATUS cli_mkdir_recv(struct tevent_req *req); +NTSTATUS cli_mkdir(struct cli_state *cli, const char *dname); +struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *dname); +NTSTATUS cli_rmdir_recv(struct tevent_req *req); +NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname); +struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + bool flag); +NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req); +NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag); +struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags); +NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *pfnum); +NTSTATUS cli_ntcreate(struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + uint16_t *pfid); +uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str, + size_t str_len, size_t *pconverted_size); +uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, + const uint8_t *bytes, size_t num_bytes); +struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, const char *fname, + int flags, int share_mode, + struct tevent_req **psmbreq); +struct tevent_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, const char *fname, + int flags, int share_mode); +NTSTATUS cli_open_recv(struct tevent_req *req, uint16_t *fnum); +NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode, uint16_t *pfnum); +struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum, + struct tevent_req **psubreq); +struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum); +NTSTATUS cli_close_recv(struct tevent_req *req); +NTSTATUS cli_close(struct cli_state *cli, uint16_t fnum); +struct tevent_req *cli_ftruncate_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t size); +NTSTATUS cli_ftruncate_recv(struct tevent_req *req); +NTSTATUS cli_ftruncate(struct cli_state *cli, uint16_t fnum, uint64_t size); +NTSTATUS cli_locktype(struct cli_state *cli, uint16_t fnum, + uint32_t offset, uint32_t len, + int timeout, unsigned char locktype); +bool cli_lock(struct cli_state *cli, uint16_t fnum, + uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type); +struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_unlock_recv(struct tevent_req *req); +NTSTATUS cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len); +bool cli_lock64(struct cli_state *cli, uint16_t fnum, + uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type); +struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_unlock64_recv(struct tevent_req *req); +NTSTATUS cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); +struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len, + bool wait_lock, + enum brl_type lock_type); +NTSTATUS cli_posix_lock_recv(struct tevent_req *req); +NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum, + uint64_t offset, uint64_t len, + bool wait_lock, enum brl_type lock_type); +struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len); +NTSTATUS cli_posix_unlock_recv(struct tevent_req *req); +NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len); +struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum); +NTSTATUS cli_getattrE_recv(struct tevent_req *req, + uint16_t *attr, + SMB_OFF_T *size, + time_t *change_time, + time_t *access_time, + time_t *write_time); +NTSTATUS cli_getattrE(struct cli_state *cli, + uint16_t fnum, + uint16_t *attr, + SMB_OFF_T *size, + time_t *change_time, + time_t *access_time, + time_t *write_time); +struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + time_t change_time, + time_t access_time, + time_t write_time); +NTSTATUS cli_setattrE_recv(struct tevent_req *req); +NTSTATUS cli_setattrE(struct cli_state *cli, + uint16_t fnum, + time_t change_time, + time_t access_time, + time_t write_time); +struct tevent_req *cli_getatr_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_getatr_recv(struct tevent_req *req, + uint16_t *attr, + SMB_OFF_T *size, + time_t *write_time); +NTSTATUS cli_getatr(struct cli_state *cli, + const char *fname, + uint16_t *attr, + SMB_OFF_T *size, + time_t *write_time); +struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint16_t attr, + time_t mtime); +NTSTATUS cli_setatr_recv(struct tevent_req *req); +NTSTATUS cli_setatr(struct cli_state *cli, + const char *fname, + uint16_t attr, + time_t mtime); +struct tevent_req *cli_chkpath_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_chkpath_recv(struct tevent_req *req); +NTSTATUS cli_chkpath(struct cli_state *cli, const char *path); +struct tevent_req *cli_dskattr_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli); +NTSTATUS cli_dskattr_recv(struct tevent_req *req, int *bsize, int *total, + int *avail); +NTSTATUS cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +struct tevent_req *cli_ctemp_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *path); +NTSTATUS cli_ctemp_recv(struct tevent_req *req, + TALLOC_CTX *ctx, + uint16_t *pfnum, + char **outfile); +NTSTATUS cli_ctemp(struct cli_state *cli, + TALLOC_CTX *ctx, + const char *path, + uint16_t *pfnum, + char **out_path); +NTSTATUS cli_raw_ioctl(struct cli_state *cli, uint16_t fnum, uint32_t code, DATA_BLOB *blob); +NTSTATUS cli_set_ea_path(struct cli_state *cli, const char *path, + const char *ea_name, const char *ea_val, + size_t ea_len); +NTSTATUS cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, + const char *ea_name, const char *ea_val, + size_t ea_len); +struct tevent_req *cli_get_ea_list_path_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + size_t *pnum_eas, struct ea_struct **peas); +NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path, + TALLOC_CTX *ctx, + size_t *pnum_eas, + struct ea_struct **pea_list); +struct tevent_req *cli_posix_open_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + int flags, + mode_t mode); +NTSTATUS cli_posix_open_recv(struct tevent_req *req, uint16_t *pfnum); +NTSTATUS cli_posix_open(struct cli_state *cli, const char *fname, + int flags, mode_t mode, uint16_t *fnum); +struct tevent_req *cli_posix_mkdir_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + mode_t mode); +NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req); +NTSTATUS cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode); + +struct tevent_req *cli_posix_unlink_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_posix_unlink_recv(struct tevent_req *req); +NTSTATUS cli_posix_unlink(struct cli_state *cli, const char *fname); + +struct tevent_req *cli_posix_rmdir_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_posix_rmdir_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx); +NTSTATUS cli_posix_rmdir(struct cli_state *cli, const char *fname); +struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, uint16_t fnum, + uint32_t buffer_size, + uint32_t completion_filter, bool recursive); +NTSTATUS cli_notify_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint32_t *pnum_changes, + struct notify_change **pchanges); + +struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas); +NTSTATUS cli_nttrans_create_recv(struct tevent_req *req, uint16_t *fnum); +NTSTATUS cli_nttrans_create(struct cli_state *cli, + const char *fname, + uint32_t CreatFlags, + uint32_t DesiredAccess, + uint32_t FileAttributes, + uint32_t ShareAccess, + uint32_t CreateDisposition, + uint32_t CreateOptions, + uint8_t SecurityFlags, + struct security_descriptor *secdesc, + struct ea_struct *eas, + int num_eas, + uint16_t *pfid); + +/* The following definitions come from libsmb/clifsinfo.c */ + +struct tevent_req *cli_unix_extensions_version_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req, + uint16_t *pmajor, uint16_t *pminor, + uint32_t *pcaplow, + uint32_t *pcaphigh); +NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, + uint16 *pminor, uint32 *pcaplow, + uint32 *pcaphigh); +struct tevent_req *cli_set_unix_extensions_capabilities_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, + uint16_t major, uint16_t minor, uint32_t caplow, uint32_t caphigh); +NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req); +NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, + uint16 major, uint16 minor, + uint32 caplow, uint32 caphigh); +struct tevent_req *cli_get_fs_attr_info_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli); +NTSTATUS cli_get_fs_attr_info_recv(struct tevent_req *req, uint32_t *fs_attr); +NTSTATUS cli_get_fs_attr_info(struct cli_state *cli, uint32_t *fs_attr); +NTSTATUS cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, + uint32 *pserial_number, time_t *pdate); +NTSTATUS cli_get_fs_full_size_info(struct cli_state *cli, + uint64_t *total_allocation_units, + uint64_t *caller_allocation_units, + uint64_t *actual_allocation_units, + uint64_t *sectors_per_allocation_unit, + uint64_t *bytes_per_sector); +NTSTATUS cli_get_posix_fs_info(struct cli_state *cli, + uint32 *optimal_transfer_size, + uint32 *block_size, + uint64_t *total_blocks, + uint64_t *blocks_available, + uint64_t *user_blocks_available, + uint64_t *total_file_nodes, + uint64_t *free_file_nodes, + uint64_t *fs_identifier); +NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, + const char *user, + const char *pass, + const char *domain); +NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli); +NTSTATUS cli_force_encryption(struct cli_state *c, + const char *username, + const char *password, + const char *domain); + +/* The following definitions come from libsmb/clilist.c */ + +NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, + NTSTATUS (*fn)(const char *, struct file_info *, + const char *, void *), void *state); +NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask, + uint16_t attribute, int info_level, + NTSTATUS (*fn)(const char *mnt, struct file_info *finfo, + const char *mask, void *private_data), + void *private_data); +struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *mask, + uint16_t attribute, + uint16_t info_level); +NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct file_info **finfo, size_t *num_finfo); +NTSTATUS cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + NTSTATUS (*fn)(const char *, struct file_info *, const char *, + void *), void *state); + +/* The following definitions come from libsmb/climessage.c */ + +struct tevent_req *cli_message_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *host, const char *username, + const char *message); +NTSTATUS cli_message_recv(struct tevent_req *req); +NTSTATUS cli_message(struct cli_state *cli, const char *host, + const char *username, const char *message); + +/* The following definitions come from libsmb/clioplock.c */ + +struct tevent_req *cli_oplock_ack_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + uint16_t fnum, uint8_t level); +NTSTATUS cli_oplock_ack_recv(struct tevent_req *req); +NTSTATUS cli_oplock_ack(struct cli_state *cli, uint16_t fnum, unsigned char level); +void cli_oplock_handler(struct cli_state *cli, + NTSTATUS (*handler)(struct cli_state *, uint16_t, unsigned char)); + +/* The following definitions come from libsmb/cliprint.c */ + +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)); +int cli_printjob_del(struct cli_state *cli, int job); + +/* The following definitions come from libsmb/cliquota.c */ + +NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum); +void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list); +NTSTATUS cli_get_user_quota(struct cli_state *cli, int quota_fnum, + SMB_NTQUOTA_STRUCT *pqt); +NTSTATUS cli_set_user_quota(struct cli_state *cli, int quota_fnum, + SMB_NTQUOTA_STRUCT *pqt); +NTSTATUS cli_list_user_quota(struct cli_state *cli, int quota_fnum, + SMB_NTQUOTA_LIST **pqt_list); +NTSTATUS cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, + SMB_NTQUOTA_STRUCT *pqt); +NTSTATUS cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, + SMB_NTQUOTA_STRUCT *pqt); + +/* The following definitions come from libsmb/clireadwrite.c */ + +struct tevent_req *cli_read_andx_create(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum, + off_t offset, size_t size, + struct tevent_req **psmbreq); +struct tevent_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum, + off_t offset, size_t size); +NTSTATUS cli_read_andx_recv(struct tevent_req *req, ssize_t *received, + uint8_t **rcvbuf); +struct tevent_req *cli_pull_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, off_t start_offset, + SMB_OFF_T size, size_t window_size, + NTSTATUS (*sink)(char *buf, size_t n, + void *priv), + void *priv); +NTSTATUS cli_pull_recv(struct tevent_req *req, SMB_OFF_T *received); +NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, + off_t start_offset, SMB_OFF_T size, size_t window_size, + NTSTATUS (*sink)(char *buf, size_t n, void *priv), + void *priv, SMB_OFF_T *received); +ssize_t cli_read(struct cli_state *cli, uint16_t fnum, char *buf, + off_t offset, size_t size); +NTSTATUS cli_smbwrite(struct cli_state *cli, uint16_t fnum, char *buf, + off_t offset, size_t size1, size_t *ptotal); +struct tevent_req *cli_write_andx_create(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum, + uint16_t mode, const uint8_t *buf, + off_t offset, size_t size, + struct tevent_req **reqs_before, + int num_reqs_before, + struct tevent_req **psmbreq); +struct tevent_req *cli_write_andx_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum, + uint16_t mode, const uint8_t *buf, + off_t offset, size_t size); +NTSTATUS cli_write_andx_recv(struct tevent_req *req, size_t *pwritten); + +NTSTATUS cli_writeall(struct cli_state *cli, uint16_t fnum, uint16_t mode, + const uint8_t *buf, off_t offset, size_t size, + size_t *pwritten); + +struct tevent_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, uint16_t mode, + off_t start_offset, size_t window_size, + size_t (*source)(uint8_t *buf, size_t n, + void *priv), + void *priv); +NTSTATUS cli_push_recv(struct tevent_req *req); +NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode, + off_t start_offset, size_t window_size, + size_t (*source)(uint8_t *buf, size_t n, void *priv), + void *priv); + +/* The following definitions come from libsmb/clisecdesc.c */ + +struct security_descriptor *cli_query_secdesc(struct cli_state *cli, uint16_t fnum, + TALLOC_CTX *mem_ctx); +NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, + struct security_descriptor *sd); + +/* The following definitions come from libsmb/clistr.c */ + +size_t clistr_push_fn(struct cli_state *cli, + void *dest, + const char *src, + int dest_len, + int flags); +size_t clistr_pull_fn(const char *inbuf, + char *dest, + const void *src, + int dest_len, + int src_len, + int flags); +size_t clistr_pull_talloc(TALLOC_CTX *ctx, + const char *base, + uint16_t flags2, + char **pp_dest, + const void *src, + int src_len, + int flags); + +/* The following definitions come from libsmb/clitrans.c */ + +struct tevent_req *cli_trans_send( + TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, uint8_t cmd, + const char *pipe_name, uint16_t fid, uint16_t function, int flags, + uint16_t *setup, uint8_t num_setup, uint8_t max_setup, + uint8_t *param, uint32_t num_param, uint32_t max_param, + uint8_t *data, uint32_t num_data, uint32_t max_data); +NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint16_t *recv_flags2, + uint16_t **setup, uint8_t min_setup, + uint8_t *num_setup, + uint8_t **param, uint32_t min_param, + uint32_t *num_param, + uint8_t **data, uint32_t min_data, + uint32_t *num_data); +NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, + uint8_t trans_cmd, + const char *pipe_name, uint16_t fid, uint16_t function, + int flags, + uint16_t *setup, uint8_t num_setup, uint8_t max_setup, + uint8_t *param, uint32_t num_param, uint32_t max_param, + uint8_t *data, uint32_t num_data, uint32_t max_data, + uint16_t *recv_flags2, + uint16_t **rsetup, uint8_t min_rsetup, uint8_t *num_rsetup, + uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam, + uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata); + +/* The following definitions come from libsmb/smb_seal.c */ + +NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num); +bool common_encryption_on(struct smb_trans_enc_state *es); +NTSTATUS common_ntlm_decrypt_buffer(struct ntlmssp_state *ntlmssp_state, char *buf); +NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out); +NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out); +NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf); +void common_free_encryption_state(struct smb_trans_enc_state **pp_es); +void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf); +bool cli_encryption_on(struct cli_state *cli); +void cli_free_encryption_context(struct cli_state *cli); +void cli_free_enc_buffer(struct cli_state *cli, char *buf); + +/* The following definitions come from libsmb/clisigning.c */ + +bool cli_simple_set_signing(struct cli_state *cli, + const DATA_BLOB user_session_key, + const DATA_BLOB response); +bool cli_temp_set_signing(struct cli_state *cli); +void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum); +bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum); +bool client_is_signing_on(struct cli_state *cli); +bool client_is_signing_allowed(struct cli_state *cli); +bool client_is_signing_mandatory(struct cli_state *cli); +void cli_set_signing_negotiated(struct cli_state *cli); + +#endif /* _LIBSMB_PROTO_H_ */ diff --git a/source3/libsmb/read_smb.c b/source3/libsmb/read_smb.c new file mode 100644 index 0000000000..f530633c9f --- /dev/null +++ b/source3/libsmb/read_smb.c @@ -0,0 +1,134 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async SMB client requests + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "lib/async_req/async_sock.h" +#include "read_smb.h" +#include "lib/util/tevent_unix.h" + +/* + * Read an smb packet asynchronously, discard keepalives + */ + +struct read_smb_state { + struct tevent_context *ev; + int fd; + uint8_t *buf; +}; + +static ssize_t read_smb_more(uint8_t *buf, size_t buflen, void *private_data); +static void read_smb_done(struct tevent_req *subreq); + +struct tevent_req *read_smb_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd) +{ + struct tevent_req *result, *subreq; + struct read_smb_state *state; + + result = tevent_req_create(mem_ctx, &state, struct read_smb_state); + if (result == NULL) { + return NULL; + } + state->ev = ev; + state->fd = fd; + + subreq = read_packet_send(state, ev, fd, 4, read_smb_more, NULL); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, read_smb_done, result); + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static ssize_t read_smb_more(uint8_t *buf, size_t buflen, void *private_data) +{ + if (buflen > 4) { + return 0; /* We've been here, we're done */ + } + return smb_len_large(buf); +} + +static void read_smb_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct read_smb_state *state = tevent_req_data( + req, struct read_smb_state); + ssize_t len; + int err; + + len = read_packet_recv(subreq, state, &state->buf, &err); + TALLOC_FREE(subreq); + if (len == -1) { + tevent_req_error(req, err); + return; + } + + if (CVAL(state->buf, 0) == SMBkeepalive) { + subreq = read_packet_send(state, state->ev, state->fd, 4, + read_smb_more, NULL); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, read_smb_done, req); + return; + } + tevent_req_done(req); +} + +ssize_t read_smb_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno) +{ + struct read_smb_state *state = tevent_req_data( + req, struct read_smb_state); + + if (tevent_req_is_unix_error(req, perrno)) { + return -1; + } + *pbuf = talloc_move(mem_ctx, &state->buf); + return talloc_get_size(*pbuf); +} + +ssize_t read_smb(int fd, TALLOC_CTX *mem_ctx, uint8_t **pbuf, int *perrno) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + ssize_t ret = -1; + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = read_smb_send(frame, ev, fd); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll(req, ev)) { + goto fail; + } + ret = read_smb_recv(req, mem_ctx, pbuf, perrno); + fail: + TALLOC_FREE(frame); + return ret; +} diff --git a/source3/libsmb/read_smb.h b/source3/libsmb/read_smb.h new file mode 100644 index 0000000000..b0846c1ec3 --- /dev/null +++ b/source3/libsmb/read_smb.h @@ -0,0 +1,34 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async SMB client requests + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __LIBSMB_READ_SMB_H +#define __LIBSMB_READ_SMB_H + +#include "lib/talloc/talloc.h" +#include "lib/tevent/tevent.h" + +struct tevent_req *read_smb_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd); + +ssize_t read_smb_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + uint8_t **pbuf, int *perrno); +ssize_t read_smb(int fd, TALLOC_CTX *mem_ctx, uint8_t **pbuf, int *perrno); + +#endif diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index facdbc7dc1..618a570c4e 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -25,6 +25,7 @@ #include "system/filesys.h" #include "librpc/gen_ndr/ndr_krb5pac.h" #include "../libcli/security/security.h" +#include "util_tdb.h" #define NETSAMLOGON_TDB "netsamlogon_cache.tdb" @@ -70,16 +71,9 @@ clear: } first_try = false; - DEBUG(0,("retry after CLEAR_IF_FIRST for '%s'\n", path)); - tdb = tdb_open_log(path, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, - O_RDWR | O_CREAT, 0600); - if (tdb) { - tdb_close(tdb); - goto again; - } - DEBUG(0,("tdb_open_log(%s) with CLEAR_IF_FIRST - failed\n", path)); - - return false; + DEBUG(0,("retry after truncate for '%s'\n", path)); + truncate(path, 0); + goto again; } @@ -155,7 +149,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) /* Prepare data */ - if (!(mem_ctx = TALLOC_P( NULL, int))) { + if (!(mem_ctx = talloc( NULL, int))) { DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n")); return false; } @@ -185,7 +179,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) data.dsize = blob.length; data.dptr = blob.data; - if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) { + if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) == 0) { result = true; } @@ -223,7 +217,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct do return NULL; } - info3 = TALLOC_ZERO_P(mem_ctx, struct netr_SamInfo3); + info3 = talloc_zero(mem_ctx, struct netr_SamInfo3); if (!info3) { goto done; } diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 0eed15d4a3..73786ac54a 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -20,6 +20,7 @@ #include "includes.h" #include "../libcli/auth/ntlmssp.h" #include "smb_crypt.h" +#include "libsmb/libsmb.h" /****************************************************************************** Pull out the encryption context for this packet. 0 means global context. @@ -464,46 +465,3 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) */ common_free_enc_buffer(cli->trans_enc_state, buf); } - -/****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS cli_decrypt_message(struct cli_state *cli) -{ - NTSTATUS status; - uint16 enc_ctx_num; - - /* Ignore non-session messages. */ - if(CVAL(cli->inbuf,0)) { - return NT_STATUS_OK; - } - - status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { - return NT_STATUS_INVALID_HANDLE; - } - - return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); -} - -/****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out) -{ - /* Ignore non-session messages. */ - if (CVAL(buf,0)) { - return NT_STATUS_OK; - } - - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - return common_encrypt_buffer(cli->trans_enc_state, buf, buf_out); -} diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 1a6c2123ed..7c0a6d2a4e 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -27,6 +27,8 @@ #include "includes.h" #include "system/filesys.h" #include "smb_share_modes.h" +#include "tdb_compat.h" +#include <ccan/hash/hash.h> /* Database context handle. */ struct smbdb_ctx { @@ -67,10 +69,12 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) memset(smb_db, '\0', sizeof(struct smbdb_ctx)); - smb_db->smb_tdb = tdb_open(db_path, - 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, - O_RDWR|O_CREAT, - 0644); + /* FIXME: We should *never* open a tdb without logging! */ + smb_db->smb_tdb = tdb_open_compat(db_path, + 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, + O_RDWR|O_CREAT, + 0644, + NULL, NULL); if (!smb_db->smb_tdb) { free(smb_db); @@ -120,7 +124,7 @@ int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx, { struct locking_key lk; return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino, - extid)); + extid)) == 0 ? 0 : -1; } int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, @@ -129,8 +133,9 @@ int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t extid) { struct locking_key lk; - return tdb_chainunlock(db_ctx->smb_tdb, - get_locking_key(&lk, dev, ino, extid)); + tdb_chainunlock(db_ctx->smb_tdb, + get_locking_key(&lk, dev, ino, extid)); + return 0; } /* @@ -199,8 +204,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, *pp_list = NULL; *p_delete_on_close = 0; - db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino, - extid)); + db_data = tdb_fetch_compat(db_ctx->smb_tdb, + get_locking_key(&lk, dev, ino, extid)); if (!db_data.dptr) { return 0; } @@ -266,7 +271,6 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, static uint32_t smb_name_hash(const char *sharepath, const char *filename, int *err) { - TDB_DATA key; char *fullpath = NULL; size_t sharepath_size = strlen(sharepath); size_t filename_size = strlen(filename); @@ -282,9 +286,7 @@ static uint32_t smb_name_hash(const char *sharepath, const char *filename, int * fullpath[sharepath_size] = '/'; memcpy(&fullpath[sharepath_size + 1], filename, filename_size + 1); - key.dptr = (uint8_t *)fullpath; - key.dsize = strlen(fullpath) + 1; - name_hash = tdb_jenkins_hash(&key); + name_hash = hash(fullpath, strlen(fullpath) + 1, 0); free(fullpath); return name_hash; } @@ -316,7 +318,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, return -1; } - db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); + db_data = tdb_fetch_compat(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ db_data.dptr = (uint8 *)malloc( @@ -345,7 +347,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, db_data.dsize = sizeof(struct locking_data) + sizeof(struct share_mode_entry) + strlen(sharepath) + 1 + strlen(filename) + 1; - if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) { + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) != 0) { free(db_data.dptr); return -1; } @@ -388,7 +390,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, db_data.dptr = new_data_p; db_data.dsize = new_data_size; - if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) != 0) { free(db_data.dptr); return -1; } @@ -433,7 +435,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, size_t i, num_share_modes; const uint8 *remaining_ptr = NULL; - db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); + db_data = tdb_fetch_compat(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { return -1; /* Error - missing entry ! */ } @@ -451,7 +453,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* It's ours - just remove the entire record. */ free(db_data.dptr); - return tdb_delete(db_ctx->smb_tdb, locking_key); + return tdb_delete(db_ctx->smb_tdb, locking_key) ? -1 : 0; } /* More than one - allocate a new record minus the one we'll delete. */ @@ -490,7 +492,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, /* None left after pruning. Delete record. */ free(db_data.dptr); free(new_data_p); - return tdb_delete(db_ctx->smb_tdb, locking_key); + return tdb_delete(db_ctx->smb_tdb, locking_key) ? -1 : 0; } /* Copy any delete tokens plus the terminating filenames. */ @@ -511,7 +513,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, db_data.dsize = sizeof(struct locking_data) + (num_share_modes * sizeof(struct share_mode_entry)) + remaining_size; - if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) != 0) { free(db_data.dptr); return -1; } @@ -535,7 +537,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, size_t i; int found_entry = 0; - db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); + db_data = tdb_fetch_compat(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { return -1; /* Error - missing entry ! */ } @@ -566,7 +568,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Save modified data. */ - if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) != 0) { free(db_data.dptr); return -1; } diff --git a/source3/libsmb/smbsock_connect.c b/source3/libsmb/smbsock_connect.c index fd8626f5ad..3a228b1b9e 100644 --- a/source3/libsmb/smbsock_connect.c +++ b/source3/libsmb/smbsock_connect.c @@ -18,7 +18,8 @@ */ #include "includes.h" -#include "../lib/async_req/async_sock.h" +#include "../lib/util/tevent_ntstatus.h" +#include "client.h" #include "async_smb.h" #include "libsmb/nmblib.h" @@ -215,7 +216,7 @@ struct tevent_req *smbsock_connect_send(TALLOC_CTX *mem_ctx, state->called_type = (called_type != -1) ? called_type : 0x20; state->calling_name = - (calling_name != NULL) ? calling_name : global_myname(); + (calling_name != NULL) ? calling_name : lp_netbios_name(); state->calling_type = (calling_type != -1) ? calling_type : 0x00; @@ -270,6 +271,7 @@ static int smbsock_connect_state_destructor( { if (state->sock != -1) { close(state->sock); + state->sock = -1; } return 0; } @@ -368,7 +370,7 @@ NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, uint16_t port, const char *called_name, int called_type, const char *calling_name, int calling_type, - int *pfd, uint16_t *ret_port) + int *pfd, uint16_t *ret_port, int sec_timeout) { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; @@ -385,6 +387,11 @@ NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, uint16_t port, if (req == NULL) { goto fail; } + if ((sec_timeout != 0) && + !tevent_req_set_endtime( + req, ev, timeval_current_ofs(sec_timeout, 0))) { + goto fail; + } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } @@ -568,7 +575,7 @@ static void smbsock_any_connect_connected(struct tevent_req *subreq) } state->num_received += 1; - if (state->num_received <= state->num_addrs) { + if (state->num_received < state->num_addrs) { /* * More addrs pending, wait for the others */ @@ -610,6 +617,7 @@ NTSTATUS smbsock_any_connect(const struct sockaddr_storage *addrs, int *calling_types, size_t num_addrs, uint16_t port, + int sec_timeout, int *pfd, size_t *chosen_index, uint16_t *chosen_port) { @@ -629,6 +637,11 @@ NTSTATUS smbsock_any_connect(const struct sockaddr_storage *addrs, if (req == NULL) { goto fail; } + if ((sec_timeout != 0) && + !tevent_req_set_endtime( + req, ev, timeval_current_ofs(sec_timeout, 0))) { + goto fail; + } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 08377fbfbc..dc2cf03a04 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -27,6 +27,7 @@ #include "../librpc/gen_ndr/ndr_netlogon.h" #include "secrets.h" #include "passdb.h" +#include "libsmb/libsmb.h" /********************************************************* Change the domain password on the PDC. @@ -168,7 +169,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* setup the anonymous connection */ - status = cli_full_connection( &cli, global_myname(), dc_name, &dc_ss, 0, "IPC$", "IPC", + status = cli_full_connection( &cli, lp_netbios_name(), dc_name, &dc_ss, 0, "IPC$", "IPC", "", "", "", 0, Undefined); if ( !NT_STATUS_IS_OK(status) ) goto done; @@ -207,20 +208,20 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, *num_domains = dom_list.count; - *domain_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_domains); + *domain_names = talloc_zero_array(mem_ctx, char *, *num_domains); if (!*domain_names) { status = NT_STATUS_NO_MEMORY; goto done; } - *sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_domains); + *sids = talloc_zero_array(mem_ctx, struct dom_sid, *num_domains); if (!*sids) { status = NT_STATUS_NO_MEMORY; goto done; } for (i=0; i< *num_domains; i++) { - (*domain_names)[i] = CONST_DISCARD(char *, dom_list.domains[i].name.string); + (*domain_names)[i] = discard_const_p(char, dom_list.domains[i].name.string); (*sids)[i] = *dom_list.domains[i].sid; } @@ -263,7 +264,7 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m /* if this next call fails, then give up. We can't do password changes on BDC's --jerry */ - if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name, + if (!NT_STATUS_IS_OK(cli_full_connection(&cli, lp_netbios_name(), dc_name, NULL, 0, "IPC$", "IPC", "", "", diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index c5ad9ecb59..cf9ed7dbc6 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "../lib/util/tevent_ntstatus.h" #include "lib/async_req/async_sock.h" #include "libsmb/nmblib.h" @@ -72,7 +73,7 @@ NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, struct tevent_fd *fde; NTSTATUS status; - result = TALLOC_ZERO_P(mem_ctx, struct nb_packet_server); + result = talloc_zero(mem_ctx, struct nb_packet_server); if (result == NULL) { status = NT_STATUS_NO_MEMORY; goto fail; @@ -139,7 +140,7 @@ static void nb_packet_server_listener(struct tevent_context *ev, } DEBUG(6,("accepted socket %d\n", sock)); - client = TALLOC_ZERO_P(server, struct nb_packet_client); + client = talloc_zero(server, struct nb_packet_client); if (client == NULL) { DEBUG(10, ("talloc failed\n")); close(sock); @@ -377,7 +378,7 @@ static void nb_packet_client_send(struct nb_packet_client *client, return; } - state = TALLOC_ZERO_P(client, struct nb_packet_client_state); + state = talloc_zero(client, struct nb_packet_client_state); if (state == NULL) { DEBUG(10, ("talloc failed\n")); return; @@ -484,7 +485,7 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, state->query.mailslot_namelen = strlen(mailslot_name); } - state->reader = TALLOC_ZERO_P(state, struct nb_packet_reader); + state->reader = talloc_zero(state, struct nb_packet_reader); if (tevent_req_nomem(state->reader, req)) { return tevent_req_post(req, ev); } |