The branch, master has been updated via e5ad524 s3: Remove two uses of cli_errstr via c3a6e9b s3: RAP errors are WERROR via c0d1683 s3: Remove some bogus error mappings via d2b1671 s3: Remove a use of cli_errstr via c318712 s3: Allow NULL for arg pwritten in cli_write_andx via 25df2fe S3: Fix some nonempty blank lines via e2498b1 s3: Read symlink information in smbclient "allinfo" via 79d27e2 s3: Fix symlink_reparse_buffer_parse via c1094a8 s3: Add cli_readlink via 61d0afe s3: Add STATUS_STOPPED_ON_SYMLINK error code from 4a83575 s3-build Require fully defined modules by default
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e5ad52490276dfec03a7a439c33384a442565a0d Author: Volker Lendecke <v...@samba.org> Date: Sun Jul 3 11:27:53 2011 +0200 s3: Remove two uses of cli_errstr Autobuild-User: Volker Lendecke <vlen...@samba.org> Autobuild-Date: Sun Jul 3 12:43:32 CEST 2011 on sn-devel-104 commit c3a6e9b7cea4f48bcb5a9de1fad26e3da3b53f7c Author: Volker Lendecke <v...@samba.org> Date: Sun Jul 3 11:21:50 2011 +0200 s3: RAP errors are WERROR commit c0d168392fc41ab8c04c40f25760d5cf5f71ed3f Author: Volker Lendecke <v...@samba.org> Date: Sun Jul 3 11:15:45 2011 +0200 s3: Remove some bogus error mappings The old cli_session_request that used this is gone commit d2b1671fb362d9e747b0c4f398ab41848cfdb921 Author: Volker Lendecke <v...@samba.org> Date: Sun Jul 3 10:38:30 2011 +0200 s3: Remove a use of cli_errstr All code above that might have failed sets result commit c31871264c3cdcbb9a05d8f4649c029a9a39ea9f Author: Volker Lendecke <v...@samba.org> Date: Sat Apr 30 10:58:35 2011 +0200 s3: Allow NULL for arg pwritten in cli_write_andx commit 25df2fe8e224fad1a665414f2b4022b42f77075c Author: Volker Lendecke <v...@samba.org> Date: Sat Jun 25 15:14:25 2011 +0200 S3: Fix some nonempty blank lines commit e2498b1110d260c917be3f938c11f68e6b6c80e4 Author: Volker Lendecke <v...@samba.org> Date: Thu Jun 30 15:26:21 2011 +0200 s3: Read symlink information in smbclient "allinfo" commit 79d27e28ad27b61169689586ca1cd30050c5ce1f Author: Volker Lendecke <v...@samba.org> Date: Thu Jun 30 15:25:42 2011 +0200 s3: Fix symlink_reparse_buffer_parse commit c1094a8cb0dd502b8c1b140ad3a90ecc450b1b11 Author: Volker Lendecke <v...@samba.org> Date: Thu Jun 30 15:06:46 2011 +0200 s3: Add cli_readlink commit 61d0afeab30d4f7a40e3ad89b97942027aee6287 Author: Volker Lendecke <v...@samba.org> Date: Thu Jun 30 15:25:16 2011 +0200 s3: Add STATUS_STOPPED_ON_SYMLINK error code ----------------------------------------------------------------------- Summary of changes: lib/util/util_net.c | 6 +- libcli/util/nterr.c | 1 + libcli/util/ntstatus.h | 1 + source3/auth/auth_domain.c | 5 +- source3/client/client.c | 17 ++++ source3/libsmb/clierror.c | 55 ++----------- source3/libsmb/clirap2.c | 12 ++- source3/libsmb/clireadwrite.c | 4 +- source3/libsmb/clisymlink.c | 175 ++++++++++++++++++++++++++++++++++++++ source3/libsmb/errormap.c | 2 +- source3/libsmb/proto.h | 11 +++ source3/libsmb/reparse_symlink.c | 3 + source3/nmbd/nmbd_winsserver.c | 52 ++++++------ 13 files changed, 258 insertions(+), 86 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/util_net.c b/lib/util/util_net.c index 64aa674..566bf56 100644 --- a/lib/util/util_net.c +++ b/lib/util/util_net.c @@ -8,17 +8,17 @@ Copyright (C) Jim McDonough (j...@us.ibm.com) 2003. Copyright (C) James J Myers 2003 Copyright (C) Tim Potter 2000-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/>. */ diff --git a/libcli/util/nterr.c b/libcli/util/nterr.c index 405ff6d..cee5664 100644 --- a/libcli/util/nterr.c +++ b/libcli/util/nterr.c @@ -37,6 +37,7 @@ const nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, + { "STATUS_STOPPED_ON_SYMLINK", STATUS_STOPPED_ON_SYMLINK }, { "STATUS_NO_MORE_EAS", STATUS_NO_MORE_EAS }, { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME }, { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT }, diff --git a/libcli/util/ntstatus.h b/libcli/util/ntstatus.h index 36a040d..2018b40 100644 --- a/libcli/util/ntstatus.h +++ b/libcli/util/ntstatus.h @@ -48,6 +48,7 @@ typedef uint32_t NTSTATUS; #define STATUS_EA_LIST_INCONSISTENT NT_STATUS(0x80000014) #define STATUS_INVALID_EA_FLAG NT_STATUS(0x80000015) #define NT_STATUS_NO_MORE_ENTRIES NT_STATUS(0x8000001a) +#define STATUS_STOPPED_ON_SYMLINK NT_STATUS(0x8000002d) #define STATUS_PENDING NT_STATUS(0x0103) /* Vista Status codes. */ diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index c18a81a..7eb020d 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -234,8 +234,9 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result))); } if(!netlogon_pipe) { - DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ -machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli))); + DEBUG(0, ("connect_to_domain_password_server: unable to open " + "the domain client session to machine %s. Error " + "was : %s.\n", dc_name, nt_errstr(result))); cli_shutdown(*cli); *cli = NULL; TALLOC_FREE(mutex); diff --git a/source3/client/client.c b/source3/client/client.c index 207147c..94c7e98 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1716,6 +1716,23 @@ static int do_allinfo(const char *name) (unsigned long long)streams[i].size); } + if (mode & FILE_ATTRIBUTE_REPARSE_POINT) { + char *subst, *print; + uint32_t flags; + + status = cli_readlink(cli, name, talloc_tos(), &subst, &print, + &flags); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "cli_readlink returned %s\n", + nt_errstr(status)); + } else { + d_printf("symlink: subst=[%s], print=[%s], flags=%x\n", + subst, print, flags); + TALLOC_FREE(subst); + TALLOC_FREE(print); + } + } + status = cli_ntcreate(cli, name, 0, CREATE_ACCESS_READ, 0, FILE_SHARE_READ|FILE_SHARE_WRITE diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index d5ac893..32de7ec 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -4,17 +4,17 @@ Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Jelmer Vernooij 2003 Copyright (C) Jeremy Allison 2006 - + 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/>. */ @@ -22,41 +22,6 @@ #include "includes.h" #include "libsmb/libsmb.h" -/***************************************************** - RAP error codes - a small start but will be extended. - - XXX: Perhaps these should move into a common function because they're - duplicated in clirap2.c - -*******************************************************/ - -static const struct { - int err; - const char *message; -} rap_errmap[] = { - {5, "RAP5: User has insufficient privilege" }, - {50, "RAP50: Not supported by server" }, - {65, "RAP65: Access denied" }, - {86, "RAP86: The specified password is invalid" }, - {2220, "RAP2220: Group does not exist" }, - {2221, "RAP2221: User does not exist" }, - {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" }, - {2237, "RAP2237: User is not in group" }, - {2242, "RAP2242: The password of this user has expired." }, - {2243, "RAP2243: The password of this user cannot change." }, - {2244, "RAP2244: This password cannot be used now (password history conflict)." }, - {2245, "RAP2245: The password is shorter than required." }, - {2246, "RAP2246: The password of this user is too recent to change."}, - - /* these really shouldn't be here ... */ - {0x80, "Not listening on called name"}, - {0x81, "Not listening for calling name"}, - {0x82, "Called name not present"}, - {0x83, "Called name present, but insufficient resources"}, - - {0, NULL} -}; - /**************************************************************************** Return a description of an SMB error. ****************************************************************************/ @@ -104,7 +69,6 @@ const char *cli_errstr(struct cli_state *cli) fstring cli_error_message; uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; uint8 errclass; - int i; char *result; if (!cli->initialised) { @@ -150,15 +114,8 @@ const char *cli_errstr(struct cli_state *cli) /* Case #1: RAP error */ if (cli->rap_error) { - for (i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->rap_error) { - return rap_errmap[i].message; - } - } - - slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d", - cli->rap_error); - + strlcpy(cli_error_message, win_errstr(W_ERROR(cli->rap_error)), + sizeof(cli_error_message)); goto done; } @@ -288,7 +245,7 @@ bool cli_is_error(struct cli_state *cli) rcls = IVAL(cli->inbuf, smb_rcls); return (rcls & 0xF0000000) == 0xC0000000; } - + /* Return error if error class in non-zero */ rcls = CVAL(cli->inbuf, smb_rcls); diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 03b4ca7..1d36ca6 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1533,8 +1533,10 @@ bool cli_get_pdc_name(struct cli_state *cli, const char *workgroup, char **pdc_n TALLOC_FREE(frame); } } else { - DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. " - "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); + DEBUG(4, ("cli_get_pdc_name: machine %s failed the " + "NetServerEnum call. Error was : %s.\n", + cli->desthost, + win_errstr(W_ERROR(cli->rap_error)))); } } @@ -1830,8 +1832,10 @@ bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty } } } else { - DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. " - "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); + DEBUG(4, ("cli_ns_check_server_type: machine %s " + "failed the NetServerEnum call. Error was : " + "%s.\n", cli->desthost, + win_errstr(W_ERROR(cli->rap_error)))); } } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 14b6401..64bdb48 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -903,7 +903,9 @@ NTSTATUS cli_write_andx_recv(struct tevent_req *req, size_t *pwritten) if (tevent_req_is_nterror(req, &status)) { return status; } - *pwritten = state->written; + if (pwritten != 0) { + *pwritten = state->written; + } return NT_STATUS_OK; } diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c index e5c2c1a..e744a38 100644 --- a/source3/libsmb/clisymlink.c +++ b/source3/libsmb/clisymlink.c @@ -226,3 +226,178 @@ NTSTATUS cli_symlink(struct cli_state *cli, const char *oldname, TALLOC_FREE(frame); return status; } + +struct cli_readlink_state { + struct tevent_context *ev; + struct cli_state *cli; + uint16_t fnum; + + uint16_t setup[4]; + NTSTATUS get_reparse_status; + uint8_t *data; + uint32_t num_data; +}; + +static void cli_readlink_opened(struct tevent_req *subreq); +static void cli_readlink_got_reparse_data(struct tevent_req *subreq); +static void cli_readlink_closed(struct tevent_req *subreq); + +struct tevent_req *cli_readlink_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname) +{ + struct tevent_req *req, *subreq; + struct cli_readlink_state *state; + + req = tevent_req_create(mem_ctx, &state, struct cli_readlink_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->cli = cli; + + subreq = cli_ntcreate_send( + state, ev, cli, fname, 0, FILE_READ_ATTRIBUTES | FILE_READ_EA, + 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_OPEN, FILE_OPEN_REPARSE_POINT, 0); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_readlink_opened, req); + return req; +} + +static void cli_readlink_opened(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_readlink_state *state = tevent_req_data( + req, struct cli_readlink_state); + NTSTATUS status; + + status = cli_ntcreate_recv(subreq, &state->fnum); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + SIVAL(state->setup, 0, FSCTL_GET_REPARSE_POINT); + SSVAL(state->setup, 4, state->fnum); + SCVAL(state->setup, 6, 1); /* IsFcntl */ + SCVAL(state->setup, 7, 0); /* IsFlags */ + + subreq = cli_trans_send(state, state->ev, state->cli, SMBnttrans, + NULL, -1, /* name, fid */ + NT_TRANSACT_IOCTL, 0, + state->setup, 4, 0, /* setup */ + NULL, 0, 0, /* param */ + NULL, 0, 16384); /* data */ + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_readlink_got_reparse_data, req); +} + +static void cli_readlink_got_reparse_data(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_readlink_state *state = tevent_req_data( + req, struct cli_readlink_state); + + state->get_reparse_status = cli_trans_recv( + subreq, state, NULL, + NULL, 0, NULL, /* rsetup */ + NULL, 0, NULL, /* rparam */ + &state->data, 20, &state->num_data); /* rdata */ + TALLOC_FREE(subreq); + + subreq = cli_close_send(state, state->ev, state->cli, state->fnum); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_readlink_closed, req); +} + +static void cli_readlink_closed(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; + + status = cli_close_recv(subreq); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + +NTSTATUS cli_readlink_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **psubstitute_name, char **pprint_name, + uint32_t *pflags) +{ + struct cli_readlink_state *state = tevent_req_data( + req, struct cli_readlink_state); + NTSTATUS status; + char *substitute_name; + char *print_name; + uint32_t flags; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + + if (!symlink_reparse_buffer_parse(state->data, state->num_data, + talloc_tos(), &substitute_name, + &print_name, &flags)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (psubstitute_name != NULL) { + *psubstitute_name = talloc_move(mem_ctx, &substitute_name); + } + TALLOC_FREE(substitute_name); + + if (pprint_name != NULL) { + *pprint_name = talloc_move(mem_ctx, &print_name); + } + TALLOC_FREE(print_name); + + if (pflags != NULL) { + *pflags = flags; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_readlink(struct cli_state *cli, const char *fname, + TALLOC_CTX *mem_ctx, char **psubstitute_name, + char **pprint_name, uint32_t *pflags) +{ + 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)) { + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_readlink_send(frame, ev, cli, fname); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_readlink_recv(req, mem_ctx, psubstitute_name, + pprint_name, pflags); + fail: + TALLOC_FREE(frame); + return status; +} diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 35b4137..975de4f 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -392,7 +392,7 @@ NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor) if (gss_maj == GSS_S_FAILURE) { return map_nt_error_from_unix((int)minor); } - + /* Look through list */ while(gss_to_ntstatus_errormap[i].gss_err != 0) { if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) { diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index a266f7c..89b1ecd 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -872,4 +872,15 @@ NTSTATUS cli_symlink_recv(struct tevent_req *req); NTSTATUS cli_symlink(struct cli_state *cli, const char *oldname, const char *newname, uint32_t flags); +struct tevent_req *cli_readlink_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname); +NTSTATUS cli_readlink_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **psubstitute_name, char **pprint_name, + uint32_t *pflags); +NTSTATUS cli_readlink(struct cli_state *cli, const char *fname, + TALLOC_CTX *mem_ctx, char **psubstitute_name, + char **pprint_name, uint32_t *pflags); + #endif /* _LIBSMB_PROTO_H_ */ diff --git a/source3/libsmb/reparse_symlink.c b/source3/libsmb/reparse_symlink.c index 9c158ee..f981b5f 100644 --- a/source3/libsmb/reparse_symlink.c +++ b/source3/libsmb/reparse_symlink.c @@ -170,5 +170,8 @@ bool symlink_reparse_buffer_parse( if (pprint_name != NULL) { *pprint_name = print_name; } + if (pflags != NULL) { + *pflags = flags; + } return true; } diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index 50cdc0a..6ac6007 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -8,15 +8,15 @@ 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/>. - + Converted to store WINS data in a tdb. Dec 2005. JRA. */ @@ -133,7 +133,7 @@ static struct name_record *wins_record_to_name_record(TDB_DATA key, TDB_DATA dat /* We're using a byte-by-byte compare, so we must be sure that * unused space doesn't have garbage in it. */ - + for( i = strlen( namerec->name.name ); i < sizeof( namerec->name.name ); i++ ) { namerec->name.name[i] = '\0'; -- Samba Shared Repository