Changeset 740 for vendor/current/source3/libsmb
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source3/libsmb
- Files:
-
- 10 added
- 3 deleted
- 53 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/async_smb.c
r594 r740 19 19 20 20 #include "includes.h" 21 #include "libsmb/libsmb.h" 22 #include "../lib/async_req/async_sock.h" 23 #include "../lib/util/tevent_ntstatus.h" 24 #include "../lib/util/tevent_unix.h" 25 #include "async_smb.h" 26 #include "smb_crypt.h" 27 #include "libsmb/nmblib.h" 21 28 22 29 /* … … 121 128 } 122 129 123 /* if the client uses dos errors, but there is no error, 124 we should return no error here, otherwise it looks 125 like an unknown bad NT_STATUS. jmcd */ 126 if (CVAL(buf, smb_rcls) == 0) 127 return NT_STATUS_OK; 128 129 return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); 130 return dos_to_ntstatus(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); 130 131 } 131 132 … … 202 203 uint32_t seqnum; 203 204 int chain_num; 205 int chain_length; 204 206 struct tevent_req **chained_requests; 205 207 }; … … 237 239 int num_pending = talloc_array_length(cli->pending); 238 240 int i; 241 242 if (state->mid != 0) { 243 /* 244 * This is a [nt]trans[2] request which waits 245 * for more than one reply. 246 */ 247 return; 248 } 239 249 240 250 if (num_pending == 1) { … … 280 290 static int cli_smb_req_destructor(struct tevent_req *req) 281 291 { 292 struct cli_smb_state *state = tevent_req_data( 293 req, struct cli_smb_state); 294 /* 295 * Make sure we really remove it from 296 * the pending array on destruction. 297 */ 298 state->mid = 0; 282 299 cli_smb_req_unset_pending(req); 283 300 return 0; … … 342 359 } 343 360 361 uint32_t cli_smb_req_seqnum(struct tevent_req *req) 362 { 363 struct cli_smb_state *state = tevent_req_data( 364 req, struct cli_smb_state); 365 return state->seqnum; 366 } 367 368 void cli_smb_req_set_seqnum(struct tevent_req *req, uint32_t seqnum) 369 { 370 struct cli_smb_state *state = tevent_req_data( 371 req, struct cli_smb_state); 372 state->seqnum = seqnum; 373 } 374 344 375 static size_t iov_len(const struct iovec *iov, int count) 345 376 { … … 424 455 state->iov_count = iov_count + 3; 425 456 426 endtime = timeval_current_ofs(0, cli->timeout * 1000); 427 if (!tevent_req_set_endtime(result, ev, endtime)) { 428 tevent_req_nomem(NULL, result); 457 if (cli->timeout) { 458 endtime = timeval_current_ofs(cli->timeout / 1000, 459 (cli->timeout % 1000) * 1000); 460 if (!tevent_req_set_endtime(result, ev, endtime)) { 461 tevent_req_nomem(NULL, result); 462 } 429 463 } 430 464 return result; … … 610 644 struct tevent_req *req; 611 645 struct cli_smb_state *state; 612 struct tevent_context *ev;613 646 NTSTATUS status; 614 647 uint8_t *inbuf; … … 699 732 req = cli->pending[i]; 700 733 state = tevent_req_data(req, struct cli_smb_state); 701 ev = state->ev;702 734 703 735 if (!oplock_break /* oplock breaks are not signed */ … … 714 746 state->inbuf = talloc_move(state, &inbuf); 715 747 talloc_set_destructor(req, NULL); 716 cli_smb_req_destructor(req); 748 cli_smb_req_unset_pending(req); 749 state->chain_num = 0; 750 state->chain_length = 1; 717 751 tevent_req_done(req); 718 752 } else { … … 726 760 state->inbuf = inbuf; 727 761 state->chain_num = i; 762 state->chain_length = num_chained; 728 763 tevent_req_done(chain[i]); 729 764 } … … 755 790 req = cli->pending[0]; 756 791 talloc_set_destructor(req, NULL); 757 cli_smb_req_ destructor(req);792 cli_smb_req_unset_pending(req); 758 793 tevent_req_nterror(req, status); 759 794 } 760 795 } 761 796 762 NTSTATUS cli_smb_recv(struct tevent_req *req, uint8_t min_wct, 763 uint8_t *pwct, uint16_t **pvwv, 797 NTSTATUS cli_smb_recv(struct tevent_req *req, 798 TALLOC_CTX *mem_ctx, uint8_t **pinbuf, 799 uint8_t min_wct, uint8_t *pwct, uint16_t **pvwv, 764 800 uint32_t *pnum_bytes, uint8_t **pbytes) 765 801 { … … 777 813 778 814 if (state->inbuf == NULL) { 815 if (min_wct != 0) { 816 return NT_STATUS_INVALID_NETWORK_RESPONSE; 817 } 818 if (pinbuf) { 819 *pinbuf = NULL; 820 } 821 if (pwct) { 822 *pwct = 0; 823 } 824 if (pvwv) { 825 *pvwv = NULL; 826 } 827 if (pnum_bytes) { 828 *pnum_bytes = 0; 829 } 830 if (pbytes) { 831 *pbytes = NULL; 832 } 779 833 /* This was a request without a reply */ 780 834 return NT_STATUS_OK; … … 819 873 status = cli_pull_error((char *)state->inbuf); 820 874 821 if (!have_andx_command((char *)state->inbuf, wct_ofs) 822 && NT_STATUS_IS_ERR(status)) { 823 /* 824 * The last command takes the error code. All further commands 825 * down the requested chain will get a 826 * NT_STATUS_REQUEST_ABORTED. 827 */ 828 return status; 829 } 875 if (!have_andx_command((char *)state->inbuf, wct_ofs)) { 876 877 if ((cmd == SMBsesssetupX) 878 && NT_STATUS_EQUAL( 879 status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 880 /* 881 * NT_STATUS_MORE_PROCESSING_REQUIRED is a 882 * valid return code for session setup 883 */ 884 goto no_err; 885 } 886 887 if (NT_STATUS_IS_ERR(status)) { 888 /* 889 * The last command takes the error code. All 890 * further commands down the requested chain 891 * will get a NT_STATUS_REQUEST_ABORTED. 892 */ 893 return status; 894 } 895 } 896 897 no_err: 830 898 831 899 wct = CVAL(state->inbuf, wct_ofs); … … 859 927 *pbytes = (uint8_t *)state->inbuf + bytes_offset + 2; 860 928 } 861 862 return NT_STATUS_OK; 929 if ((mem_ctx != NULL) && (pinbuf != NULL)) { 930 if (state->chain_num == state->chain_length-1) { 931 *pinbuf = talloc_move(mem_ctx, &state->inbuf); 932 } else { 933 *pinbuf = state->inbuf; 934 } 935 } 936 937 return status; 863 938 } 864 939 … … 1044 1119 uint32_t num_bytes; 1045 1120 uint8_t *bytes; 1121 uint8_t *inbuf; 1046 1122 NTSTATUS status; 1047 1123 1048 status = cli_smb_recv(subreq, 8, &wct, &vwv, &num_bytes, &bytes); 1124 status = cli_smb_recv(subreq, state, &inbuf, 8, &wct, &vwv, 1125 &num_bytes, &bytes); 1126 TALLOC_FREE(subreq); 1049 1127 if (!NT_STATUS_IS_OK(status)) { 1050 TALLOC_FREE(subreq);1051 1128 tevent_req_nterror(req, status); 1052 1129 return; -
vendor/current/source3/libsmb/cliconnect.c
r597 r740 4 4 Copyright (C) Andrew Tridgell 1994-1998 5 5 Copyright (C) Andrew Bartlett 2001-2003 6 6 Copyright (C) Volker Lendecke 2011 7 Copyright (C) Jeremy Allison 2011 8 7 9 This program is free software; you can redistribute it and/or modify 8 10 it under the terms of the GNU General Public License as published by 9 11 the Free Software Foundation; either version 3 of the License, or 10 12 (at your option) any later version. 11 13 12 14 This program is distributed in the hope that it will be useful, 13 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 17 GNU General Public License for more details. 16 18 17 19 You should have received a copy of the GNU General Public License 18 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 22 21 23 #include "includes.h" 24 #include "libsmb/libsmb.h" 25 #include "popt_common.h" 22 26 #include "../libcli/auth/libcli_auth.h" 23 27 #include "../libcli/auth/spnego.h" 24 28 #include "smb_krb5.h" 29 #include "../libcli/auth/ntlmssp.h" 30 #include "libads/kerberos_proto.h" 31 #include "krb5_env.h" 32 #include "../lib/util/tevent_ntstatus.h" 33 #include "async_smb.h" 34 #include "libsmb/nmblib.h" 25 35 26 36 static const struct { … … 42 52 #define STAR_SMBSERVER "*SMBSERVER" 43 53 54 /******************************************************** 55 Utility function to ensure we always return at least 56 a valid char * pointer to an empty string for the 57 cli->server_os, cli->server_type and cli->server_domain 58 strings. 59 *******************************************************/ 60 61 static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli, 62 char *inbuf, 63 char **dest, 64 uint8_t *src, 65 size_t srclen, 66 ssize_t *destlen) 67 { 68 *destlen = clistr_pull_talloc(cli, 69 inbuf, 70 SVAL(inbuf, smb_flg2), 71 dest, 72 (char *)src, 73 srclen, 74 STR_TERMINATE); 75 if (*destlen == -1) { 76 return NT_STATUS_NO_MEMORY; 77 } 78 79 if (*dest == NULL) { 80 *dest = talloc_strdup(cli, ""); 81 if (*dest == NULL) { 82 return NT_STATUS_NO_MEMORY; 83 } 84 } 85 return NT_STATUS_OK; 86 } 87 44 88 /** 45 89 * Set the user session key for a connection … … 58 102 ****************************************************************************/ 59 103 60 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, 61 const char *user, 104 struct cli_session_setup_lanman2_state { 105 struct cli_state *cli; 106 uint16_t vwv[10]; 107 const char *user; 108 }; 109 110 static void cli_session_setup_lanman2_done(struct tevent_req *subreq); 111 112 static struct tevent_req *cli_session_setup_lanman2_send( 113 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 114 struct cli_state *cli, const char *user, 115 const char *pass, size_t passlen, 116 const char *workgroup) 117 { 118 struct tevent_req *req, *subreq; 119 struct cli_session_setup_lanman2_state *state; 120 DATA_BLOB lm_response = data_blob_null; 121 uint16_t *vwv; 122 uint8_t *bytes; 123 char *tmp; 124 125 req = tevent_req_create(mem_ctx, &state, 126 struct cli_session_setup_lanman2_state); 127 if (req == NULL) { 128 return NULL; 129 } 130 state->cli = cli; 131 state->user = user; 132 vwv = state->vwv; 133 134 /* 135 * LANMAN servers predate NT status codes and Unicode and 136 * ignore those smb flags so we must disable the corresponding 137 * default capabilities that would otherwise cause the Unicode 138 * and NT Status flags to be set (and even returned by the 139 * server) 140 */ 141 142 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); 143 144 /* 145 * if in share level security then don't send a password now 146 */ 147 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { 148 passlen = 0; 149 } 150 151 if (passlen > 0 152 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) 153 && passlen != 24) { 154 /* 155 * Encrypted mode needed, and non encrypted password 156 * supplied. 157 */ 158 lm_response = data_blob(NULL, 24); 159 if (tevent_req_nomem(lm_response.data, req)) { 160 return tevent_req_post(req, ev); 161 } 162 163 if (!SMBencrypt(pass, cli->secblob.data, 164 (uint8_t *)lm_response.data)) { 165 DEBUG(1, ("Password is > 14 chars in length, and is " 166 "therefore incompatible with Lanman " 167 "authentication\n")); 168 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 169 return tevent_req_post(req, ev); 170 } 171 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) 172 && passlen == 24) { 173 /* 174 * Encrypted mode needed, and encrypted password 175 * supplied. 176 */ 177 lm_response = data_blob(pass, passlen); 178 if (tevent_req_nomem(lm_response.data, req)) { 179 return tevent_req_post(req, ev); 180 } 181 } else if (passlen > 0) { 182 uint8_t *buf; 183 size_t converted_size; 184 /* 185 * Plaintext mode needed, assume plaintext supplied. 186 */ 187 buf = talloc_array(talloc_tos(), uint8_t, 0); 188 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1, 189 &converted_size); 190 if (tevent_req_nomem(buf, req)) { 191 return tevent_req_post(req, ev); 192 } 193 lm_response = data_blob(pass, passlen); 194 TALLOC_FREE(buf); 195 if (tevent_req_nomem(lm_response.data, req)) { 196 return tevent_req_post(req, ev); 197 } 198 } 199 200 SCVAL(vwv+0, 0, 0xff); 201 SCVAL(vwv+0, 1, 0); 202 SSVAL(vwv+1, 0, 0); 203 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 204 SSVAL(vwv+3, 0, 2); 205 SSVAL(vwv+4, 0, 1); 206 SIVAL(vwv+5, 0, cli->sesskey); 207 SSVAL(vwv+7, 0, lm_response.length); 208 209 bytes = talloc_array(state, uint8_t, lm_response.length); 210 if (tevent_req_nomem(bytes, req)) { 211 return tevent_req_post(req, ev); 212 } 213 if (lm_response.length != 0) { 214 memcpy(bytes, lm_response.data, lm_response.length); 215 } 216 data_blob_free(&lm_response); 217 218 tmp = talloc_strdup_upper(talloc_tos(), user); 219 if (tevent_req_nomem(tmp, req)) { 220 return tevent_req_post(req, ev); 221 } 222 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1, 223 NULL); 224 TALLOC_FREE(tmp); 225 226 tmp = talloc_strdup_upper(talloc_tos(), workgroup); 227 if (tevent_req_nomem(tmp, req)) { 228 return tevent_req_post(req, ev); 229 } 230 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1, 231 NULL); 232 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL); 233 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL); 234 235 if (tevent_req_nomem(bytes, req)) { 236 return tevent_req_post(req, ev); 237 } 238 239 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv, 240 talloc_get_size(bytes), bytes); 241 if (tevent_req_nomem(subreq, req)) { 242 return tevent_req_post(req, ev); 243 } 244 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req); 245 return req; 246 } 247 248 static void cli_session_setup_lanman2_done(struct tevent_req *subreq) 249 { 250 struct tevent_req *req = tevent_req_callback_data( 251 subreq, struct tevent_req); 252 struct cli_session_setup_lanman2_state *state = tevent_req_data( 253 req, struct cli_session_setup_lanman2_state); 254 struct cli_state *cli = state->cli; 255 uint32_t num_bytes; 256 uint8_t *in; 257 char *inbuf; 258 uint8_t *bytes; 259 uint8_t *p; 260 NTSTATUS status; 261 ssize_t ret; 262 uint8_t wct; 263 uint16_t *vwv; 264 265 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 266 &num_bytes, &bytes); 267 TALLOC_FREE(subreq); 268 if (!NT_STATUS_IS_OK(status)) { 269 tevent_req_nterror(req, status); 270 return; 271 } 272 273 inbuf = (char *)in; 274 p = bytes; 275 276 cli->vuid = SVAL(inbuf, smb_uid); 277 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 278 279 status = smb_bytes_talloc_string(cli, 280 inbuf, 281 &cli->server_os, 282 p, 283 bytes+num_bytes-p, 284 &ret); 285 286 if (!NT_STATUS_IS_OK(status)) { 287 tevent_req_nterror(req, status); 288 return; 289 } 290 p += ret; 291 292 status = smb_bytes_talloc_string(cli, 293 inbuf, 294 &cli->server_type, 295 p, 296 bytes+num_bytes-p, 297 &ret); 298 299 if (!NT_STATUS_IS_OK(status)) { 300 tevent_req_nterror(req, status); 301 return; 302 } 303 p += ret; 304 305 status = smb_bytes_talloc_string(cli, 306 inbuf, 307 &cli->server_domain, 308 p, 309 bytes+num_bytes-p, 310 &ret); 311 312 if (!NT_STATUS_IS_OK(status)) { 313 tevent_req_nterror(req, status); 314 return; 315 } 316 p += ret; 317 318 if (strstr(cli->server_type, "Samba")) { 319 cli->is_samba = True; 320 } 321 status = cli_set_username(cli, state->user); 322 if (tevent_req_nterror(req, status)) { 323 return; 324 } 325 tevent_req_done(req); 326 } 327 328 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req) 329 { 330 return tevent_req_simple_recv_ntstatus(req); 331 } 332 333 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user, 62 334 const char *pass, size_t passlen, 63 335 const char *workgroup) 64 336 { 65 DATA_BLOB session_key = data_blob_null; 66 DATA_BLOB lm_response = data_blob_null; 67 NTSTATUS status; 68 fstring pword; 69 char *p; 70 71 if (passlen > sizeof(pword)-1) { 72 return NT_STATUS_INVALID_PARAMETER; 73 } 74 75 /* LANMAN servers predate NT status codes and Unicode and ignore those 76 smb flags so we must disable the corresponding default capabilities 77 that would otherwise cause the Unicode and NT Status flags to be 78 set (and even returned by the server) */ 79 80 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); 81 82 /* if in share level security then don't send a password now */ 83 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) 84 passlen = 0; 85 86 if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { 87 /* Encrypted mode needed, and non encrypted password supplied. */ 88 lm_response = data_blob(NULL, 24); 89 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { 90 DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); 91 return NT_STATUS_ACCESS_DENIED; 92 } 93 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { 94 /* Encrypted mode needed, and encrypted password supplied. */ 95 lm_response = data_blob(pass, passlen); 96 } else if (passlen > 0) { 97 /* Plaintext mode needed, assume plaintext supplied. */ 98 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); 99 lm_response = data_blob(pass, passlen); 100 } 101 102 /* send a session setup command */ 103 memset(cli->outbuf,'\0',smb_size); 104 cli_set_message(cli->outbuf,10, 0, True); 105 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 106 cli_setup_packet(cli); 107 108 SCVAL(cli->outbuf,smb_vwv0,0xFF); 109 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); 110 SSVAL(cli->outbuf,smb_vwv3,2); 111 SSVAL(cli->outbuf,smb_vwv4,1); 112 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); 113 SSVAL(cli->outbuf,smb_vwv7,lm_response.length); 114 115 p = smb_buf(cli->outbuf); 116 memcpy(p,lm_response.data,lm_response.length); 117 p += lm_response.length; 118 p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); 119 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); 120 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 121 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); 122 cli_setup_bcc(cli, p); 123 124 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { 125 return cli_nt_error(cli); 126 } 127 128 show_msg(cli->inbuf); 129 130 if (cli_is_error(cli)) { 131 return cli_nt_error(cli); 132 } 133 134 /* use the returned vuid from now on */ 135 cli->vuid = SVAL(cli->inbuf,smb_uid); 136 status = cli_set_username(cli, user); 137 if (!NT_STATUS_IS_OK(status)) { 138 return status; 139 } 140 141 if (session_key.data) { 142 /* Have plaintext orginal */ 143 cli_set_session_key(cli, session_key); 144 } 145 146 return NT_STATUS_OK; 337 TALLOC_CTX *frame = talloc_stackframe(); 338 struct event_context *ev; 339 struct tevent_req *req; 340 NTSTATUS status = NT_STATUS_NO_MEMORY; 341 342 if (cli_has_async_calls(cli)) { 343 /* 344 * Can't use sync call while an async call is in flight 345 */ 346 status = NT_STATUS_INVALID_PARAMETER; 347 goto fail; 348 } 349 ev = event_context_init(frame); 350 if (ev == NULL) { 351 goto fail; 352 } 353 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen, 354 workgroup); 355 if (req == NULL) { 356 goto fail; 357 } 358 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 359 goto fail; 360 } 361 status = cli_session_setup_lanman2_recv(req); 362 fail: 363 TALLOC_FREE(frame); 364 if (!NT_STATUS_IS_OK(status)) { 365 cli_set_error(cli, status); 366 } 367 return status; 147 368 } 148 369 … … 171 392 struct cli_session_setup_guest_state { 172 393 struct cli_state *cli; 173 uint16_t vwv[1 6];394 uint16_t vwv[13]; 174 395 struct iovec bytes; 175 396 }; … … 264 485 struct cli_state *cli = state->cli; 265 486 uint32_t num_bytes; 487 uint8_t *in; 266 488 char *inbuf; 267 489 uint8_t *bytes; 268 490 uint8_t *p; 269 491 NTSTATUS status; 270 271 status = cli_smb_recv(subreq, 0, NULL, NULL, &num_bytes, &bytes); 272 if (!NT_STATUS_IS_OK(status)) { 273 TALLOC_FREE(subreq); 492 ssize_t ret; 493 uint8_t wct; 494 uint16_t *vwv; 495 496 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 497 &num_bytes, &bytes); 498 TALLOC_FREE(subreq); 499 if (!NT_STATUS_IS_OK(status)) { 274 500 tevent_req_nterror(req, status); 275 501 return; 276 502 } 277 503 278 inbuf = (char *) cli_smb_inbuf(subreq);504 inbuf = (char *)in; 279 505 p = bytes; 280 506 281 507 cli->vuid = SVAL(inbuf, smb_uid); 282 283 p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring), 284 bytes+num_bytes-p, STR_TERMINATE); 285 p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring), 286 bytes+num_bytes-p, STR_TERMINATE); 287 p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring), 288 bytes+num_bytes-p, STR_TERMINATE); 508 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 509 510 status = smb_bytes_talloc_string(cli, 511 inbuf, 512 &cli->server_os, 513 p, 514 bytes+num_bytes-p, 515 &ret); 516 517 if (!NT_STATUS_IS_OK(status)) { 518 tevent_req_nterror(req, status); 519 return; 520 } 521 p += ret; 522 523 status = smb_bytes_talloc_string(cli, 524 inbuf, 525 &cli->server_type, 526 p, 527 bytes+num_bytes-p, 528 &ret); 529 530 if (!NT_STATUS_IS_OK(status)) { 531 tevent_req_nterror(req, status); 532 return; 533 } 534 p += ret; 535 536 status = smb_bytes_talloc_string(cli, 537 inbuf, 538 &cli->server_domain, 539 p, 540 bytes+num_bytes-p, 541 &ret); 542 543 if (!NT_STATUS_IS_OK(status)) { 544 tevent_req_nterror(req, status); 545 return; 546 } 547 p += ret; 289 548 290 549 if (strstr(cli->server_type, "Samba")) { 291 550 cli->is_samba = True; 292 551 } 293 294 TALLOC_FREE(subreq);295 552 296 553 status = cli_set_username(cli, ""); … … 352 609 ****************************************************************************/ 353 610 354 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, 355 const char *user, const char *pass, 356 const char *workgroup) 357 { 358 uint32 capabilities = cli_session_setup_capabilities(cli); 359 char *p; 611 struct cli_session_setup_plain_state { 612 struct cli_state *cli; 613 uint16_t vwv[13]; 614 const char *user; 615 }; 616 617 static void cli_session_setup_plain_done(struct tevent_req *subreq); 618 619 static struct tevent_req *cli_session_setup_plain_send( 620 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 621 struct cli_state *cli, 622 const char *user, const char *pass, const char *workgroup) 623 { 624 struct tevent_req *req, *subreq; 625 struct cli_session_setup_plain_state *state; 626 uint16_t *vwv; 627 uint8_t *bytes; 628 size_t passlen; 629 char *version; 630 631 req = tevent_req_create(mem_ctx, &state, 632 struct cli_session_setup_plain_state); 633 if (req == NULL) { 634 return NULL; 635 } 636 state->cli = cli; 637 state->user = user; 638 vwv = state->vwv; 639 640 SCVAL(vwv+0, 0, 0xff); 641 SCVAL(vwv+0, 1, 0); 642 SSVAL(vwv+1, 0, 0); 643 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 644 SSVAL(vwv+3, 0, 2); 645 SSVAL(vwv+4, 0, cli->pid); 646 SIVAL(vwv+5, 0, cli->sesskey); 647 SSVAL(vwv+7, 0, 0); 648 SSVAL(vwv+8, 0, 0); 649 SSVAL(vwv+9, 0, 0); 650 SSVAL(vwv+10, 0, 0); 651 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli)); 652 653 bytes = talloc_array(state, uint8_t, 0); 654 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1, 655 &passlen); 656 if (tevent_req_nomem(bytes, req)) { 657 return tevent_req_post(req, ev); 658 } 659 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen); 660 661 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 662 user, strlen(user)+1, NULL); 663 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 664 workgroup, strlen(workgroup)+1, NULL); 665 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 666 "Unix", 5, NULL); 667 668 version = talloc_asprintf(talloc_tos(), "Samba %s", 669 samba_version_string()); 670 if (tevent_req_nomem(version, req)){ 671 return tevent_req_post(req, ev); 672 } 673 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 674 version, strlen(version)+1, NULL); 675 TALLOC_FREE(version); 676 677 if (tevent_req_nomem(bytes, req)) { 678 return tevent_req_post(req, ev); 679 } 680 681 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv, 682 talloc_get_size(bytes), bytes); 683 if (tevent_req_nomem(subreq, req)) { 684 return tevent_req_post(req, ev); 685 } 686 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req); 687 return req; 688 } 689 690 static void cli_session_setup_plain_done(struct tevent_req *subreq) 691 { 692 struct tevent_req *req = tevent_req_callback_data( 693 subreq, struct tevent_req); 694 struct cli_session_setup_plain_state *state = tevent_req_data( 695 req, struct cli_session_setup_plain_state); 696 struct cli_state *cli = state->cli; 697 uint32_t num_bytes; 698 uint8_t *in; 699 char *inbuf; 700 uint8_t *bytes; 701 uint8_t *p; 360 702 NTSTATUS status; 361 fstring lanman; 362 363 fstr_sprintf( lanman, "Samba %s", samba_version_string()); 364 365 memset(cli->outbuf, '\0', smb_size); 366 cli_set_message(cli->outbuf,13,0,True); 367 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 368 cli_setup_packet(cli); 369 370 SCVAL(cli->outbuf,smb_vwv0,0xFF); 371 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); 372 SSVAL(cli->outbuf,smb_vwv3,2); 373 SSVAL(cli->outbuf,smb_vwv4,cli->pid); 374 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); 375 SSVAL(cli->outbuf,smb_vwv8,0); 376 SIVAL(cli->outbuf,smb_vwv11,capabilities); 377 p = smb_buf(cli->outbuf); 378 379 /* check wether to send the ASCII or UNICODE version of the password */ 380 381 if ( (capabilities & CAP_UNICODE) == 0 ) { 382 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ 383 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); 384 } 385 else { 386 /* For ucs2 passwords clistr_push calls ucs2_align, which causes 387 * the space taken by the unicode password to be one byte too 388 * long (as we're on an odd byte boundary here). Reduce the 389 * count by 1 to cope with this. Fixes smbclient against NetApp 390 * servers which can't cope. Fix from 391 * bryan.kolodziej@allenlund.com in bug #3840. 392 */ 393 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */ 394 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1); 395 } 396 397 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ 398 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ 399 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 400 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); 401 cli_setup_bcc(cli, p); 402 403 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { 404 return cli_nt_error(cli); 405 } 406 407 show_msg(cli->inbuf); 408 409 if (cli_is_error(cli)) { 410 return cli_nt_error(cli); 411 } 412 413 cli->vuid = SVAL(cli->inbuf,smb_uid); 414 p = smb_buf(cli->inbuf); 415 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), 416 -1, STR_TERMINATE); 417 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 418 -1, STR_TERMINATE); 419 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), 420 -1, STR_TERMINATE); 421 status = cli_set_username(cli, user); 422 if (!NT_STATUS_IS_OK(status)) { 423 return status; 703 ssize_t ret; 704 uint8_t wct; 705 uint16_t *vwv; 706 707 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 708 &num_bytes, &bytes); 709 TALLOC_FREE(subreq); 710 if (tevent_req_nterror(req, status)) { 711 return; 712 } 713 714 inbuf = (char *)in; 715 p = bytes; 716 717 cli->vuid = SVAL(inbuf, smb_uid); 718 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 719 720 status = smb_bytes_talloc_string(cli, 721 inbuf, 722 &cli->server_os, 723 p, 724 bytes+num_bytes-p, 725 &ret); 726 727 if (!NT_STATUS_IS_OK(status)) { 728 tevent_req_nterror(req, status); 729 return; 730 } 731 p += ret; 732 733 status = smb_bytes_talloc_string(cli, 734 inbuf, 735 &cli->server_type, 736 p, 737 bytes+num_bytes-p, 738 &ret); 739 740 if (!NT_STATUS_IS_OK(status)) { 741 tevent_req_nterror(req, status); 742 return; 743 } 744 p += ret; 745 746 status = smb_bytes_talloc_string(cli, 747 inbuf, 748 &cli->server_domain, 749 p, 750 bytes+num_bytes-p, 751 &ret); 752 753 if (!NT_STATUS_IS_OK(status)) { 754 tevent_req_nterror(req, status); 755 return; 756 } 757 p += ret; 758 759 status = cli_set_username(cli, state->user); 760 if (tevent_req_nterror(req, status)) { 761 return; 424 762 } 425 763 if (strstr(cli->server_type, "Samba")) { 426 764 cli->is_samba = True; 427 765 } 428 429 return NT_STATUS_OK; 766 tevent_req_done(req); 767 } 768 769 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req) 770 { 771 return tevent_req_simple_recv_ntstatus(req); 772 } 773 774 static NTSTATUS cli_session_setup_plain(struct cli_state *cli, 775 const char *user, const char *pass, 776 const char *workgroup) 777 { 778 TALLOC_CTX *frame = talloc_stackframe(); 779 struct event_context *ev; 780 struct tevent_req *req; 781 NTSTATUS status = NT_STATUS_NO_MEMORY; 782 783 if (cli_has_async_calls(cli)) { 784 /* 785 * Can't use sync call while an async call is in flight 786 */ 787 status = NT_STATUS_INVALID_PARAMETER; 788 goto fail; 789 } 790 ev = event_context_init(frame); 791 if (ev == NULL) { 792 goto fail; 793 } 794 req = cli_session_setup_plain_send(frame, ev, cli, user, pass, 795 workgroup); 796 if (req == NULL) { 797 goto fail; 798 } 799 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 800 goto fail; 801 } 802 status = cli_session_setup_plain_recv(req); 803 fail: 804 TALLOC_FREE(frame); 805 if (!NT_STATUS_IS_OK(status)) { 806 cli_set_error(cli, status); 807 } 808 return status; 430 809 } 431 810 … … 440 819 ****************************************************************************/ 441 820 442 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, 443 const char *pass, size_t passlen, 444 const char *ntpass, size_t ntpasslen, 445 const char *workgroup) 446 { 447 uint32 capabilities = cli_session_setup_capabilities(cli); 821 struct cli_session_setup_nt1_state { 822 struct cli_state *cli; 823 uint16_t vwv[13]; 824 DATA_BLOB response; 825 DATA_BLOB session_key; 826 const char *user; 827 }; 828 829 static void cli_session_setup_nt1_done(struct tevent_req *subreq); 830 831 static struct tevent_req *cli_session_setup_nt1_send( 832 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 833 struct cli_state *cli, const char *user, 834 const char *pass, size_t passlen, 835 const char *ntpass, size_t ntpasslen, 836 const char *workgroup) 837 { 838 struct tevent_req *req, *subreq; 839 struct cli_session_setup_nt1_state *state; 448 840 DATA_BLOB lm_response = data_blob_null; 449 841 DATA_BLOB nt_response = data_blob_null; 450 842 DATA_BLOB session_key = data_blob_null; 451 NTSTATUS result; 452 char *p; 453 bool ok; 843 uint16_t *vwv; 844 uint8_t *bytes; 845 char *workgroup_upper; 846 847 req = tevent_req_create(mem_ctx, &state, 848 struct cli_session_setup_nt1_state); 849 if (req == NULL) { 850 return NULL; 851 } 852 state->cli = cli; 853 state->user = user; 854 vwv = state->vwv; 454 855 455 856 if (passlen == 0) { … … 459 860 DATA_BLOB server_chal; 460 861 DATA_BLOB names_blob; 461 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); 462 463 /* note that the 'workgroup' here is a best guess - we don't know 464 the server's domain at this point. The 'server name' is also 465 dodgy... 466 */ 467 names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup); 468 469 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal, 470 &names_blob, 471 &lm_response, &nt_response, NULL, &session_key)) { 862 863 server_chal = data_blob(cli->secblob.data, 864 MIN(cli->secblob.length, 8)); 865 if (tevent_req_nomem(server_chal.data, req)) { 866 return tevent_req_post(req, ev); 867 } 868 869 /* 870 * note that the 'workgroup' here is a best 871 * guess - we don't know the server's domain 872 * at this point. The 'server name' is also 873 * dodgy... 874 */ 875 names_blob = NTLMv2_generate_names_blob( 876 NULL, cli->called.name, workgroup); 877 878 if (tevent_req_nomem(names_blob.data, req)) { 879 return tevent_req_post(req, ev); 880 } 881 882 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, 883 &server_chal, &names_blob, 884 &lm_response, &nt_response, 885 NULL, &session_key)) { 472 886 data_blob_free(&names_blob); 473 887 data_blob_free(&server_chal); 474 return NT_STATUS_ACCESS_DENIED; 888 tevent_req_nterror( 889 req, NT_STATUS_ACCESS_DENIED); 890 return tevent_req_post(req, ev); 475 891 } 476 892 data_blob_free(&names_blob); … … 485 901 #else 486 902 nt_response = data_blob(NULL, 24); 487 SMBNTencrypt(pass,cli->secblob.data,nt_response.data); 903 if (tevent_req_nomem(nt_response.data, req)) { 904 return tevent_req_post(req, ev); 905 } 906 907 SMBNTencrypt(pass, cli->secblob.data, 908 nt_response.data); 488 909 #endif 489 910 /* non encrypted password supplied. Ignore ntpass. */ 490 911 if (lp_client_lanman_auth()) { 912 491 913 lm_response = data_blob(NULL, 24); 492 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) { 493 /* Oops, the LM response is invalid, just put 494 the NT response there instead */ 914 if (tevent_req_nomem(lm_response.data, req)) { 915 return tevent_req_post(req, ev); 916 } 917 918 if (!SMBencrypt(pass,cli->secblob.data, 919 lm_response.data)) { 920 /* 921 * Oops, the LM response is 922 * invalid, just put the NT 923 * response there instead 924 */ 495 925 data_blob_free(&lm_response); 496 lm_response = data_blob(nt_response.data, nt_response.length); 926 lm_response = data_blob( 927 nt_response.data, 928 nt_response.length); 497 929 } 498 930 } else { 499 /* LM disabled, place NT# in LM field instead */ 500 lm_response = data_blob(nt_response.data, nt_response.length); 931 /* 932 * LM disabled, place NT# in LM field 933 * instead 934 */ 935 lm_response = data_blob( 936 nt_response.data, nt_response.length); 501 937 } 502 938 939 if (tevent_req_nomem(lm_response.data, req)) { 940 return tevent_req_post(req, ev); 941 } 942 503 943 session_key = data_blob(NULL, 16); 944 if (tevent_req_nomem(session_key.data, req)) { 945 return tevent_req_post(req, ev); 946 } 504 947 #ifdef LANMAN_ONLY 505 948 E_deshash(pass, session_key.data); … … 516 959 517 960 lm_response = data_blob(pass, passlen); 961 if (tevent_req_nomem(lm_response.data, req)) { 962 return tevent_req_post(req, ev); 963 } 964 518 965 nt_response = data_blob(ntpass, ntpasslen); 519 } 520 521 /* send a session setup command */ 522 memset(cli->outbuf,'\0',smb_size); 523 524 cli_set_message(cli->outbuf,13,0,True); 525 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 526 cli_setup_packet(cli); 527 528 SCVAL(cli->outbuf,smb_vwv0,0xFF); 529 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); 530 SSVAL(cli->outbuf,smb_vwv3,2); 531 SSVAL(cli->outbuf,smb_vwv4,cli->pid); 532 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); 533 SSVAL(cli->outbuf,smb_vwv7,lm_response.length); 534 SSVAL(cli->outbuf,smb_vwv8,nt_response.length); 535 SIVAL(cli->outbuf,smb_vwv11,capabilities); 536 p = smb_buf(cli->outbuf); 537 if (lm_response.length) { 538 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length; 539 } 540 if (nt_response.length) { 541 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length; 542 } 543 p += clistr_push(cli, p, user, -1, STR_TERMINATE); 544 545 /* Upper case here might help some NTLMv2 implementations */ 546 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); 547 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 548 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); 549 cli_setup_bcc(cli, p); 550 551 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { 552 result = cli_nt_error(cli); 553 goto end; 554 } 555 556 /* show_msg(cli->inbuf); */ 557 558 if (cli_is_error(cli)) { 559 result = cli_nt_error(cli); 560 goto end; 966 if (tevent_req_nomem(nt_response.data, req)) { 967 return tevent_req_post(req, ev); 968 } 561 969 } 562 970 563 971 #ifdef LANMAN_ONLY 564 ok = cli_simple_set_signing(cli, session_key, lm_response); 972 state->response = data_blob_talloc( 973 state, lm_response.data, lm_response.length); 565 974 #else 566 ok = cli_simple_set_signing(cli, session_key, nt_response); 975 state->response = data_blob_talloc( 976 state, nt_response.data, nt_response.length); 567 977 #endif 568 if (ok) { 569 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { 570 result = NT_STATUS_ACCESS_DENIED; 571 goto end; 572 } 573 } 574 575 /* use the returned vuid from now on */ 576 cli->vuid = SVAL(cli->inbuf,smb_uid); 577 578 p = smb_buf(cli->inbuf); 579 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), 580 -1, STR_TERMINATE); 581 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 582 -1, STR_TERMINATE); 583 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), 584 -1, STR_TERMINATE); 978 if (tevent_req_nomem(state->response.data, req)) { 979 return tevent_req_post(req, ev); 980 } 981 982 if (session_key.data) { 983 state->session_key = data_blob_talloc( 984 state, session_key.data, session_key.length); 985 if (tevent_req_nomem(state->session_key.data, req)) { 986 return tevent_req_post(req, ev); 987 } 988 } 989 data_blob_free(&session_key); 990 991 SCVAL(vwv+0, 0, 0xff); 992 SCVAL(vwv+0, 1, 0); 993 SSVAL(vwv+1, 0, 0); 994 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 995 SSVAL(vwv+3, 0, 2); 996 SSVAL(vwv+4, 0, cli->pid); 997 SIVAL(vwv+5, 0, cli->sesskey); 998 SSVAL(vwv+7, 0, lm_response.length); 999 SSVAL(vwv+8, 0, nt_response.length); 1000 SSVAL(vwv+9, 0, 0); 1001 SSVAL(vwv+10, 0, 0); 1002 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli)); 1003 1004 bytes = talloc_array(state, uint8_t, 1005 lm_response.length + nt_response.length); 1006 if (tevent_req_nomem(bytes, req)) { 1007 return tevent_req_post(req, ev); 1008 } 1009 if (lm_response.length != 0) { 1010 memcpy(bytes, lm_response.data, lm_response.length); 1011 } 1012 if (nt_response.length != 0) { 1013 memcpy(bytes + lm_response.length, 1014 nt_response.data, nt_response.length); 1015 } 1016 data_blob_free(&lm_response); 1017 data_blob_free(&nt_response); 1018 1019 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 1020 user, strlen(user)+1, NULL); 1021 1022 /* 1023 * Upper case here might help some NTLMv2 implementations 1024 */ 1025 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup); 1026 if (tevent_req_nomem(workgroup_upper, req)) { 1027 return tevent_req_post(req, ev); 1028 } 1029 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 1030 workgroup_upper, strlen(workgroup_upper)+1, 1031 NULL); 1032 TALLOC_FREE(workgroup_upper); 1033 1034 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL); 1035 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL); 1036 if (tevent_req_nomem(bytes, req)) { 1037 return tevent_req_post(req, ev); 1038 } 1039 1040 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv, 1041 talloc_get_size(bytes), bytes); 1042 if (tevent_req_nomem(subreq, req)) { 1043 return tevent_req_post(req, ev); 1044 } 1045 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req); 1046 return req; 1047 } 1048 1049 static void cli_session_setup_nt1_done(struct tevent_req *subreq) 1050 { 1051 struct tevent_req *req = tevent_req_callback_data( 1052 subreq, struct tevent_req); 1053 struct cli_session_setup_nt1_state *state = tevent_req_data( 1054 req, struct cli_session_setup_nt1_state); 1055 struct cli_state *cli = state->cli; 1056 uint32_t num_bytes; 1057 uint8_t *in; 1058 char *inbuf; 1059 uint8_t *bytes; 1060 uint8_t *p; 1061 NTSTATUS status; 1062 ssize_t ret; 1063 uint8_t wct; 1064 uint16_t *vwv; 1065 1066 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 1067 &num_bytes, &bytes); 1068 TALLOC_FREE(subreq); 1069 if (!NT_STATUS_IS_OK(status)) { 1070 tevent_req_nterror(req, status); 1071 return; 1072 } 1073 1074 inbuf = (char *)in; 1075 p = bytes; 1076 1077 cli->vuid = SVAL(inbuf, smb_uid); 1078 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 1079 1080 status = smb_bytes_talloc_string(cli, 1081 inbuf, 1082 &cli->server_os, 1083 p, 1084 bytes+num_bytes-p, 1085 &ret); 1086 if (!NT_STATUS_IS_OK(status)) { 1087 tevent_req_nterror(req, status); 1088 return; 1089 } 1090 p += ret; 1091 1092 status = smb_bytes_talloc_string(cli, 1093 inbuf, 1094 &cli->server_type, 1095 p, 1096 bytes+num_bytes-p, 1097 &ret); 1098 if (!NT_STATUS_IS_OK(status)) { 1099 tevent_req_nterror(req, status); 1100 return; 1101 } 1102 p += ret; 1103 1104 status = smb_bytes_talloc_string(cli, 1105 inbuf, 1106 &cli->server_domain, 1107 p, 1108 bytes+num_bytes-p, 1109 &ret); 1110 if (!NT_STATUS_IS_OK(status)) { 1111 tevent_req_nterror(req, status); 1112 return; 1113 } 1114 p += ret; 585 1115 586 1116 if (strstr(cli->server_type, "Samba")) { … … 588 1118 } 589 1119 590 result = cli_set_username(cli, user); 591 if (!NT_STATUS_IS_OK(result)) { 592 goto end; 593 } 594 595 if (session_key.data) { 1120 status = cli_set_username(cli, state->user); 1121 if (tevent_req_nterror(req, status)) { 1122 return; 1123 } 1124 if (cli_simple_set_signing(cli, state->session_key, state->response) 1125 && !cli_check_sign_mac(cli, (char *)in, 1)) { 1126 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1127 return; 1128 } 1129 if (state->session_key.data) { 596 1130 /* Have plaintext orginal */ 597 cli_set_session_key(cli, session_key); 598 } 599 600 result = NT_STATUS_OK; 601 end: 602 data_blob_free(&lm_response); 603 data_blob_free(&nt_response); 604 data_blob_free(&session_key); 605 return result; 606 } 607 608 /**************************************************************************** 609 Send a extended security session setup blob 610 ****************************************************************************/ 611 612 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) 613 { 614 uint32 capabilities = cli_session_setup_capabilities(cli); 615 char *p; 616 617 capabilities |= CAP_EXTENDED_SECURITY; 618 619 /* send a session setup command */ 620 memset(cli->outbuf,'\0',smb_size); 621 622 cli_set_message(cli->outbuf,12,0,True); 623 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 624 625 cli_setup_packet(cli); 626 627 SCVAL(cli->outbuf,smb_vwv0,0xFF); 628 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); 629 SSVAL(cli->outbuf,smb_vwv3,2); 630 SSVAL(cli->outbuf,smb_vwv4,1); 631 SIVAL(cli->outbuf,smb_vwv5,0); 632 SSVAL(cli->outbuf,smb_vwv7,blob.length); 633 SIVAL(cli->outbuf,smb_vwv10,capabilities); 634 p = smb_buf(cli->outbuf); 635 memcpy(p, blob.data, blob.length); 636 p += blob.length; 637 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 638 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); 639 cli_setup_bcc(cli, p); 640 return cli_send_smb(cli); 641 } 642 643 /**************************************************************************** 644 Send a extended security session setup blob, returning a reply blob. 645 ****************************************************************************/ 646 647 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) 648 { 649 DATA_BLOB blob2 = data_blob_null; 650 char *p; 651 size_t len; 652 653 if (!cli_receive_smb(cli)) 654 return blob2; 655 656 show_msg(cli->inbuf); 657 658 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli), 659 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 660 return blob2; 661 } 662 663 /* use the returned vuid from now on */ 664 cli->vuid = SVAL(cli->inbuf,smb_uid); 665 666 p = smb_buf(cli->inbuf); 667 668 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3)); 669 670 p += blob2.length; 671 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), 672 -1, STR_TERMINATE); 673 674 /* w2k with kerberos doesn't properly null terminate this field */ 675 len = smb_bufrem(cli->inbuf, p); 676 if (p + len < cli->inbuf + cli->bufsize+SAFETY_MARGIN - 2) { 677 char *end_of_buf = p + len; 678 679 SSVAL(p, len, 0); 680 /* Now it's null terminated. */ 681 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 682 -1, STR_TERMINATE); 1131 cli_set_session_key(cli, state->session_key); 1132 } 1133 tevent_req_done(req); 1134 } 1135 1136 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req) 1137 { 1138 return tevent_req_simple_recv_ntstatus(req); 1139 } 1140 1141 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, 1142 const char *pass, size_t passlen, 1143 const char *ntpass, size_t ntpasslen, 1144 const char *workgroup) 1145 { 1146 TALLOC_CTX *frame = talloc_stackframe(); 1147 struct event_context *ev; 1148 struct tevent_req *req; 1149 NTSTATUS status = NT_STATUS_NO_MEMORY; 1150 1151 if (cli_has_async_calls(cli)) { 683 1152 /* 684 * See if there's another string. If so it's the 685 * server domain (part of the 'standard' Samba 686 * server signature). 1153 * Can't use sync call while an async call is in flight 687 1154 */ 688 if (p < end_of_buf) { 689 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), 690 -1, STR_TERMINATE); 691 } 692 } else { 693 /* 694 * No room to null terminate so we can't see if there 695 * is another string (server_domain) afterwards. 696 */ 697 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 698 len, 0); 699 } 700 return blob2; 701 } 702 703 #ifdef HAVE_KRB5 704 /**************************************************************************** 705 Send a extended security session setup blob, returning a reply blob. 706 ****************************************************************************/ 1155 status = NT_STATUS_INVALID_PARAMETER; 1156 goto fail; 1157 } 1158 ev = event_context_init(frame); 1159 if (ev == NULL) { 1160 goto fail; 1161 } 1162 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen, 1163 ntpass, ntpasslen, workgroup); 1164 if (req == NULL) { 1165 goto fail; 1166 } 1167 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1168 goto fail; 1169 } 1170 status = cli_session_setup_nt1_recv(req); 1171 fail: 1172 TALLOC_FREE(frame); 1173 if (!NT_STATUS_IS_OK(status)) { 1174 cli_set_error(cli, status); 1175 } 1176 return status; 1177 } 707 1178 708 1179 /* The following is calculated from : … … 715 1186 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22) 716 1187 717 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) 718 { 719 int32 remaining = blob.length; 720 int32 cur = 0; 721 DATA_BLOB send_blob = data_blob_null; 722 int32 max_blob_size = 0; 723 DATA_BLOB receive_blob = data_blob_null; 1188 struct cli_sesssetup_blob_state { 1189 struct tevent_context *ev; 1190 struct cli_state *cli; 1191 DATA_BLOB blob; 1192 uint16_t max_blob_size; 1193 uint16_t vwv[12]; 1194 uint8_t *buf; 1195 1196 NTSTATUS status; 1197 char *inbuf; 1198 DATA_BLOB ret_blob; 1199 }; 1200 1201 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state, 1202 struct tevent_req **psubreq); 1203 static void cli_sesssetup_blob_done(struct tevent_req *subreq); 1204 1205 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx, 1206 struct tevent_context *ev, 1207 struct cli_state *cli, 1208 DATA_BLOB blob) 1209 { 1210 struct tevent_req *req, *subreq; 1211 struct cli_sesssetup_blob_state *state; 1212 1213 req = tevent_req_create(mem_ctx, &state, 1214 struct cli_sesssetup_blob_state); 1215 if (req == NULL) { 1216 return NULL; 1217 } 1218 state->ev = ev; 1219 state->blob = blob; 1220 state->cli = cli; 724 1221 725 1222 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { 726 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small " 727 "(was %u, need minimum %u)\n", 728 (unsigned int)cli->max_xmit, 729 BASE_SESSSETUP_BLOB_PACKET_SIZE)); 730 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER); 731 return False; 732 } 733 734 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE; 735 736 while ( remaining > 0) { 737 if (remaining >= max_blob_size) { 738 send_blob.length = max_blob_size; 739 remaining -= max_blob_size; 740 } else { 741 send_blob.length = remaining; 742 remaining = 0; 743 } 744 745 send_blob.data = &blob.data[cur]; 746 cur += send_blob.length; 747 748 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", 749 (unsigned int)remaining, 750 (unsigned int)send_blob.length, 751 (unsigned int)cur )); 752 753 if (!cli_session_setup_blob_send(cli, send_blob)) { 754 DEBUG(0, ("cli_session_setup_blob: send failed\n")); 755 return False; 756 } 757 758 receive_blob = cli_session_setup_blob_receive(cli); 759 data_blob_free(&receive_blob); 760 761 if (cli_is_error(cli) && 762 !NT_STATUS_EQUAL( cli_get_nt_error(cli), 763 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 764 DEBUG(0, ("cli_session_setup_blob: receive failed " 765 "(%s)\n", nt_errstr(cli_get_nt_error(cli)))); 766 cli->vuid = 0; 767 return False; 768 } 769 } 770 771 return True; 772 } 1223 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small " 1224 "(was %u, need minimum %u)\n", 1225 (unsigned int)cli->max_xmit, 1226 BASE_SESSSETUP_BLOB_PACKET_SIZE)); 1227 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 1228 return tevent_req_post(req, ev); 1229 } 1230 state->max_blob_size = 1231 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF); 1232 1233 if (!cli_sesssetup_blob_next(state, &subreq)) { 1234 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1235 return tevent_req_post(req, ev); 1236 } 1237 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); 1238 return req; 1239 } 1240 1241 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state, 1242 struct tevent_req **psubreq) 1243 { 1244 struct tevent_req *subreq; 1245 uint16_t thistime; 1246 1247 SCVAL(state->vwv+0, 0, 0xFF); 1248 SCVAL(state->vwv+0, 1, 0); 1249 SSVAL(state->vwv+1, 0, 0); 1250 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE); 1251 SSVAL(state->vwv+3, 0, 2); 1252 SSVAL(state->vwv+4, 0, 1); 1253 SIVAL(state->vwv+5, 0, 0); 1254 1255 thistime = MIN(state->blob.length, state->max_blob_size); 1256 SSVAL(state->vwv+7, 0, thistime); 1257 1258 SSVAL(state->vwv+8, 0, 0); 1259 SSVAL(state->vwv+9, 0, 0); 1260 SIVAL(state->vwv+10, 0, 1261 cli_session_setup_capabilities(state->cli) 1262 | CAP_EXTENDED_SECURITY); 1263 1264 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data, 1265 thistime); 1266 if (state->buf == NULL) { 1267 return false; 1268 } 1269 state->blob.data += thistime; 1270 state->blob.length -= thistime; 1271 1272 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli), 1273 "Unix", 5, NULL); 1274 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli), 1275 "Samba", 6, NULL); 1276 if (state->buf == NULL) { 1277 return false; 1278 } 1279 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0, 1280 12, state->vwv, 1281 talloc_get_size(state->buf), state->buf); 1282 if (subreq == NULL) { 1283 return false; 1284 } 1285 *psubreq = subreq; 1286 return true; 1287 } 1288 1289 static void cli_sesssetup_blob_done(struct tevent_req *subreq) 1290 { 1291 struct tevent_req *req = tevent_req_callback_data( 1292 subreq, struct tevent_req); 1293 struct cli_sesssetup_blob_state *state = tevent_req_data( 1294 req, struct cli_sesssetup_blob_state); 1295 struct cli_state *cli = state->cli; 1296 uint8_t wct; 1297 uint16_t *vwv; 1298 uint32_t num_bytes; 1299 uint8_t *bytes; 1300 NTSTATUS status; 1301 uint8_t *p; 1302 uint16_t blob_length; 1303 uint8_t *inbuf; 1304 ssize_t ret; 1305 1306 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, 1307 &num_bytes, &bytes); 1308 TALLOC_FREE(subreq); 1309 if (!NT_STATUS_IS_OK(status) 1310 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1311 tevent_req_nterror(req, status); 1312 return; 1313 } 1314 1315 state->status = status; 1316 TALLOC_FREE(state->buf); 1317 1318 state->inbuf = (char *)inbuf; 1319 cli->vuid = SVAL(state->inbuf, smb_uid); 1320 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 1321 1322 blob_length = SVAL(vwv+3, 0); 1323 if (blob_length > num_bytes) { 1324 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1325 return; 1326 } 1327 state->ret_blob = data_blob_const(bytes, blob_length); 1328 1329 p = bytes + blob_length; 1330 1331 status = smb_bytes_talloc_string(cli, 1332 (char *)inbuf, 1333 &cli->server_os, 1334 p, 1335 bytes+num_bytes-p, 1336 &ret); 1337 1338 if (!NT_STATUS_IS_OK(status)) { 1339 tevent_req_nterror(req, status); 1340 return; 1341 } 1342 p += ret; 1343 1344 status = smb_bytes_talloc_string(cli, 1345 (char *)inbuf, 1346 &cli->server_type, 1347 p, 1348 bytes+num_bytes-p, 1349 &ret); 1350 1351 if (!NT_STATUS_IS_OK(status)) { 1352 tevent_req_nterror(req, status); 1353 return; 1354 } 1355 p += ret; 1356 1357 status = smb_bytes_talloc_string(cli, 1358 (char *)inbuf, 1359 &cli->server_domain, 1360 p, 1361 bytes+num_bytes-p, 1362 &ret); 1363 1364 if (!NT_STATUS_IS_OK(status)) { 1365 tevent_req_nterror(req, status); 1366 return; 1367 } 1368 p += ret; 1369 1370 if (strstr(cli->server_type, "Samba")) { 1371 cli->is_samba = True; 1372 } 1373 1374 if (state->blob.length != 0) { 1375 /* 1376 * More to send 1377 */ 1378 if (!cli_sesssetup_blob_next(state, &subreq)) { 1379 tevent_req_nomem(NULL, req); 1380 return; 1381 } 1382 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); 1383 return; 1384 } 1385 tevent_req_done(req); 1386 } 1387 1388 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req, 1389 TALLOC_CTX *mem_ctx, 1390 DATA_BLOB *pblob, 1391 char **pinbuf) 1392 { 1393 struct cli_sesssetup_blob_state *state = tevent_req_data( 1394 req, struct cli_sesssetup_blob_state); 1395 NTSTATUS status; 1396 char *inbuf; 1397 1398 if (tevent_req_is_nterror(req, &status)) { 1399 state->cli->vuid = 0; 1400 return status; 1401 } 1402 1403 inbuf = talloc_move(mem_ctx, &state->inbuf); 1404 if (pblob != NULL) { 1405 *pblob = state->ret_blob; 1406 } 1407 if (pinbuf != NULL) { 1408 *pinbuf = inbuf; 1409 } 1410 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */ 1411 return state->status; 1412 } 1413 1414 #ifdef HAVE_KRB5 773 1415 774 1416 /**************************************************************************** … … 784 1426 ****************************************************************************/ 785 1427 786 st atic ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)787 { 1428 struct cli_session_setup_kerberos_state { 1429 struct cli_state *cli; 788 1430 DATA_BLOB negTokenTarg; 789 1431 DATA_BLOB session_key_krb5; 790 NTSTATUS nt_status; 1432 ADS_STATUS ads_status; 1433 }; 1434 1435 static void cli_session_setup_kerberos_done(struct tevent_req *subreq); 1436 1437 static struct tevent_req *cli_session_setup_kerberos_send( 1438 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 1439 const char *principal, const char *workgroup) 1440 { 1441 struct tevent_req *req, *subreq; 1442 struct cli_session_setup_kerberos_state *state; 791 1443 int rc; 792 1444 1445 DEBUG(2,("Doing kerberos session setup\n")); 1446 1447 req = tevent_req_create(mem_ctx, &state, 1448 struct cli_session_setup_kerberos_state); 1449 if (req == NULL) { 1450 return NULL; 1451 } 1452 state->cli = cli; 1453 state->ads_status = ADS_SUCCESS; 1454 793 1455 cli_temp_set_signing(cli); 794 1456 795 DEBUG(2,("Doing kerberos session setup\n")); 796 797 /* generate the encapsulated kerberos5 ticket */ 798 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL); 799 1457 /* 1458 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if 1459 * we have to acquire a ticket. To be fixed later :-) 1460 */ 1461 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg, 1462 &state->session_key_krb5, 0, NULL); 800 1463 if (rc) { 801 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n", 802 error_message(rc))); 803 return ADS_ERROR_KRB5(rc); 1464 DEBUG(1, ("cli_session_setup_kerberos: " 1465 "spnego_gen_krb5_negTokenInit failed: %s\n", 1466 error_message(rc))); 1467 state->ads_status = ADS_ERROR_KRB5(rc); 1468 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 1469 return tevent_req_post(req, ev); 804 1470 } 805 1471 806 1472 #if 0 807 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); 1473 file_save("negTokenTarg.dat", state->negTokenTarg.data, 1474 state->negTokenTarg.length); 808 1475 #endif 809 1476 810 if (!cli_session_setup_blob(cli, negTokenTarg)) { 811 nt_status = cli_nt_error(cli); 812 goto nt_error; 813 } 814 815 if (cli_is_error(cli)) { 816 nt_status = cli_nt_error(cli); 817 if (NT_STATUS_IS_OK(nt_status)) { 818 nt_status = NT_STATUS_UNSUCCESSFUL; 819 } 820 goto nt_error; 821 } 822 823 cli_set_session_key(cli, session_key_krb5); 824 825 if (cli_simple_set_signing( 826 cli, session_key_krb5, data_blob_null)) { 827 828 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { 829 nt_status = NT_STATUS_ACCESS_DENIED; 830 goto nt_error; 831 } 832 } 833 834 data_blob_free(&negTokenTarg); 835 data_blob_free(&session_key_krb5); 836 837 return ADS_ERROR_NT(NT_STATUS_OK); 838 839 nt_error: 840 data_blob_free(&negTokenTarg); 841 data_blob_free(&session_key_krb5); 842 cli->vuid = 0; 843 return ADS_ERROR_NT(nt_status); 1477 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg); 1478 if (tevent_req_nomem(subreq, req)) { 1479 return tevent_req_post(req, ev); 1480 } 1481 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req); 1482 return req; 1483 } 1484 1485 static void cli_session_setup_kerberos_done(struct tevent_req *subreq) 1486 { 1487 struct tevent_req *req = tevent_req_callback_data( 1488 subreq, struct tevent_req); 1489 struct cli_session_setup_kerberos_state *state = tevent_req_data( 1490 req, struct cli_session_setup_kerberos_state); 1491 char *inbuf = NULL; 1492 NTSTATUS status; 1493 1494 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf); 1495 if (!NT_STATUS_IS_OK(status)) { 1496 TALLOC_FREE(subreq); 1497 tevent_req_nterror(req, status); 1498 return; 1499 } 1500 1501 cli_set_session_key(state->cli, state->session_key_krb5); 1502 1503 if (cli_simple_set_signing(state->cli, state->session_key_krb5, 1504 data_blob_null) 1505 && !cli_check_sign_mac(state->cli, inbuf, 1)) { 1506 TALLOC_FREE(subreq); 1507 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1508 return; 1509 } 1510 TALLOC_FREE(subreq); 1511 tevent_req_done(req); 1512 } 1513 1514 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) 1515 { 1516 struct cli_session_setup_kerberos_state *state = tevent_req_data( 1517 req, struct cli_session_setup_kerberos_state); 1518 NTSTATUS status; 1519 1520 if (tevent_req_is_nterror(req, &status)) { 1521 return ADS_ERROR_NT(status); 1522 } 1523 return state->ads_status; 1524 } 1525 1526 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, 1527 const char *principal, 1528 const char *workgroup) 1529 { 1530 struct tevent_context *ev; 1531 struct tevent_req *req; 1532 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1533 1534 if (cli_has_async_calls(cli)) { 1535 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1536 } 1537 ev = tevent_context_init(talloc_tos()); 1538 if (ev == NULL) { 1539 goto fail; 1540 } 1541 req = cli_session_setup_kerberos_send(ev, ev, cli, principal, 1542 workgroup); 1543 if (req == NULL) { 1544 goto fail; 1545 } 1546 if (!tevent_req_poll(req, ev)) { 1547 status = ADS_ERROR_SYSTEM(errno); 1548 goto fail; 1549 } 1550 status = cli_session_setup_kerberos_recv(req); 1551 fail: 1552 TALLOC_FREE(ev); 1553 return status; 844 1554 } 845 1555 #endif /* HAVE_KRB5 */ 846 847 1556 848 1557 /**************************************************************************** … … 850 1559 ****************************************************************************/ 851 1560 852 st atic NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,853 const char *pass, const char *domain)854 { 1561 struct cli_session_setup_ntlmssp_state { 1562 struct tevent_context *ev; 1563 struct cli_state *cli; 855 1564 struct ntlmssp_state *ntlmssp_state; 856 NTSTATUS nt_status; 857 int turn = 1; 858 DATA_BLOB msg1; 859 DATA_BLOB blob = data_blob_null; 860 DATA_BLOB blob_in = data_blob_null; 861 DATA_BLOB blob_out = data_blob_null; 1565 int turn; 1566 DATA_BLOB blob_out; 1567 }; 1568 1569 static int cli_session_setup_ntlmssp_state_destructor( 1570 struct cli_session_setup_ntlmssp_state *state) 1571 { 1572 if (state->ntlmssp_state != NULL) { 1573 TALLOC_FREE(state->ntlmssp_state); 1574 } 1575 return 0; 1576 } 1577 1578 static void cli_session_setup_ntlmssp_done(struct tevent_req *req); 1579 1580 static struct tevent_req *cli_session_setup_ntlmssp_send( 1581 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 1582 const char *user, const char *pass, const char *domain) 1583 { 1584 struct tevent_req *req, *subreq; 1585 struct cli_session_setup_ntlmssp_state *state; 1586 NTSTATUS status; 1587 DATA_BLOB blob_out; 1588 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; 1589 1590 req = tevent_req_create(mem_ctx, &state, 1591 struct cli_session_setup_ntlmssp_state); 1592 if (req == NULL) { 1593 return NULL; 1594 } 1595 state->ev = ev; 1596 state->cli = cli; 1597 state->turn = 1; 1598 1599 state->ntlmssp_state = NULL; 1600 talloc_set_destructor( 1601 state, cli_session_setup_ntlmssp_state_destructor); 862 1602 863 1603 cli_temp_set_signing(cli); 864 1604 865 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { 866 return nt_status; 867 } 868 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); 1605 status = ntlmssp_client_start(state, 1606 global_myname(), 1607 lp_workgroup(), 1608 lp_client_ntlmv2_auth(), 1609 &state->ntlmssp_state); 1610 if (!NT_STATUS_IS_OK(status)) { 1611 goto fail; 1612 } 1613 ntlmssp_want_feature(state->ntlmssp_state, 1614 NTLMSSP_FEATURE_SESSION_KEY); 869 1615 if (cli->use_ccache) { 870 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_CCACHE); 871 } 872 873 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { 874 return nt_status; 875 } 876 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { 877 return nt_status; 878 } 879 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { 880 return nt_status; 881 } 882 883 do { 884 nt_status = ntlmssp_update(ntlmssp_state, 885 blob_in, &blob_out); 886 data_blob_free(&blob_in); 887 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) { 888 if (turn == 1) { 889 /* and wrap it in a SPNEGO wrapper */ 890 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); 891 } else { 892 /* wrap it in SPNEGO */ 893 msg1 = spnego_gen_auth(blob_out); 1616 ntlmssp_want_feature(state->ntlmssp_state, 1617 NTLMSSP_FEATURE_CCACHE); 1618 } 1619 status = ntlmssp_set_username(state->ntlmssp_state, user); 1620 if (!NT_STATUS_IS_OK(status)) { 1621 goto fail; 1622 } 1623 status = ntlmssp_set_domain(state->ntlmssp_state, domain); 1624 if (!NT_STATUS_IS_OK(status)) { 1625 goto fail; 1626 } 1627 status = ntlmssp_set_password(state->ntlmssp_state, pass); 1628 if (!NT_STATUS_IS_OK(status)) { 1629 goto fail; 1630 } 1631 status = ntlmssp_update(state->ntlmssp_state, data_blob_null, 1632 &blob_out); 1633 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1634 goto fail; 1635 } 1636 1637 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL); 1638 data_blob_free(&blob_out); 1639 1640 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); 1641 if (tevent_req_nomem(subreq, req)) { 1642 return tevent_req_post(req, ev); 1643 } 1644 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); 1645 return req; 1646 fail: 1647 tevent_req_nterror(req, status); 1648 return tevent_req_post(req, ev); 1649 } 1650 1651 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) 1652 { 1653 struct tevent_req *req = tevent_req_callback_data( 1654 subreq, struct tevent_req); 1655 struct cli_session_setup_ntlmssp_state *state = tevent_req_data( 1656 req, struct cli_session_setup_ntlmssp_state); 1657 DATA_BLOB blob_in, msg_in, blob_out; 1658 char *inbuf = NULL; 1659 bool parse_ret; 1660 NTSTATUS status; 1661 1662 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in, 1663 &inbuf); 1664 TALLOC_FREE(subreq); 1665 data_blob_free(&state->blob_out); 1666 1667 if (NT_STATUS_IS_OK(status)) { 1668 if (state->cli->server_domain[0] == '\0') { 1669 TALLOC_FREE(state->cli->server_domain); 1670 state->cli->server_domain = talloc_strdup(state->cli, 1671 state->ntlmssp_state->server.netbios_domain); 1672 if (state->cli->server_domain == NULL) { 1673 TALLOC_FREE(subreq); 1674 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1675 return; 894 1676 } 895 896 /* now send that blob on its way */ 897 if (!cli_session_setup_blob_send(cli, msg1)) { 898 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n")); 899 nt_status = NT_STATUS_UNSUCCESSFUL; 900 } else { 901 blob = cli_session_setup_blob_receive(cli); 902 903 nt_status = cli_nt_error(cli); 904 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { 905 if (cli->smb_rw_error == SMB_READ_BAD_SIG) { 906 nt_status = NT_STATUS_ACCESS_DENIED; 907 } else { 908 nt_status = NT_STATUS_UNSUCCESSFUL; 909 } 910 } 911 } 912 data_blob_free(&msg1); 913 } 914 915 if (!blob.length) { 916 if (NT_STATUS_IS_OK(nt_status)) { 917 nt_status = NT_STATUS_UNSUCCESSFUL; 918 } 919 } else if ((turn == 1) && 920 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 921 DATA_BLOB tmp_blob = data_blob_null; 922 /* the server might give us back two challenges */ 923 if (!spnego_parse_challenge(blob, &blob_in, 924 &tmp_blob)) { 925 DEBUG(3,("Failed to parse challenges\n")); 926 nt_status = NT_STATUS_INVALID_PARAMETER; 927 } 928 data_blob_free(&tmp_blob); 929 } else { 930 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, 931 &blob_in)) { 932 DEBUG(3,("Failed to parse auth response\n")); 933 if (NT_STATUS_IS_OK(nt_status) 934 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 935 nt_status = NT_STATUS_INVALID_PARAMETER; 936 } 937 } 938 data_blob_free(&blob); 939 data_blob_free(&blob_out); 940 turn++; 941 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); 942 943 data_blob_free(&blob_in); 944 945 if (NT_STATUS_IS_OK(nt_status)) { 946 947 if (cli->server_domain[0] == '\0') { 948 fstrcpy(cli->server_domain, ntlmssp_state->server_domain); 949 } 950 cli_set_session_key(cli, ntlmssp_state->session_key); 1677 } 1678 cli_set_session_key( 1679 state->cli, state->ntlmssp_state->session_key); 951 1680 952 1681 if (cli_simple_set_signing( 953 cli, ntlmssp_state->session_key, data_blob_null)) { 954 955 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { 956 nt_status = NT_STATUS_ACCESS_DENIED; 957 } 958 } 959 } 960 961 /* we have a reference conter on ntlmssp_state, if we are signing 962 then the state will be kept by the signing engine */ 963 964 ntlmssp_end(&ntlmssp_state); 965 966 if (!NT_STATUS_IS_OK(nt_status)) { 967 cli->vuid = 0; 968 } 969 return nt_status; 1682 state->cli, state->ntlmssp_state->session_key, 1683 data_blob_null) 1684 && !cli_check_sign_mac(state->cli, inbuf, 1)) { 1685 TALLOC_FREE(subreq); 1686 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1687 return; 1688 } 1689 TALLOC_FREE(subreq); 1690 TALLOC_FREE(state->ntlmssp_state); 1691 tevent_req_done(req); 1692 return; 1693 } 1694 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1695 tevent_req_nterror(req, status); 1696 return; 1697 } 1698 1699 if (blob_in.length == 0) { 1700 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 1701 return; 1702 } 1703 1704 if ((state->turn == 1) 1705 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1706 DATA_BLOB tmp_blob = data_blob_null; 1707 /* the server might give us back two challenges */ 1708 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in, 1709 &tmp_blob); 1710 data_blob_free(&tmp_blob); 1711 } else { 1712 parse_ret = spnego_parse_auth_response(state, blob_in, status, 1713 OID_NTLMSSP, &msg_in); 1714 } 1715 state->turn += 1; 1716 1717 if (!parse_ret) { 1718 DEBUG(3,("Failed to parse auth response\n")); 1719 if (NT_STATUS_IS_OK(status) 1720 || NT_STATUS_EQUAL(status, 1721 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1722 tevent_req_nterror( 1723 req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1724 return; 1725 } 1726 } 1727 1728 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out); 1729 1730 if (!NT_STATUS_IS_OK(status) 1731 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1732 TALLOC_FREE(subreq); 1733 TALLOC_FREE(state->ntlmssp_state); 1734 tevent_req_nterror(req, status); 1735 return; 1736 } 1737 1738 state->blob_out = spnego_gen_auth(state, blob_out); 1739 TALLOC_FREE(subreq); 1740 if (tevent_req_nomem(state->blob_out.data, req)) { 1741 return; 1742 } 1743 1744 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, 1745 state->blob_out); 1746 if (tevent_req_nomem(subreq, req)) { 1747 return; 1748 } 1749 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); 1750 } 1751 1752 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) 1753 { 1754 struct cli_session_setup_ntlmssp_state *state = tevent_req_data( 1755 req, struct cli_session_setup_ntlmssp_state); 1756 NTSTATUS status; 1757 1758 if (tevent_req_is_nterror(req, &status)) { 1759 state->cli->vuid = 0; 1760 return status; 1761 } 1762 return NT_STATUS_OK; 1763 } 1764 1765 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, 1766 const char *user, 1767 const char *pass, 1768 const char *domain) 1769 { 1770 struct tevent_context *ev; 1771 struct tevent_req *req; 1772 NTSTATUS status = NT_STATUS_NO_MEMORY; 1773 1774 if (cli_has_async_calls(cli)) { 1775 return NT_STATUS_INVALID_PARAMETER; 1776 } 1777 ev = tevent_context_init(talloc_tos()); 1778 if (ev == NULL) { 1779 goto fail; 1780 } 1781 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain); 1782 if (req == NULL) { 1783 goto fail; 1784 } 1785 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1786 goto fail; 1787 } 1788 status = cli_session_setup_ntlmssp_recv(req); 1789 fail: 1790 TALLOC_FREE(ev); 1791 if (!NT_STATUS_IS_OK(status)) { 1792 cli_set_error(cli, status); 1793 } 1794 return status; 970 1795 } 971 1796 … … 1008 1833 * negprot reply, but right now we do it. If we don't receive one, 1009 1834 * we try to best guess, then fall back to NTLM. */ 1010 if (!spnego_parse_negTokenInit( blob, OIDs, &principal) ||1835 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) || 1011 1836 OIDs[0] == NULL) { 1012 1837 data_blob_free(&blob); … … 1032 1857 status = cli_set_username(cli, user); 1033 1858 if (!NT_STATUS_IS_OK(status)) { 1859 TALLOC_FREE(principal); 1034 1860 return ADS_ERROR_NT(status); 1035 1861 } … … 1075 1901 if (dest_realm) { 1076 1902 realm = SMB_STRDUP(dest_realm); 1903 if (!realm) { 1904 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1905 } 1077 1906 strupper_m(realm); 1078 1907 } else { … … 1086 1915 } 1087 1916 1088 if (realm && *realm) { 1089 principal = talloc_asprintf(talloc_tos(), 1090 "cifs/%s@%s", 1091 cli->desthost, 1092 realm); 1093 if (!principal) { 1094 SAFE_FREE(realm); 1917 if (realm == NULL || *realm == '\0') { 1918 realm = SMB_STRDUP(lp_realm()); 1919 if (!realm) { 1095 1920 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1096 1921 } 1097 DEBUG(3,("cli_session_setup_spnego: guessed " 1098 "server principal=%s\n", 1099 principal ? principal : "<null>")); 1922 strupper_m(realm); 1923 DEBUG(3,("cli_session_setup_spnego: cannot " 1924 "get realm from dest_realm %s, " 1925 "desthost %s. Using default " 1926 "smb.conf realm %s\n", 1927 dest_realm ? dest_realm : "<null>", 1928 cli->desthost, 1929 realm)); 1100 1930 } 1931 1932 principal = talloc_asprintf(talloc_tos(), 1933 "cifs/%s@%s", 1934 cli->desthost, 1935 realm); 1936 if (!principal) { 1937 SAFE_FREE(realm); 1938 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1939 } 1940 DEBUG(3,("cli_session_setup_spnego: guessed " 1941 "server principal=%s\n", 1942 principal ? principal : "<null>")); 1943 1101 1944 SAFE_FREE(realm); 1102 1945 } … … 1145 1988 { 1146 1989 char *p; 1147 fstringuser2;1990 char *user2; 1148 1991 1149 1992 if (user) { 1150 fstrcpy(user2, user);1993 user2 = talloc_strdup(talloc_tos(), user); 1151 1994 } else { 1152 user2[0] ='\0'; 1995 user2 = talloc_strdup(talloc_tos(), ""); 1996 } 1997 if (user2 == NULL) { 1998 return NT_STATUS_NO_MEMORY; 1153 1999 } 1154 2000 … … 1162 2008 *p = 0; 1163 2009 user = p+1; 2010 strupper_m(user2); 1164 2011 workgroup = user2; 1165 2012 } … … 1177 2024 if (cli->protocol < PROTOCOL_NT1) { 1178 2025 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { 1179 DEBUG(1, ("Server requested LM password but 'client lanman auth '"1180 " is disabled\n"));2026 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'" 2027 " or 'client ntlmv2 auth = yes'\n")); 1181 2028 return NT_STATUS_ACCESS_DENIED; 1182 2029 } … … 1184 2031 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && 1185 2032 !lp_client_plaintext_auth() && (*pass)) { 1186 DEBUG(1, ("Server requested plaintext password but"1187 " 'client plaintext auth' is disabled\n"));2033 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'" 2034 " or 'client ntlmv2 auth = yes'\n")); 1188 2035 return NT_STATUS_ACCESS_DENIED; 1189 2036 } … … 1204 2051 1205 2052 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 1206 return cli_session_setup_plain text(cli, user, "", workgroup);2053 return cli_session_setup_plain(cli, user, "", workgroup); 1207 2054 1208 2055 /* if the server doesn't support encryption then we have to use … … 1211 2058 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { 1212 2059 if (!lp_client_plaintext_auth() && (*pass)) { 1213 DEBUG(1, ("Server requested plaintext password but"1214 " 'client plaintext auth' is disabled\n"));2060 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'" 2061 " or 'client ntlmv2 auth = yes'\n")); 1215 2062 return NT_STATUS_ACCESS_DENIED; 1216 2063 } 1217 return cli_session_setup_plain text(cli, user, pass, workgroup);2064 return cli_session_setup_plain(cli, user, pass, workgroup); 1218 2065 } 1219 2066 … … 1251 2098 *****************************************************************************/ 1252 2099 1253 bool cli_ulogoff(struct cli_state *cli) 1254 { 1255 memset(cli->outbuf,'\0',smb_size); 1256 cli_set_message(cli->outbuf,2,0,True); 1257 SCVAL(cli->outbuf,smb_com,SMBulogoffX); 1258 cli_setup_packet(cli); 1259 SSVAL(cli->outbuf,smb_vwv0,0xFF); 1260 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ 1261 1262 cli_send_smb(cli); 1263 if (!cli_receive_smb(cli)) 1264 return False; 1265 1266 if (cli_is_error(cli)) { 1267 return False; 1268 } 1269 1270 cli->vuid = -1; 1271 return True; 2100 struct cli_ulogoff_state { 2101 struct cli_state *cli; 2102 uint16_t vwv[3]; 2103 }; 2104 2105 static void cli_ulogoff_done(struct tevent_req *subreq); 2106 2107 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx, 2108 struct tevent_context *ev, 2109 struct cli_state *cli) 2110 { 2111 struct tevent_req *req, *subreq; 2112 struct cli_ulogoff_state *state; 2113 2114 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state); 2115 if (req == NULL) { 2116 return NULL; 2117 } 2118 state->cli = cli; 2119 2120 SCVAL(state->vwv+0, 0, 0xFF); 2121 SCVAL(state->vwv+1, 0, 0); 2122 SSVAL(state->vwv+2, 0, 0); 2123 2124 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv, 2125 0, NULL); 2126 if (tevent_req_nomem(subreq, req)) { 2127 return tevent_req_post(req, ev); 2128 } 2129 tevent_req_set_callback(subreq, cli_ulogoff_done, req); 2130 return req; 2131 } 2132 2133 static void cli_ulogoff_done(struct tevent_req *subreq) 2134 { 2135 struct tevent_req *req = tevent_req_callback_data( 2136 subreq, struct tevent_req); 2137 struct cli_ulogoff_state *state = tevent_req_data( 2138 req, struct cli_ulogoff_state); 2139 NTSTATUS status; 2140 2141 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2142 if (!NT_STATUS_IS_OK(status)) { 2143 tevent_req_nterror(req, status); 2144 return; 2145 } 2146 state->cli->vuid = -1; 2147 tevent_req_done(req); 2148 } 2149 2150 NTSTATUS cli_ulogoff_recv(struct tevent_req *req) 2151 { 2152 return tevent_req_simple_recv_ntstatus(req); 2153 } 2154 2155 NTSTATUS cli_ulogoff(struct cli_state *cli) 2156 { 2157 struct tevent_context *ev; 2158 struct tevent_req *req; 2159 NTSTATUS status = NT_STATUS_NO_MEMORY; 2160 2161 if (cli_has_async_calls(cli)) { 2162 return NT_STATUS_INVALID_PARAMETER; 2163 } 2164 ev = tevent_context_init(talloc_tos()); 2165 if (ev == NULL) { 2166 goto fail; 2167 } 2168 req = cli_ulogoff_send(ev, ev, cli); 2169 if (req == NULL) { 2170 goto fail; 2171 } 2172 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2173 goto fail; 2174 } 2175 status = cli_ulogoff_recv(req); 2176 fail: 2177 TALLOC_FREE(ev); 2178 if (!NT_STATUS_IS_OK(status)) { 2179 cli_set_error(cli, status); 2180 } 2181 return status; 1272 2182 } 1273 2183 … … 1293 2203 struct tevent_req *req, *subreq; 1294 2204 struct cli_tcon_andx_state *state; 1295 fstring pword;2205 uint8_t p24[24]; 1296 2206 uint16_t *vwv; 1297 2207 char *tmp = NULL; … … 1307 2217 vwv = state->vwv; 1308 2218 1309 fstrcpy(cli->share, share); 2219 cli->share = talloc_strdup(cli, share); 2220 if (!cli->share) { 2221 return NULL; 2222 } 1310 2223 1311 2224 /* in user level security don't send a password now */ … … 1324 2237 DEBUG(1, ("Server requested LANMAN password " 1325 2238 "(share-level security) but " 1326 "'client lanman auth ' is disabled\n"));2239 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n")); 1327 2240 goto access_denied; 1328 2241 } … … 1332 2245 * encryption. 1333 2246 */ 2247 SMBencrypt(pass, cli->secblob.data, p24); 1334 2248 passlen = 24; 1335 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);2249 pass = (const char *)p24; 1336 2250 } else { 1337 2251 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL 1338 2252 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) 1339 2253 == 0) { 2254 char *tmp_pass; 2255 1340 2256 if (!lp_client_plaintext_auth() && (*pass)) { 1341 2257 DEBUG(1, ("Server requested plaintext " 1342 "password but 'client plaintext"1343 " auth' is disabled\n"));2258 "password but " 2259 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n")); 1344 2260 goto access_denied; 1345 2261 } … … 1349 2265 * before using. 1350 2266 */ 1351 passlen = clistr_push(cli, pword, pass, sizeof(pword), 1352 STR_TERMINATE); 2267 tmp_pass = talloc_array(talloc_tos(), char, 128); 2268 if (tmp_pass == NULL) { 2269 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2270 return tevent_req_post(req, ev); 2271 } 2272 passlen = clistr_push(cli, 2273 tmp_pass, 2274 pass, 2275 talloc_get_size(tmp_pass), 2276 STR_TERMINATE); 1353 2277 if (passlen == -1) { 1354 DEBUG(1, ("clistr_push(pword) failed\n"));1355 goto access_denied;2278 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2279 return tevent_req_post(req, ev); 1356 2280 } 1357 } else { 1358 if (passlen) { 1359 memcpy(pword, pass, passlen); 1360 } 2281 pass = tmp_pass; 1361 2282 } 1362 2283 } … … 1368 2289 SSVAL(vwv+3, 0, passlen); 1369 2290 1370 if (passlen ) {1371 bytes = (uint8_t *)talloc_memdup(state, p word, passlen);2291 if (passlen && pass) { 2292 bytes = (uint8_t *)talloc_memdup(state, pass, passlen); 1372 2293 } else { 1373 2294 bytes = talloc_array(state, uint8_t, 0); … … 1453 2374 req, struct cli_tcon_andx_state); 1454 2375 struct cli_state *cli = state->cli; 1455 char *inbuf = (char *)cli_smb_inbuf(subreq); 2376 uint8_t *in; 2377 char *inbuf; 1456 2378 uint8_t wct; 1457 2379 uint16_t *vwv; … … 1460 2382 NTSTATUS status; 1461 2383 1462 status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes); 1463 if (!NT_STATUS_IS_OK(status)) { 1464 TALLOC_FREE(subreq); 2384 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv, 2385 &num_bytes, &bytes); 2386 TALLOC_FREE(subreq); 2387 if (!NT_STATUS_IS_OK(status)) { 1465 2388 tevent_req_nterror(req, status); 1466 2389 return; 1467 2390 } 1468 2391 1469 clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes, 1470 STR_TERMINATE|STR_ASCII); 2392 inbuf = (char *)in; 2393 2394 if (num_bytes) { 2395 if (clistr_pull_talloc(cli, 2396 inbuf, 2397 SVAL(inbuf, smb_flg2), 2398 &cli->dev, 2399 bytes, 2400 num_bytes, 2401 STR_TERMINATE|STR_ASCII) == -1) { 2402 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2403 return; 2404 } 2405 } else { 2406 cli->dev = talloc_strdup(cli, ""); 2407 if (cli->dev == NULL) { 2408 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2409 return; 2410 } 2411 } 1471 2412 1472 2413 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) { … … 1541 2482 ****************************************************************************/ 1542 2483 1543 bool cli_tdis(struct cli_state *cli) 1544 { 1545 memset(cli->outbuf,'\0',smb_size); 1546 cli_set_message(cli->outbuf,0,0,True); 1547 SCVAL(cli->outbuf,smb_com,SMBtdis); 1548 SSVAL(cli->outbuf,smb_tid,cli->cnum); 1549 cli_setup_packet(cli); 1550 1551 cli_send_smb(cli); 1552 if (!cli_receive_smb(cli)) 1553 return False; 1554 1555 if (cli_is_error(cli)) { 1556 return False; 1557 } 1558 1559 cli->cnum = -1; 1560 return True; 1561 } 1562 1563 /**************************************************************************** 1564 Send a negprot command. 1565 ****************************************************************************/ 1566 1567 void cli_negprot_sendsync(struct cli_state *cli) 1568 { 1569 char *p; 1570 int numprots; 1571 1572 if (cli->protocol < PROTOCOL_NT1) 1573 cli->use_spnego = False; 1574 1575 memset(cli->outbuf,'\0',smb_size); 1576 1577 /* setup the protocol strings */ 1578 cli_set_message(cli->outbuf,0,0,True); 1579 1580 p = smb_buf(cli->outbuf); 1581 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) { 1582 if (prots[numprots].prot > cli->protocol) { 1583 break; 1584 } 1585 *p++ = 2; 1586 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); 1587 } 1588 1589 SCVAL(cli->outbuf,smb_com,SMBnegprot); 1590 cli_setup_bcc(cli, p); 1591 cli_setup_packet(cli); 1592 1593 SCVAL(smb_buf(cli->outbuf),0,2); 1594 1595 cli_send_smb(cli); 2484 struct cli_tdis_state { 2485 struct cli_state *cli; 2486 }; 2487 2488 static void cli_tdis_done(struct tevent_req *subreq); 2489 2490 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx, 2491 struct tevent_context *ev, 2492 struct cli_state *cli) 2493 { 2494 struct tevent_req *req, *subreq; 2495 struct cli_tdis_state *state; 2496 2497 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state); 2498 if (req == NULL) { 2499 return NULL; 2500 } 2501 state->cli = cli; 2502 2503 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL); 2504 if (tevent_req_nomem(subreq, req)) { 2505 return tevent_req_post(req, ev); 2506 } 2507 tevent_req_set_callback(subreq, cli_tdis_done, req); 2508 return req; 2509 } 2510 2511 static void cli_tdis_done(struct tevent_req *subreq) 2512 { 2513 struct tevent_req *req = tevent_req_callback_data( 2514 subreq, struct tevent_req); 2515 struct cli_tdis_state *state = tevent_req_data( 2516 req, struct cli_tdis_state); 2517 NTSTATUS status; 2518 2519 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2520 TALLOC_FREE(subreq); 2521 if (!NT_STATUS_IS_OK(status)) { 2522 tevent_req_nterror(req, status); 2523 return; 2524 } 2525 state->cli->cnum = -1; 2526 tevent_req_done(req); 2527 } 2528 2529 NTSTATUS cli_tdis_recv(struct tevent_req *req) 2530 { 2531 return tevent_req_simple_recv_ntstatus(req); 2532 } 2533 2534 NTSTATUS cli_tdis(struct cli_state *cli) 2535 { 2536 struct tevent_context *ev; 2537 struct tevent_req *req; 2538 NTSTATUS status = NT_STATUS_NO_MEMORY; 2539 2540 if (cli_has_async_calls(cli)) { 2541 return NT_STATUS_INVALID_PARAMETER; 2542 } 2543 ev = tevent_context_init(talloc_tos()); 2544 if (ev == NULL) { 2545 goto fail; 2546 } 2547 req = cli_tdis_send(ev, ev, cli); 2548 if (req == NULL) { 2549 goto fail; 2550 } 2551 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2552 goto fail; 2553 } 2554 status = cli_tdis_recv(req); 2555 fail: 2556 TALLOC_FREE(ev); 2557 if (!NT_STATUS_IS_OK(status)) { 2558 cli_set_error(cli, status); 2559 } 2560 return status; 1596 2561 } 1597 2562 … … 1672 2637 NTSTATUS status; 1673 2638 uint16_t protnum; 1674 1675 status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes); 1676 if (!NT_STATUS_IS_OK(status)) { 1677 TALLOC_FREE(subreq); 2639 uint8_t *inbuf; 2640 2641 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv, 2642 &num_bytes, &bytes); 2643 TALLOC_FREE(subreq); 2644 if (!NT_STATUS_IS_OK(status)) { 1678 2645 tevent_req_nterror(req, status); 1679 2646 return; … … 1719 2686 /* work out if they sent us a workgroup */ 1720 2687 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) && 1721 smb_buflen(cli->inbuf) > 8) { 1722 clistr_pull(cli->inbuf, cli->server_domain, 1723 bytes+8, sizeof(cli->server_domain), 1724 num_bytes-8, 1725 STR_UNICODE|STR_NOALIGN); 2688 smb_buflen(inbuf) > 8) { 2689 ssize_t ret; 2690 status = smb_bytes_talloc_string( 2691 cli, (char *)inbuf, &cli->server_domain, 2692 bytes + 8, num_bytes - 8, &ret); 2693 if (tevent_req_nterror(req, status)) { 2694 return; 2695 } 1726 2696 } 1727 2697 … … 1762 2732 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); 1763 2733 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); 2734 if (!cli->outbuf || !cli->inbuf) { 2735 tevent_req_nterror(req, 2736 NT_STATUS_NO_MEMORY); 2737 return; 2738 } 1764 2739 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE; 1765 2740 } … … 1774 2749 cli->serverzone *= 60; 1775 2750 /* this time is converted to GMT by make_unix_date */ 1776 cli->servertime = cli_make_unix_date(1777 cli, (char *)(vwv + 8));2751 cli->servertime = make_unix_date( 2752 (char *)(vwv + 8), cli->serverzone); 1778 2753 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0); 1779 2754 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0); … … 2070 3045 } 2071 3046 2072 fstrcpy(cli->desthost, host); 3047 cli->desthost = talloc_strdup(cli, host); 3048 if (cli->desthost == NULL) { 3049 return NT_STATUS_NO_MEMORY; 3050 } 2073 3051 2074 3052 /* allow hostnames of the form NAME#xx and do a netbios lookup */ … … 2078 3056 } 2079 3057 2080 if (!dest_ss || is_zero_addr( (struct sockaddr *)dest_ss)) {3058 if (!dest_ss || is_zero_addr(dest_ss)) { 2081 3059 NTSTATUS status =resolve_name_list(frame, 2082 3060 cli->desthost, … … 2143 3121 @param dest_ss (optional) The the destination IP, NULL for name based lookup 2144 3122 @param port (optional) The destination port (0 for default) 2145 @param retry bool. Did this connection fail with a retryable error ?2146 2147 3123 */ 2148 3124 NTSTATUS cli_start_connection(struct cli_state **output_cli, … … 2150 3126 const char *dest_host, 2151 3127 struct sockaddr_storage *dest_ss, int port, 2152 int signing_state, int flags, 2153 bool *retry) 3128 int signing_state, int flags) 2154 3129 { 2155 3130 NTSTATUS nt_status; … … 2158 3133 struct cli_state *cli; 2159 3134 struct sockaddr_storage ss; 2160 2161 if (retry)2162 *retry = False;2163 3135 2164 3136 if (!my_name) … … 2194 3166 return nt_status; 2195 3167 } 2196 2197 if (retry)2198 *retry = True;2199 3168 2200 3169 if (!cli_session_request(cli, &calling, &called)) { … … 2249 3218 @param domain User's domain 2250 3219 @param password User's password, unencrypted unix string. 2251 @param retry bool. Did this connection fail with a retryable error ?2252 3220 */ 2253 3221 … … 2259 3227 const char *user, const char *domain, 2260 3228 const char *password, int flags, 2261 int signing_state, 2262 bool *retry) 3229 int signing_state) 2263 3230 { 2264 3231 NTSTATUS nt_status; … … 2274 3241 nt_status = cli_start_connection(&cli, my_name, dest_host, 2275 3242 dest_ss, port, signing_state, 2276 flags , retry);3243 flags); 2277 3244 2278 3245 if (!NT_STATUS_IS_OK(nt_status)) { … … 2399 3366 uint16 *max_xmit, uint16 *tid) 2400 3367 { 2401 char *p; 3368 struct tevent_req *req; 3369 uint16_t *ret_vwv; 3370 uint8_t *bytes; 3371 NTSTATUS status; 2402 3372 2403 3373 if (!lp_client_plaintext_auth() && (*pass)) { … … 2407 3377 } 2408 3378 2409 memset(cli->outbuf,'\0',smb_size); 2410 memset(cli->inbuf,'\0',smb_size); 2411 2412 cli_set_message(cli->outbuf, 0, 0, True); 2413 SCVAL(cli->outbuf,smb_com,SMBtcon); 2414 cli_setup_packet(cli); 2415 2416 p = smb_buf(cli->outbuf); 2417 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN); 2418 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN); 2419 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN); 2420 2421 cli_setup_bcc(cli, p); 2422 2423 cli_send_smb(cli); 2424 if (!cli_receive_smb(cli)) { 2425 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 2426 } 2427 2428 if (cli_is_error(cli)) { 2429 return cli_nt_error(cli); 2430 } 2431 2432 *max_xmit = SVAL(cli->inbuf, smb_vwv0); 2433 *tid = SVAL(cli->inbuf, smb_vwv1); 3379 bytes = talloc_array(talloc_tos(), uint8_t, 0); 3380 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3381 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 3382 service, strlen(service)+1, NULL); 3383 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3384 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 3385 pass, strlen(pass)+1, NULL); 3386 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3387 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 3388 dev, strlen(dev)+1, NULL); 3389 3390 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL, 3391 talloc_get_size(bytes), bytes, &req, 3392 2, NULL, &ret_vwv, NULL, NULL); 3393 if (!NT_STATUS_IS_OK(status)) { 3394 return status; 3395 } 3396 3397 *max_xmit = SVAL(ret_vwv + 0, 0); 3398 *tid = SVAL(ret_vwv + 1, 0); 2434 3399 2435 3400 return NT_STATUS_OK; … … 2455 3420 user_info->password ? user_info->password : "", 2456 3421 flags, 2457 Undefined , NULL);3422 Undefined); 2458 3423 2459 3424 if (NT_STATUS_IS_OK(nt_status)) { … … 2485 3450 2486 3451 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, 2487 struct ip_service *mb_ip,3452 struct sockaddr_storage *mb_ip, 2488 3453 const struct user_auth_info *user_info, 2489 3454 char **pp_workgroup_out) … … 2496 3461 *pp_workgroup_out = NULL; 2497 3462 2498 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);3463 print_sockaddr(addr, sizeof(addr), mb_ip); 2499 3464 DEBUG(99, ("Looking up name of master browser %s\n", 2500 3465 addr)); … … 2511 3476 * MSBROWSE if the wildcard query fails. 2512 3477 */ 2513 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&2514 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {3478 if (!name_status_find("*", 0, 0x1d, mb_ip, name) && 3479 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) { 2515 3480 2516 3481 DEBUG(99, ("Could not retrieve name status for %s\n", … … 2543 3508 char **pp_workgroup_out) 2544 3509 { 2545 struct ip_service *ip_list;3510 struct sockaddr_storage *ip_list; 2546 3511 struct cli_state *cli; 2547 3512 int i, count; 3513 NTSTATUS status; 2548 3514 2549 3515 *pp_workgroup_out = NULL; … … 2553 3519 /* Go looking for workgroups by broadcasting on the local network */ 2554 3520 2555 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, 2556 &count))) { 2557 DEBUG(99, ("No master browsers responded\n")); 3521 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(), 3522 &ip_list, &count); 3523 if (!NT_STATUS_IS_OK(status)) { 3524 DEBUG(99, ("No master browsers responded: %s\n", 3525 nt_errstr(status))); 2558 3526 return False; 2559 3527 } … … 2561 3529 for (i = 0; i < count; i++) { 2562 3530 char addr[INET6_ADDRSTRLEN]; 2563 print_sockaddr(addr, sizeof(addr), &ip_list[i] .ss);3531 print_sockaddr(addr, sizeof(addr), &ip_list[i]); 2564 3532 DEBUG(99, ("Found master browser %s\n", addr)); 2565 3533 -
vendor/current/source3/libsmb/clidfs.c
r597 r740 21 21 22 22 #include "includes.h" 23 #include "libsmb/libsmb.h" 24 #include "libsmb/clirap.h" 25 #include "msdfs.h" 26 #include "trans2.h" 27 #include "libsmb/nmblib.h" 23 28 24 29 /******************************************************************** … … 128 133 129 134 /* have to open a new connection */ 130 if (!(c=cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)))) { 135 c = cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); 136 if (c == NULL) { 131 137 d_printf("Connection to %s failed\n", server_n); 132 if (c) {133 cli_shutdown(c);134 }135 138 return NULL; 136 139 } … … 321 324 } 322 325 323 if (referring_cli && referring_cli-> posix_capabilities) {326 if (referring_cli && referring_cli->requested_posix_capabilities) { 324 327 uint16 major, minor; 325 328 uint32 caplow, caphigh; … … 352 355 353 356 /* Search to the start of the list. */ 354 for (p = cli; p; p = p->prev) {357 for (p = cli; p; p = DLIST_PREV(p)) { 355 358 if (strequal(server, p->desthost) && 356 359 strequal(share,p->share)) { … … 453 456 **********************************************************************/ 454 457 455 static voidsplit_dfs_path(TALLOC_CTX *ctx,458 static bool split_dfs_path(TALLOC_CTX *ctx, 456 459 const char *nodepath, 457 460 char **pp_server, … … 468 471 path = talloc_strdup(ctx, nodepath); 469 472 if (!path) { 470 return;473 goto fail; 471 474 } 472 475 473 476 if ( path[0] != '\\' ) { 474 return;477 goto fail; 475 478 } 476 479 477 480 p = strchr_m( path + 1, '\\' ); 478 481 if ( !p ) { 479 return;482 goto fail; 480 483 } 481 484 … … 492 495 *pp_extrapath = talloc_strdup(ctx, ""); 493 496 } 497 if (*pp_extrapath == NULL) { 498 goto fail; 499 } 494 500 495 501 *pp_share = talloc_strdup(ctx, p); 502 if (*pp_share == NULL) { 503 goto fail; 504 } 505 496 506 *pp_server = talloc_strdup(ctx, &path[1]); 507 if (*pp_server == NULL) { 508 goto fail; 509 } 510 511 TALLOC_FREE(path); 512 return true; 513 514 fail: 515 TALLOC_FREE(*pp_share); 516 TALLOC_FREE(*pp_extrapath); 517 TALLOC_FREE(path); 518 return false; 497 519 } 498 520 … … 565 587 } 566 588 567 if (cli-> posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {589 if (cli->requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 568 590 path_sep = '/'; 569 591 } … … 581 603 ********************************************************************/ 582 604 583 static bool cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) 584 { 585 uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); 586 605 static bool cli_dfs_check_error(struct cli_state *cli, NTSTATUS expected, 606 NTSTATUS status) 607 { 587 608 /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ 588 609 589 if (!((flgs2&FLAGS2_32_BIT_ERROR_CODES) && 590 (flgs2&FLAGS2_UNICODE_STRINGS))) 591 return false; 592 593 if (NT_STATUS_EQUAL(status, NT_STATUS(IVAL(cli->inbuf,smb_rcls)))) 610 if (!(cli->capabilities & CAP_UNICODE)) { 611 return false; 612 } 613 if (!(cli->capabilities & CAP_STATUS32)) { 614 return false; 615 } 616 if (NT_STATUS_EQUAL(status, expected)) { 594 617 return true; 595 618 } 596 619 return false; 597 620 } … … 601 624 ********************************************************************/ 602 625 603 boolcli_dfs_get_referral(TALLOC_CTX *ctx,626 NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx, 604 627 struct cli_state *cli, 605 628 const char *path, 606 CLIENT_DFS_REFERRAL**refs,629 struct client_dfs_referral **refs, 607 630 size_t *num_refs, 608 631 size_t *consumed) … … 610 633 unsigned int data_len = 0; 611 634 unsigned int param_len = 0; 612 uint16 setup = TRANSACT2_GET_DFS_REFERRAL;613 char*param = NULL;614 char *rparam=NULL, *rdata=NULL;635 uint16 setup[1]; 636 uint8_t *param = NULL; 637 uint8_t *rdata = NULL; 615 638 char *p; 616 639 char *endp; … … 620 643 uint16_t consumed_ucs; 621 644 uint16 num_referrals; 622 CLIENT_DFS_REFERRAL*referrals = NULL;623 bool ret = false;645 struct client_dfs_referral *referrals = NULL; 646 NTSTATUS status; 624 647 625 648 *num_refs = 0; 626 649 *refs = NULL; 627 650 628 param = SMB_MALLOC_ARRAY(char, 2+pathlen+2); 651 SSVAL(setup, 0, TRANSACT2_GET_DFS_REFERRAL); 652 653 param = SMB_MALLOC_ARRAY(uint8_t, 2+pathlen+2); 629 654 if (!param) { 655 status = NT_STATUS_NO_MEMORY; 630 656 goto out; 631 657 } 632 658 SSVAL(param, 0, 0x03); /* max referral level */ 633 p = ¶m[2];659 p = (char *)(¶m[2]); 634 660 635 661 path_ucs = (smb_ucs2_t *)p; … … 637 663 param_len = PTR_DIFF(p, param); 638 664 639 if (!cli_send_trans(cli, SMBtrans2, 640 NULL, /* name */ 641 -1, 0, /* fid, flags */ 642 &setup, 1, 0, /* setup, length, max */ 643 param, param_len, 2, /* param, length, max */ 644 NULL, 0, cli->max_xmit /* data, length, max */ 645 )) { 665 status = cli_trans(talloc_tos(), cli, SMBtrans2, 666 NULL, 0xffff, 0, 0, 667 setup, 1, 0, 668 param, param_len, 2, 669 NULL, 0, cli->max_xmit, 670 NULL, 671 NULL, 0, NULL, /* rsetup */ 672 NULL, 0, NULL, 673 &rdata, 4, &data_len); 674 if (!NT_STATUS_IS_OK(status)) { 646 675 goto out; 647 676 } 648 649 if (!cli_receive_trans(cli, SMBtrans2,650 &rparam, ¶m_len,651 &rdata, &data_len)) {652 goto out;653 }654 655 677 if (data_len < 4) { 656 678 goto out; 657 679 } 658 680 659 endp = rdata + data_len;681 endp = (char *)rdata + data_len; 660 682 661 683 consumed_ucs = SVAL(rdata, 0); … … 689 711 uint16 node_offset; 690 712 691 referrals = TALLOC_ARRAY(ctx, CLIENT_DFS_REFERRAL,692 num_referrals);713 referrals = talloc_array(ctx, struct client_dfs_referral, 714 num_referrals); 693 715 694 716 if (!referrals) { … … 697 719 /* start at the referrals array */ 698 720 699 p = rdata+8;721 p = (char *)rdata+8; 700 722 for (i=0; i<num_referrals && p < endp; i++) { 701 723 if (p + 18 > endp) { … … 718 740 } 719 741 clistr_pull_talloc(ctx, cli->inbuf, 742 SVAL(cli->inbuf, smb_flg2), 720 743 &referrals[i].dfspath, 721 744 p+node_offset, -1, … … 732 755 } 733 756 734 ret = true;735 736 757 *num_refs = num_referrals; 737 758 *refs = referrals; … … 741 762 TALLOC_FREE(consumed_path); 742 763 SAFE_FREE(param); 743 SAFE_FREE(rdata); 744 SAFE_FREE(rparam); 745 return ret; 764 TALLOC_FREE(rdata); 765 return status; 746 766 } 747 767 … … 757 777 char **pp_targetpath) 758 778 { 759 CLIENT_DFS_REFERRAL*refs = NULL;779 struct client_dfs_referral *refs = NULL; 760 780 size_t num_refs = 0; 761 781 size_t consumed = 0; … … 773 793 SMB_STRUCT_STAT sbuf; 774 794 uint32 attributes; 795 NTSTATUS status; 775 796 776 797 if ( !rootcli || !path || !targetcli ) { … … 803 824 } 804 825 805 if (cli_qpathinfo_basic( rootcli, dfs_path, &sbuf, &attributes)) { 826 status = cli_qpathinfo_basic( rootcli, dfs_path, &sbuf, &attributes); 827 if (NT_STATUS_IS_OK(status)) { 806 828 /* This is an ordinary path, just return it. */ 807 829 *targetcli = rootcli; … … 815 837 /* Special case where client asked for a path that does not exist */ 816 838 817 if (cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 839 if (cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND, 840 status)) { 818 841 *targetcli = rootcli; 819 842 *pp_targetpath = talloc_strdup(ctx, path); … … 826 849 /* We got an error, check for DFS referral. */ 827 850 828 if (!cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED)) { 851 if (!cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED, 852 status)) { 829 853 return false; 830 854 } … … 845 869 } 846 870 847 if (!cli_dfs_get_referral(ctx, cli_ipc, dfs_path, &refs, 848 &num_refs, &consumed) || !num_refs) { 871 status = cli_dfs_get_referral(ctx, cli_ipc, dfs_path, &refs, 872 &num_refs, &consumed); 873 if (!NT_STATUS_IS_OK(status) || !num_refs) { 849 874 return false; 850 875 } … … 855 880 return false; 856 881 } 857 split_dfs_path(ctx, refs[0].dfspath, &server, &share, &extrapath ); 858 859 if (!server || !share) { 882 if (!split_dfs_path(ctx, refs[0].dfspath, &server, &share, 883 &extrapath)) { 860 884 return false; 861 885 } … … 997 1021 const char *domain) 998 1022 { 999 CLIENT_DFS_REFERRAL*refs = NULL;1023 struct client_dfs_referral *refs = NULL; 1000 1024 size_t num_refs = 0; 1001 1025 size_t consumed = 0; … … 1004 1028 uint16 cnum; 1005 1029 char *newextrapath = NULL; 1030 NTSTATUS status; 1006 1031 1007 1032 if (!cli || !sharename) { … … 1031 1056 1032 1057 if (force_encrypt) { 1033 NTSTATUSstatus = cli_cm_force_encryption(cli,1058 status = cli_cm_force_encryption(cli, 1034 1059 username, 1035 1060 password, … … 1041 1066 } 1042 1067 1043 res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed); 1044 1045 if (!cli_tdis(cli)) { 1068 status = cli_dfs_get_referral(ctx, cli, fullpath, &refs, 1069 &num_refs, &consumed); 1070 res = NT_STATUS_IS_OK(status); 1071 1072 status = cli_tdis(cli); 1073 if (!NT_STATUS_IS_OK(status)) { 1046 1074 return false; 1047 1075 } … … 1057 1085 } 1058 1086 1059 split_dfs_path(ctx, refs[0].dfspath, pp_newserver, 1060 pp_newshare, &newextrapath ); 1061 1062 if ((*pp_newserver == NULL) || (*pp_newshare == NULL)) { 1087 if (!split_dfs_path(ctx, refs[0].dfspath, pp_newserver, 1088 pp_newshare, &newextrapath)) { 1063 1089 return false; 1064 1090 } -
vendor/current/source3/libsmb/clidgram.c
r594 r740 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 21 21 22 22 #include "includes.h" 23 #include "libsmb/libsmb.h" 24 #include "../lib/util/tevent_ntstatus.h" 25 #include "libsmb/clidgram.h" 26 #include "libsmb/nmblib.h" 27 #include "messages.h" 23 28 24 29 /* … … 26 31 */ 27 32 28 static bool cli_send_mailslot(struct messaging_context *msg_ctx, 29 bool unique, const char *mailslot, 33 static bool cli_prep_mailslot(bool unique, const char *mailslot, 30 34 uint16 priority, 31 35 char *buf, int len, 32 36 const char *srcname, int src_type, 33 37 const char *dstname, int dest_type, 34 const struct sockaddr_storage *dest_ss) 35 { 36 struct packet_struct p; 37 struct dgram_packet *dgram = &p.packet.dgram; 38 const struct sockaddr_storage *dest_ss, 39 int dgm_id, 40 struct packet_struct *p) 41 { 42 struct dgram_packet *dgram = &p->packet.dgram; 38 43 char *ptr, *p2; 39 44 char tmp[4]; 40 pid_t nmbd_pid;41 45 char addr[INET6_ADDRSTRLEN]; 42 46 43 if ((nmbd_pid = pidfile_pid("nmbd")) == 0) { 44 DEBUG(3, ("No nmbd found\n")); 45 return False; 46 } 47 48 if (dest_ss->ss_family != AF_INET) { 49 DEBUG(3, ("cli_send_mailslot: can't send to IPv6 address.\n")); 50 return false; 51 } 52 53 memset((char *)&p, '\0', sizeof(p)); 47 ZERO_STRUCTP(p); 54 48 55 49 /* … … 62 56 dgram->header.flags.first = True; 63 57 dgram->header.flags.more = False; 64 dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + 65 ((unsigned)sys_getpid()%(unsigned)100); 58 dgram->header.dgm_id = dgm_id; 66 59 /* source ip is filled by nmbd */ 67 60 dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ … … 105 98 dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ 106 99 107 p .packet_type = DGRAM_PACKET;108 p .ip = ((const struct sockaddr_in *)dest_ss)->sin_addr;109 p .timestamp = time(NULL);100 p->packet_type = DGRAM_PACKET; 101 p->ip = ((const struct sockaddr_in *)dest_ss)->sin_addr; 102 p->timestamp = time(NULL); 110 103 111 104 DEBUG(4,("send_mailslot: Sending to mailslot %s from %s ", … … 115 108 DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), addr)); 116 109 117 return NT_STATUS_IS_OK(messaging_send_buf(msg_ctx, 118 pid_to_procid(nmbd_pid), 119 MSG_SEND_PACKET, 120 (uint8 *)&p, sizeof(p))); 121 } 122 123 static const char *mailslot_name(TALLOC_CTX *mem_ctx, struct in_addr dc_ip) 110 return true; 111 } 112 113 static char *mailslot_name(TALLOC_CTX *mem_ctx, struct in_addr dc_ip) 124 114 { 125 115 return talloc_asprintf(mem_ctx, "%s%X", … … 127 117 } 128 118 129 bool send_getdc_request(TALLOC_CTX *mem_ctx,130 struct messaging_context *msg_ctx,131 struct sockaddr_storage *dc_ss,132 const char *domain_name,133 const DOM_SID *sid,134 uint32_t nt_version)135 { 136 struct in_addr dc_ip; 137 const char *my_acct_name = NULL;138 const char *my_ mailslot = NULL;119 static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, 120 const char *domain_name, 121 const struct dom_sid *sid, 122 uint32_t nt_version, 123 const char *my_mailslot, 124 int dgm_id, 125 struct packet_struct *p) 126 { 127 TALLOC_CTX *frame = talloc_stackframe(); 128 const char *my_acct_name; 139 129 struct nbt_netlogon_packet packet; 140 130 struct NETLOGON_SAM_LOGON_REQUEST *s; 141 131 enum ndr_err_code ndr_err; 142 DATA_BLOB blob ;132 DATA_BLOB blob = data_blob_null; 143 133 struct dom_sid my_sid; 134 bool ret = false; 144 135 145 136 ZERO_STRUCT(packet); 146 137 ZERO_STRUCT(my_sid); 147 138 148 if (dc_ss->ss_family != AF_INET) { 149 return false; 150 } 151 152 if (sid) { 139 if (sid != NULL) { 153 140 my_sid = *sid; 154 141 } 155 142 156 dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; 157 my_mailslot = mailslot_name(mem_ctx, dc_ip); 158 if (!my_mailslot) { 159 return false; 160 } 161 162 my_acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname()); 163 if (!my_acct_name) { 164 return false; 143 my_acct_name = talloc_asprintf(talloc_tos(), "%s$", global_myname()); 144 if (my_acct_name == NULL) { 145 goto fail; 165 146 } 166 147 … … 182 163 } 183 164 184 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &packet,165 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &packet, 185 166 (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); 186 167 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 187 return false;188 } 189 190 ret urn cli_send_mailslot(msg_ctx,191 false, NBT_MAILSLOT_NTLOGON, 0,192 (char *)blob.data, blob.length,193 global_myname(), 0, domain_name, 0x1c,194 dc_ss); 195 } 196 197 bool receive_getdc_response(TALLOC_CTX *mem_ctx, 198 struct sockaddr_storage *dc_ss, 199 const char *domain_name, 200 uint32_t *nt_version,201 const char **dc_name,202 struct netlogon_samlogon_response **_r)203 { 204 struct packet_struct *packet;205 const char *my_mailslot = NULL;206 struct in_addr dc_ip; 168 goto fail; 169 } 170 171 ret = cli_prep_mailslot(false, NBT_MAILSLOT_NTLOGON, 0, 172 (char *)blob.data, blob.length, 173 global_myname(), 0, domain_name, 0x1c, 174 dc_ss, dgm_id, p); 175 fail: 176 TALLOC_FREE(frame); 177 return ret; 178 } 179 180 static bool parse_getdc_response( 181 struct packet_struct *packet, 182 TALLOC_CTX *mem_ctx, 183 const char *domain_name, 184 uint32_t *nt_version, 185 const char **dc_name, 186 struct netlogon_samlogon_response **samlogon_response) 187 { 207 188 DATA_BLOB blob; 208 struct netlogon_samlogon_response r;189 struct netlogon_samlogon_response *r; 209 190 union dgram_message_body p; 210 191 enum ndr_err_code ndr_err; … … 214 195 const char *returned_domain = NULL; 215 196 216 if (dc_ss->ss_family != AF_INET) {217 return false;218 }219 220 dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr;221 222 my_mailslot = mailslot_name(mem_ctx, dc_ip);223 if (!my_mailslot) {224 return false;225 }226 227 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);228 229 if (packet == NULL) {230 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));231 return False;232 }233 234 DEBUG(5, ("Received packet for %s\n", my_mailslot));235 236 197 blob = data_blob_const(packet->packet.dgram.data, 237 198 packet->packet.dgram.datasize); 238 239 199 if (blob.length < 4) { 240 DEBUG(0,("invalid length: %d\n", (int)blob.length)); 241 free_packet(packet); 200 DEBUG(1, ("invalid length: %d\n", (int)blob.length)); 242 201 return false; 243 202 } 244 203 245 204 if (RIVAL(blob.data,0) != DGRAM_SMB) { 246 DEBUG(0,("invalid packet\n")); 247 free_packet(packet); 205 DEBUG(1, ("invalid packet\n")); 248 206 return false; 249 207 } … … 252 210 blob.length -= 4; 253 211 254 ndr_err = ndr_pull_union_blob_all(&blob, mem_ctx, NULL,&p, DGRAM_SMB,212 ndr_err = ndr_pull_union_blob_all(&blob, mem_ctx, &p, DGRAM_SMB, 255 213 (ndr_pull_flags_fn_t)ndr_pull_dgram_smb_packet); 256 214 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 257 DEBUG(0,("failed to parse packet\n")); 258 free_packet(packet); 215 DEBUG(1, ("failed to parse packet\n")); 259 216 return false; 260 217 } 261 218 262 219 if (p.smb.smb_command != SMB_TRANSACTION) { 263 DEBUG(0,("invalid smb_command: %d\n", p.smb.smb_command)); 264 free_packet(packet); 220 DEBUG(1, ("invalid smb_command: %d\n", p.smb.smb_command)); 265 221 return false; 266 222 } … … 272 228 blob = p.smb.body.trans.data; 273 229 274 ZERO_STRUCT(r); 275 276 status = pull_netlogon_samlogon_response(&blob, mem_ctx, NULL, &r); 230 r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); 231 if (!r) { 232 return false; 233 } 234 235 status = pull_netlogon_samlogon_response(&blob, r, r); 277 236 if (!NT_STATUS_IS_OK(status)) { 278 free_packet(packet);279 return false; 280 } 281 282 map_netlogon_samlogon_response( &r);237 TALLOC_FREE(r); 238 return false; 239 } 240 241 map_netlogon_samlogon_response(r); 283 242 284 243 /* do we still need this ? */ 285 *nt_version = r .ntver;286 287 returned_domain = r .data.nt5_ex.domain;288 returned_dc = r .data.nt5_ex.pdc_name;244 *nt_version = r->ntver; 245 246 returned_domain = r->data.nt5_ex.domain_name; 247 returned_dc = r->data.nt5_ex.pdc_name; 289 248 290 249 if (!strequal(returned_domain, domain_name)) { 291 250 DEBUG(3, ("GetDC: Expected domain %s, got %s\n", 292 251 domain_name, returned_domain)); 293 free_packet(packet); 294 return false; 295 } 252 TALLOC_FREE(r); 253 return false; 254 } 255 256 if (*returned_dc == '\\') returned_dc += 1; 257 if (*returned_dc == '\\') returned_dc += 1; 296 258 297 259 *dc_name = talloc_strdup(mem_ctx, returned_dc); 298 260 if (!*dc_name) { 299 free_packet(packet); 300 return false; 301 } 302 303 if (**dc_name == '\\') *dc_name += 1; 304 if (**dc_name == '\\') *dc_name += 1; 305 306 if (_r) { 307 *_r = (struct netlogon_samlogon_response *)talloc_memdup( 308 mem_ctx, &r, sizeof(struct netlogon_samlogon_response)); 309 if (!*_r) { 310 free_packet(packet); 311 return false; 312 } 261 TALLOC_FREE(r); 262 return false; 263 } 264 265 if (samlogon_response) { 266 *samlogon_response = r; 267 } else { 268 TALLOC_FREE(r); 313 269 } 314 270 … … 316 272 *dc_name, returned_domain)); 317 273 318 free_packet(packet);319 274 return True; 320 275 } 276 277 struct nbt_getdc_state { 278 struct tevent_context *ev; 279 struct messaging_context *msg_ctx; 280 struct nb_packet_reader *reader; 281 const char *my_mailslot; 282 pid_t nmbd_pid; 283 284 const struct sockaddr_storage *dc_addr; 285 const char *domain_name; 286 const struct dom_sid *sid; 287 uint32_t nt_version; 288 const char *dc_name; 289 struct netlogon_samlogon_response *samlogon_response; 290 291 struct packet_struct p; 292 }; 293 294 static void nbt_getdc_got_reader(struct tevent_req *subreq); 295 static void nbt_getdc_got_response(struct tevent_req *subreq); 296 297 struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx, 298 struct tevent_context *ev, 299 struct messaging_context *msg_ctx, 300 const struct sockaddr_storage *dc_addr, 301 const char *domain_name, 302 const struct dom_sid *sid, 303 uint32_t nt_version) 304 { 305 struct tevent_req *req, *subreq; 306 struct nbt_getdc_state *state; 307 uint16_t dgm_id; 308 309 req = tevent_req_create(mem_ctx, &state, struct nbt_getdc_state); 310 if (req == NULL) { 311 return NULL; 312 } 313 state->ev = ev; 314 state->msg_ctx = msg_ctx; 315 state->dc_addr = dc_addr; 316 state->domain_name = domain_name; 317 state->sid = sid; 318 state->nt_version = nt_version; 319 320 if (dc_addr->ss_family != AF_INET) { 321 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 322 return tevent_req_post(req, ev); 323 } 324 state->my_mailslot = mailslot_name( 325 state, ((struct sockaddr_in *)dc_addr)->sin_addr); 326 if (tevent_req_nomem(state->my_mailslot, req)) { 327 return tevent_req_post(req, ev); 328 } 329 state->nmbd_pid = pidfile_pid("nmbd"); 330 if (state->nmbd_pid == 0) { 331 DEBUG(3, ("No nmbd found\n")); 332 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 333 return tevent_req_post(req, ev); 334 } 335 336 generate_random_buffer((uint8_t *)(void *)&dgm_id, sizeof(dgm_id)); 337 338 if (!prep_getdc_request(dc_addr, domain_name, sid, nt_version, 339 state->my_mailslot, dgm_id & 0x7fff, 340 &state->p)) { 341 DEBUG(3, ("prep_getdc_request failed\n")); 342 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 343 return tevent_req_post(req, ev); 344 } 345 346 subreq = nb_packet_reader_send(state, ev, DGRAM_PACKET, -1, 347 state->my_mailslot); 348 if (tevent_req_nomem(subreq, req)) { 349 return tevent_req_post(req, ev); 350 } 351 tevent_req_set_callback(subreq, nbt_getdc_got_reader, req); 352 return req; 353 } 354 355 static void nbt_getdc_got_reader(struct tevent_req *subreq) 356 { 357 struct tevent_req *req = tevent_req_callback_data( 358 subreq, struct tevent_req); 359 struct nbt_getdc_state *state = tevent_req_data( 360 req, struct nbt_getdc_state); 361 NTSTATUS status; 362 363 status = nb_packet_reader_recv(subreq, state, &state->reader); 364 TALLOC_FREE(subreq); 365 if (tevent_req_nterror(req, status)) { 366 DEBUG(10, ("nb_packet_reader_recv returned %s\n", 367 nt_errstr(status))); 368 return; 369 } 370 371 status = messaging_send_buf( 372 state->msg_ctx, pid_to_procid(state->nmbd_pid), 373 MSG_SEND_PACKET, (uint8_t *)&state->p, sizeof(state->p)); 374 375 if (tevent_req_nterror(req, status)) { 376 DEBUG(10, ("messaging_send_buf returned %s\n", 377 nt_errstr(status))); 378 return; 379 } 380 subreq = nb_packet_read_send(state, state->ev, state->reader); 381 if (tevent_req_nomem(subreq, req)) { 382 return; 383 } 384 tevent_req_set_callback(subreq, nbt_getdc_got_response, req); 385 } 386 387 static void nbt_getdc_got_response(struct tevent_req *subreq) 388 { 389 struct tevent_req *req = tevent_req_callback_data( 390 subreq, struct tevent_req); 391 struct nbt_getdc_state *state = tevent_req_data( 392 req, struct nbt_getdc_state); 393 struct packet_struct *p; 394 NTSTATUS status; 395 bool ret; 396 397 status = nb_packet_read_recv(subreq, &p); 398 TALLOC_FREE(subreq); 399 if (tevent_req_nterror(req, status)) { 400 return; 401 } 402 403 ret = parse_getdc_response(p, state, state->domain_name, 404 &state->nt_version, &state->dc_name, 405 &state->samlogon_response); 406 free_packet(p); 407 if (!ret) { 408 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 409 return; 410 } 411 tevent_req_done(req); 412 } 413 414 NTSTATUS nbt_getdc_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 415 uint32_t *nt_version, const char **dc_name, 416 struct netlogon_samlogon_response **samlogon_response) 417 { 418 struct nbt_getdc_state *state = tevent_req_data( 419 req, struct nbt_getdc_state); 420 NTSTATUS status; 421 422 if (tevent_req_is_nterror(req, &status)) { 423 return status; 424 } 425 if (nt_version != NULL) { 426 *nt_version = state->nt_version; 427 } 428 if (dc_name != NULL) { 429 *dc_name = talloc_move(mem_ctx, &state->dc_name); 430 } 431 if (samlogon_response != NULL) { 432 *samlogon_response = talloc_move( 433 mem_ctx, &state->samlogon_response); 434 } 435 return NT_STATUS_OK; 436 } 437 438 NTSTATUS nbt_getdc(struct messaging_context *msg_ctx, 439 const struct sockaddr_storage *dc_addr, 440 const char *domain_name, 441 const struct dom_sid *sid, 442 uint32_t nt_version, 443 TALLOC_CTX *mem_ctx, 444 uint32_t *pnt_version, 445 const char **dc_name, 446 struct netlogon_samlogon_response **samlogon_response) 447 { 448 TALLOC_CTX *frame = talloc_stackframe(); 449 struct tevent_context *ev; 450 struct tevent_req *req; 451 NTSTATUS status = NT_STATUS_NO_MEMORY; 452 453 ev = tevent_context_init(frame); 454 if (ev == NULL) { 455 goto fail; 456 } 457 req = nbt_getdc_send(ev, ev, msg_ctx, dc_addr, domain_name, 458 sid, nt_version); 459 if (req == NULL) { 460 goto fail; 461 } 462 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 463 goto fail; 464 } 465 status = nbt_getdc_recv(req, mem_ctx, pnt_version, dc_name, 466 samlogon_response); 467 fail: 468 TALLOC_FREE(frame); 469 return status; 470 } -
vendor/current/source3/libsmb/clientgen.c
r427 r740 20 20 21 21 #include "includes.h" 22 #include "libsmb/libsmb.h" 23 #include "../lib/util/tevent_ntstatus.h" 24 #include "smb_signing.h" 25 #include "async_smb.h" 22 26 23 27 /******************************************************************* … … 247 251 /* If the server is not responding, note that now */ 248 252 if (len < 0) { 249 DEBUG(0, ("Receiving SMB: Server stopped responding\n")); 250 close(cli->fd); 251 cli->fd = -1; 253 /* 254 * only log if the connection should still be open and not when 255 * the connection was closed due to a dropped ip message 256 */ 257 if (cli->fd != -1) { 258 char addr[INET6_ADDRSTRLEN]; 259 print_sockaddr(addr, sizeof(addr), &cli->dest_ss); 260 DEBUG(0, ("Receiving SMB: Server %s stopped responding\n", 261 addr)); 262 close(cli->fd); 263 cli->fd = -1; 264 } 252 265 return false; 253 266 } … … 286 299 } 287 300 288 /****************************************************************************289 Read the data portion of a readX smb.290 The timeout is in milliseconds291 ****************************************************************************/292 293 ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len)294 {295 NTSTATUS status;296 297 set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK);298 299 status = read_fd_with_timeout(300 cli->fd, buffer, len, len, cli->timeout, NULL);301 if (NT_STATUS_IS_OK(status)) {302 return len;303 }304 305 if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {306 set_smb_read_error(&cli->smb_rw_error, SMB_READ_EOF);307 return -1;308 }309 310 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {311 set_smb_read_error(&cli->smb_rw_error, SMB_READ_TIMEOUT);312 return -1;313 }314 315 set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR);316 return -1;317 }318 319 301 static ssize_t write_socket(int fd, const char *buf, size_t len) 320 302 { … … 391 373 if (enc_on) { 392 374 cli_free_enc_buffer(cli, buf_out); 393 }394 395 /* Increment the mid so we can tell between responses. */396 cli->mid++;397 if (!cli->mid)398 cli->mid++;399 return true;400 }401 402 /****************************************************************************403 Send a "direct" writeX smb to a fd.404 ****************************************************************************/405 406 bool cli_send_smb_direct_writeX(struct cli_state *cli,407 const char *p,408 size_t extradata)409 {410 /* First length to send is the offset to the data. */411 size_t len = SVAL(cli->outbuf,smb_vwv11) + 4;412 size_t nwritten=0;413 struct iovec iov[2];414 415 /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */416 if (cli->fd == -1) {417 return false;418 }419 420 if (client_is_signing_on(cli)) {421 DEBUG(0,("cli_send_smb_large: cannot send signed packet.\n"));422 return false;423 }424 425 iov[0].iov_base = (void *)cli->outbuf;426 iov[0].iov_len = len;427 iov[1].iov_base = CONST_DISCARD(void *, p);428 iov[1].iov_len = extradata;429 430 nwritten = write_data_iov(cli->fd, iov, 2);431 if (nwritten < (len + extradata)) {432 close(cli->fd);433 cli->fd = -1;434 cli->smb_rw_error = SMB_WRITE_ERROR;435 DEBUG(0,("Error writing %d bytes to client. (%s)\n",436 (int)(len+extradata), strerror(errno)));437 return false;438 375 } 439 376 … … 639 576 #if defined(DEVELOPER) 640 577 /* just because we over-allocate, doesn't mean it's right to use it */ 641 clobber_region( FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN);642 clobber_region( FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN);578 clobber_region(__FUNCTION__, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); 579 clobber_region(__FUNCTION__, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); 643 580 #endif 644 581 … … 694 631 ****************************************************************************/ 695 632 696 void cli_shutdown(struct cli_state *cli) 697 { 698 if (cli == NULL) { 699 return; 700 } 701 702 if (cli->prev == NULL) { 703 /* 704 * Possible head of a DFS list, 705 * shutdown all subsidiary DFS 706 * connections. 707 */ 708 struct cli_state *p, *next; 709 710 for (p = cli->next; p; p = next) { 711 next = p->next; 712 cli_shutdown(p); 713 } 714 } else { 715 /* 716 * We're a subsidiary connection. 717 * Just remove ourselves from the 718 * DFS list. 719 */ 720 DLIST_REMOVE(cli->prev, cli); 721 } 722 633 static void _cli_shutdown(struct cli_state *cli) 634 { 723 635 cli_nt_pipes_close(cli); 724 636 … … 760 672 } 761 673 674 void cli_shutdown(struct cli_state *cli) 675 { 676 struct cli_state *cli_head; 677 if (cli == NULL) { 678 return; 679 } 680 DLIST_HEAD(cli, cli_head); 681 if (cli_head == cli) { 682 /* 683 * head of a DFS list, shutdown all subsidiary DFS 684 * connections. 685 */ 686 struct cli_state *p, *next; 687 688 for (p = cli_head->next; p; p = next) { 689 next = p->next; 690 DLIST_REMOVE(cli_head, p); 691 _cli_shutdown(p); 692 } 693 } else { 694 DLIST_REMOVE(cli_head, cli); 695 } 696 697 _cli_shutdown(cli); 698 } 699 762 700 /**************************************************************************** 763 701 Set socket options on a open connection. … … 789 727 cli->case_sensitive = case_sensitive; 790 728 return ret; 791 }792 793 /****************************************************************************794 Send a keepalive packet to the server795 ****************************************************************************/796 797 bool cli_send_keepalive(struct cli_state *cli)798 {799 if (cli->fd == -1) {800 DEBUG(3, ("cli_send_keepalive: fd == -1\n"));801 return false;802 }803 if (!send_keepalive(cli->fd)) {804 close(cli->fd);805 cli->fd = -1;806 DEBUG(0,("Error sending keepalive packet to client.\n"));807 return false;808 }809 return true;810 729 } 811 730 … … 854 773 uint32_t num_bytes; 855 774 uint8_t *bytes; 856 857 status = cli_smb_recv(subreq, 0, NULL, NULL, &num_bytes, &bytes); 775 uint8_t *inbuf; 776 777 status = cli_smb_recv(subreq, state, &inbuf, 0, NULL, NULL, 778 &num_bytes, &bytes); 858 779 if (!NT_STATUS_IS_OK(status)) { 859 780 tevent_req_nterror(req, status); … … 964 885 return false; 965 886 } 887 888 NTSTATUS cli_smb(TALLOC_CTX *mem_ctx, struct cli_state *cli, 889 uint8_t smb_command, uint8_t additional_flags, 890 uint8_t wct, uint16_t *vwv, 891 uint32_t num_bytes, const uint8_t *bytes, 892 struct tevent_req **result_parent, 893 uint8_t min_wct, uint8_t *pwct, uint16_t **pvwv, 894 uint32_t *pnum_bytes, uint8_t **pbytes) 895 { 896 struct tevent_context *ev; 897 struct tevent_req *req = NULL; 898 NTSTATUS status = NT_STATUS_NO_MEMORY; 899 900 if (cli_has_async_calls(cli)) { 901 return NT_STATUS_INVALID_PARAMETER; 902 } 903 ev = tevent_context_init(mem_ctx); 904 if (ev == NULL) { 905 goto fail; 906 } 907 req = cli_smb_send(mem_ctx, ev, cli, smb_command, additional_flags, 908 wct, vwv, num_bytes, bytes); 909 if (req == NULL) { 910 goto fail; 911 } 912 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 913 goto fail; 914 } 915 status = cli_smb_recv(req, NULL, NULL, min_wct, pwct, pvwv, 916 pnum_bytes, pbytes); 917 fail: 918 TALLOC_FREE(ev); 919 if (NT_STATUS_IS_OK(status) && (result_parent != NULL)) { 920 *result_parent = req; 921 } 922 return status; 923 } -
vendor/current/source3/libsmb/clierror.c
r427 r740 21 21 22 22 #include "includes.h" 23 #include "libsmb/libsmb.h" 23 24 24 25 /***************************************************** -
vendor/current/source3/libsmb/clifile.c
r414 r740 4 4 Copyright (C) Andrew Tridgell 1994-1998 5 5 Copyright (C) Jeremy Allison 2001-2009 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "system/filesys.h" 23 #include "libsmb/libsmb.h" 24 #include "../lib/util/tevent_ntstatus.h" 25 #include "async_smb.h" 26 #include "libsmb/clirap.h" 27 #include "trans2.h" 28 #include "ntioctl.h" 22 29 23 30 /*********************************************************** … … 92 99 } 93 100 101 uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, 102 const uint8_t *bytes, size_t num_bytes) 103 { 104 size_t buflen; 105 106 if (buf == NULL) { 107 return NULL; 108 } 109 buflen = talloc_get_size(buf); 110 111 buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, 112 buflen + 1 + num_bytes); 113 if (buf == NULL) { 114 return NULL; 115 } 116 buf[buflen] = prefix; 117 memcpy(&buf[buflen+1], bytes, num_bytes); 118 return buf; 119 } 120 94 121 /*********************************************************** 95 122 Same as smb_bytes_push_str(), but without the odd byte … … 107 134 } 108 135 136 struct cli_setpathinfo_state { 137 uint16_t setup; 138 uint8_t *param; 139 }; 140 141 static void cli_setpathinfo_done(struct tevent_req *subreq); 142 143 struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx, 144 struct tevent_context *ev, 145 struct cli_state *cli, 146 uint16_t level, 147 const char *path, 148 uint8_t *data, 149 size_t data_len) 150 { 151 struct tevent_req *req, *subreq; 152 struct cli_setpathinfo_state *state; 153 154 req = tevent_req_create(mem_ctx, &state, 155 struct cli_setpathinfo_state); 156 if (req == NULL) { 157 return NULL; 158 } 159 160 /* Setup setup word. */ 161 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO); 162 163 /* Setup param array. */ 164 state->param = TALLOC_ZERO_ARRAY(state, uint8_t, 6); 165 if (tevent_req_nomem(state->param, req)) { 166 return tevent_req_post(req, ev); 167 } 168 SSVAL(state->param, 0, level); 169 170 state->param = trans2_bytes_push_str( 171 state->param, cli_ucs2(cli), path, strlen(path)+1, NULL); 172 if (tevent_req_nomem(state->param, req)) { 173 return tevent_req_post(req, ev); 174 } 175 176 subreq = cli_trans_send( 177 state, /* mem ctx. */ 178 ev, /* event ctx. */ 179 cli, /* cli_state. */ 180 SMBtrans2, /* cmd. */ 181 NULL, /* pipe name. */ 182 -1, /* fid. */ 183 0, /* function. */ 184 0, /* flags. */ 185 &state->setup, /* setup. */ 186 1, /* num setup uint16_t words. */ 187 0, /* max returned setup. */ 188 state->param, /* param. */ 189 talloc_get_size(state->param), /* num param. */ 190 2, /* max returned param. */ 191 data, /* data. */ 192 data_len, /* num data. */ 193 0); /* max returned data. */ 194 195 if (tevent_req_nomem(subreq, req)) { 196 return tevent_req_post(req, ev); 197 } 198 tevent_req_set_callback(subreq, cli_setpathinfo_done, req); 199 return req; 200 } 201 202 static void cli_setpathinfo_done(struct tevent_req *subreq) 203 { 204 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 205 NULL, 0, NULL, NULL, 0, NULL); 206 tevent_req_simple_finish_ntstatus(subreq, status); 207 } 208 209 NTSTATUS cli_setpathinfo_recv(struct tevent_req *req) 210 { 211 return tevent_req_simple_recv_ntstatus(req); 212 } 213 214 NTSTATUS cli_setpathinfo(struct cli_state *cli, 215 uint16_t level, 216 const char *path, 217 uint8_t *data, 218 size_t data_len) 219 { 220 TALLOC_CTX *frame = talloc_stackframe(); 221 struct tevent_context *ev; 222 struct tevent_req *req; 223 NTSTATUS status = NT_STATUS_NO_MEMORY; 224 225 if (cli_has_async_calls(cli)) { 226 /* 227 * Can't use sync call while an async call is in flight 228 */ 229 status = NT_STATUS_INVALID_PARAMETER; 230 goto fail; 231 } 232 ev = tevent_context_init(frame); 233 if (ev == NULL) { 234 goto fail; 235 } 236 req = cli_setpathinfo_send(ev, ev, cli, level, path, data, data_len); 237 if (req == NULL) { 238 goto fail; 239 } 240 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 241 goto fail; 242 } 243 status = cli_setpathinfo_recv(req); 244 fail: 245 TALLOC_FREE(frame); 246 return status; 247 } 248 109 249 /**************************************************************************** 110 250 Hard/Symlink a file (UNIX extensions). … … 112 252 ****************************************************************************/ 113 253 114 struct link_state { 115 uint16_t setup; 116 uint8_t *param; 254 struct cli_posix_link_internal_state { 117 255 uint8_t *data; 118 256 }; 119 257 120 static void cli_posix_link_internal_done(struct tevent_req *subreq) 121 { 122 struct tevent_req *req = tevent_req_callback_data( 123 subreq, struct tevent_req); 124 struct link_state *state = tevent_req_data(req, struct link_state); 125 NTSTATUS status; 126 127 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 128 TALLOC_FREE(subreq); 129 if (!NT_STATUS_IS_OK(status)) { 130 tevent_req_nterror(req, status); 131 return; 132 } 133 tevent_req_done(req); 134 } 258 static void cli_posix_link_internal_done(struct tevent_req *subreq); 135 259 136 260 static struct tevent_req *cli_posix_link_internal_send(TALLOC_CTX *mem_ctx, 137 261 struct event_context *ev, 138 262 struct cli_state *cli, 263 uint16_t level, 139 264 const char *oldname, 140 const char *newname, 141 bool hardlink) 265 const char *newname) 142 266 { 143 267 struct tevent_req *req = NULL, *subreq = NULL; 144 struct link_state *state = NULL; 145 146 req = tevent_req_create(mem_ctx, &state, struct link_state); 268 struct cli_posix_link_internal_state *state = NULL; 269 270 req = tevent_req_create(mem_ctx, &state, 271 struct cli_posix_link_internal_state); 147 272 if (req == NULL) { 148 273 return NULL; 149 }150 151 /* Setup setup word. */152 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);153 154 /* Setup param array. */155 state->param = talloc_array(state, uint8_t, 6);156 if (tevent_req_nomem(state->param, req)) {157 return tevent_req_post(req, ev);158 }159 memset(state->param, '\0', 6);160 SSVAL(state->param,0,hardlink ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);161 162 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), newname,163 strlen(newname)+1, NULL);164 165 if (tevent_req_nomem(state->param, req)) {166 return tevent_req_post(req, ev);167 274 } 168 275 … … 172 279 return tevent_req_post(req, ev); 173 280 } 174 state->data = trans2_bytes_push_str(state->data, cli_ucs2(cli), oldname, 175 strlen(oldname)+1, NULL); 176 177 subreq = cli_trans_send(state, /* mem ctx. */ 178 ev, /* event ctx. */ 179 cli, /* cli_state. */ 180 SMBtrans2, /* cmd. */ 181 NULL, /* pipe name. */ 182 -1, /* fid. */ 183 0, /* function. */ 184 0, /* flags. */ 185 &state->setup, /* setup. */ 186 1, /* num setup uint16_t words. */ 187 0, /* max returned setup. */ 188 state->param, /* param. */ 189 talloc_get_size(state->param), /* num param. */ 190 2, /* max returned param. */ 191 state->data, /* data. */ 192 talloc_get_size(state->data), /* num data. */ 193 0); /* max returned data. */ 194 281 state->data = trans2_bytes_push_str( 282 state->data, cli_ucs2(cli), oldname, strlen(oldname)+1, NULL); 283 284 subreq = cli_setpathinfo_send( 285 state, ev, cli, level, newname, 286 state->data, talloc_get_size(state->data)); 195 287 if (tevent_req_nomem(subreq, req)) { 196 288 return tevent_req_post(req, ev); … … 198 290 tevent_req_set_callback(subreq, cli_posix_link_internal_done, req); 199 291 return req; 292 } 293 294 static void cli_posix_link_internal_done(struct tevent_req *subreq) 295 { 296 NTSTATUS status = cli_setpathinfo_recv(subreq); 297 tevent_req_simple_finish_ntstatus(subreq, status); 200 298 } 201 299 … … 210 308 const char *newname) 211 309 { 212 return cli_posix_link_internal_send( mem_ctx, ev, cli,213 oldname, newname, false);310 return cli_posix_link_internal_send( 311 mem_ctx, ev, cli, SMB_SET_FILE_UNIX_LINK, oldname, newname); 214 312 } 215 313 216 314 NTSTATUS cli_posix_symlink_recv(struct tevent_req *req) 217 315 { 218 NTSTATUS status; 219 220 if (tevent_req_is_nterror(req, &status)) { 221 return status; 222 } 223 return NT_STATUS_OK; 316 return tevent_req_simple_recv_ntstatus(req); 224 317 } 225 318 … … 277 370 278 371 struct readlink_state { 279 uint16_t setup;280 uint8_t *param;281 372 uint8_t *data; 282 373 uint32_t num_data; 283 374 }; 284 375 285 static void cli_posix_readlink_done(struct tevent_req *subreq) 286 { 287 struct tevent_req *req = tevent_req_callback_data( 288 subreq, struct tevent_req); 289 struct readlink_state *state = tevent_req_data(req, struct readlink_state); 290 NTSTATUS status; 291 292 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, 293 &state->data, &state->num_data); 294 TALLOC_FREE(subreq); 295 if (!NT_STATUS_IS_OK(status)) { 296 tevent_req_nterror(req, status); 297 return; 298 } 299 if (state->num_data == 0) { 300 tevent_req_nterror(req, NT_STATUS_DATA_ERROR); 301 return; 302 } 303 if (state->data[state->num_data-1] != '\0') { 304 tevent_req_nterror(req, NT_STATUS_DATA_ERROR); 305 return; 306 } 307 tevent_req_done(req); 308 } 376 static void cli_posix_readlink_done(struct tevent_req *subreq); 309 377 310 378 struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx, … … 318 386 uint32_t maxbytelen = (uint32_t)(cli_ucs2(cli) ? len*3 : len); 319 387 320 if (maxbytelen < len) { 388 req = tevent_req_create(mem_ctx, &state, struct readlink_state); 389 if (req == NULL) { 321 390 return NULL; 322 391 } 323 392 324 req = tevent_req_create(mem_ctx, &state, struct readlink_state); 325 if (req == NULL) { 326 return NULL; 327 } 328 329 /* Setup setup word. */ 330 SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); 331 332 /* Setup param array. */ 333 state->param = talloc_array(state, uint8_t, 6); 334 if (tevent_req_nomem(state->param, req)) { 335 return tevent_req_post(req, ev); 336 } 337 memset(state->param, '\0', 6); 338 SSVAL(state->param,0,SMB_QUERY_FILE_UNIX_LINK); 339 340 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, 341 strlen(fname)+1, NULL); 342 343 if (tevent_req_nomem(state->param, req)) { 344 return tevent_req_post(req, ev); 345 } 346 347 subreq = cli_trans_send(state, /* mem ctx. */ 348 ev, /* event ctx. */ 349 cli, /* cli_state. */ 350 SMBtrans2, /* cmd. */ 351 NULL, /* pipe name. */ 352 -1, /* fid. */ 353 0, /* function. */ 354 0, /* flags. */ 355 &state->setup, /* setup. */ 356 1, /* num setup uint16_t words. */ 357 0, /* max returned setup. */ 358 state->param, /* param. */ 359 talloc_get_size(state->param), /* num param. */ 360 2, /* max returned param. */ 361 NULL, /* data. */ 362 0, /* num data. */ 363 maxbytelen); /* max returned data. */ 364 393 /* 394 * Len is in bytes, we need it in UCS2 units. 395 */ 396 if ((2*len < len) || (maxbytelen < len)) { 397 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 398 return tevent_req_post(req, ev); 399 } 400 401 subreq = cli_qpathinfo_send(state, ev, cli, fname, 402 SMB_QUERY_FILE_UNIX_LINK, 1, maxbytelen); 365 403 if (tevent_req_nomem(subreq, req)) { 366 404 return tevent_req_post(req, ev); … … 368 406 tevent_req_set_callback(subreq, cli_posix_readlink_done, req); 369 407 return req; 408 } 409 410 static void cli_posix_readlink_done(struct tevent_req *subreq) 411 { 412 struct tevent_req *req = tevent_req_callback_data( 413 subreq, struct tevent_req); 414 struct readlink_state *state = tevent_req_data( 415 req, struct readlink_state); 416 NTSTATUS status; 417 418 status = cli_qpathinfo_recv(subreq, state, &state->data, 419 &state->num_data); 420 TALLOC_FREE(subreq); 421 if (tevent_req_nterror(req, status)) { 422 return; 423 } 424 /* 425 * num_data is > 1, we've given 1 as minimum to cli_qpathinfo_send 426 */ 427 if (state->data[state->num_data-1] != '\0') { 428 tevent_req_nterror(req, NT_STATUS_DATA_ERROR); 429 return; 430 } 431 tevent_req_done(req); 370 432 } 371 433 … … 423 485 } 424 486 425 /* Len is in bytes, we need it in UCS2 units. */426 if (2*len < len) {427 status = NT_STATUS_INVALID_PARAMETER;428 goto fail;429 }430 431 487 req = cli_posix_readlink_send(frame, 432 488 ev, … … 464 520 const char *newname) 465 521 { 466 return cli_posix_link_internal_send( mem_ctx, ev, cli,467 oldname, newname, true);522 return cli_posix_link_internal_send( 523 mem_ctx, ev, cli, SMB_SET_FILE_UNIX_HLINK, oldname, newname); 468 524 } 469 525 470 526 NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req) 471 527 { 472 NTSTATUS status; 473 474 if (tevent_req_is_nterror(req, &status)) { 475 return status; 476 } 477 return NT_STATUS_OK; 528 return tevent_req_simple_recv_ntstatus(req); 478 529 } 479 530 … … 625 676 626 677 struct getfacl_state { 627 uint16_t setup;628 uint8_t *param;629 678 uint32_t num_data; 630 679 uint8_t *data; 631 680 }; 632 681 633 static void cli_posix_getfacl_done(struct tevent_req *subreq) 634 { 635 struct tevent_req *req = tevent_req_callback_data( 636 subreq, struct tevent_req); 637 struct getfacl_state *state = tevent_req_data(req, struct getfacl_state); 638 NTSTATUS status; 639 640 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, 641 &state->data, &state->num_data); 642 TALLOC_FREE(subreq); 643 if (!NT_STATUS_IS_OK(status)) { 644 tevent_req_nterror(req, status); 645 return; 646 } 647 tevent_req_done(req); 648 } 682 static void cli_posix_getfacl_done(struct tevent_req *subreq); 649 683 650 684 struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx, … … 654 688 { 655 689 struct tevent_req *req = NULL, *subreq = NULL; 656 struct link_state *state = NULL;690 struct getfacl_state *state = NULL; 657 691 658 692 req = tevent_req_create(mem_ctx, &state, struct getfacl_state); … … 660 694 return NULL; 661 695 } 662 663 /* Setup setup word. */ 664 SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO); 665 666 /* Setup param array. */ 667 state->param = talloc_array(state, uint8_t, 6); 668 if (tevent_req_nomem(state->param, req)) { 669 return tevent_req_post(req, ev); 670 } 671 memset(state->param, '\0', 6); 672 SSVAL(state->param, 0, SMB_QUERY_POSIX_ACL); 673 674 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname, 675 strlen(fname)+1, NULL); 676 677 if (tevent_req_nomem(state->param, req)) { 678 return tevent_req_post(req, ev); 679 } 680 681 subreq = cli_trans_send(state, /* mem ctx. */ 682 ev, /* event ctx. */ 683 cli, /* cli_state. */ 684 SMBtrans2, /* cmd. */ 685 NULL, /* pipe name. */ 686 -1, /* fid. */ 687 0, /* function. */ 688 0, /* flags. */ 689 &state->setup, /* setup. */ 690 1, /* num setup uint16_t words. */ 691 0, /* max returned setup. */ 692 state->param, /* param. */ 693 talloc_get_size(state->param), /* num param. */ 694 2, /* max returned param. */ 695 NULL, /* data. */ 696 0, /* num data. */ 697 cli->max_xmit); /* max returned data. */ 698 696 subreq = cli_qpathinfo_send(state, ev, cli, fname, SMB_QUERY_POSIX_ACL, 697 0, cli->max_xmit); 699 698 if (tevent_req_nomem(subreq, req)) { 700 699 return tevent_req_post(req, ev); … … 702 701 tevent_req_set_callback(subreq, cli_posix_getfacl_done, req); 703 702 return req; 703 } 704 705 static void cli_posix_getfacl_done(struct tevent_req *subreq) 706 { 707 struct tevent_req *req = tevent_req_callback_data( 708 subreq, struct tevent_req); 709 struct getfacl_state *state = tevent_req_data( 710 req, struct getfacl_state); 711 NTSTATUS status; 712 713 status = cli_qpathinfo_recv(subreq, state, &state->data, 714 &state->num_data); 715 TALLOC_FREE(subreq); 716 if (tevent_req_nterror(req, status)) { 717 return; 718 } 719 tevent_req_done(req); 704 720 } 705 721 … … 774 790 775 791 struct stat_state { 776 uint16_t setup;777 uint8_t *param;778 792 uint32_t num_data; 779 793 uint8_t *data; 780 794 }; 795 796 static void cli_posix_stat_done(struct tevent_req *subreq); 797 798 struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx, 799 struct event_context *ev, 800 struct cli_state *cli, 801 const char *fname) 802 { 803 struct tevent_req *req = NULL, *subreq = NULL; 804 struct stat_state *state = NULL; 805 806 req = tevent_req_create(mem_ctx, &state, struct stat_state); 807 if (req == NULL) { 808 return NULL; 809 } 810 subreq = cli_qpathinfo_send(state, ev, cli, fname, 811 SMB_QUERY_FILE_UNIX_BASIC, 100, 100); 812 if (tevent_req_nomem(subreq, req)) { 813 return tevent_req_post(req, ev); 814 } 815 tevent_req_set_callback(subreq, cli_posix_stat_done, req); 816 return req; 817 } 781 818 782 819 static void cli_posix_stat_done(struct tevent_req *subreq) … … 787 824 NTSTATUS status; 788 825 789 status = cli_ trans_recv(subreq, state, NULL, NULL, NULL, NULL,790 &state->data,&state->num_data);826 status = cli_qpathinfo_recv(subreq, state, &state->data, 827 &state->num_data); 791 828 TALLOC_FREE(subreq); 792 if (!NT_STATUS_IS_OK(status)) { 793 tevent_req_nterror(req, status); 829 if (tevent_req_nterror(req, status)) { 794 830 return; 795 831 } 796 832 tevent_req_done(req); 797 }798 799 struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,800 struct event_context *ev,801 struct cli_state *cli,802 const char *fname)803 {804 struct tevent_req *req = NULL, *subreq = NULL;805 struct stat_state *state = NULL;806 807 req = tevent_req_create(mem_ctx, &state, struct stat_state);808 if (req == NULL) {809 return NULL;810 }811 812 /* Setup setup word. */813 SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);814 815 /* Setup param array. */816 state->param = talloc_array(state, uint8_t, 6);817 if (tevent_req_nomem(state->param, req)) {818 return tevent_req_post(req, ev);819 }820 memset(state->param, '\0', 6);821 SSVAL(state->param, 0, SMB_QUERY_FILE_UNIX_BASIC);822 823 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,824 strlen(fname)+1, NULL);825 826 if (tevent_req_nomem(state->param, req)) {827 return tevent_req_post(req, ev);828 }829 830 subreq = cli_trans_send(state, /* mem ctx. */831 ev, /* event ctx. */832 cli, /* cli_state. */833 SMBtrans2, /* cmd. */834 NULL, /* pipe name. */835 -1, /* fid. */836 0, /* function. */837 0, /* flags. */838 &state->setup, /* setup. */839 1, /* num setup uint16_t words. */840 0, /* max returned setup. */841 state->param, /* param. */842 talloc_get_size(state->param), /* num param. */843 2, /* max returned param. */844 NULL, /* data. */845 0, /* num data. */846 96); /* max returned data. */847 848 if (tevent_req_nomem(subreq, req)) {849 return tevent_req_post(req, ev);850 }851 tevent_req_set_callback(subreq, cli_posix_stat_done, req);852 return req;853 833 } 854 834 … … 861 841 if (tevent_req_is_nterror(req, &status)) { 862 842 return status; 863 }864 865 if (state->num_data != 96) {866 return NT_STATUS_DATA_ERROR;867 843 } 868 844 … … 891 867 sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(state->data,76); /* inode */ 892 868 sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(state->data,84)); /* protection */ 893 sbuf->st_ex_nlink = IVAL(state->data,92);/* number of hard links */869 sbuf->st_ex_nlink = BIG_UINT(state->data,92); /* number of hard links */ 894 870 895 871 return NT_STATUS_OK; … … 947 923 ****************************************************************************/ 948 924 949 struct ch_state { 950 uint16_t setup; 951 uint8_t *param; 952 uint8_t *data; 925 struct cli_posix_chown_chmod_internal_state { 926 uint8_t data[100]; 953 927 }; 954 928 955 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq) 956 { 957 struct tevent_req *req = tevent_req_callback_data( 958 subreq, struct tevent_req); 959 struct ch_state *state = tevent_req_data(req, struct ch_state); 960 NTSTATUS status; 961 962 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 963 TALLOC_FREE(subreq); 964 if (!NT_STATUS_IS_OK(status)) { 965 tevent_req_nterror(req, status); 966 return; 967 } 968 tevent_req_done(req); 969 } 929 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq); 970 930 971 931 static struct tevent_req *cli_posix_chown_chmod_internal_send(TALLOC_CTX *mem_ctx, … … 978 938 { 979 939 struct tevent_req *req = NULL, *subreq = NULL; 980 struct ch_state *state = NULL; 981 982 req = tevent_req_create(mem_ctx, &state, struct ch_state); 940 struct cli_posix_chown_chmod_internal_state *state = NULL; 941 942 req = tevent_req_create(mem_ctx, &state, 943 struct cli_posix_chown_chmod_internal_state); 983 944 if (req == NULL) { 984 945 return NULL; 985 946 } 986 947 987 /* Setup setup word. */988 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);989 990 /* Setup param array. */991 state->param = talloc_array(state, uint8_t, 6);992 if (tevent_req_nomem(state->param, req)) {993 return tevent_req_post(req, ev);994 }995 memset(state->param, '\0', 6);996 SSVAL(state->param,0,SMB_SET_FILE_UNIX_BASIC);997 998 state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,999 strlen(fname)+1, NULL);1000 1001 if (tevent_req_nomem(state->param, req)) {1002 return tevent_req_post(req, ev);1003 }1004 1005 /* Setup data array. */1006 state->data = talloc_array(state, uint8_t, 100);1007 if (tevent_req_nomem(state->data, req)) {1008 return tevent_req_post(req, ev);1009 }1010 948 memset(state->data, 0xff, 40); /* Set all sizes/times to no change. */ 1011 949 memset(&state->data[40], '\0', 60); … … 1014 952 SIVAL(state->data,84,mode); 1015 953 1016 subreq = cli_trans_send(state, /* mem ctx. */ 1017 ev, /* event ctx. */ 1018 cli, /* cli_state. */ 1019 SMBtrans2, /* cmd. */ 1020 NULL, /* pipe name. */ 1021 -1, /* fid. */ 1022 0, /* function. */ 1023 0, /* flags. */ 1024 &state->setup, /* setup. */ 1025 1, /* num setup uint16_t words. */ 1026 0, /* max returned setup. */ 1027 state->param, /* param. */ 1028 talloc_get_size(state->param), /* num param. */ 1029 2, /* max returned param. */ 1030 state->data, /* data. */ 1031 talloc_get_size(state->data), /* num data. */ 1032 0); /* max returned data. */ 1033 954 subreq = cli_setpathinfo_send(state, ev, cli, SMB_SET_FILE_UNIX_BASIC, 955 fname, state->data, sizeof(state->data)); 1034 956 if (tevent_req_nomem(subreq, req)) { 1035 957 return tevent_req_post(req, ev); 1036 958 } 1037 tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, req); 959 tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, 960 req); 1038 961 return req; 962 } 963 964 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq) 965 { 966 NTSTATUS status = cli_setpathinfo_recv(subreq); 967 tevent_req_simple_finish_ntstatus(subreq, status); 1039 968 } 1040 969 … … 1058 987 NTSTATUS cli_posix_chmod_recv(struct tevent_req *req) 1059 988 { 1060 NTSTATUS status; 1061 1062 if (tevent_req_is_nterror(req, &status)) { 1063 return status; 1064 } 1065 return NT_STATUS_OK; 989 return tevent_req_simple_recv_ntstatus(req); 1066 990 } 1067 991 … … 1132 1056 NTSTATUS cli_posix_chown_recv(struct tevent_req *req) 1133 1057 { 1134 NTSTATUS status; 1135 1136 if (tevent_req_is_nterror(req, &status)) { 1137 return status; 1138 } 1139 return NT_STATUS_OK; 1058 return tevent_req_simple_recv_ntstatus(req); 1140 1059 } 1141 1060 … … 1216 1135 } 1217 1136 1218 SSVAL(state->vwv+0, 0, aSYSTEM | aHIDDEN | aDIR);1137 SSVAL(state->vwv+0, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); 1219 1138 1220 1139 bytes = talloc_array(state, uint8_t, 1); … … 1257 1176 NTSTATUS status; 1258 1177 1259 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1178 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1260 1179 TALLOC_FREE(subreq); 1261 if (!NT_STATUS_IS_OK(status)) { 1262 tevent_req_nterror(req, status); 1180 if (tevent_req_nterror(req, status)) { 1263 1181 return; 1264 1182 } … … 1341 1259 } 1342 1260 1343 SSVAL(state->vwv+0, 0 , aSYSTEM | aHIDDEN | aDIR);1261 SSVAL(state->vwv+0, 0 ,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY); 1344 1262 SSVAL(state->vwv+1, 0, rename_flag); 1345 1263 … … 1383 1301 NTSTATUS status; 1384 1302 1385 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1303 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1386 1304 TALLOC_FREE(subreq); 1387 if (!NT_STATUS_IS_OK(status)) { 1388 tevent_req_nterror(req, status); 1305 if (tevent_req_nterror(req, status)) { 1389 1306 return; 1390 1307 } … … 1578 1495 NTSTATUS status; 1579 1496 1580 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1497 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1581 1498 TALLOC_FREE(subreq); 1582 if (!NT_STATUS_IS_OK(status)) { 1583 tevent_req_nterror(req, status); 1499 if (tevent_req_nterror(req, status)) { 1584 1500 return; 1585 1501 } … … 1686 1602 NTSTATUS status; 1687 1603 1688 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1604 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1689 1605 TALLOC_FREE(subreq); 1690 if (!NT_STATUS_IS_OK(status)) { 1691 tevent_req_nterror(req, status); 1606 if (tevent_req_nterror(req, status)) { 1692 1607 return; 1693 1608 } … … 1794 1709 NTSTATUS status; 1795 1710 1796 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);1711 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 1797 1712 TALLOC_FREE(subreq); 1798 if (!NT_STATUS_IS_OK(status)) { 1799 tevent_req_nterror(req, status); 1713 if (tevent_req_nterror(req, status)) { 1800 1714 return; 1801 1715 } … … 1862 1776 static void cli_nt_delete_on_close_done(struct tevent_req *subreq) 1863 1777 { 1864 struct tevent_req *req = tevent_req_callback_data( 1865 subreq, struct tevent_req); 1866 struct doc_state *state = tevent_req_data(req, struct doc_state); 1867 NTSTATUS status; 1868 1869 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 1870 TALLOC_FREE(subreq); 1871 if (!NT_STATUS_IS_OK(status)) { 1872 tevent_req_nterror(req, status); 1873 return; 1874 } 1875 tevent_req_done(req); 1778 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 1779 NULL, 0, NULL, NULL, 0, NULL); 1780 tevent_req_simple_finish_ntstatus(subreq, status); 1876 1781 } 1877 1782 … … 1927 1832 NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req) 1928 1833 { 1929 NTSTATUS status; 1930 1931 if (tevent_req_is_nterror(req, &status)) { 1932 return status; 1933 } 1934 return NT_STATUS_OK; 1834 return tevent_req_simple_recv_ntstatus(req); 1935 1835 } 1936 1836 … … 2066 1966 uint32_t num_bytes; 2067 1967 uint8_t *bytes; 1968 uint8_t *inbuf; 2068 1969 NTSTATUS status; 2069 1970 2070 status = cli_smb_recv(subreq, 3, &wct, &vwv, &num_bytes, &bytes);2071 if (!NT_STATUS_IS_OK(status)) {2072 2073 tevent_req_nterror(req, status);1971 status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, 1972 &num_bytes, &bytes); 1973 TALLOC_FREE(subreq); 1974 if (tevent_req_nterror(req, status)) { 2074 1975 return; 2075 1976 } … … 2209 2110 SSVAL(state->vwv + 2, 0, 0); /* no additional info */ 2210 2111 SSVAL(state->vwv + 3, 0, accessmode); 2211 SSVAL(state->vwv + 4, 0, aSYSTEM | aHIDDEN);2112 SSVAL(state->vwv + 4, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); 2212 2113 SSVAL(state->vwv + 5, 0, 0); 2213 2114 SIVAL(state->vwv + 6, 0, 0); … … 2263 2164 2264 2165 status = cli_smb_req_send(subreq); 2265 if (!NT_STATUS_IS_OK(status)) { 2266 tevent_req_nterror(req, status); 2166 if (tevent_req_nterror(req, status)) { 2267 2167 return tevent_req_post(req, ev); 2268 2168 } … … 2278 2178 uint8_t wct; 2279 2179 uint16_t *vwv; 2180 uint8_t *inbuf; 2280 2181 NTSTATUS status; 2281 2182 2282 status = cli_smb_recv(subreq, 3, &wct, &vwv, NULL, NULL);2283 if (!NT_STATUS_IS_OK(status)) {2284 2285 tevent_req_nterror(req, status);2183 status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, NULL, 2184 NULL); 2185 TALLOC_FREE(subreq); 2186 if (tevent_req_nterror(req, status)) { 2286 2187 return; 2287 2188 } … … 2397 2298 2398 2299 status = cli_smb_req_send(subreq); 2399 if (!NT_STATUS_IS_OK(status)) { 2400 tevent_req_nterror(req, status); 2300 if (tevent_req_nterror(req, status)) { 2401 2301 return tevent_req_post(req, ev); 2402 2302 } … … 2410 2310 NTSTATUS status; 2411 2311 2412 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);2312 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2413 2313 TALLOC_FREE(subreq); 2414 if (!NT_STATUS_IS_OK(status)) { 2415 tevent_req_nterror(req, status); 2314 if (tevent_req_nterror(req, status)) { 2416 2315 return; 2417 2316 } … … 2477 2376 static void cli_ftruncate_done(struct tevent_req *subreq) 2478 2377 { 2479 struct tevent_req *req = tevent_req_callback_data( 2480 subreq, struct tevent_req); 2481 struct ftrunc_state *state = tevent_req_data(req, struct ftrunc_state); 2482 NTSTATUS status; 2483 2484 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 2485 TALLOC_FREE(subreq); 2486 if (!NT_STATUS_IS_OK(status)) { 2487 tevent_req_nterror(req, status); 2488 return; 2489 } 2490 tevent_req_done(req); 2378 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 2379 NULL, 0, NULL, NULL, 0, NULL); 2380 tevent_req_simple_finish_ntstatus(subreq, status); 2491 2381 } 2492 2382 … … 2543 2433 NTSTATUS cli_ftruncate_recv(struct tevent_req *req) 2544 2434 { 2545 NTSTATUS status; 2546 2547 if (tevent_req_is_nterror(req, &status)) { 2548 return status; 2549 } 2550 return NT_STATUS_OK; 2435 return tevent_req_simple_recv_ntstatus(req); 2551 2436 } 2552 2437 … … 2606 2491 int timeout, unsigned char locktype) 2607 2492 { 2608 char *p; 2609 int saved_timeout = cli->timeout; 2610 2611 memset(cli->outbuf,'\0',smb_size); 2612 memset(cli->inbuf,'\0', smb_size); 2613 2614 cli_set_message(cli->outbuf,8,0,True); 2615 2616 SCVAL(cli->outbuf,smb_com,SMBlockingX); 2617 SSVAL(cli->outbuf,smb_tid,cli->cnum); 2618 cli_setup_packet(cli); 2619 2620 SCVAL(cli->outbuf,smb_vwv0,0xFF); 2621 SSVAL(cli->outbuf,smb_vwv2,fnum); 2622 SCVAL(cli->outbuf,smb_vwv3,locktype); 2623 SIVALS(cli->outbuf, smb_vwv4, timeout); 2624 SSVAL(cli->outbuf,smb_vwv6,0); 2625 SSVAL(cli->outbuf,smb_vwv7,1); 2626 2627 p = smb_buf(cli->outbuf); 2628 SSVAL(p, 0, cli->pid); 2629 SIVAL(p, 2, offset); 2630 SIVAL(p, 6, len); 2631 2632 p += 10; 2633 2634 cli_setup_bcc(cli, p); 2635 2636 cli_send_smb(cli); 2493 uint16_t vwv[8]; 2494 uint8_t bytes[10]; 2495 NTSTATUS status; 2496 int saved_timeout; 2497 2498 SCVAL(vwv + 0, 0, 0xff); 2499 SCVAL(vwv + 0, 1, 0); 2500 SSVAL(vwv + 1, 0, 0); 2501 SSVAL(vwv + 2, 0, fnum); 2502 SCVAL(vwv + 3, 0, locktype); 2503 SCVAL(vwv + 3, 1, 0); 2504 SIVALS(vwv + 4, 0, timeout); 2505 SSVAL(vwv + 6, 0, 0); 2506 SSVAL(vwv + 7, 0, 1); 2507 2508 SSVAL(bytes, 0, cli->pid); 2509 SIVAL(bytes, 2, offset); 2510 SIVAL(bytes, 6, len); 2511 2512 saved_timeout = cli->timeout; 2637 2513 2638 2514 if (timeout != 0) { 2639 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); 2640 } 2641 2642 if (!cli_receive_smb(cli)) { 2643 cli->timeout = saved_timeout; 2644 return NT_STATUS_UNSUCCESSFUL; 2645 } 2515 cli->timeout = (timeout == -1) 2516 ? 0x7FFFFFFF : (timeout + 2*1000); 2517 } 2518 2519 status = cli_smb(talloc_tos(), cli, SMBlockingX, 0, 8, vwv, 2520 10, bytes, NULL, 0, NULL, NULL, NULL, NULL); 2646 2521 2647 2522 cli->timeout = saved_timeout; 2648 2523 2649 return cli_nt_error(cli);2524 return status; 2650 2525 } 2651 2526 … … 2656 2531 2657 2532 bool cli_lock(struct cli_state *cli, uint16_t fnum, 2658 uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type) 2659 { 2660 char *p; 2661 int saved_timeout = cli->timeout; 2662 2663 memset(cli->outbuf,'\0',smb_size); 2664 memset(cli->inbuf,'\0', smb_size); 2665 2666 cli_set_message(cli->outbuf,8,0,True); 2667 2668 SCVAL(cli->outbuf,smb_com,SMBlockingX); 2669 SSVAL(cli->outbuf,smb_tid,cli->cnum); 2670 cli_setup_packet(cli); 2671 2672 SCVAL(cli->outbuf,smb_vwv0,0xFF); 2673 SSVAL(cli->outbuf,smb_vwv2,fnum); 2674 SCVAL(cli->outbuf,smb_vwv3,(lock_type == READ_LOCK? 1 : 0)); 2675 SIVALS(cli->outbuf, smb_vwv4, timeout); 2676 SSVAL(cli->outbuf,smb_vwv6,0); 2677 SSVAL(cli->outbuf,smb_vwv7,1); 2678 2679 p = smb_buf(cli->outbuf); 2680 SSVAL(p, 0, cli->pid); 2681 SIVAL(p, 2, offset); 2682 SIVAL(p, 6, len); 2683 2684 p += 10; 2685 2686 cli_setup_bcc(cli, p); 2687 2688 cli_send_smb(cli); 2689 2690 if (timeout != 0) { 2691 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000); 2692 } 2693 2694 if (!cli_receive_smb(cli)) { 2695 cli->timeout = saved_timeout; 2696 return False; 2697 } 2698 2699 cli->timeout = saved_timeout; 2700 2701 if (cli_is_error(cli)) { 2702 return False; 2703 } 2704 2705 return True; 2533 uint32_t offset, uint32_t len, int timeout, 2534 enum brl_type lock_type) 2535 { 2536 NTSTATUS status; 2537 2538 status = cli_locktype(cli, fnum, offset, len, timeout, 2539 (lock_type == READ_LOCK? 1 : 0)); 2540 cli_set_error(cli, status); 2541 return NT_STATUS_IS_OK(status); 2706 2542 } 2707 2543 … … 2760 2596 NTSTATUS status; 2761 2597 2762 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);2598 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2763 2599 TALLOC_FREE(subreq); 2764 if (!NT_STATUS_IS_OK(status)) { 2765 tevent_req_nterror(req, status); 2600 if (tevent_req_nterror(req, status)) { 2766 2601 return; 2767 2602 } … … 2825 2660 2826 2661 bool cli_lock64(struct cli_state *cli, uint16_t fnum, 2827 uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type) 2828 { 2829 char *p; 2662 uint64_t offset, uint64_t len, int timeout, 2663 enum brl_type lock_type) 2664 { 2665 uint16_t vwv[8]; 2666 uint8_t bytes[20]; 2830 2667 int saved_timeout = cli->timeout; 2831 2668 int ltype; 2669 NTSTATUS status; 2832 2670 2833 2671 if (! (cli->capabilities & CAP_LARGE_FILES)) { … … 2838 2676 ltype |= LOCKING_ANDX_LARGE_FILES; 2839 2677 2840 memset(cli->outbuf,'\0',smb_size); 2841 memset(cli->inbuf,'\0', smb_size); 2842 2843 cli_set_message(cli->outbuf,8,0,True); 2844 2845 SCVAL(cli->outbuf,smb_com,SMBlockingX); 2846 SSVAL(cli->outbuf,smb_tid,cli->cnum); 2847 cli_setup_packet(cli); 2848 2849 SCVAL(cli->outbuf,smb_vwv0,0xFF); 2850 SSVAL(cli->outbuf,smb_vwv2,fnum); 2851 SCVAL(cli->outbuf,smb_vwv3,ltype); 2852 SIVALS(cli->outbuf, smb_vwv4, timeout); 2853 SSVAL(cli->outbuf,smb_vwv6,0); 2854 SSVAL(cli->outbuf,smb_vwv7,1); 2855 2856 p = smb_buf(cli->outbuf); 2857 SIVAL(p, 0, cli->pid); 2858 SOFF_T_R(p, 4, offset); 2859 SOFF_T_R(p, 12, len); 2860 p += 20; 2861 2862 cli_setup_bcc(cli, p); 2863 cli_send_smb(cli); 2678 SCVAL(vwv + 0, 0, 0xff); 2679 SCVAL(vwv + 0, 1, 0); 2680 SSVAL(vwv + 1, 0, 0); 2681 SSVAL(vwv + 2, 0, fnum); 2682 SCVAL(vwv + 3, 0, ltype); 2683 SCVAL(vwv + 3, 1, 0); 2684 SIVALS(vwv + 4, 0, timeout); 2685 SSVAL(vwv + 6, 0, 0); 2686 SSVAL(vwv + 7, 0, 1); 2687 2688 SIVAL(bytes, 0, cli->pid); 2689 SOFF_T_R(bytes, 4, offset); 2690 SOFF_T_R(bytes, 12, len); 2691 2692 saved_timeout = cli->timeout; 2864 2693 2865 2694 if (timeout != 0) { 2866 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 5*1000); 2867 } 2868 2869 if (!cli_receive_smb(cli)) { 2870 cli->timeout = saved_timeout; 2871 return False; 2872 } 2695 cli->timeout = (timeout == -1) 2696 ? 0x7FFFFFFF : (timeout + 2*1000); 2697 } 2698 2699 status = cli_smb(talloc_tos(), cli, SMBlockingX, 0, 8, vwv, 2700 20, bytes, NULL, 0, NULL, NULL, NULL, NULL); 2873 2701 2874 2702 cli->timeout = saved_timeout; 2875 2703 2876 if (cli_is_error(cli)) { 2877 return False; 2878 } 2879 2880 return True; 2704 cli_set_error(cli, status); 2705 return NT_STATUS_IS_OK(status); 2881 2706 } 2882 2707 … … 2935 2760 NTSTATUS status; 2936 2761 2937 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);2762 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2938 2763 TALLOC_FREE(subreq); 2939 if (!NT_STATUS_IS_OK(status)) { 2940 tevent_req_nterror(req, status); 2764 if (tevent_req_nterror(req, status)) { 2941 2765 return; 2942 2766 } … … 3011 2835 static void cli_posix_unlock_internal_done(struct tevent_req *subreq) 3012 2836 { 3013 struct tevent_req *req = tevent_req_callback_data( 3014 subreq, struct tevent_req); 3015 struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state); 3016 NTSTATUS status; 3017 3018 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 3019 TALLOC_FREE(subreq); 3020 if (!NT_STATUS_IS_OK(status)) { 3021 tevent_req_nterror(req, status); 3022 return; 3023 } 3024 tevent_req_done(req); 2837 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 2838 NULL, 0, NULL, NULL, 0, NULL); 2839 tevent_req_simple_finish_ntstatus(subreq, status); 3025 2840 } 3026 2841 … … 3123 2938 NTSTATUS cli_posix_lock_recv(struct tevent_req *req) 3124 2939 { 3125 NTSTATUS status; 3126 3127 if (tevent_req_is_nterror(req, &status)) { 3128 return status; 3129 } 3130 return NT_STATUS_OK; 2940 return tevent_req_simple_recv_ntstatus(req); 3131 2941 } 3132 2942 … … 3204 3014 NTSTATUS cli_posix_unlock_recv(struct tevent_req *req) 3205 3015 { 3206 NTSTATUS status; 3207 3208 if (tevent_req_is_nterror(req, &status)) { 3209 return status; 3210 } 3211 return NT_STATUS_OK; 3016 return tevent_req_simple_recv_ntstatus(req); 3212 3017 } 3213 3018 … … 3309 3114 uint8_t wct; 3310 3115 uint16_t *vwv = NULL; 3116 uint8_t *inbuf; 3311 3117 NTSTATUS status; 3312 3118 3313 status = cli_smb_recv(subreq, 11, &wct, &vwv, NULL, NULL); 3314 if (!NT_STATUS_IS_OK(status)) { 3315 tevent_req_nterror(req, status); 3119 status = cli_smb_recv(subreq, state, &inbuf, 11, &wct, &vwv, 3120 NULL, NULL); 3121 TALLOC_FREE(subreq); 3122 if (tevent_req_nterror(req, status)) { 3316 3123 return; 3317 3124 } … … 3323 3130 state->write_time = make_unix_date2(vwv+4, state->zone_offset); 3324 3131 3325 TALLOC_FREE(subreq);3326 3132 tevent_req_done(req); 3327 3133 } … … 3471 3277 uint8_t wct; 3472 3278 uint16_t *vwv = NULL; 3279 uint8_t *inbuf; 3473 3280 NTSTATUS status; 3474 3281 3475 status = cli_smb_recv(subreq, 4, &wct, &vwv, NULL, NULL); 3476 if (!NT_STATUS_IS_OK(status)) { 3477 tevent_req_nterror(req, status); 3282 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL, 3283 NULL); 3284 TALLOC_FREE(subreq); 3285 if (tevent_req_nterror(req, status)) { 3478 3286 return; 3479 3287 } … … 3483 3291 state->write_time = make_unix_date3(vwv+1, state->zone_offset); 3484 3292 3485 TALLOC_FREE(subreq);3486 3293 tevent_req_done(req); 3487 3294 } … … 3588 3395 3589 3396 SSVAL(state->vwv+0, 0, fnum); 3590 cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time); 3591 cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time); 3592 cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time); 3397 push_dos_date2((uint8_t *)&state->vwv[1], 0, change_time, 3398 cli->serverzone); 3399 push_dos_date2((uint8_t *)&state->vwv[3], 0, access_time, 3400 cli->serverzone); 3401 push_dos_date2((uint8_t *)&state->vwv[5], 0, write_time, 3402 cli->serverzone); 3593 3403 3594 3404 subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags, … … 3607 3417 NTSTATUS status; 3608 3418 3609 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);3419 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 3610 3420 TALLOC_FREE(subreq); 3611 if (!NT_STATUS_IS_OK(status)) { 3612 tevent_req_nterror(req, status); 3421 if (tevent_req_nterror(req, status)) { 3613 3422 return; 3614 3423 } … … 3701 3510 3702 3511 SSVAL(state->vwv+0, 0, attr); 3703 cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime);3512 push_dos_date3((uint8_t *)&state->vwv[1], 0, mtime, cli->serverzone); 3704 3513 3705 3514 bytes = talloc_array(state, uint8_t, 1); … … 3741 3550 NTSTATUS status; 3742 3551 3743 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);3552 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 3744 3553 TALLOC_FREE(subreq); 3745 if (!NT_STATUS_IS_OK(status)) { 3746 tevent_req_nterror(req, status); 3554 if (tevent_req_nterror(req, status)) { 3747 3555 return; 3748 3556 } … … 3852 3660 NTSTATUS status; 3853 3661 3854 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);3662 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 3855 3663 TALLOC_FREE(subreq); 3856 if (!NT_STATUS_IS_OK(status)) { 3857 tevent_req_nterror(req, status); 3664 if (tevent_req_nterror(req, status)) { 3858 3665 return; 3859 3666 } … … 3965 3772 uint8_t wct; 3966 3773 uint16_t *vwv = NULL; 3774 uint8_t *inbuf; 3967 3775 NTSTATUS status; 3968 3776 3969 status = cli_smb_recv(subreq, 4, &wct, &vwv, NULL, NULL); 3970 if (!NT_STATUS_IS_OK(status)) { 3971 tevent_req_nterror(req, status); 3777 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL, 3778 NULL); 3779 TALLOC_FREE(subreq); 3780 if (tevent_req_nterror(req, status)) { 3972 3781 return; 3973 3782 } … … 3975 3784 state->total = SVAL(vwv+0, 0); 3976 3785 state->avail = SVAL(vwv+3, 0); 3977 TALLOC_FREE(subreq);3978 3786 tevent_req_done(req); 3979 3787 } … … 4097 3905 uint32_t num_bytes = 0; 4098 3906 uint8_t *bytes = NULL; 4099 4100 status = cli_smb_recv(subreq, 1, &wcnt, &vwv, &num_bytes, &bytes); 4101 if (!NT_STATUS_IS_OK(status)) { 4102 TALLOC_FREE(subreq); 4103 tevent_req_nterror(req, status); 3907 uint8_t *inbuf; 3908 3909 status = cli_smb_recv(subreq, state, &inbuf, 1, &wcnt, &vwv, 3910 &num_bytes, &bytes); 3911 TALLOC_FREE(subreq); 3912 if (tevent_req_nterror(req, status)) { 4104 3913 return; 4105 3914 } 4106 3915 4107 3916 state->fnum = SVAL(vwv+0, 0); 4108 4109 TALLOC_FREE(subreq);4110 3917 4111 3918 /* From W2K3, the result is just the ASCII name */ … … 4199 4006 NTSTATUS cli_raw_ioctl(struct cli_state *cli, uint16_t fnum, uint32_t code, DATA_BLOB *blob) 4200 4007 { 4201 memset(cli->outbuf,'\0',smb_size); 4202 memset(cli->inbuf,'\0',smb_size); 4203 4204 cli_set_message(cli->outbuf, 3, 0, True); 4205 SCVAL(cli->outbuf,smb_com,SMBioctl); 4206 cli_setup_packet(cli); 4207 4208 SSVAL(cli->outbuf, smb_vwv0, fnum); 4209 SSVAL(cli->outbuf, smb_vwv1, code>>16); 4210 SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF)); 4211 4212 cli_send_smb(cli); 4213 if (!cli_receive_smb(cli)) { 4214 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 4215 } 4216 4217 if (cli_is_error(cli)) { 4218 return cli_nt_error(cli); 4219 } 4220 4008 uint16_t vwv[3]; 4009 NTSTATUS status; 4010 4011 SSVAL(vwv+0, 0, fnum); 4012 SSVAL(vwv+1, 0, code>>16); 4013 SSVAL(vwv+2, 0, (code&0xFFFF)); 4014 4015 status = cli_smb(talloc_tos(), cli, SMBioctl, 0, 3, vwv, 0, NULL, 4016 NULL, 0, NULL, NULL, NULL, NULL); 4017 if (!NT_STATUS_IS_OK(status)) { 4018 return status; 4019 } 4221 4020 *blob = data_blob_null; 4222 4223 4021 return NT_STATUS_OK; 4224 4022 } … … 4228 4026 *********************************************************/ 4229 4027 4230 static bool cli_set_ea(struct cli_state *cli, uint16_t setup, char *param, unsigned int param_len, 4231 const char *ea_name, const char *ea_val, size_t ea_len) 4232 { 4028 static NTSTATUS cli_set_ea(struct cli_state *cli, uint16_t setup_val, 4029 uint8_t *param, unsigned int param_len, 4030 const char *ea_name, 4031 const char *ea_val, size_t ea_len) 4032 { 4033 uint16_t setup[1]; 4233 4034 unsigned int data_len = 0; 4234 char *data = NULL; 4235 char *rparam=NULL, *rdata=NULL; 4035 uint8_t *data = NULL; 4236 4036 char *p; 4237 4037 size_t ea_namelen = strlen(ea_name); 4038 NTSTATUS status; 4039 4040 SSVAL(setup, 0, setup_val); 4238 4041 4239 4042 if (ea_namelen == 0 && ea_len == 0) { 4240 4043 data_len = 4; 4241 data = ( char*)SMB_MALLOC(data_len);4044 data = (uint8_t *)SMB_MALLOC(data_len); 4242 4045 if (!data) { 4243 return False;4046 return NT_STATUS_NO_MEMORY; 4244 4047 } 4245 p = data;4048 p = (char *)data; 4246 4049 SIVAL(p,0,data_len); 4247 4050 } else { 4248 4051 data_len = 4 + 4 + ea_namelen + 1 + ea_len; 4249 data = ( char*)SMB_MALLOC(data_len);4052 data = (uint8_t *)SMB_MALLOC(data_len); 4250 4053 if (!data) { 4251 return False;4054 return NT_STATUS_NO_MEMORY; 4252 4055 } 4253 p = data;4056 p = (char *)data; 4254 4057 SIVAL(p,0,data_len); 4255 4058 p += 4; … … 4261 4064 } 4262 4065 4263 if (!cli_send_trans(cli, SMBtrans2, 4264 NULL, /* name */ 4265 -1, 0, /* fid, flags */ 4266 &setup, 1, 0, /* setup, length, max */ 4267 param, param_len, 2, /* param, length, max */ 4268 data, data_len, cli->max_xmit /* data, length, max */ 4269 )) { 4270 SAFE_FREE(data); 4271 return False; 4272 } 4273 4274 if (!cli_receive_trans(cli, SMBtrans2, 4275 &rparam, ¶m_len, 4276 &rdata, &data_len)) { 4277 SAFE_FREE(data); 4278 return false; 4279 } 4280 4066 status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, -1, 0, 0, 4067 setup, 1, 0, 4068 param, param_len, 2, 4069 data, data_len, cli->max_xmit, 4070 NULL, 4071 NULL, 0, NULL, /* rsetup */ 4072 NULL, 0, NULL, /* rparam */ 4073 NULL, 0, NULL); /* rdata */ 4281 4074 SAFE_FREE(data); 4282 SAFE_FREE(rdata); 4283 SAFE_FREE(rparam); 4284 4285 return True; 4075 return status; 4286 4076 } 4287 4077 … … 4290 4080 *********************************************************/ 4291 4081 4292 bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) 4293 { 4294 uint16_t setup = TRANSACT2_SETPATHINFO; 4082 NTSTATUS cli_set_ea_path(struct cli_state *cli, const char *path, 4083 const char *ea_name, const char *ea_val, 4084 size_t ea_len) 4085 { 4295 4086 unsigned int param_len = 0; 4296 char*param;4087 uint8_t *param; 4297 4088 size_t srclen = 2*(strlen(path)+1); 4298 4089 char *p; 4299 bool ret;4300 4301 param = SMB_MALLOC_ARRAY( char, 6+srclen+2);4090 NTSTATUS status; 4091 4092 param = SMB_MALLOC_ARRAY(uint8_t, 6+srclen+2); 4302 4093 if (!param) { 4303 return false;4094 return NT_STATUS_NO_MEMORY; 4304 4095 } 4305 4096 memset(param, '\0', 6); 4306 4097 SSVAL(param,0,SMB_INFO_SET_EA); 4307 p = ¶m[6];4098 p = (char *)(¶m[6]); 4308 4099 4309 4100 p += clistr_push(cli, p, path, srclen, STR_TERMINATE); 4310 4101 param_len = PTR_DIFF(p, param); 4311 4102 4312 ret = cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len); 4103 status = cli_set_ea(cli, TRANSACT2_SETPATHINFO, param, param_len, 4104 ea_name, ea_val, ea_len); 4313 4105 SAFE_FREE(param); 4314 return ret;4106 return status; 4315 4107 } 4316 4108 … … 4319 4111 *********************************************************/ 4320 4112 4321 bool cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, const char *ea_name, const char *ea_val, size_t ea_len) 4322 { 4323 char param[6]; 4324 uint16_t setup = TRANSACT2_SETFILEINFO; 4113 NTSTATUS cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, 4114 const char *ea_name, const char *ea_val, 4115 size_t ea_len) 4116 { 4117 uint8_t param[6]; 4325 4118 4326 4119 memset(param, 0, 6); … … 4328 4121 SSVAL(param,2,SMB_INFO_SET_EA); 4329 4122 4330 return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, ea_len); 4123 return cli_set_ea(cli, TRANSACT2_SETFILEINFO, param, 6, 4124 ea_name, ea_val, ea_len); 4331 4125 } 4332 4126 … … 4335 4129 *********************************************************/ 4336 4130 4337 static bool cli_get_ea_list(struct cli_state *cli, 4338 uint16_t setup, char *param, unsigned int param_len, 4339 TALLOC_CTX *ctx, 4340 size_t *pnum_eas, 4341 struct ea_struct **pea_list) 4342 { 4343 unsigned int data_len = 0; 4344 unsigned int rparam_len, rdata_len; 4345 char *rparam=NULL, *rdata=NULL; 4346 char *p; 4131 static bool parse_ea_blob(TALLOC_CTX *ctx, const uint8_t *rdata, 4132 size_t rdata_len, 4133 size_t *pnum_eas, struct ea_struct **pea_list) 4134 { 4135 struct ea_struct *ea_list = NULL; 4136 size_t num_eas; 4347 4137 size_t ea_size; 4348 size_t num_eas; 4349 bool ret = False; 4350 struct ea_struct *ea_list; 4351 4352 *pnum_eas = 0; 4353 if (pea_list) { 4354 *pea_list = NULL; 4355 } 4356 4357 if (!cli_send_trans(cli, SMBtrans2, 4358 NULL, /* Name */ 4359 -1, 0, /* fid, flags */ 4360 &setup, 1, 0, /* setup, length, max */ 4361 param, param_len, 10, /* param, length, max */ 4362 NULL, data_len, cli->max_xmit /* data, length, max */ 4363 )) { 4364 return False; 4365 } 4366 4367 if (!cli_receive_trans(cli, SMBtrans2, 4368 &rparam, &rparam_len, 4369 &rdata, &rdata_len)) { 4370 return False; 4371 } 4372 4373 if (!rdata || rdata_len < 4) { 4374 goto out; 4138 const uint8_t *p; 4139 4140 if (rdata_len < 4) { 4141 return false; 4375 4142 } 4376 4143 4377 4144 ea_size = (size_t)IVAL(rdata,0); 4378 4145 if (ea_size > rdata_len) { 4379 goto out;4146 return false; 4380 4147 } 4381 4148 4382 4149 if (ea_size == 0) { 4383 4150 /* No EA's present. */ 4384 ret = True; 4385 goto out; 4151 *pnum_eas = 0; 4152 *pea_list = NULL; 4153 return true; 4386 4154 } 4387 4155 … … 4394 4162 unsigned int ea_valuelen = SVAL(p,2); 4395 4163 if (ea_namelen == 0) { 4396 goto out;4164 return false; 4397 4165 } 4398 4166 if (4 + ea_namelen + 1 + ea_valuelen > ea_size) { 4399 goto out;4167 return false; 4400 4168 } 4401 4169 ea_size -= 4 + ea_namelen + 1 + ea_valuelen; … … 4404 4172 4405 4173 if (num_eas == 0) { 4406 ret = True; 4407 goto out; 4174 *pnum_eas = 0; 4175 *pea_list = NULL; 4176 return true; 4408 4177 } 4409 4178 … … 4411 4180 if (!pea_list) { 4412 4181 /* Caller only wants number of EA's. */ 4413 ret = True; 4414 goto out; 4182 return true; 4415 4183 } 4416 4184 4417 4185 ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); 4418 4186 if (!ea_list) { 4419 goto out;4187 return false; 4420 4188 } 4421 4189 … … 4432 4200 unix_ea_name[0] = '\0'; 4433 4201 pull_ascii_fstring(unix_ea_name, p + 4); 4434 ea->name = talloc_strdup(ctx, unix_ea_name); 4202 ea->name = talloc_strdup(ea_list, unix_ea_name); 4203 if (!ea->name) { 4204 goto fail; 4205 } 4435 4206 /* Ensure the value is null terminated (in case it's a string). */ 4436 ea->value = data_blob_talloc( ctx, NULL, ea_valuelen + 1);4207 ea->value = data_blob_talloc(ea_list, NULL, ea_valuelen + 1); 4437 4208 if (!ea->value.data) { 4438 goto out;4209 goto fail; 4439 4210 } 4440 4211 if (ea_valuelen) { … … 4447 4218 4448 4219 *pea_list = ea_list; 4449 ret = True; 4450 4451 out : 4452 4453 SAFE_FREE(rdata); 4454 SAFE_FREE(rparam); 4455 return ret; 4220 return true; 4221 4222 fail: 4223 TALLOC_FREE(ea_list); 4224 return false; 4456 4225 } 4457 4226 … … 4460 4229 *********************************************************/ 4461 4230 4462 bool cli_get_ea_list_path(struct cli_state *cli, const char *path, 4231 struct cli_get_ea_list_path_state { 4232 uint32_t num_data; 4233 uint8_t *data; 4234 }; 4235 4236 static void cli_get_ea_list_path_done(struct tevent_req *subreq); 4237 4238 struct tevent_req *cli_get_ea_list_path_send(TALLOC_CTX *mem_ctx, 4239 struct tevent_context *ev, 4240 struct cli_state *cli, 4241 const char *fname) 4242 { 4243 struct tevent_req *req, *subreq; 4244 struct cli_get_ea_list_path_state *state; 4245 4246 req = tevent_req_create(mem_ctx, &state, 4247 struct cli_get_ea_list_path_state); 4248 if (req == NULL) { 4249 return NULL; 4250 } 4251 subreq = cli_qpathinfo_send(state, ev, cli, fname, 4252 SMB_INFO_QUERY_ALL_EAS, 4, 4253 cli->max_xmit); 4254 if (tevent_req_nomem(subreq, req)) { 4255 return tevent_req_post(req, ev); 4256 } 4257 tevent_req_set_callback(subreq, cli_get_ea_list_path_done, req); 4258 return req; 4259 } 4260 4261 static void cli_get_ea_list_path_done(struct tevent_req *subreq) 4262 { 4263 struct tevent_req *req = tevent_req_callback_data( 4264 subreq, struct tevent_req); 4265 struct cli_get_ea_list_path_state *state = tevent_req_data( 4266 req, struct cli_get_ea_list_path_state); 4267 NTSTATUS status; 4268 4269 status = cli_qpathinfo_recv(subreq, state, &state->data, 4270 &state->num_data); 4271 TALLOC_FREE(subreq); 4272 if (tevent_req_nterror(req, status)) { 4273 return; 4274 } 4275 tevent_req_done(req); 4276 } 4277 4278 NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 4279 size_t *pnum_eas, struct ea_struct **peas) 4280 { 4281 struct cli_get_ea_list_path_state *state = tevent_req_data( 4282 req, struct cli_get_ea_list_path_state); 4283 NTSTATUS status; 4284 4285 if (tevent_req_is_nterror(req, &status)) { 4286 return status; 4287 } 4288 if (!parse_ea_blob(mem_ctx, state->data, state->num_data, 4289 pnum_eas, peas)) { 4290 return NT_STATUS_INVALID_NETWORK_RESPONSE; 4291 } 4292 return NT_STATUS_OK; 4293 } 4294 4295 NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path, 4463 4296 TALLOC_CTX *ctx, 4464 4297 size_t *pnum_eas, 4465 4298 struct ea_struct **pea_list) 4466 4299 { 4467 uint16_t setup = TRANSACT2_QPATHINFO; 4468 unsigned int param_len = 0; 4469 char *param; 4470 char *p; 4471 size_t srclen = 2*(strlen(path)+1); 4472 bool ret; 4473 4474 param = SMB_MALLOC_ARRAY(char, 6+srclen+2); 4475 if (!param) { 4476 return false; 4477 } 4478 p = param; 4479 memset(p, 0, 6); 4480 SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); 4481 p += 6; 4482 p += clistr_push(cli, p, path, srclen, STR_TERMINATE); 4483 param_len = PTR_DIFF(p, param); 4484 4485 ret = cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); 4486 SAFE_FREE(param); 4487 return ret; 4488 } 4489 4490 /********************************************************* 4491 Get an extended attribute list from an fnum. 4492 *********************************************************/ 4493 4494 bool cli_get_ea_list_fnum(struct cli_state *cli, uint16_t fnum, 4495 TALLOC_CTX *ctx, 4496 size_t *pnum_eas, 4497 struct ea_struct **pea_list) 4498 { 4499 uint16_t setup = TRANSACT2_QFILEINFO; 4500 char param[6]; 4501 4502 memset(param, 0, 6); 4503 SSVAL(param,0,fnum); 4504 SSVAL(param,2,SMB_INFO_SET_EA); 4505 4506 return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list); 4300 TALLOC_CTX *frame = talloc_stackframe(); 4301 struct event_context *ev = NULL; 4302 struct tevent_req *req = NULL; 4303 NTSTATUS status = NT_STATUS_NO_MEMORY; 4304 4305 if (cli_has_async_calls(cli)) { 4306 /* 4307 * Can't use sync call while an async call is in flight 4308 */ 4309 status = NT_STATUS_INVALID_PARAMETER; 4310 goto fail; 4311 } 4312 ev = event_context_init(frame); 4313 if (ev == NULL) { 4314 goto fail; 4315 } 4316 req = cli_get_ea_list_path_send(frame, ev, cli, path); 4317 if (req == NULL) { 4318 goto fail; 4319 } 4320 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 4321 goto fail; 4322 } 4323 status = cli_get_ea_list_path_recv(req, ctx, pnum_eas, pea_list); 4324 fail: 4325 TALLOC_FREE(frame); 4326 if (!NT_STATUS_IS_OK(status)) { 4327 cli_set_error(cli, status); 4328 } 4329 return status; 4507 4330 } 4508 4331 … … 4553 4376 #if defined(O_DIRECTORY) 4554 4377 if (flags & O_DIRECTORY) { 4555 ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);4556 4378 ret |= SMB_O_DIRECTORY; 4557 4379 } … … 4580 4402 uint32_t num_data; 4581 4403 4582 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &data, &num_data); 4404 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 4405 NULL, 0, NULL, &data, 12, &num_data); 4583 4406 TALLOC_FREE(subreq); 4584 if (!NT_STATUS_IS_OK(status)) { 4585 tevent_req_nterror(req, status); 4586 return; 4587 } 4588 if (num_data < 12) { 4589 tevent_req_nterror(req, status); 4407 if (tevent_req_nterror(req, status)) { 4590 4408 return; 4591 4409 } … … 4631 4449 /* Setup data words. */ 4632 4450 if (is_dir) { 4633 wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);4634 4451 wire_flags |= SMB_O_DIRECTORY; 4635 4452 } … … 4754 4571 NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req) 4755 4572 { 4756 NTSTATUS status; 4757 4758 if (tevent_req_is_nterror(req, &status)) { 4759 return status; 4760 } 4761 return NT_STATUS_OK; 4573 return tevent_req_simple_recv_ntstatus(req); 4762 4574 } 4763 4575 … … 4812 4624 ****************************************************************************/ 4813 4625 4814 struct unlink_state { 4815 uint16_t setup; 4626 struct cli_posix_unlink_internal_state { 4816 4627 uint8_t data[2]; 4817 4628 }; 4818 4629 4819 static void cli_posix_unlink_internal_done(struct tevent_req *subreq) 4820 { 4821 struct tevent_req *req = tevent_req_callback_data( 4822 subreq, struct tevent_req); 4823 struct unlink_state *state = tevent_req_data(req, struct unlink_state); 4824 NTSTATUS status; 4825 4826 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL); 4827 TALLOC_FREE(subreq); 4828 if (!NT_STATUS_IS_OK(status)) { 4829 tevent_req_nterror(req, status); 4830 return; 4831 } 4832 tevent_req_done(req); 4833 } 4630 static void cli_posix_unlink_internal_done(struct tevent_req *subreq); 4834 4631 4835 4632 static struct tevent_req *cli_posix_unlink_internal_send(TALLOC_CTX *mem_ctx, … … 4837 4634 struct cli_state *cli, 4838 4635 const char *fname, 4839 bool is_dir)4636 uint16_t level) 4840 4637 { 4841 4638 struct tevent_req *req = NULL, *subreq = NULL; 4842 struct unlink_state *state = NULL;4843 uint8_t *param = NULL; 4844 4845 req = tevent_req_create(mem_ctx, &state, struct unlink_state);4639 struct cli_posix_unlink_internal_state *state = NULL; 4640 4641 req = tevent_req_create(mem_ctx, &state, 4642 struct cli_posix_unlink_internal_state); 4846 4643 if (req == NULL) { 4847 4644 return NULL; 4848 4645 } 4849 4646 4850 /* Setup setup word. */4851 SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);4852 4853 /* Setup param array. */4854 param = talloc_array(state, uint8_t, 6);4855 if (tevent_req_nomem(param, req)) {4856 return tevent_req_post(req, ev);4857 }4858 memset(param, '\0', 6);4859 SSVAL(param, 0, SMB_POSIX_PATH_UNLINK);4860 4861 param = trans2_bytes_push_str(param, cli_ucs2(cli), fname,4862 strlen(fname)+1, NULL);4863 4864 if (tevent_req_nomem(param, req)) {4865 return tevent_req_post(req, ev);4866 }4867 4868 4647 /* Setup data word. */ 4869 SSVAL(state->data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET : 4870 SMB_POSIX_UNLINK_FILE_TARGET); 4871 4872 subreq = cli_trans_send(state, /* mem ctx. */ 4873 ev, /* event ctx. */ 4874 cli, /* cli_state. */ 4875 SMBtrans2, /* cmd. */ 4876 NULL, /* pipe name. */ 4877 -1, /* fid. */ 4878 0, /* function. */ 4879 0, /* flags. */ 4880 &state->setup, /* setup. */ 4881 1, /* num setup uint16_t words. */ 4882 0, /* max returned setup. */ 4883 param, /* param. */ 4884 talloc_get_size(param), /* num param. */ 4885 2, /* max returned param. */ 4886 state->data, /* data. */ 4887 2, /* num data. */ 4888 0); /* max returned data. */ 4889 4648 SSVAL(state->data, 0, level); 4649 4650 subreq = cli_setpathinfo_send(state, ev, cli, 4651 SMB_POSIX_PATH_UNLINK, 4652 fname, 4653 state->data, sizeof(state->data)); 4890 4654 if (tevent_req_nomem(subreq, req)) { 4891 4655 return tevent_req_post(req, ev); … … 4893 4657 tevent_req_set_callback(subreq, cli_posix_unlink_internal_done, req); 4894 4658 return req; 4659 } 4660 4661 static void cli_posix_unlink_internal_done(struct tevent_req *subreq) 4662 { 4663 NTSTATUS status = cli_setpathinfo_recv(subreq); 4664 tevent_req_simple_finish_ntstatus(subreq, status); 4895 4665 } 4896 4666 … … 4900 4670 const char *fname) 4901 4671 { 4902 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, false); 4672 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, 4673 SMB_POSIX_UNLINK_FILE_TARGET); 4903 4674 } 4904 4675 4905 4676 NTSTATUS cli_posix_unlink_recv(struct tevent_req *req) 4906 4677 { 4907 NTSTATUS status; 4908 4909 if (tevent_req_is_nterror(req, &status)) { 4910 return status; 4911 } 4912 return NT_STATUS_OK; 4678 return tevent_req_simple_recv_ntstatus(req); 4913 4679 } 4914 4680 … … 4971 4737 const char *fname) 4972 4738 { 4973 return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, true); 4739 return cli_posix_unlink_internal_send( 4740 mem_ctx, ev, cli, fname, 4741 SMB_POSIX_UNLINK_DIRECTORY_TARGET); 4974 4742 } 4975 4743 4976 4744 NTSTATUS cli_posix_rmdir_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx) 4977 4745 { 4978 NTSTATUS status; 4979 4980 if (tevent_req_is_nterror(req, &status)) { 4981 return status; 4982 } 4983 return NT_STATUS_OK; 4746 return tevent_req_simple_recv_ntstatus(req); 4984 4747 } 4985 4748 … … 5094 4857 uint8_t *params; 5095 4858 uint32_t i, ofs, num_params; 5096 5097 status = cli_trans_recv(subreq, talloc_tos(), NULL, NULL, 5098 ¶ms, &num_params, NULL, NULL); 4859 uint16_t flags2; 4860 4861 status = cli_trans_recv(subreq, talloc_tos(), &flags2, NULL, 0, NULL, 4862 ¶ms, 0, &num_params, NULL, 0, NULL); 5099 4863 TALLOC_FREE(subreq); 5100 if ( !NT_STATUS_IS_OK(status)) {4864 if (tevent_req_nterror(req, status)) { 5101 4865 DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status))); 5102 tevent_req_nterror(req, status);5103 4866 return; 5104 4867 } … … 5140 4903 5141 4904 state->changes[i].action = IVAL(params, ofs+4); 5142 ret = clistr_pull_talloc(params, (char *)params, &name,5143 params+ofs+12, len,4905 ret = clistr_pull_talloc(params, (char *)params, flags2, 4906 &name, params+ofs+12, len, 5144 4907 STR_TERMINATE|STR_UNICODE); 5145 4908 if (ret == -1) { … … 5172 4935 return NT_STATUS_OK; 5173 4936 } 4937 4938 struct cli_qpathinfo_state { 4939 uint8_t *param; 4940 uint8_t *data; 4941 uint16_t setup[1]; 4942 uint32_t min_rdata; 4943 uint8_t *rdata; 4944 uint32_t num_rdata; 4945 }; 4946 4947 static void cli_qpathinfo_done(struct tevent_req *subreq); 4948 4949 struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx, 4950 struct tevent_context *ev, 4951 struct cli_state *cli, const char *fname, 4952 uint16_t level, uint32_t min_rdata, 4953 uint32_t max_rdata) 4954 { 4955 struct tevent_req *req, *subreq; 4956 struct cli_qpathinfo_state *state; 4957 4958 req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo_state); 4959 if (req == NULL) { 4960 return NULL; 4961 } 4962 state->min_rdata = min_rdata; 4963 SSVAL(state->setup, 0, TRANSACT2_QPATHINFO); 4964 4965 state->param = talloc_zero_array(state, uint8_t, 6); 4966 if (tevent_req_nomem(state->param, req)) { 4967 return tevent_req_post(req, ev); 4968 } 4969 SSVAL(state->param, 0, level); 4970 state->param = trans2_bytes_push_str( 4971 state->param, cli_ucs2(cli), fname, strlen(fname)+1, NULL); 4972 if (tevent_req_nomem(state->param, req)) { 4973 return tevent_req_post(req, ev); 4974 } 4975 4976 subreq = cli_trans_send( 4977 state, /* mem ctx. */ 4978 ev, /* event ctx. */ 4979 cli, /* cli_state. */ 4980 SMBtrans2, /* cmd. */ 4981 NULL, /* pipe name. */ 4982 -1, /* fid. */ 4983 0, /* function. */ 4984 0, /* flags. */ 4985 state->setup, /* setup. */ 4986 1, /* num setup uint16_t words. */ 4987 0, /* max returned setup. */ 4988 state->param, /* param. */ 4989 talloc_get_size(state->param), /* num param. */ 4990 2, /* max returned param. */ 4991 NULL, /* data. */ 4992 0, /* num data. */ 4993 max_rdata); /* max returned data. */ 4994 4995 if (tevent_req_nomem(subreq, req)) { 4996 return tevent_req_post(req, ev); 4997 } 4998 tevent_req_set_callback(subreq, cli_qpathinfo_done, req); 4999 return req; 5000 } 5001 5002 static void cli_qpathinfo_done(struct tevent_req *subreq) 5003 { 5004 struct tevent_req *req = tevent_req_callback_data( 5005 subreq, struct tevent_req); 5006 struct cli_qpathinfo_state *state = tevent_req_data( 5007 req, struct cli_qpathinfo_state); 5008 NTSTATUS status; 5009 5010 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 5011 NULL, 0, NULL, 5012 &state->rdata, state->min_rdata, 5013 &state->num_rdata); 5014 if (tevent_req_nterror(req, status)) { 5015 return; 5016 } 5017 tevent_req_done(req); 5018 } 5019 5020 NTSTATUS cli_qpathinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5021 uint8_t **rdata, uint32_t *num_rdata) 5022 { 5023 struct cli_qpathinfo_state *state = tevent_req_data( 5024 req, struct cli_qpathinfo_state); 5025 NTSTATUS status; 5026 5027 if (tevent_req_is_nterror(req, &status)) { 5028 return status; 5029 } 5030 if (rdata != NULL) { 5031 *rdata = talloc_move(mem_ctx, &state->rdata); 5032 } else { 5033 TALLOC_FREE(state->rdata); 5034 } 5035 if (num_rdata != NULL) { 5036 *num_rdata = state->num_rdata; 5037 } 5038 return NT_STATUS_OK; 5039 } 5040 5041 NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5042 const char *fname, uint16_t level, uint32_t min_rdata, 5043 uint32_t max_rdata, 5044 uint8_t **rdata, uint32_t *num_rdata) 5045 { 5046 TALLOC_CTX *frame = talloc_stackframe(); 5047 struct event_context *ev; 5048 struct tevent_req *req; 5049 NTSTATUS status = NT_STATUS_NO_MEMORY; 5050 5051 if (cli_has_async_calls(cli)) { 5052 /* 5053 * Can't use sync call while an async call is in flight 5054 */ 5055 status = NT_STATUS_INVALID_PARAMETER; 5056 goto fail; 5057 } 5058 ev = event_context_init(frame); 5059 if (ev == NULL) { 5060 goto fail; 5061 } 5062 req = cli_qpathinfo_send(frame, ev, cli, fname, level, min_rdata, 5063 max_rdata); 5064 if (req == NULL) { 5065 goto fail; 5066 } 5067 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5068 goto fail; 5069 } 5070 status = cli_qpathinfo_recv(req, mem_ctx, rdata, num_rdata); 5071 fail: 5072 TALLOC_FREE(frame); 5073 if (!NT_STATUS_IS_OK(status)) { 5074 cli_set_error(cli, status); 5075 } 5076 return status; 5077 } 5078 5079 struct cli_qfileinfo_state { 5080 uint16_t setup[1]; 5081 uint8_t param[4]; 5082 uint8_t *data; 5083 uint32_t min_rdata; 5084 uint8_t *rdata; 5085 uint32_t num_rdata; 5086 }; 5087 5088 static void cli_qfileinfo_done(struct tevent_req *subreq); 5089 5090 struct tevent_req *cli_qfileinfo_send(TALLOC_CTX *mem_ctx, 5091 struct tevent_context *ev, 5092 struct cli_state *cli, uint16_t fnum, 5093 uint16_t level, uint32_t min_rdata, 5094 uint32_t max_rdata) 5095 { 5096 struct tevent_req *req, *subreq; 5097 struct cli_qfileinfo_state *state; 5098 5099 req = tevent_req_create(mem_ctx, &state, struct cli_qfileinfo_state); 5100 if (req == NULL) { 5101 return NULL; 5102 } 5103 state->min_rdata = min_rdata; 5104 SSVAL(state->param, 0, fnum); 5105 SSVAL(state->param, 2, level); 5106 SSVAL(state->setup, 0, TRANSACT2_QFILEINFO); 5107 5108 subreq = cli_trans_send( 5109 state, /* mem ctx. */ 5110 ev, /* event ctx. */ 5111 cli, /* cli_state. */ 5112 SMBtrans2, /* cmd. */ 5113 NULL, /* pipe name. */ 5114 -1, /* fid. */ 5115 0, /* function. */ 5116 0, /* flags. */ 5117 state->setup, /* setup. */ 5118 1, /* num setup uint16_t words. */ 5119 0, /* max returned setup. */ 5120 state->param, /* param. */ 5121 sizeof(state->param), /* num param. */ 5122 2, /* max returned param. */ 5123 NULL, /* data. */ 5124 0, /* num data. */ 5125 max_rdata); /* max returned data. */ 5126 5127 if (tevent_req_nomem(subreq, req)) { 5128 return tevent_req_post(req, ev); 5129 } 5130 tevent_req_set_callback(subreq, cli_qfileinfo_done, req); 5131 return req; 5132 } 5133 5134 static void cli_qfileinfo_done(struct tevent_req *subreq) 5135 { 5136 struct tevent_req *req = tevent_req_callback_data( 5137 subreq, struct tevent_req); 5138 struct cli_qfileinfo_state *state = tevent_req_data( 5139 req, struct cli_qfileinfo_state); 5140 NTSTATUS status; 5141 5142 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 5143 NULL, 0, NULL, 5144 &state->rdata, state->min_rdata, 5145 &state->num_rdata); 5146 if (tevent_req_nterror(req, status)) { 5147 return; 5148 } 5149 tevent_req_done(req); 5150 } 5151 5152 NTSTATUS cli_qfileinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5153 uint8_t **rdata, uint32_t *num_rdata) 5154 { 5155 struct cli_qfileinfo_state *state = tevent_req_data( 5156 req, struct cli_qfileinfo_state); 5157 NTSTATUS status; 5158 5159 if (tevent_req_is_nterror(req, &status)) { 5160 return status; 5161 } 5162 if (rdata != NULL) { 5163 *rdata = talloc_move(mem_ctx, &state->rdata); 5164 } else { 5165 TALLOC_FREE(state->rdata); 5166 } 5167 if (num_rdata != NULL) { 5168 *num_rdata = state->num_rdata; 5169 } 5170 return NT_STATUS_OK; 5171 } 5172 5173 NTSTATUS cli_qfileinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5174 uint16_t fnum, uint16_t level, uint32_t min_rdata, 5175 uint32_t max_rdata, 5176 uint8_t **rdata, uint32_t *num_rdata) 5177 { 5178 TALLOC_CTX *frame = talloc_stackframe(); 5179 struct event_context *ev; 5180 struct tevent_req *req; 5181 NTSTATUS status = NT_STATUS_NO_MEMORY; 5182 5183 if (cli_has_async_calls(cli)) { 5184 /* 5185 * Can't use sync call while an async call is in flight 5186 */ 5187 status = NT_STATUS_INVALID_PARAMETER; 5188 goto fail; 5189 } 5190 ev = event_context_init(frame); 5191 if (ev == NULL) { 5192 goto fail; 5193 } 5194 req = cli_qfileinfo_send(frame, ev, cli, fnum, level, min_rdata, 5195 max_rdata); 5196 if (req == NULL) { 5197 goto fail; 5198 } 5199 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5200 goto fail; 5201 } 5202 status = cli_qfileinfo_recv(req, mem_ctx, rdata, num_rdata); 5203 fail: 5204 TALLOC_FREE(frame); 5205 if (!NT_STATUS_IS_OK(status)) { 5206 cli_set_error(cli, status); 5207 } 5208 return status; 5209 } 5210 5211 struct cli_flush_state { 5212 uint16_t vwv[1]; 5213 }; 5214 5215 static void cli_flush_done(struct tevent_req *subreq); 5216 5217 struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx, 5218 struct event_context *ev, 5219 struct cli_state *cli, 5220 uint16_t fnum) 5221 { 5222 struct tevent_req *req, *subreq; 5223 struct cli_flush_state *state; 5224 5225 req = tevent_req_create(mem_ctx, &state, struct cli_flush_state); 5226 if (req == NULL) { 5227 return NULL; 5228 } 5229 SSVAL(state->vwv + 0, 0, fnum); 5230 5231 subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv, 5232 0, NULL); 5233 if (tevent_req_nomem(subreq, req)) { 5234 return tevent_req_post(req, ev); 5235 } 5236 tevent_req_set_callback(subreq, cli_flush_done, req); 5237 return req; 5238 } 5239 5240 static void cli_flush_done(struct tevent_req *subreq) 5241 { 5242 struct tevent_req *req = tevent_req_callback_data( 5243 subreq, struct tevent_req); 5244 NTSTATUS status; 5245 5246 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 5247 TALLOC_FREE(subreq); 5248 if (tevent_req_nterror(req, status)) { 5249 return; 5250 } 5251 tevent_req_done(req); 5252 } 5253 5254 NTSTATUS cli_flush_recv(struct tevent_req *req) 5255 { 5256 return tevent_req_simple_recv_ntstatus(req); 5257 } 5258 5259 NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum) 5260 { 5261 TALLOC_CTX *frame = talloc_stackframe(); 5262 struct event_context *ev; 5263 struct tevent_req *req; 5264 NTSTATUS status = NT_STATUS_NO_MEMORY; 5265 5266 if (cli_has_async_calls(cli)) { 5267 /* 5268 * Can't use sync call while an async call is in flight 5269 */ 5270 status = NT_STATUS_INVALID_PARAMETER; 5271 goto fail; 5272 } 5273 ev = event_context_init(frame); 5274 if (ev == NULL) { 5275 goto fail; 5276 } 5277 req = cli_flush_send(frame, ev, cli, fnum); 5278 if (req == NULL) { 5279 goto fail; 5280 } 5281 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5282 goto fail; 5283 } 5284 status = cli_flush_recv(req); 5285 fail: 5286 TALLOC_FREE(frame); 5287 if (!NT_STATUS_IS_OK(status)) { 5288 cli_set_error(cli, status); 5289 } 5290 return status; 5291 } 5292 5293 struct cli_shadow_copy_data_state { 5294 uint16_t setup[4]; 5295 uint8_t *data; 5296 uint32_t num_data; 5297 bool get_names; 5298 }; 5299 5300 static void cli_shadow_copy_data_done(struct tevent_req *subreq); 5301 5302 struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx, 5303 struct tevent_context *ev, 5304 struct cli_state *cli, 5305 uint16_t fnum, 5306 bool get_names) 5307 { 5308 struct tevent_req *req, *subreq; 5309 struct cli_shadow_copy_data_state *state; 5310 uint32_t ret_size; 5311 5312 req = tevent_req_create(mem_ctx, &state, 5313 struct cli_shadow_copy_data_state); 5314 if (req == NULL) { 5315 return NULL; 5316 } 5317 state->get_names = get_names; 5318 ret_size = get_names ? cli->max_xmit : 16; 5319 5320 SIVAL(state->setup + 0, 0, FSCTL_GET_SHADOW_COPY_DATA); 5321 SSVAL(state->setup + 2, 0, fnum); 5322 SCVAL(state->setup + 3, 0, 0); /* isFsctl */ 5323 SCVAL(state->setup + 3, 1, 0); /* compfilter, isFlags (WSSP) */ 5324 5325 subreq = cli_trans_send( 5326 state, ev, cli, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0, 5327 state->setup, ARRAY_SIZE(state->setup), 0, 5328 NULL, 0, 0, 5329 NULL, 0, ret_size); 5330 if (tevent_req_nomem(subreq, req)) { 5331 return tevent_req_post(req, ev); 5332 } 5333 tevent_req_set_callback(subreq, cli_shadow_copy_data_done, req); 5334 return req; 5335 } 5336 5337 static void cli_shadow_copy_data_done(struct tevent_req *subreq) 5338 { 5339 struct tevent_req *req = tevent_req_callback_data( 5340 subreq, struct tevent_req); 5341 struct cli_shadow_copy_data_state *state = tevent_req_data( 5342 req, struct cli_shadow_copy_data_state); 5343 NTSTATUS status; 5344 5345 status = cli_trans_recv(subreq, state, NULL, 5346 NULL, 0, NULL, /* setup */ 5347 NULL, 0, NULL, /* param */ 5348 &state->data, 12, &state->num_data); 5349 TALLOC_FREE(subreq); 5350 if (tevent_req_nterror(req, status)) { 5351 return; 5352 } 5353 tevent_req_done(req); 5354 } 5355 5356 NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 5357 char ***pnames, int *pnum_names) 5358 { 5359 struct cli_shadow_copy_data_state *state = tevent_req_data( 5360 req, struct cli_shadow_copy_data_state); 5361 char **names; 5362 int i, num_names; 5363 uint32_t dlength; 5364 NTSTATUS status; 5365 5366 if (tevent_req_is_nterror(req, &status)) { 5367 return status; 5368 } 5369 num_names = IVAL(state->data, 4); 5370 dlength = IVAL(state->data, 8); 5371 5372 if (!state->get_names) { 5373 *pnum_names = num_names; 5374 return NT_STATUS_OK; 5375 } 5376 5377 if (dlength+12 > state->num_data) { 5378 return NT_STATUS_INVALID_NETWORK_RESPONSE; 5379 } 5380 names = talloc_array(mem_ctx, char *, num_names); 5381 if (names == NULL) { 5382 return NT_STATUS_NO_MEMORY; 5383 } 5384 5385 for (i=0; i<num_names; i++) { 5386 bool ret; 5387 uint8_t *src; 5388 size_t converted_size; 5389 5390 src = state->data + 12 + i * 2 * sizeof(SHADOW_COPY_LABEL); 5391 ret = convert_string_talloc( 5392 names, CH_UTF16LE, CH_UNIX, 5393 src, 2 * sizeof(SHADOW_COPY_LABEL), 5394 &names[i], &converted_size, True); 5395 if (!ret) { 5396 TALLOC_FREE(names); 5397 return NT_STATUS_INVALID_NETWORK_RESPONSE; 5398 } 5399 } 5400 *pnum_names = num_names; 5401 *pnames = names; 5402 return NT_STATUS_OK; 5403 } 5404 5405 NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli, 5406 uint16_t fnum, bool get_names, 5407 char ***pnames, int *pnum_names) 5408 { 5409 TALLOC_CTX *frame = talloc_stackframe(); 5410 struct event_context *ev; 5411 struct tevent_req *req; 5412 NTSTATUS status = NT_STATUS_NO_MEMORY; 5413 5414 if (cli_has_async_calls(cli)) { 5415 /* 5416 * Can't use sync call while an async call is in flight 5417 */ 5418 status = NT_STATUS_INVALID_PARAMETER; 5419 goto fail; 5420 } 5421 ev = event_context_init(frame); 5422 if (ev == NULL) { 5423 goto fail; 5424 } 5425 req = cli_shadow_copy_data_send(frame, ev, cli, fnum, get_names); 5426 if (req == NULL) { 5427 goto fail; 5428 } 5429 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 5430 goto fail; 5431 } 5432 status = cli_shadow_copy_data_recv(req, mem_ctx, pnames, pnum_names); 5433 fail: 5434 TALLOC_FREE(frame); 5435 if (!NT_STATUS_IS_OK(status)) { 5436 cli_set_error(cli, status); 5437 } 5438 return status; 5439 } -
vendor/current/source3/libsmb/clifsinfo.c
r414 r740 4 4 Copyright (C) Stefan (metze) Metzmacher 2003 5 5 Copyright (C) Jeremy Allison 2007 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "libsmb/libsmb.h" 22 23 #include "../libcli/auth/spnego.h" 24 #include "../libcli/auth/ntlmssp.h" 25 #include "../lib/util/tevent_ntstatus.h" 26 #include "async_smb.h" 27 #include "smb_crypt.h" 28 #include "trans2.h" 23 29 24 30 /**************************************************************************** … … 27 33 28 34 struct cli_unix_extensions_version_state { 35 struct cli_state *cli; 29 36 uint16_t setup[1]; 30 37 uint8_t param[2]; … … 47 54 return NULL; 48 55 } 56 state->cli = cli; 49 57 SSVAL(state->setup, 0, TRANSACT2_QFSINFO); 50 58 SSVAL(state->param, 0, SMB_QUERY_CIFS_UNIX_INFO); … … 72 80 NTSTATUS status; 73 81 74 status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,75 &data, &num_data);82 status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL, 83 NULL, 0, NULL, &data, 12, &num_data); 76 84 TALLOC_FREE(subreq); 77 85 if (!NT_STATUS_IS_OK(status)) { 78 86 tevent_req_nterror(req, status); 79 return;80 }81 if (num_data < 12) {82 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);83 87 return; 84 88 } … … 108 112 *pcaplow = state->caplow; 109 113 *pcaphigh = state->caphigh; 114 state->cli->server_posix_capabilities = *pcaplow; 110 115 return NT_STATUS_OK; 111 116 } … … 147 152 status = cli_unix_extensions_version_recv(req, pmajor, pminor, pcaplow, 148 153 pcaphigh); 149 if (NT_STATUS_IS_OK(status)) {150 cli->posix_capabilities = *pcaplow;151 }152 154 fail: 153 155 TALLOC_FREE(frame); … … 162 164 ****************************************************************************/ 163 165 164 bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, 165 uint32 caplow, uint32 caphigh) 166 { 167 bool ret = False; 168 uint16 setup; 169 char param[4]; 170 char data[12]; 171 char *rparam=NULL, *rdata=NULL; 172 unsigned int rparam_count=0, rdata_count=0; 173 174 setup = TRANSACT2_SETFSINFO; 175 176 SSVAL(param,0,0); 177 SSVAL(param,2,SMB_SET_CIFS_UNIX_INFO); 178 179 SSVAL(data,0,major); 180 SSVAL(data,2,minor); 181 SIVAL(data,4,caplow); 182 SIVAL(data,8,caphigh); 183 184 if (!cli_send_trans(cli, SMBtrans2, 185 NULL, 186 0, 0, 187 &setup, 1, 0, 188 param, 4, 0, 189 data, 12, 560)) { 190 goto cleanup; 191 } 192 193 if (!cli_receive_trans(cli, SMBtrans2, 194 &rparam, &rparam_count, 195 &rdata, &rdata_count)) { 196 goto cleanup; 197 } 198 199 if (cli_is_error(cli)) { 200 ret = False; 201 goto cleanup; 202 } else { 203 ret = True; 204 } 205 206 cleanup: 207 SAFE_FREE(rparam); 208 SAFE_FREE(rdata); 209 210 return ret; 211 } 212 213 bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) 214 { 215 bool ret = False; 216 uint16 setup; 217 char param[2]; 218 char *rparam=NULL, *rdata=NULL; 219 unsigned int rparam_count=0, rdata_count=0; 220 221 if (!cli||!fs_attr) 222 smb_panic("cli_get_fs_attr_info() called with NULL Pionter!"); 223 224 setup = TRANSACT2_QFSINFO; 225 226 SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO); 227 228 if (!cli_send_trans(cli, SMBtrans2, 229 NULL, 230 0, 0, 231 &setup, 1, 0, 232 param, 2, 0, 233 NULL, 0, 560)) { 234 goto cleanup; 235 } 236 237 if (!cli_receive_trans(cli, SMBtrans2, 238 &rparam, &rparam_count, 239 &rdata, &rdata_count)) { 240 goto cleanup; 241 } 242 243 if (cli_is_error(cli)) { 244 ret = False; 245 goto cleanup; 246 } else { 247 ret = True; 248 } 249 250 if (rdata_count < 12) { 251 goto cleanup; 252 } 253 254 *fs_attr = IVAL(rdata,0); 166 struct cli_set_unix_extensions_capabilities_state { 167 struct cli_state *cli; 168 uint16_t setup[1]; 169 uint8_t param[4]; 170 uint8_t data[12]; 171 }; 172 173 static void cli_set_unix_extensions_capabilities_done( 174 struct tevent_req *subreq); 175 176 struct tevent_req *cli_set_unix_extensions_capabilities_send( 177 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 178 uint16_t major, uint16_t minor, uint32_t caplow, uint32_t caphigh) 179 { 180 struct tevent_req *req, *subreq; 181 struct cli_set_unix_extensions_capabilities_state *state; 182 183 req = tevent_req_create( 184 mem_ctx, &state, 185 struct cli_set_unix_extensions_capabilities_state); 186 if (req == NULL) { 187 return NULL; 188 } 189 190 state->cli = cli; 191 SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO); 192 193 SSVAL(state->param, 0, 0); 194 SSVAL(state->param, 2, SMB_SET_CIFS_UNIX_INFO); 195 196 SSVAL(state->data, 0, major); 197 SSVAL(state->data, 2, minor); 198 SIVAL(state->data, 4, caplow); 199 SIVAL(state->data, 8, caphigh); 200 201 subreq = cli_trans_send(state, ev, cli, SMBtrans2, 202 NULL, 0, 0, 0, 203 state->setup, 1, 0, 204 state->param, 4, 0, 205 state->data, 12, 560); 206 if (tevent_req_nomem(subreq, req)) { 207 return tevent_req_post(req, ev); 208 } 209 tevent_req_set_callback( 210 subreq, cli_set_unix_extensions_capabilities_done, req); 211 return req; 212 } 213 214 static void cli_set_unix_extensions_capabilities_done( 215 struct tevent_req *subreq) 216 { 217 struct tevent_req *req = tevent_req_callback_data( 218 subreq, struct tevent_req); 219 struct cli_set_unix_extensions_capabilities_state *state = tevent_req_data( 220 req, struct cli_set_unix_extensions_capabilities_state); 221 222 NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL, 223 NULL, 0, NULL, NULL, 0, NULL); 224 if (NT_STATUS_IS_OK(status)) { 225 state->cli->requested_posix_capabilities = IVAL(state->data, 4); 226 } 227 tevent_req_simple_finish_ntstatus(subreq, status); 228 } 229 230 NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req) 231 { 232 return tevent_req_simple_recv_ntstatus(req); 233 } 234 235 NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, 236 uint16 major, uint16 minor, 237 uint32 caplow, uint32 caphigh) 238 { 239 struct tevent_context *ev; 240 struct tevent_req *req; 241 NTSTATUS status = NT_STATUS_NO_MEMORY; 242 243 if (cli_has_async_calls(cli)) { 244 return NT_STATUS_INVALID_PARAMETER; 245 } 246 ev = tevent_context_init(talloc_tos()); 247 if (ev == NULL) { 248 goto fail; 249 } 250 req = cli_set_unix_extensions_capabilities_send( 251 ev, ev, cli, major, minor, caplow, caphigh); 252 if (req == NULL) { 253 goto fail; 254 } 255 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 256 goto fail; 257 } 258 status = cli_set_unix_extensions_capabilities_recv(req); 259 fail: 260 TALLOC_FREE(ev); 261 if (!NT_STATUS_IS_OK(status)) { 262 cli_set_error(cli, status); 263 } 264 return status; 265 } 266 267 struct cli_get_fs_attr_info_state { 268 uint16_t setup[1]; 269 uint8_t param[2]; 270 uint32_t fs_attr; 271 }; 272 273 static void cli_get_fs_attr_info_done(struct tevent_req *subreq); 274 275 struct tevent_req *cli_get_fs_attr_info_send(TALLOC_CTX *mem_ctx, 276 struct tevent_context *ev, 277 struct cli_state *cli) 278 { 279 struct tevent_req *subreq, *req; 280 struct cli_get_fs_attr_info_state *state; 281 282 req = tevent_req_create(mem_ctx, &state, 283 struct cli_get_fs_attr_info_state); 284 if (req == NULL) { 285 return NULL; 286 } 287 SSVAL(state->setup+0, 0, TRANSACT2_QFSINFO); 288 SSVAL(state->param+0, 0, SMB_QUERY_FS_ATTRIBUTE_INFO); 289 290 subreq = cli_trans_send(state, ev, cli, SMBtrans2, 291 NULL, 0, 0, 0, 292 state->setup, 1, 0, 293 state->param, 2, 0, 294 NULL, 0, 560); 295 if (tevent_req_nomem(subreq, req)) { 296 return tevent_req_post(req, ev); 297 } 298 tevent_req_set_callback(subreq, cli_get_fs_attr_info_done, req); 299 return req; 300 } 301 302 static void cli_get_fs_attr_info_done(struct tevent_req *subreq) 303 { 304 struct tevent_req *req = tevent_req_callback_data( 305 subreq, struct tevent_req); 306 struct cli_get_fs_attr_info_state *state = tevent_req_data( 307 req, struct cli_get_fs_attr_info_state); 308 uint8_t *data; 309 uint32_t num_data; 310 NTSTATUS status; 311 312 status = cli_trans_recv(subreq, talloc_tos(), NULL, NULL, 0, NULL, 313 NULL, 0, NULL, &data, 12, &num_data); 314 TALLOC_FREE(subreq); 315 if (!NT_STATUS_IS_OK(status)) { 316 tevent_req_nterror(req, status); 317 return; 318 } 319 state->fs_attr = IVAL(data, 0); 320 TALLOC_FREE(data); 321 tevent_req_done(req); 322 } 323 324 NTSTATUS cli_get_fs_attr_info_recv(struct tevent_req *req, uint32_t *fs_attr) 325 { 326 struct cli_get_fs_attr_info_state *state = tevent_req_data( 327 req, struct cli_get_fs_attr_info_state); 328 NTSTATUS status; 329 330 if (tevent_req_is_nterror(req, &status)) { 331 return status; 332 } 333 *fs_attr = state->fs_attr; 334 return NT_STATUS_OK; 335 } 336 337 NTSTATUS cli_get_fs_attr_info(struct cli_state *cli, uint32_t *fs_attr) 338 { 339 struct tevent_context *ev; 340 struct tevent_req *req; 341 NTSTATUS status = NT_STATUS_NO_MEMORY; 342 343 if (cli_has_async_calls(cli)) { 344 return NT_STATUS_INVALID_PARAMETER; 345 } 346 ev = tevent_context_init(talloc_tos()); 347 if (ev == NULL) { 348 goto fail; 349 } 350 req = cli_get_fs_attr_info_send(ev, ev, cli); 351 if (req == NULL) { 352 goto fail; 353 } 354 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 355 goto fail; 356 } 357 status = cli_get_fs_attr_info_recv(req, fs_attr); 358 fail: 359 TALLOC_FREE(ev); 360 if (!NT_STATUS_IS_OK(status)) { 361 cli_set_error(cli, status); 362 } 363 return status; 364 } 365 366 NTSTATUS cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, 367 uint32 *pserial_number, time_t *pdate) 368 { 369 NTSTATUS status; 370 uint16 setup[1]; 371 uint8_t param[2]; 372 uint8_t *rdata; 373 uint32_t rdata_count; 374 unsigned int nlen; 375 376 SSVAL(setup, 0, TRANSACT2_QFSINFO); 377 SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO); 378 379 status = cli_trans(talloc_tos(), cli, SMBtrans2, 380 NULL, 0, 0, 0, 381 setup, 1, 0, 382 param, 2, 0, 383 NULL, 0, 560, 384 NULL, 385 NULL, 0, NULL, 386 NULL, 0, NULL, 387 &rdata, 10, &rdata_count); 388 if (!NT_STATUS_IS_OK(status)) { 389 return status; 390 } 391 392 if (pdate) { 393 struct timespec ts; 394 ts = interpret_long_date((char *)rdata); 395 *pdate = ts.tv_sec; 396 } 397 if (pserial_number) { 398 *pserial_number = IVAL(rdata,8); 399 } 400 nlen = IVAL(rdata,12); 401 clistr_pull(cli->inbuf, volume_name, rdata + 18, sizeof(fstring), 402 nlen, STR_UNICODE); 255 403 256 404 /* todo: but not yet needed … … 258 406 */ 259 407 260 cleanup: 261 SAFE_FREE(rparam); 262 SAFE_FREE(rdata); 263 264 return ret; 265 } 266 267 bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number) 268 { 269 bool ret = False; 270 uint16 setup; 271 char param[2]; 272 char *rparam=NULL, *rdata=NULL; 273 unsigned int rparam_count=0, rdata_count=0; 274 unsigned char nlen; 275 276 setup = TRANSACT2_QFSINFO; 277 278 SSVAL(param,0,SMB_INFO_VOLUME); 279 280 if (!cli_send_trans(cli, SMBtrans2, 281 NULL, 282 0, 0, 283 &setup, 1, 0, 284 param, 2, 0, 285 NULL, 0, 560)) { 286 goto cleanup; 287 } 288 289 if (!cli_receive_trans(cli, SMBtrans2, 290 &rparam, &rparam_count, 291 &rdata, &rdata_count)) { 292 goto cleanup; 293 } 294 295 if (cli_is_error(cli)) { 296 ret = False; 297 goto cleanup; 298 } else { 299 ret = True; 300 } 301 302 if (rdata_count < 5) { 303 goto cleanup; 304 } 305 306 if (pserial_number) { 307 *pserial_number = IVAL(rdata,0); 308 } 309 nlen = CVAL(rdata,l2_vol_cch); 310 clistr_pull(cli->inbuf, volume_name, rdata + l2_vol_szVolLabel, 311 sizeof(fstring), nlen, STR_NOALIGN); 312 313 /* todo: but not yet needed 314 * return the other stuff 315 */ 316 317 cleanup: 318 SAFE_FREE(rparam); 319 SAFE_FREE(rdata); 320 321 return ret; 322 } 323 324 bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate) 325 { 326 bool ret = False; 327 uint16 setup; 328 char param[2]; 329 char *rparam=NULL, *rdata=NULL; 330 unsigned int rparam_count=0, rdata_count=0; 331 unsigned int nlen; 332 333 setup = TRANSACT2_QFSINFO; 334 335 SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO); 336 337 if (!cli_send_trans(cli, SMBtrans2, 338 NULL, 339 0, 0, 340 &setup, 1, 0, 341 param, 2, 0, 342 NULL, 0, 560)) { 343 goto cleanup; 344 } 345 346 if (!cli_receive_trans(cli, SMBtrans2, 347 &rparam, &rparam_count, 348 &rdata, &rdata_count)) { 349 goto cleanup; 350 } 351 352 if (cli_is_error(cli)) { 353 ret = False; 354 goto cleanup; 355 } else { 356 ret = True; 357 } 358 359 if (rdata_count < 19) { 360 goto cleanup; 361 } 362 363 if (pdate) { 364 struct timespec ts; 365 ts = interpret_long_date(rdata); 366 *pdate = ts.tv_sec; 367 } 368 if (pserial_number) { 369 *pserial_number = IVAL(rdata,8); 370 } 371 nlen = IVAL(rdata,12); 372 clistr_pull(cli->inbuf, volume_name, rdata + 18, sizeof(fstring), 373 nlen, STR_UNICODE); 374 375 /* todo: but not yet needed 376 * return the other stuff 377 */ 378 379 cleanup: 380 SAFE_FREE(rparam); 381 SAFE_FREE(rdata); 382 383 return ret; 384 } 385 386 bool cli_get_fs_full_size_info(struct cli_state *cli, 387 uint64_t *total_allocation_units, 388 uint64_t *caller_allocation_units, 389 uint64_t *actual_allocation_units, 390 uint64_t *sectors_per_allocation_unit, 391 uint64_t *bytes_per_sector) 392 { 393 bool ret = False; 394 uint16 setup; 395 char param[2]; 396 char *rparam=NULL, *rdata=NULL; 397 unsigned int rparam_count=0, rdata_count=0; 398 399 setup = TRANSACT2_QFSINFO; 400 401 SSVAL(param,0,SMB_FS_FULL_SIZE_INFORMATION); 402 403 if (!cli_send_trans(cli, SMBtrans2, 404 NULL, 405 0, 0, 406 &setup, 1, 0, 407 param, 2, 0, 408 NULL, 0, 560)) { 409 goto cleanup; 410 } 411 412 if (!cli_receive_trans(cli, SMBtrans2, 413 &rparam, &rparam_count, 414 &rdata, &rdata_count)) { 415 goto cleanup; 416 } 417 418 if (cli_is_error(cli)) { 419 ret = False; 420 goto cleanup; 421 } else { 422 ret = True; 423 } 424 425 if (rdata_count != 32) { 426 goto cleanup; 408 TALLOC_FREE(rdata); 409 return NT_STATUS_OK; 410 } 411 412 NTSTATUS cli_get_fs_full_size_info(struct cli_state *cli, 413 uint64_t *total_allocation_units, 414 uint64_t *caller_allocation_units, 415 uint64_t *actual_allocation_units, 416 uint64_t *sectors_per_allocation_unit, 417 uint64_t *bytes_per_sector) 418 { 419 uint16 setup[1]; 420 uint8_t param[2]; 421 uint8_t *rdata = NULL; 422 uint32_t rdata_count; 423 NTSTATUS status; 424 425 SSVAL(setup, 0, TRANSACT2_QFSINFO); 426 SSVAL(param, 0, SMB_FS_FULL_SIZE_INFORMATION); 427 428 status = cli_trans(talloc_tos(), cli, SMBtrans2, 429 NULL, 0, 0, 0, 430 setup, 1, 0, /* setup */ 431 param, 2, 0, /* param */ 432 NULL, 0, 560, /* data */ 433 NULL, 434 NULL, 0, NULL, /* rsetup */ 435 NULL, 0, NULL, /* rparam */ 436 &rdata, 32, &rdata_count); /* rdata */ 437 if (!NT_STATUS_IS_OK(status)) { 438 goto fail; 427 439 } 428 440 … … 443 455 } 444 456 445 cleanup: 446 SAFE_FREE(rparam); 447 SAFE_FREE(rdata); 448 449 return ret; 450 } 451 452 bool cli_get_posix_fs_info(struct cli_state *cli, 453 uint32 *optimal_transfer_size, 454 uint32 *block_size, 455 uint64_t *total_blocks, 456 uint64_t *blocks_available, 457 uint64_t *user_blocks_available, 458 uint64_t *total_file_nodes, 459 uint64_t *free_file_nodes, 460 uint64_t *fs_identifier) 461 { 462 bool ret = False; 463 uint16 setup; 464 char param[2]; 465 char *rparam=NULL, *rdata=NULL; 466 unsigned int rparam_count=0, rdata_count=0; 467 468 setup = TRANSACT2_QFSINFO; 469 457 fail: 458 TALLOC_FREE(rdata); 459 return status; 460 } 461 462 NTSTATUS cli_get_posix_fs_info(struct cli_state *cli, 463 uint32 *optimal_transfer_size, 464 uint32 *block_size, 465 uint64_t *total_blocks, 466 uint64_t *blocks_available, 467 uint64_t *user_blocks_available, 468 uint64_t *total_file_nodes, 469 uint64_t *free_file_nodes, 470 uint64_t *fs_identifier) 471 { 472 uint16 setup[1]; 473 uint8_t param[2]; 474 uint8_t *rdata = NULL; 475 uint32_t rdata_count; 476 NTSTATUS status; 477 478 SSVAL(setup, 0, TRANSACT2_QFSINFO); 470 479 SSVAL(param,0,SMB_QUERY_POSIX_FS_INFO); 471 480 472 if (!cli_send_trans(cli, SMBtrans2, 473 NULL, 474 0, 0, 475 &setup, 1, 0, 476 param, 2, 0, 477 NULL, 0, 560)) { 478 goto cleanup; 479 } 480 481 if (!cli_receive_trans(cli, SMBtrans2, 482 &rparam, &rparam_count, 483 &rdata, &rdata_count)) { 484 goto cleanup; 485 } 486 487 if (cli_is_error(cli)) { 488 ret = False; 489 goto cleanup; 490 } else { 491 ret = True; 492 } 493 494 if (rdata_count != 56) { 495 goto cleanup; 481 status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, 0, 0, 0, 482 setup, 1, 0, 483 param, 2, 0, 484 NULL, 0, 560, 485 NULL, 486 NULL, 0, NULL, /* rsetup */ 487 NULL, 0, NULL, /* rparam */ 488 &rdata, 56, &rdata_count); 489 if (!NT_STATUS_IS_OK(status)) { 490 return status; 496 491 } 497 492 … … 520 515 *fs_identifier = BIG_UINT(rdata,48); 521 516 } 522 523 cleanup: 524 SAFE_FREE(rparam); 525 SAFE_FREE(rdata); 526 527 return ret; 517 return NT_STATUS_OK; 528 518 } 529 519 … … 535 525 static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out, DATA_BLOB *param_out) 536 526 { 537 uint16 setup; 538 char param[4]; 539 char *rparam=NULL, *rdata=NULL; 540 unsigned int rparam_count=0, rdata_count=0; 541 NTSTATUS status = NT_STATUS_OK; 542 543 setup = TRANSACT2_SETFSINFO; 544 527 uint16_t setup[1]; 528 uint8_t param[4]; 529 uint8_t *rparam=NULL, *rdata=NULL; 530 uint32_t num_rparam, num_rdata; 531 NTSTATUS status; 532 533 SSVAL(setup+0, 0, TRANSACT2_SETFSINFO); 545 534 SSVAL(param,0,0); 546 535 SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION); 547 536 548 if (!cli_send_trans(cli, SMBtrans2, 549 NULL, 550 0, 0, 551 &setup, 1, 0, 552 param, 4, 0, 553 (char *)in->data, in->length, CLI_BUFFER_SIZE)) { 554 status = cli_nt_error(cli); 555 goto out; 556 } 557 558 if (!cli_receive_trans(cli, SMBtrans2, 559 &rparam, &rparam_count, 560 &rdata, &rdata_count)) { 561 status = cli_nt_error(cli); 562 goto out; 563 } 564 565 if (cli_is_error(cli)) { 566 status = cli_nt_error(cli); 567 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 568 goto out; 569 } 570 } 571 572 *out = data_blob(rdata, rdata_count); 573 *param_out = data_blob(rparam, rparam_count); 574 575 out: 576 577 SAFE_FREE(rparam); 578 SAFE_FREE(rdata); 537 status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, 0, 0, 0, 538 setup, 1, 0, 539 param, 4, 2, 540 (uint8_t *)in->data, in->length, CLI_BUFFER_SIZE, 541 NULL, /* recv_flags */ 542 NULL, 0, NULL, /* rsetup */ 543 &rparam, 0, &num_rparam, 544 &rdata, 0, &num_rdata); 545 546 if (!NT_STATUS_IS_OK(status) && 547 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 548 return status; 549 } 550 551 *out = data_blob(rdata, num_rdata); 552 *param_out = data_blob(rparam, num_rparam); 553 554 TALLOC_FREE(rparam); 555 TALLOC_FREE(rdata); 579 556 return status; 580 557 } … … 625 602 return NT_STATUS_NO_MEMORY; 626 603 } 627 status = ntlmssp_client_start(&es->s.ntlmssp_state); 604 status = ntlmssp_client_start(NULL, 605 global_myname(), 606 lp_workgroup(), 607 lp_client_ntlmv2_auth(), 608 &es->s.ntlmssp_state); 628 609 if (!NT_STATUS_IS_OK(status)) { 629 610 goto fail; … … 693 674 ******************************************************************************/ 694 675 695 static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, 676 static NTSTATUS make_cli_gss_blob(TALLOC_CTX *ctx, 677 struct smb_trans_enc_state *es, 696 678 const char *service, 697 679 const char *host, … … 740 722 } else { 741 723 /* Remove the SPNEGO wrapper */ 742 if (!spnego_parse_auth_response( spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) {724 if (!spnego_parse_auth_response(ctx, spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) { 743 725 status = NT_STATUS_UNSUCCESSFUL; 744 726 goto fail; … … 775 757 } 776 758 777 blob_out = data_blob (tok_out.value, tok_out.length);759 blob_out = data_blob_talloc(ctx, tok_out.value, tok_out.length); 778 760 779 761 /* Wrap in an SPNEGO wrapper */ 780 *p_blob_out = gen_negTokenTarg(krb_mechs, blob_out);762 *p_blob_out = spnego_gen_negTokenInit(ctx, krb_mechs, &blob_out, NULL); 781 763 782 764 fail: … … 814 796 815 797 servicename = "cifs"; 816 status = make_cli_gss_blob( es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send);798 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); 817 799 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { 818 800 servicename = "host"; 819 status = make_cli_gss_blob( es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send);801 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); 820 802 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { 821 803 goto fail; … … 830 812 } 831 813 data_blob_free(&blob_send); 832 status = make_cli_gss_blob( es, servicename, fqdn, status, blob_recv, &blob_send);814 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, status, blob_recv, &blob_send); 833 815 } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); 834 816 data_blob_free(&blob_recv); -
vendor/current/source3/libsmb/clikrb5.c
r594 r740 23 23 #include "includes.h" 24 24 #include "smb_krb5.h" 25 #include "authdata.h" 25 #include "../librpc/gen_ndr/krb5pac.h" 26 #include "../lib/util/asn1.h" 27 #include "libsmb/nmblib.h" 28 29 #ifndef KRB5_AUTHDATA_WIN2K_PAC 30 #define KRB5_AUTHDATA_WIN2K_PAC 128 31 #endif 32 33 #ifndef KRB5_AUTHDATA_IF_RELEVANT 34 #define KRB5_AUTHDATA_IF_RELEVANT 1 35 #endif 26 36 27 37 #ifdef HAVE_KRB5 … … 348 358 349 359 asn1_start_tag(data, ASN1_CONTEXT(2)); 350 asn1_read_OctetString(data, talloc_ autofree_context(), &edata_contents);360 asn1_read_OctetString(data, talloc_tos(), &edata_contents); 351 361 asn1_end_tag(data); 352 362 asn1_end_tag(data); … … 391 401 asn1_end_tag(data); 392 402 asn1_start_tag(data, ASN1_CONTEXT(1)); 393 asn1_read_OctetString(data, talloc_ autofree_context(), &pac_contents);403 asn1_read_OctetString(data, talloc_tos(), &pac_contents); 394 404 asn1_end_tag(data); 395 405 asn1_end_tag(data); … … 929 939 930 940 /* 931 get a kerberos5 ticket for the given service 941 get a kerberos5 ticket for the given service 932 942 */ 933 int cli_krb5_get_ticket(const char *principal, time_t time_offset, 934 DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, 935 uint32 extra_ap_opts, const char *ccname, 943 int cli_krb5_get_ticket(TALLOC_CTX *mem_ctx, 944 const char *principal, time_t time_offset, 945 DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, 946 uint32_t extra_ap_opts, const char *ccname, 936 947 time_t *tgs_expire, 937 948 const char *impersonate_princ_s) … … 944 955 krb5_auth_context auth_context = NULL; 945 956 krb5_enctype enc_types[] = { 946 #ifdef ENCTYPE_ARCFOUR_HMAC947 957 ENCTYPE_ARCFOUR_HMAC, 948 #endif 949 ENCTYPE_DES_CBC_MD5, 950 ENCTYPE_DES_CBC_CRC, 958 ENCTYPE_DES_CBC_MD5, 959 ENCTYPE_DES_CBC_CRC, 951 960 ENCTYPE_NULL}; 952 961 … … 954 963 retval = krb5_init_context(&context); 955 964 if (retval) { 956 DEBUG(1, ("cli_krb5_get_ticket: krb5_init_context failed (%s)\n",965 DEBUG(1, ("krb5_init_context failed (%s)\n", 957 966 error_message(retval))); 958 967 goto failed; … … 965 974 if ((retval = krb5_cc_resolve(context, ccname ? 966 975 ccname : krb5_cc_default_name(context), &ccdef))) { 967 DEBUG(1, ("cli_krb5_get_ticket:krb5_cc_default failed (%s)\n",976 DEBUG(1, ("krb5_cc_default failed (%s)\n", 968 977 error_message(retval))); 969 978 goto failed; … … 971 980 972 981 if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { 973 DEBUG(1, ("cli_krb5_get_ticket:krb5_set_default_tgs_ktypes failed (%s)\n",982 DEBUG(1, ("krb5_set_default_tgs_ktypes failed (%s)\n", 974 983 error_message(retval))); 975 984 goto failed; 976 985 } 977 986 978 if ((retval = ads_krb5_mk_req(context, 979 &auth_context, 980 AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, 981 principal, 982 ccdef, &packet, 983 tgs_expire, 984 impersonate_princ_s))) { 987 retval = ads_krb5_mk_req(context, &auth_context, 988 AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, 989 principal, ccdef, &packet, 990 tgs_expire, impersonate_princ_s); 991 if (retval) { 985 992 goto failed; 986 993 } 987 994 988 get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); 989 990 *ticket = data_blob(packet.data, packet.length); 991 992 kerberos_free_data_contents(context, &packet); 995 get_krb5_smb_session_key(mem_ctx, context, auth_context, 996 session_key_krb5, false); 997 998 *ticket = data_blob_talloc(mem_ctx, packet.data, packet.length); 999 1000 kerberos_free_data_contents(context, &packet); 993 1001 994 1002 failed: 995 1003 996 if ( context) {1004 if (context) { 997 1005 if (ccdef) 998 1006 krb5_cc_close(context, ccdef); … … 1001 1009 krb5_free_context(context); 1002 1010 } 1003 1011 1004 1012 return retval; 1005 1013 } 1006 1014 1007 bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote) 1008 { 1015 bool get_krb5_smb_session_key(TALLOC_CTX *mem_ctx, 1016 krb5_context context, 1017 krb5_auth_context auth_context, 1018 DATA_BLOB *session_key, bool remote) 1019 { 1009 1020 krb5_keyblock *skey = NULL; 1010 1021 krb5_error_code err = 0; … … 1012 1023 1013 1024 if (remote) { 1014 err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); 1025 err = krb5_auth_con_getremotesubkey(context, 1026 auth_context, &skey); 1015 1027 } else { 1016 err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); 1028 err = krb5_auth_con_getlocalsubkey(context, 1029 auth_context, &skey); 1017 1030 } 1018 1031 … … 1022 1035 } 1023 1036 1024 DEBUG(10, ("Got KRB5 session key of length %d\n", (int)KRB5_KEY_LENGTH(skey))); 1025 *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); 1026 dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); 1037 DEBUG(10, ("Got KRB5 session key of length %d\n", 1038 (int)KRB5_KEY_LENGTH(skey))); 1039 1040 *session_key = data_blob_talloc(mem_ctx, 1041 KRB5_KEY_DATA(skey), 1042 KRB5_KEY_LENGTH(skey)); 1043 dump_data_pw("KRB5 Session Key:\n", 1044 session_key->data, 1045 session_key->length); 1027 1046 1028 1047 ret = true; 1029 1048 1030 1049 done: 1031 1050 if (skey) { 1032 1051 krb5_free_keyblock(context, skey); … … 1034 1053 1035 1054 return ret; 1036 1055 } 1037 1056 1038 1057 … … 2252 2271 #else /* HAVE_KRB5 */ 2253 2272 /* this saves a few linking headaches */ 2254 int cli_krb5_get_ticket(const char *principal, time_t time_offset, 2255 DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, 2273 int cli_krb5_get_ticket(TALLOC_CTX *mem_ctx, 2274 const char *principal, time_t time_offset, 2275 DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, 2276 uint32_t extra_ap_opts, 2256 2277 const char *ccname, time_t *tgs_expire, 2257 2278 const char *impersonate_princ_s) … … 2261 2282 } 2262 2283 2263 #endif 2284 bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data) 2285 { 2286 DEBUG(0,("NO KERBEROS SUPPORT\n")); 2287 return false; 2288 } 2289 2290 #endif /* HAVE_KRB5 */ -
vendor/current/source3/libsmb/clilist.c
r414 r740 19 19 20 20 #include "includes.h" 21 #include "libsmb/libsmb.h" 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "async_smb.h" 24 #include "trans2.h" 21 25 22 26 /**************************************************************************** … … 47 51 struct cli_state *cli, 48 52 int level, 53 const char *base_ptr, 54 uint16_t recv_flags2, 49 55 const char *p, 50 56 const char *pdata_end, 51 file_info *finfo,57 struct file_info *finfo, 52 58 uint32 *p_resume_key, 53 59 DATA_BLOB *p_last_name_raw) … … 63 69 } 64 70 ZERO_STRUCTP(finfo); 65 finfo->cli = cli;66 71 67 72 switch (level) { … … 72 77 return pdata_end - base; 73 78 } 74 finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); 75 finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); 76 finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); 79 finfo->ctime_ts = convert_time_t_to_timespec( 80 make_unix_date2(p+4, cli->serverzone)); 81 finfo->atime_ts = convert_time_t_to_timespec( 82 make_unix_date2(p+8, cli->serverzone)); 83 finfo->mtime_ts = convert_time_t_to_timespec( 84 make_unix_date2(p+12, cli->serverzone)); 77 85 finfo->size = IVAL(p,16); 78 86 finfo->mode = CVAL(p,24); 79 87 len = CVAL(p, 26); 80 88 p += 27; 81 p += clistr_align_in(cli, p, 0);89 p += align_string(base_ptr, p, 0); 82 90 83 91 /* We can safely use len here (which is required by OS/2) … … 100 108 (tridge) */ 101 109 ret = clistr_pull_talloc(ctx, 102 cli->inbuf, 110 base_ptr, 111 recv_flags2, 103 112 &finfo->name, 104 113 p, … … 117 126 return pdata_end - base; 118 127 } 119 finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); 120 finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); 121 finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); 128 finfo->ctime_ts = convert_time_t_to_timespec( 129 make_unix_date2(p+4, cli->serverzone)); 130 finfo->atime_ts = convert_time_t_to_timespec( 131 make_unix_date2(p+8, cli->serverzone)); 132 finfo->mtime_ts = convert_time_t_to_timespec( 133 make_unix_date2(p+12, cli->serverzone)); 122 134 finfo->size = IVAL(p,16); 123 135 finfo->mode = CVAL(p,24); … … 129 141 } 130 142 ret = clistr_pull_talloc(ctx, 131 cli->inbuf, 143 base_ptr, 144 recv_flags2, 132 145 &finfo->name, 133 146 p, … … 181 194 int flags = 0; 182 195 if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; 183 clistr_pull( cli->inbuf, finfo->short_name, p,196 clistr_pull(base_ptr, finfo->short_name, p, 184 197 sizeof(finfo->short_name), 185 198 slen, flags); … … 190 203 } 191 204 ret = clistr_pull_talloc(ctx, 192 cli->inbuf, 205 base_ptr, 206 recv_flags2, 193 207 &finfo->name, 194 208 p, … … 218 232 219 233 /**************************************************************************** 220 Do a directory listing, calling fn on each file found.221 ****************************************************************************/222 223 int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,224 void (*fn)(const char *, file_info *, const char *, void *), void *state)225 {226 #if 1227 int max_matches = 1366; /* Match W2k - was 512. */228 #else229 int max_matches = 512;230 #endif231 int info_level;232 char *p, *p2, *rdata_end;233 char *mask = NULL;234 file_info finfo;235 int i;236 char *dirlist = NULL;237 int dirlist_len = 0;238 int total_received = -1;239 bool First = True;240 int ff_searchcount=0;241 int ff_eos=0;242 int ff_dir_handle=0;243 int loop_count = 0;244 char *rparam=NULL, *rdata=NULL;245 unsigned int param_len, data_len;246 uint16 setup;247 char *param;248 uint32 resume_key = 0;249 TALLOC_CTX *frame = talloc_stackframe();250 DATA_BLOB last_name_raw = data_blob(NULL, 0);251 252 /* NT uses SMB_FIND_FILE_BOTH_DIRECTORY_INFO,253 OS/2 uses SMB_FIND_EA_SIZE. Both accept SMB_FIND_INFO_STANDARD. */254 info_level = (cli->capabilities&CAP_NT_SMBS)?255 SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_INFO_STANDARD;256 257 mask = SMB_STRDUP(Mask);258 if (!mask) {259 TALLOC_FREE(frame);260 return -1;261 }262 263 while (ff_eos == 0) {264 size_t nlen = 2*(strlen(mask)+1);265 266 loop_count++;267 if (loop_count > 200) {268 DEBUG(0,("Error: Looping in FIND_NEXT??\n"));269 break;270 }271 272 param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2);273 if (!param) {274 break;275 }276 277 if (First) {278 setup = TRANSACT2_FINDFIRST;279 SSVAL(param,0,attribute); /* attribute */280 SSVAL(param,2,max_matches); /* max count */281 SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */282 SSVAL(param,6,info_level);283 SIVAL(param,8,0);284 p = param+12;285 p += clistr_push(cli, param+12, mask,286 nlen, STR_TERMINATE);287 } else {288 setup = TRANSACT2_FINDNEXT;289 SSVAL(param,0,ff_dir_handle);290 SSVAL(param,2,max_matches); /* max count */291 SSVAL(param,4,info_level);292 /* For W2K servers serving out FAT filesystems we *must* set the293 resume key. If it's not FAT then it's returned as zero. */294 SIVAL(param,6,resume_key); /* ff_resume_key */295 /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren296 can miss filenames. Use last filename continue instead. JRA */297 SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */298 p = param+12;299 if (last_name_raw.length) {300 memcpy(p, last_name_raw.data, last_name_raw.length);301 p += last_name_raw.length;302 } else {303 p += clistr_push(cli, param+12, mask,304 nlen, STR_TERMINATE);305 }306 }307 308 param_len = PTR_DIFF(p, param);309 310 if (!cli_send_trans(cli, SMBtrans2,311 NULL, /* Name */312 -1, 0, /* fid, flags */313 &setup, 1, 0, /* setup, length, max */314 param, param_len, 10, /* param, length, max */315 NULL, 0,316 #if 0317 /* w2k value. */318 MIN(16384,cli->max_xmit) /* data, length, max. */319 #else320 cli->max_xmit /* data, length, max. */321 #endif322 )) {323 SAFE_FREE(param);324 TALLOC_FREE(frame);325 break;326 }327 328 SAFE_FREE(param);329 330 if (!cli_receive_trans(cli, SMBtrans2,331 &rparam, ¶m_len,332 &rdata, &data_len) &&333 cli_is_dos_error(cli)) {334 /* We need to work around a Win95 bug - sometimes335 it gives ERRSRV/ERRerror temprarily */336 uint8 eclass;337 uint32 ecode;338 339 SAFE_FREE(rdata);340 SAFE_FREE(rparam);341 342 cli_dos_error(cli, &eclass, &ecode);343 344 /*345 * OS/2 might return "no more files",346 * which just tells us, that searchcount is zero347 * in this search.348 * Guenter Kukkukk <linux@kukkukk.com>349 */350 351 if (eclass == ERRDOS && ecode == ERRnofiles) {352 ff_searchcount = 0;353 cli_reset_error(cli);354 break;355 }356 357 if (eclass != ERRSRV || ecode != ERRerror)358 break;359 smb_msleep(100);360 continue;361 }362 363 if (cli_is_error(cli) || !rdata || !rparam) {364 SAFE_FREE(rdata);365 SAFE_FREE(rparam);366 break;367 }368 369 if (total_received == -1)370 total_received = 0;371 372 /* parse out some important return info */373 p = rparam;374 if (First) {375 ff_dir_handle = SVAL(p,0);376 ff_searchcount = SVAL(p,2);377 ff_eos = SVAL(p,4);378 } else {379 ff_searchcount = SVAL(p,0);380 ff_eos = SVAL(p,2);381 }382 383 if (ff_searchcount == 0) {384 SAFE_FREE(rdata);385 SAFE_FREE(rparam);386 break;387 }388 389 /* point to the data bytes */390 p = rdata;391 rdata_end = rdata + data_len;392 393 /* we might need the lastname for continuations */394 for (p2=p,i=0;i<ff_searchcount && p2 < rdata_end;i++) {395 if ((info_level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) &&396 (i == ff_searchcount-1)) {397 /* Last entry - fixup the last offset length. */398 SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));399 }400 p2 += interpret_long_filename(frame,401 cli,402 info_level,403 p2,404 rdata_end,405 &finfo,406 &resume_key,407 &last_name_raw);408 409 if (!finfo.name) {410 DEBUG(0,("cli_list_new: Error: unable to parse name from info level %d\n",411 info_level));412 ff_eos = 1;413 break;414 }415 if (!First && *mask && strcsequal(finfo.name, mask)) {416 DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n",417 finfo.name));418 ff_eos = 1;419 break;420 }421 }422 423 SAFE_FREE(mask);424 if (ff_searchcount > 0 && ff_eos == 0 && finfo.name) {425 mask = SMB_STRDUP(finfo.name);426 } else {427 mask = SMB_STRDUP("");428 }429 if (!mask) {430 SAFE_FREE(rdata);431 SAFE_FREE(rparam);432 break;433 }434 435 /* grab the data for later use */436 /* and add them to the dirlist pool */437 dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len);438 439 if (!dirlist) {440 DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));441 SAFE_FREE(rdata);442 SAFE_FREE(rparam);443 break;444 }445 446 memcpy(dirlist+dirlist_len,p,data_len);447 dirlist_len += data_len;448 449 total_received += ff_searchcount;450 451 SAFE_FREE(rdata);452 SAFE_FREE(rparam);453 454 DEBUG(3,("received %d entries (eos=%d)\n",455 ff_searchcount,ff_eos));456 457 if (ff_searchcount > 0)458 loop_count = 0;459 460 First = False;461 }462 463 /* see if the server disconnected or the connection otherwise failed */464 if (cli_is_error(cli)) {465 total_received = -1;466 } else {467 /* no connection problem. let user function add each entry */468 rdata_end = dirlist + dirlist_len;469 for (p=dirlist,i=0;i<total_received;i++) {470 p += interpret_long_filename(frame,471 cli,472 info_level,473 p,474 rdata_end,475 &finfo,476 NULL,477 NULL);478 if (!finfo.name) {479 DEBUG(0,("cli_list_new: unable to parse name from info level %d\n",480 info_level));481 break;482 }483 fn(cli->dfs_mountpoint, &finfo, Mask, state);484 }485 }486 487 /* free up the dirlist buffer and last name raw blob */488 SAFE_FREE(dirlist);489 data_blob_free(&last_name_raw);490 SAFE_FREE(mask);491 TALLOC_FREE(frame);492 return(total_received);493 }494 495 /****************************************************************************496 234 Interpret a short filename structure. 497 235 The length of the structure is returned. … … 501 239 struct cli_state *cli, 502 240 char *p, 503 file_info *finfo)241 struct file_info *finfo) 504 242 { 505 243 size_t ret; 506 244 ZERO_STRUCTP(finfo); 507 245 508 finfo->cli = cli;509 246 finfo->mode = CVAL(p,21); 510 247 511 248 /* this date is converted to GMT by make_unix_date */ 512 finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22);249 finfo->ctime_ts.tv_sec = make_unix_date(p+22, cli->serverzone); 513 250 finfo->ctime_ts.tv_nsec = 0; 514 251 finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; … … 517 254 ret = clistr_pull_talloc(ctx, 518 255 cli->inbuf, 256 SVAL(cli->inbuf, smb_flg2), 519 257 &finfo->name, 520 258 p+30, … … 531 269 } 532 270 return true; 533 return(DIR_STRUCT_SIZE); 534 } 535 536 /**************************************************************************** 537 Do a directory listing, calling fn on each file found. 538 this uses the old SMBsearch interface. It is needed for testing Samba, 539 but should otherwise not be used. 540 ****************************************************************************/ 541 542 int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, 543 void (*fn)(const char *, file_info *, const char *, void *), void *state) 544 { 271 } 272 273 struct cli_list_old_state { 274 struct tevent_context *ev; 275 struct cli_state *cli; 276 uint16_t vwv[2]; 277 char *mask; 278 int num_asked; 279 uint16_t attribute; 280 uint8_t search_status[23]; 281 bool first; 282 bool done; 283 uint8_t *dirlist; 284 }; 285 286 static void cli_list_old_done(struct tevent_req *subreq); 287 288 static struct tevent_req *cli_list_old_send(TALLOC_CTX *mem_ctx, 289 struct tevent_context *ev, 290 struct cli_state *cli, 291 const char *mask, 292 uint16_t attribute) 293 { 294 struct tevent_req *req, *subreq; 295 struct cli_list_old_state *state; 296 uint8_t *bytes; 297 static const uint16_t zero = 0; 298 299 req = tevent_req_create(mem_ctx, &state, struct cli_list_old_state); 300 if (req == NULL) { 301 return NULL; 302 } 303 state->ev = ev; 304 state->cli = cli; 305 state->attribute = attribute; 306 state->first = true; 307 state->mask = talloc_strdup(state, mask); 308 if (tevent_req_nomem(state->mask, req)) { 309 return tevent_req_post(req, ev); 310 } 311 state->num_asked = (cli->max_xmit - 100) / DIR_STRUCT_SIZE; 312 313 SSVAL(state->vwv + 0, 0, state->num_asked); 314 SSVAL(state->vwv + 1, 0, state->attribute); 315 316 bytes = talloc_array(state, uint8_t, 1); 317 if (tevent_req_nomem(bytes, req)) { 318 return tevent_req_post(req, ev); 319 } 320 bytes[0] = 4; 321 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), mask, 322 strlen(mask)+1, NULL); 323 324 bytes = smb_bytes_push_bytes(bytes, 5, (uint8_t *)&zero, 2); 325 if (tevent_req_nomem(bytes, req)) { 326 return tevent_req_post(req, ev); 327 } 328 329 subreq = cli_smb_send(state, state->ev, state->cli, SMBsearch, 330 0, 2, state->vwv, talloc_get_size(bytes), bytes); 331 if (tevent_req_nomem(subreq, req)) { 332 return tevent_req_post(req, ev); 333 } 334 tevent_req_set_callback(subreq, cli_list_old_done, req); 335 return req; 336 } 337 338 static void cli_list_old_done(struct tevent_req *subreq) 339 { 340 struct tevent_req *req = tevent_req_callback_data( 341 subreq, struct tevent_req); 342 struct cli_list_old_state *state = tevent_req_data( 343 req, struct cli_list_old_state); 344 NTSTATUS status; 345 uint8_t cmd; 346 uint8_t wct; 347 uint16_t *vwv; 348 uint32_t num_bytes; 349 uint8_t *bytes; 350 uint16_t received; 351 size_t dirlist_len; 352 uint8_t *tmp; 353 354 status = cli_smb_recv(subreq, state, NULL, 0, &wct, &vwv, &num_bytes, 355 &bytes); 356 if (!NT_STATUS_IS_OK(status) 357 && !NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnofiles)) 358 && !NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) { 359 TALLOC_FREE(subreq); 360 tevent_req_nterror(req, status); 361 return; 362 } 363 if (NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnofiles)) 364 || NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES)) { 365 received = 0; 366 } else { 367 if (wct < 1) { 368 TALLOC_FREE(subreq); 369 tevent_req_nterror( 370 req, NT_STATUS_INVALID_NETWORK_RESPONSE); 371 return; 372 } 373 received = SVAL(vwv + 0, 0); 374 } 375 376 if (received > 0) { 377 /* 378 * I don't think this can wrap. received is 379 * initialized from a 16-bit value. 380 */ 381 if (num_bytes < (received * DIR_STRUCT_SIZE + 3)) { 382 TALLOC_FREE(subreq); 383 tevent_req_nterror( 384 req, NT_STATUS_INVALID_NETWORK_RESPONSE); 385 return; 386 } 387 388 dirlist_len = talloc_get_size(state->dirlist); 389 390 tmp = TALLOC_REALLOC_ARRAY( 391 state, state->dirlist, uint8_t, 392 dirlist_len + received * DIR_STRUCT_SIZE); 393 if (tevent_req_nomem(tmp, req)) { 394 return; 395 } 396 state->dirlist = tmp; 397 memcpy(state->dirlist + dirlist_len, bytes + 3, 398 received * DIR_STRUCT_SIZE); 399 400 SSVAL(state->search_status, 0, 21); 401 memcpy(state->search_status + 2, 402 bytes + 3 + (received-1)*DIR_STRUCT_SIZE, 21); 403 cmd = SMBsearch; 404 } else { 405 if (state->first || state->done) { 406 tevent_req_done(req); 407 return; 408 } 409 state->done = true; 410 state->num_asked = 0; 411 cmd = SMBfclose; 412 } 413 TALLOC_FREE(subreq); 414 415 state->first = false; 416 417 SSVAL(state->vwv + 0, 0, state->num_asked); 418 SSVAL(state->vwv + 1, 0, state->attribute); 419 420 bytes = talloc_array(state, uint8_t, 1); 421 if (tevent_req_nomem(bytes, req)) { 422 return; 423 } 424 bytes[0] = 4; 425 bytes = smb_bytes_push_str(bytes, cli_ucs2(state->cli), "", 426 1, NULL); 427 bytes = smb_bytes_push_bytes(bytes, 5, state->search_status, 428 sizeof(state->search_status)); 429 if (tevent_req_nomem(bytes, req)) { 430 return; 431 } 432 subreq = cli_smb_send(state, state->ev, state->cli, cmd, 0, 433 2, state->vwv, talloc_get_size(bytes), bytes); 434 if (tevent_req_nomem(subreq, req)) { 435 return; 436 } 437 tevent_req_set_callback(subreq, cli_list_old_done, req); 438 } 439 440 static NTSTATUS cli_list_old_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 441 struct file_info **pfinfo) 442 { 443 struct cli_list_old_state *state = tevent_req_data( 444 req, struct cli_list_old_state); 445 NTSTATUS status; 446 size_t i, num_received; 447 struct file_info *finfo; 448 449 if (tevent_req_is_nterror(req, &status)) { 450 return status; 451 } 452 453 num_received = talloc_array_length(state->dirlist) / DIR_STRUCT_SIZE; 454 455 finfo = TALLOC_ARRAY(mem_ctx, struct file_info, num_received); 456 if (finfo == NULL) { 457 return NT_STATUS_NO_MEMORY; 458 } 459 460 for (i=0; i<num_received; i++) { 461 if (!interpret_short_filename( 462 finfo, state->cli, 463 (char *)state->dirlist + i * DIR_STRUCT_SIZE, 464 &finfo[i])) { 465 TALLOC_FREE(finfo); 466 return NT_STATUS_NO_MEMORY; 467 } 468 } 469 *pfinfo = finfo; 470 return NT_STATUS_OK; 471 } 472 473 NTSTATUS cli_list_old(struct cli_state *cli, const char *mask, 474 uint16 attribute, 475 NTSTATUS (*fn)(const char *, struct file_info *, 476 const char *, void *), void *state) 477 { 478 TALLOC_CTX *frame = talloc_stackframe(); 479 struct event_context *ev; 480 struct tevent_req *req; 481 NTSTATUS status = NT_STATUS_NO_MEMORY; 482 struct file_info *finfo; 483 size_t i, num_finfo; 484 485 if (cli_has_async_calls(cli)) { 486 /* 487 * Can't use sync call while an async call is in flight 488 */ 489 status = NT_STATUS_INVALID_PARAMETER; 490 goto fail; 491 } 492 ev = event_context_init(frame); 493 if (ev == NULL) { 494 goto fail; 495 } 496 req = cli_list_old_send(frame, ev, cli, mask, attribute); 497 if (req == NULL) { 498 goto fail; 499 } 500 if (!tevent_req_poll(req, ev)) { 501 status = map_nt_error_from_unix(errno); 502 goto fail; 503 } 504 status = cli_list_old_recv(req, frame, &finfo); 505 if (!NT_STATUS_IS_OK(status)) { 506 goto fail; 507 } 508 num_finfo = talloc_array_length(finfo); 509 for (i=0; i<num_finfo; i++) { 510 status = fn(cli->dfs_mountpoint, &finfo[i], mask, state); 511 if (!NT_STATUS_IS_OK(status)) { 512 goto fail; 513 } 514 } 515 fail: 516 TALLOC_FREE(frame); 517 if (!NT_STATUS_IS_OK(status)) { 518 cli_set_error(cli, status); 519 } 520 return status; 521 } 522 523 struct cli_list_trans_state { 524 struct tevent_context *ev; 525 struct cli_state *cli; 526 char *mask; 527 uint16_t attribute; 528 uint16_t info_level; 529 530 int loop_count; 531 int total_received; 532 uint16_t max_matches; 533 bool first; 534 535 int ff_eos; 536 int ff_dir_handle; 537 538 uint16_t setup[1]; 539 uint8_t *param; 540 541 struct file_info *finfo; 542 }; 543 544 static void cli_list_trans_done(struct tevent_req *subreq); 545 546 static struct tevent_req *cli_list_trans_send(TALLOC_CTX *mem_ctx, 547 struct tevent_context *ev, 548 struct cli_state *cli, 549 const char *mask, 550 uint16_t attribute, 551 uint16_t info_level) 552 { 553 struct tevent_req *req, *subreq; 554 struct cli_list_trans_state *state; 555 size_t nlen, param_len; 545 556 char *p; 546 int received = 0; 547 bool first = True; 548 char status[21]; 549 int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; 550 int num_received = 0; 557 558 req = tevent_req_create(mem_ctx, &state, 559 struct cli_list_trans_state); 560 if (req == NULL) { 561 return NULL; 562 } 563 state->ev = ev; 564 state->cli = cli; 565 state->mask = talloc_strdup(state, mask); 566 if (tevent_req_nomem(state->mask, req)) { 567 return tevent_req_post(req, ev); 568 } 569 state->attribute = attribute; 570 state->info_level = info_level; 571 state->loop_count = 0; 572 state->first = true; 573 574 state->max_matches = 1366; /* Match W2k */ 575 576 SSVAL(&state->setup[0], 0, TRANSACT2_FINDFIRST); 577 578 nlen = 2*(strlen(mask)+1); 579 state->param = TALLOC_ARRAY(state, uint8_t, 12+nlen+2); 580 if (tevent_req_nomem(state->param, req)) { 581 return tevent_req_post(req, ev); 582 } 583 584 SSVAL(state->param, 0, state->attribute); 585 SSVAL(state->param, 2, state->max_matches); 586 SSVAL(state->param, 4, 587 FLAG_TRANS2_FIND_REQUIRE_RESUME 588 |FLAG_TRANS2_FIND_CLOSE_IF_END); 589 SSVAL(state->param, 6, state->info_level); 590 SIVAL(state->param, 8, 0); 591 592 p = ((char *)state->param)+12; 593 p += clistr_push(state->cli, p, state->mask, nlen, 594 STR_TERMINATE); 595 param_len = PTR_DIFF(p, state->param); 596 597 subreq = cli_trans_send(state, state->ev, state->cli, 598 SMBtrans2, NULL, -1, 0, 0, 599 state->setup, 1, 0, 600 state->param, param_len, 10, 601 NULL, 0, cli->max_xmit); 602 if (tevent_req_nomem(subreq, req)) { 603 return tevent_req_post(req, ev); 604 } 605 tevent_req_set_callback(subreq, cli_list_trans_done, req); 606 return req; 607 } 608 609 static void cli_list_trans_done(struct tevent_req *subreq) 610 { 611 struct tevent_req *req = tevent_req_callback_data( 612 subreq, struct tevent_req); 613 struct cli_list_trans_state *state = tevent_req_data( 614 req, struct cli_list_trans_state); 615 NTSTATUS status; 616 uint8_t *param; 617 uint32_t num_param; 618 uint8_t *data; 619 char *data_end; 620 uint32_t num_data; 621 uint32_t min_param; 622 struct file_info *tmp; 623 size_t old_num_finfo; 624 uint16_t recv_flags2; 625 int ff_searchcount; 626 bool ff_eos; 627 char *p, *p2; 628 uint32_t resume_key = 0; 551 629 int i; 552 char *dirlist = NULL; 553 char *mask = NULL; 554 TALLOC_CTX *frame = NULL; 555 556 ZERO_ARRAY(status); 557 558 mask = SMB_STRDUP(Mask); 559 if (!mask) { 560 return -1; 561 } 562 563 while (1) { 564 memset(cli->outbuf,'\0',smb_size); 565 memset(cli->inbuf,'\0',smb_size); 566 567 cli_set_message(cli->outbuf,2,0,True); 568 569 SCVAL(cli->outbuf,smb_com,SMBsearch); 570 571 SSVAL(cli->outbuf,smb_tid,cli->cnum); 572 cli_setup_packet(cli); 573 574 SSVAL(cli->outbuf,smb_vwv0,num_asked); 575 SSVAL(cli->outbuf,smb_vwv1,attribute); 576 577 p = smb_buf(cli->outbuf); 578 *p++ = 4; 579 580 p += clistr_push(cli, p, first?mask:"", 581 cli->bufsize - PTR_DIFF(p,cli->outbuf), 582 STR_TERMINATE); 583 *p++ = 5; 584 if (first) { 585 SSVAL(p,0,0); 586 p += 2; 587 } else { 588 SSVAL(p,0,21); 589 p += 2; 590 memcpy(p,status,21); 591 p += 21; 592 } 593 594 cli_setup_bcc(cli, p); 595 cli_send_smb(cli); 596 if (!cli_receive_smb(cli)) break; 597 598 received = SVAL(cli->inbuf,smb_vwv0); 599 if (received <= 0) break; 600 601 /* Ensure we received enough data. */ 602 if ((cli->inbuf+4+smb_len(cli->inbuf) - (smb_buf(cli->inbuf)+3)) < 603 received*DIR_STRUCT_SIZE) { 630 DATA_BLOB last_name_raw; 631 struct file_info *finfo = NULL; 632 size_t nlen, param_len; 633 634 min_param = (state->first ? 6 : 4); 635 636 status = cli_trans_recv(subreq, talloc_tos(), &recv_flags2, 637 NULL, 0, NULL, 638 ¶m, min_param, &num_param, 639 &data, 0, &num_data); 640 TALLOC_FREE(subreq); 641 if (!NT_STATUS_IS_OK(status)) { 642 /* 643 * TODO: retry, OS/2 nofiles 644 */ 645 tevent_req_nterror(req, status); 646 return; 647 } 648 649 if (state->first) { 650 state->ff_dir_handle = SVAL(param, 0); 651 ff_searchcount = SVAL(param, 2); 652 ff_eos = SVAL(param, 4) != 0; 653 } else { 654 ff_searchcount = SVAL(param, 0); 655 ff_eos = SVAL(param, 2) != 0; 656 } 657 658 old_num_finfo = talloc_array_length(state->finfo); 659 660 tmp = TALLOC_REALLOC_ARRAY(state, state->finfo, struct file_info, 661 old_num_finfo + ff_searchcount); 662 if (tevent_req_nomem(tmp, req)) { 663 return; 664 } 665 state->finfo = tmp; 666 667 p2 = p = (char *)data; 668 data_end = (char *)data + num_data; 669 last_name_raw = data_blob_null; 670 671 for (i=0; i<ff_searchcount; i++) { 672 if (p2 >= data_end) { 673 ff_eos = true; 604 674 break; 605 675 } 606 607 first = False; 608 609 dirlist = (char *)SMB_REALLOC( 610 dirlist,(num_received + received)*DIR_STRUCT_SIZE); 611 if (!dirlist) { 612 DEBUG(0,("cli_list_old: failed to expand dirlist")); 613 SAFE_FREE(mask); 614 return 0; 615 } 616 617 p = smb_buf(cli->inbuf) + 3; 618 619 memcpy(dirlist+num_received*DIR_STRUCT_SIZE, 620 p,received*DIR_STRUCT_SIZE); 621 622 memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); 623 624 num_received += received; 625 626 if (cli_is_error(cli)) break; 627 } 628 629 if (!first) { 630 memset(cli->outbuf,'\0',smb_size); 631 memset(cli->inbuf,'\0',smb_size); 632 633 cli_set_message(cli->outbuf,2,0,True); 634 SCVAL(cli->outbuf,smb_com,SMBfclose); 635 SSVAL(cli->outbuf,smb_tid,cli->cnum); 636 cli_setup_packet(cli); 637 638 SSVAL(cli->outbuf, smb_vwv0, 0); /* find count? */ 639 SSVAL(cli->outbuf, smb_vwv1, attribute); 640 641 p = smb_buf(cli->outbuf); 642 *p++ = 4; 643 fstrcpy(p, ""); 644 p += strlen(p) + 1; 645 *p++ = 5; 646 SSVAL(p, 0, 21); 647 p += 2; 648 memcpy(p,status,21); 649 p += 21; 650 651 cli_setup_bcc(cli, p); 652 cli_send_smb(cli); 653 if (!cli_receive_smb(cli)) { 654 DEBUG(0,("Error closing search: %s\n",cli_errstr(cli))); 655 } 656 } 657 658 frame = talloc_stackframe(); 659 for (p=dirlist,i=0;i<num_received;i++) { 660 file_info finfo; 661 if (!interpret_short_filename(frame, cli, p, &finfo)) { 676 if ((state->info_level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) 677 && (i == ff_searchcount-1)) { 678 /* Last entry - fixup the last offset length. */ 679 SIVAL(p2, 0, PTR_DIFF((data + num_data), p2)); 680 } 681 682 data_blob_free(&last_name_raw); 683 684 finfo = &state->finfo[old_num_finfo + i]; 685 686 p2 += interpret_long_filename( 687 state->finfo, /* Stick fname to the array as such */ 688 state->cli, state->info_level, 689 (char *)data, recv_flags2, p2, 690 data_end, finfo, &resume_key, &last_name_raw); 691 692 if (finfo->name == NULL) { 693 DEBUG(1, ("cli_list: Error: unable to parse name from " 694 "info level %d\n", state->info_level)); 695 ff_eos = true; 662 696 break; 663 697 } 664 p += DIR_STRUCT_SIZE; 665 fn("\\", &finfo, Mask, state); 666 } 698 if (!state->first && (state->mask[0] != '\0') && 699 strcsequal(finfo->name, state->mask)) { 700 DEBUG(1, ("Error: Looping in FIND_NEXT as name %s has " 701 "already been seen?\n", finfo->name)); 702 ff_eos = true; 703 break; 704 } 705 } 706 707 if (ff_searchcount == 0) { 708 ff_eos = true; 709 } 710 711 TALLOC_FREE(param); 712 TALLOC_FREE(data); 713 714 /* 715 * Shrink state->finfo to the real length we received 716 */ 717 tmp = TALLOC_REALLOC_ARRAY(state, state->finfo, struct file_info, 718 old_num_finfo + i); 719 if (tevent_req_nomem(tmp, req)) { 720 return; 721 } 722 state->finfo = tmp; 723 724 state->first = false; 725 726 if (ff_eos) { 727 data_blob_free(&last_name_raw); 728 tevent_req_done(req); 729 return; 730 } 731 732 TALLOC_FREE(state->mask); 733 state->mask = talloc_strdup(state, finfo->name); 734 if (tevent_req_nomem(state->mask, req)) { 735 return; 736 } 737 738 SSVAL(&state->setup[0], 0, TRANSACT2_FINDNEXT); 739 740 nlen = 2*(strlen(state->mask) + 1); 741 742 param = TALLOC_REALLOC_ARRAY(state, state->param, uint8_t, 743 12 + nlen + last_name_raw.length + 2); 744 if (tevent_req_nomem(param, req)) { 745 return; 746 } 747 state->param = param; 748 749 SSVAL(param, 0, state->ff_dir_handle); 750 SSVAL(param, 2, state->max_matches); /* max count */ 751 SSVAL(param, 4, state->info_level); 752 /* 753 * For W2K servers serving out FAT filesystems we *must* set 754 * the resume key. If it's not FAT then it's returned as zero. 755 */ 756 SIVAL(param, 6, resume_key); /* ff_resume_key */ 757 /* 758 * NB. *DON'T* use continue here. If you do it seems that W2K 759 * and bretheren can miss filenames. Use last filename 760 * continue instead. JRA 761 */ 762 SSVAL(param, 10, (FLAG_TRANS2_FIND_REQUIRE_RESUME 763 |FLAG_TRANS2_FIND_CLOSE_IF_END)); 764 p = ((char *)param)+12; 765 if (last_name_raw.length) { 766 memcpy(p, last_name_raw.data, last_name_raw.length); 767 p += last_name_raw.length; 768 data_blob_free(&last_name_raw); 769 } else { 770 p += clistr_push(state->cli, p, state->mask, nlen, 771 STR_TERMINATE); 772 } 773 774 param_len = PTR_DIFF(p, param); 775 776 subreq = cli_trans_send(state, state->ev, state->cli, 777 SMBtrans2, NULL, -1, 0, 0, 778 state->setup, 1, 0, 779 state->param, param_len, 10, 780 NULL, 0, state->cli->max_xmit); 781 if (tevent_req_nomem(subreq, req)) { 782 return; 783 } 784 tevent_req_set_callback(subreq, cli_list_trans_done, req); 785 } 786 787 static NTSTATUS cli_list_trans_recv(struct tevent_req *req, 788 TALLOC_CTX *mem_ctx, 789 struct file_info **finfo) 790 { 791 struct cli_list_trans_state *state = tevent_req_data( 792 req, struct cli_list_trans_state); 793 NTSTATUS status; 794 795 if (tevent_req_is_nterror(req, &status)) { 796 return status; 797 } 798 *finfo = talloc_move(mem_ctx, &state->finfo); 799 return NT_STATUS_OK; 800 } 801 802 NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask, 803 uint16_t attribute, int info_level, 804 NTSTATUS (*fn)(const char *mnt, struct file_info *finfo, 805 const char *mask, void *private_data), 806 void *private_data) 807 { 808 TALLOC_CTX *frame = talloc_stackframe(); 809 struct event_context *ev; 810 struct tevent_req *req; 811 int i, num_finfo; 812 struct file_info *finfo = NULL; 813 NTSTATUS status = NT_STATUS_NO_MEMORY; 814 815 if (cli_has_async_calls(cli)) { 816 /* 817 * Can't use sync call while an async call is in flight 818 */ 819 status = NT_STATUS_INVALID_PARAMETER; 820 goto fail; 821 } 822 ev = event_context_init(frame); 823 if (ev == NULL) { 824 goto fail; 825 } 826 req = cli_list_trans_send(frame, ev, cli, mask, attribute, info_level); 827 if (req == NULL) { 828 goto fail; 829 } 830 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 831 goto fail; 832 } 833 status = cli_list_trans_recv(req, frame, &finfo); 834 if (!NT_STATUS_IS_OK(status)) { 835 goto fail; 836 } 837 num_finfo = talloc_array_length(finfo); 838 for (i=0; i<num_finfo; i++) { 839 status = fn(cli->dfs_mountpoint, &finfo[i], mask, private_data); 840 if (!NT_STATUS_IS_OK(status)) { 841 goto fail; 842 } 843 } 844 fail: 667 845 TALLOC_FREE(frame); 668 669 SAFE_FREE(mask); 670 SAFE_FREE(dirlist); 671 return(num_received); 672 } 673 674 /**************************************************************************** 675 Do a directory listing, calling fn on each file found. 676 This auto-switches between old and new style. 677 ****************************************************************************/ 678 679 int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, 680 void (*fn)(const char *, file_info *, const char *, void *), void *state) 681 { 682 if (cli->protocol <= PROTOCOL_LANMAN1) 683 return cli_list_old(cli, Mask, attribute, fn, state); 684 return cli_list_new(cli, Mask, attribute, fn, state); 685 } 846 if (!NT_STATUS_IS_OK(status)) { 847 cli_set_error(cli, status); 848 } 849 return status; 850 } 851 852 struct cli_list_state { 853 NTSTATUS (*recv_fn)(struct tevent_req *req, TALLOC_CTX *mem_ctx, 854 struct file_info **finfo); 855 struct file_info *finfo; 856 }; 857 858 static void cli_list_done(struct tevent_req *subreq); 859 860 struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx, 861 struct tevent_context *ev, 862 struct cli_state *cli, 863 const char *mask, 864 uint16_t attribute, 865 uint16_t info_level) 866 { 867 struct tevent_req *req, *subreq; 868 struct cli_list_state *state; 869 870 req = tevent_req_create(mem_ctx, &state, struct cli_list_state); 871 if (req == NULL) { 872 return NULL; 873 } 874 875 if (cli->protocol <= PROTOCOL_LANMAN1) { 876 subreq = cli_list_old_send(state, ev, cli, mask, attribute); 877 state->recv_fn = cli_list_old_recv; 878 } else { 879 subreq = cli_list_trans_send(state, ev, cli, mask, attribute, 880 info_level); 881 state->recv_fn = cli_list_trans_recv; 882 } 883 if (tevent_req_nomem(subreq, req)) { 884 return tevent_req_post(req, ev); 885 } 886 tevent_req_set_callback(subreq, cli_list_done, req); 887 return req; 888 } 889 890 static void cli_list_done(struct tevent_req *subreq) 891 { 892 struct tevent_req *req = tevent_req_callback_data( 893 subreq, struct tevent_req); 894 struct cli_list_state *state = tevent_req_data( 895 req, struct cli_list_state); 896 NTSTATUS status; 897 898 status = state->recv_fn(subreq, state, &state->finfo); 899 TALLOC_FREE(subreq); 900 if (!NT_STATUS_IS_OK(status)) { 901 tevent_req_nterror(req, status); 902 return; 903 } 904 tevent_req_done(req); 905 } 906 907 NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 908 struct file_info **finfo, size_t *num_finfo) 909 { 910 struct cli_list_state *state = tevent_req_data( 911 req, struct cli_list_state); 912 NTSTATUS status; 913 914 if (tevent_req_is_nterror(req, &status)) { 915 return status; 916 } 917 *num_finfo = talloc_array_length(state->finfo); 918 *finfo = talloc_move(mem_ctx, &state->finfo); 919 return NT_STATUS_OK; 920 } 921 922 NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16 attribute, 923 NTSTATUS (*fn)(const char *, struct file_info *, const char *, 924 void *), void *state) 925 { 926 TALLOC_CTX *frame = talloc_stackframe(); 927 struct event_context *ev; 928 struct tevent_req *req; 929 NTSTATUS status = NT_STATUS_NO_MEMORY; 930 struct file_info *finfo; 931 size_t i, num_finfo; 932 uint16_t info_level; 933 934 if (cli_has_async_calls(cli)) { 935 /* 936 * Can't use sync call while an async call is in flight 937 */ 938 status = NT_STATUS_INVALID_PARAMETER; 939 goto fail; 940 } 941 ev = event_context_init(frame); 942 if (ev == NULL) { 943 goto fail; 944 } 945 946 info_level = (cli->capabilities & CAP_NT_SMBS) 947 ? SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_INFO_STANDARD; 948 949 req = cli_list_send(frame, ev, cli, mask, attribute, info_level); 950 if (req == NULL) { 951 goto fail; 952 } 953 if (!tevent_req_poll(req, ev)) { 954 status = map_nt_error_from_unix(errno); 955 goto fail; 956 } 957 958 status = cli_list_recv(req, frame, &finfo, &num_finfo); 959 if (!NT_STATUS_IS_OK(status)) { 960 goto fail; 961 } 962 963 for (i=0; i<num_finfo; i++) { 964 status = fn(cli->dfs_mountpoint, &finfo[i], mask, state); 965 if (!NT_STATUS_IS_OK(status)) { 966 goto fail; 967 } 968 } 969 fail: 970 TALLOC_FREE(frame); 971 if (!NT_STATUS_IS_OK(status)) { 972 cli_set_error(cli, status); 973 } 974 return status; 975 } -
vendor/current/source3/libsmb/climessage.c
r587 r740 19 19 20 20 #include "includes.h" 21 #include "../lib/util/tevent_ntstatus.h" 22 #include "async_smb.h" 23 #include "libsmb/libsmb.h" 21 24 22 25 struct cli_message_start_state { … … 94 97 uint8_t wct; 95 98 uint16_t *vwv; 96 97 status = cli_smb_recv(subreq, 0, &wct, &vwv, NULL, NULL); 99 uint8_t *inbuf; 100 101 status = cli_smb_recv(subreq, state, &inbuf, 0, &wct, &vwv, 102 NULL, NULL); 103 TALLOC_FREE(subreq); 98 104 if (!NT_STATUS_IS_OK(status)) { 99 105 TALLOC_FREE(subreq); … … 106 112 state->grp = 0; 107 113 } 108 TALLOC_FREE(subreq);109 114 tevent_req_done(req); 110 115 } … … 186 191 NTSTATUS status; 187 192 188 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);193 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 189 194 TALLOC_FREE(subreq); 190 195 if (!NT_STATUS_IS_OK(status)) { … … 237 242 NTSTATUS status; 238 243 239 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);244 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 240 245 TALLOC_FREE(subreq); 241 246 if (!NT_STATUS_IS_OK(status)) { -
vendor/current/source3/libsmb/clioplock.c
r414 r740 19 19 20 20 #include "includes.h" 21 #include "../lib/util/tevent_ntstatus.h" 22 #include "async_smb.h" 23 #include "libsmb/libsmb.h" 21 24 22 25 /**************************************************************************** … … 38 41 struct cli_oplock_ack_state *state; 39 42 40 req = tevent_req_create(mem_ctx, &state, struct cli_oplock_ack_state); ;43 req = tevent_req_create(mem_ctx, &state, struct cli_oplock_ack_state); 41 44 if (req == NULL) { 42 45 return NULL; … … 67 70 NTSTATUS status; 68 71 69 status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);72 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 70 73 TALLOC_FREE(subreq); 71 74 if (!NT_STATUS_IS_OK(status)) { -
vendor/current/source3/libsmb/cliprint.c
r414 r740 19 19 20 20 #include "includes.h" 21 #include "libsmb/libsmb.h" 22 #include "libsmb/clirap.h" 21 23 22 24 /***************************************************************************** … … 28 30 char *rdata, int rdrcnt) 29 31 { 32 unsigned int offset; 33 30 34 if (datap == 0) { 31 35 /* turn NULL pointers into zero length strings */ 32 36 return ""; 33 } else { 34 unsigned int offset = datap - converter; 37 } 35 38 36 if (offset >= rdrcnt) { 37 DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", 38 datap, converter, rdrcnt)); 39 return "<ERROR>"; 40 } else { 41 return &rdata[offset]; 42 } 39 offset = datap - converter; 40 41 if (offset >= rdrcnt) { 42 DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", 43 datap, converter, rdrcnt)); 44 return "<ERROR>"; 43 45 } 46 return &rdata[offset]; 44 47 } 45 48 … … 98 101 fix_char_ptr(SVAL(p,4), converter, 99 102 rdata, rdrcnt)); 100 job.t = cli_make_unix_date3(cli, p + 12); 103 job.t = make_unix_date3( 104 p + 12, cli->serverzone); 101 105 job.size = IVAL(p,16); 102 106 fstrcpy(job.name,fix_char_ptr(SVAL(p,24), … … 154 158 return ret; 155 159 } 156 157 158 /****************************************************************************159 Open a spool file160 ****************************************************************************/161 162 int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_mode)163 {164 char *p;165 unsigned openfn=0;166 unsigned accessmode=0;167 168 if (flags & O_CREAT)169 openfn |= (1<<4);170 if (!(flags & O_EXCL)) {171 if (flags & O_TRUNC)172 openfn |= (1<<1);173 else174 openfn |= (1<<0);175 }176 177 accessmode = (share_mode<<4);178 179 if ((flags & O_ACCMODE) == O_RDWR) {180 accessmode |= 2;181 } else if ((flags & O_ACCMODE) == O_WRONLY) {182 accessmode |= 1;183 }184 185 #if defined(O_SYNC)186 if ((flags & O_SYNC) == O_SYNC) {187 accessmode |= (1<<14);188 }189 #endif /* O_SYNC */190 191 if (share_mode == DENY_FCB) {192 accessmode = 0xFF;193 }194 195 memset(cli->outbuf,'\0',smb_size);196 memset(cli->inbuf,'\0',smb_size);197 198 cli_set_message(cli->outbuf,15,0,True);199 200 SCVAL(cli->outbuf,smb_com,SMBsplopen);201 SSVAL(cli->outbuf,smb_tid,cli->cnum);202 cli_setup_packet(cli);203 204 SSVAL(cli->outbuf,smb_vwv0,0xFF);205 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */206 SSVAL(cli->outbuf,smb_vwv3,accessmode);207 SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);208 SSVAL(cli->outbuf,smb_vwv5,0);209 SSVAL(cli->outbuf,smb_vwv8,openfn);210 211 if (cli->use_oplocks) {212 /* if using oplocks then ask for a batch oplock via213 core and extended methods */214 SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)|215 FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK);216 SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);217 }218 219 p = smb_buf(cli->outbuf);220 p += clistr_push(cli, p, fname, -1, STR_TERMINATE);221 222 cli_setup_bcc(cli, p);223 224 cli_send_smb(cli);225 if (!cli_receive_smb(cli)) {226 return -1;227 }228 229 if (cli_is_error(cli)) {230 return -1;231 }232 233 return SVAL(cli->inbuf,smb_vwv2);234 }235 236 /****************************************************************************237 Close a file.238 ****************************************************************************/239 240 bool cli_spl_close(struct cli_state *cli, uint16_t fnum)241 {242 memset(cli->outbuf,'\0',smb_size);243 memset(cli->inbuf,'\0',smb_size);244 245 cli_set_message(cli->outbuf,3,0,True);246 247 SCVAL(cli->outbuf,smb_com,SMBsplclose);248 SSVAL(cli->outbuf,smb_tid,cli->cnum);249 cli_setup_packet(cli);250 251 SSVAL(cli->outbuf,smb_vwv0,fnum);252 SIVALS(cli->outbuf,smb_vwv1,-1);253 254 cli_send_smb(cli);255 if (!cli_receive_smb(cli)) {256 return False;257 }258 259 return !cli_is_error(cli);260 } -
vendor/current/source3/libsmb/cliquota.c
r581 r740 19 19 20 20 #include "includes.h" 21 #include "libsmb/libsmb.h" 22 #include "../librpc/gen_ndr/ndr_security.h" 23 #include "fake_file.h" 24 #include "../libcli/security/security.h" 25 #include "trans2.h" 21 26 22 27 NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum) … … 41 46 } 42 47 43 static bool parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt) 48 static bool parse_user_quota_record(const uint8_t *rdata, 49 unsigned int rdata_count, 50 unsigned int *offset, 51 SMB_NTQUOTA_STRUCT *pqt) 44 52 { 45 53 int sid_len; … … 74 82 75 83 /* the used space 8 bytes (uint64_t)*/ 76 qt.usedspace = (uint64_t)IVAL(rdata,16); 77 #ifdef LARGE_SMB_OFF_T 78 qt.usedspace |= (((uint64_t)IVAL(rdata,20)) << 32); 79 #else /* LARGE_SMB_OFF_T */ 80 if ((IVAL(rdata,20) != 0)&& 81 ((qt.usedspace != 0xFFFFFFFF)|| 82 (IVAL(rdata,20)!=0xFFFFFFFF))) { 83 /* more than 32 bits? */ 84 return False; 85 } 86 #endif /* LARGE_SMB_OFF_T */ 84 qt.usedspace = BVAL(rdata,16); 87 85 88 86 /* the soft quotas 8 bytes (uint64_t)*/ 89 qt.softlim = (uint64_t)IVAL(rdata,24); 90 #ifdef LARGE_SMB_OFF_T 91 qt.softlim |= (((uint64_t)IVAL(rdata,28)) << 32); 92 #else /* LARGE_SMB_OFF_T */ 93 if ((IVAL(rdata,28) != 0)&& 94 ((qt.softlim != 0xFFFFFFFF)|| 95 (IVAL(rdata,28)!=0xFFFFFFFF))) { 96 /* more than 32 bits? */ 97 return False; 98 } 99 #endif /* LARGE_SMB_OFF_T */ 87 qt.softlim = BVAL(rdata,24); 100 88 101 89 /* the hard quotas 8 bytes (uint64_t)*/ 102 qt.hardlim = (uint64_t)IVAL(rdata,32); 103 #ifdef LARGE_SMB_OFF_T 104 qt.hardlim |= (((uint64_t)IVAL(rdata,36)) << 32); 105 #else /* LARGE_SMB_OFF_T */ 106 if ((IVAL(rdata,36) != 0)&& 107 ((qt.hardlim != 0xFFFFFFFF)|| 108 (IVAL(rdata,36)!=0xFFFFFFFF))) { 109 /* more than 32 bits? */ 110 return False; 111 } 112 #endif /* LARGE_SMB_OFF_T */ 113 114 if (!sid_parse(rdata+40,sid_len,&qt.sid)) { 90 qt.hardlim = BVAL(rdata,32); 91 92 if (!sid_parse((char *)rdata+40,sid_len,&qt.sid)) { 115 93 return false; 116 94 } … … 123 101 } 124 102 125 bool cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) 126 { 127 bool ret = False; 128 uint16 setup;129 charparams[16];103 NTSTATUS cli_get_user_quota(struct cli_state *cli, int quota_fnum, 104 SMB_NTQUOTA_STRUCT *pqt) 105 { 106 uint16_t setup[1]; 107 uint8_t params[16]; 130 108 unsigned int data_len; 131 chardata[SID_MAX_SIZE+8];132 char *rparam=NULL, *rdata=NULL;133 u nsigned int rparam_count=0, rdata_count=0;109 uint8_t data[SID_MAX_SIZE+8]; 110 uint8_t *rparam, *rdata; 111 uint32_t rparam_count, rdata_count; 134 112 unsigned int sid_len; 135 113 unsigned int offset; 114 NTSTATUS status; 136 115 137 116 if (!cli||!pqt) { … … 139 118 } 140 119 141 setup = NT_TRANSACT_GET_USER_QUOTA;120 SSVAL(setup + 0, 0, NT_TRANSACT_GET_USER_QUOTA); 142 121 143 122 SSVAL(params, 0,quota_fnum); … … 147 126 SIVAL(params,12,0x00000024); 148 127 149 sid_len = ndr_size_dom_sid(&pqt->sid, NULL,0);128 sid_len = ndr_size_dom_sid(&pqt->sid, 0); 150 129 data_len = sid_len+8; 151 130 SIVAL(data, 0, 0x00000000); 152 131 SIVAL(data, 4, sid_len); 153 sid_linearize(data+8, sid_len, &pqt->sid); 154 155 if (!cli_send_nt_trans(cli, 156 NT_TRANSACT_GET_USER_QUOTA, 157 0, 158 &setup, 1, 0, 159 params, 16, 4, 160 data, data_len, 112)) { 161 DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); 162 goto cleanup; 163 } 164 165 166 if (!cli_receive_nt_trans(cli, 167 &rparam, &rparam_count, 168 &rdata, &rdata_count)) { 169 DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); 170 goto cleanup; 171 } 172 173 if (cli_is_error(cli)) { 174 ret = False; 175 goto cleanup; 176 } else { 177 ret = True; 178 } 179 180 if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) { 181 ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt); 182 } else { 132 sid_linearize((char *)data+8, sid_len, &pqt->sid); 133 134 status = cli_trans(talloc_tos(), cli, SMBnttrans, 135 NULL, -1, /* name, fid */ 136 NT_TRANSACT_GET_USER_QUOTA, 0, 137 setup, 1, 0, /* setup */ 138 params, 16, 4, /* params */ 139 data, data_len, 112, /* data */ 140 NULL, /* recv_flags2 */ 141 NULL, 0, NULL, /* rsetup */ 142 &rparam, 4, &rparam_count, 143 &rdata, 8, &rdata_count); 144 if (!NT_STATUS_IS_OK(status)) { 145 DEBUG(1, ("NT_TRANSACT_GET_USER_QUOTA failed: %s\n", 146 nt_errstr(status))); 147 return status; 148 } 149 150 if (!parse_user_quota_record(rdata, rdata_count, &offset, pqt)) { 151 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 183 152 DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n")); 184 ret = False; 185 } 186 187 cleanup: 188 SAFE_FREE(rparam); 189 SAFE_FREE(rdata); 190 return ret; 191 } 192 193 bool cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) 194 { 195 bool ret = False; 196 uint16 setup; 197 char params[2]; 198 char data[112]; 199 char *rparam=NULL, *rdata=NULL; 200 unsigned int rparam_count=0, rdata_count=0; 153 } 154 155 TALLOC_FREE(rparam); 156 TALLOC_FREE(rdata); 157 return status; 158 } 159 160 NTSTATUS cli_set_user_quota(struct cli_state *cli, int quota_fnum, 161 SMB_NTQUOTA_STRUCT *pqt) 162 { 163 uint16_t setup[1]; 164 uint8_t params[2]; 165 uint8_t data[112]; 201 166 unsigned int sid_len; 167 NTSTATUS status; 168 202 169 memset(data,'\0',112); 203 170 … … 206 173 } 207 174 208 setup = NT_TRANSACT_SET_USER_QUOTA;175 SSVAL(setup + 0, 0, NT_TRANSACT_SET_USER_QUOTA); 209 176 210 177 SSVAL(params,0,quota_fnum); 211 178 212 sid_len = ndr_size_dom_sid(&pqt->sid, NULL,0);179 sid_len = ndr_size_dom_sid(&pqt->sid, 0); 213 180 SIVAL(data,0,0); 214 181 SIVAL(data,4,sid_len); … … 217 184 SBIG_UINT(data,24,pqt->softlim); 218 185 SBIG_UINT(data,32,pqt->hardlim); 219 sid_linearize(data+40, sid_len, &pqt->sid); 220 221 if (!cli_send_nt_trans(cli, 222 NT_TRANSACT_SET_USER_QUOTA, 223 0, 224 &setup, 1, 0, 225 params, 2, 0, 226 data, 112, 0)) { 227 DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n")); 228 goto cleanup; 229 } 230 231 232 if (!cli_receive_nt_trans(cli, 233 &rparam, &rparam_count, 234 &rdata, &rdata_count)) { 235 DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n")); 236 goto cleanup; 237 } 238 239 if (cli_is_error(cli)) { 240 ret = False; 241 goto cleanup; 242 } else { 243 ret = True; 244 } 245 246 cleanup: 247 SAFE_FREE(rparam); 248 SAFE_FREE(rdata); 249 return ret; 250 } 251 252 bool cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list) 253 { 254 bool ret = False; 255 uint16 setup; 256 char params[16]; 257 char *rparam=NULL, *rdata=NULL; 258 unsigned int rparam_count=0, rdata_count=0; 186 sid_linearize((char *)data+40, sid_len, &pqt->sid); 187 188 status = cli_trans(talloc_tos(), cli, SMBnttrans, 189 NULL, -1, /* name, fid */ 190 NT_TRANSACT_SET_USER_QUOTA, 0, 191 setup, 1, 0, /* setup */ 192 params, 2, 0, /* params */ 193 data, 112, 0, /* data */ 194 NULL, /* recv_flags2 */ 195 NULL, 0, NULL, /* rsetup */ 196 NULL, 0, NULL, /* rparams */ 197 NULL, 0, NULL); /* rdata */ 198 199 if (!NT_STATUS_IS_OK(status)) { 200 DEBUG(1, ("NT_TRANSACT_SET_USER_QUOTA failed: %s\n", 201 nt_errstr(status))); 202 } 203 204 return status; 205 } 206 207 NTSTATUS cli_list_user_quota(struct cli_state *cli, int quota_fnum, 208 SMB_NTQUOTA_LIST **pqt_list) 209 { 210 uint16_t setup[1]; 211 uint8_t params[16]; 212 uint8_t *rparam=NULL, *rdata=NULL; 213 uint32_t rparam_count=0, rdata_count=0; 259 214 unsigned int offset; 260 const char*curdata = NULL;215 const uint8_t *curdata = NULL; 261 216 unsigned int curdata_count = 0; 262 217 TALLOC_CTX *mem_ctx = NULL; 263 218 SMB_NTQUOTA_STRUCT qt; 264 219 SMB_NTQUOTA_LIST *tmp_list_ent; 220 NTSTATUS status; 265 221 266 222 if (!cli||!pqt_list) { … … 268 224 } 269 225 270 setup = NT_TRANSACT_GET_USER_QUOTA;226 SSVAL(setup + 0, 0, NT_TRANSACT_GET_USER_QUOTA); 271 227 272 228 SSVAL(params, 0,quota_fnum); … … 276 232 SIVAL(params,12,0x00000000); 277 233 278 if (!cli_send_nt_trans(cli, 279 NT_TRANSACT_GET_USER_QUOTA, 280 0, 281 &setup, 1, 0, 282 params, 16, 4, 283 NULL, 0, 2048)) { 284 DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); 234 status = cli_trans(talloc_tos(), cli, SMBnttrans, 235 NULL, -1, /* name, fid */ 236 NT_TRANSACT_GET_USER_QUOTA, 0, 237 setup, 1, 0, /* setup */ 238 params, 16, 4, /* params */ 239 NULL, 0, 2048, /* data */ 240 NULL, /* recv_flags2 */ 241 NULL, 0, NULL, /* rsetup */ 242 &rparam, 0, &rparam_count, 243 &rdata, 0, &rdata_count); 244 245 if (!NT_STATUS_IS_OK(status)) { 246 DEBUG(1, ("NT_TRANSACT_GET_USER_QUOTA failed: %s\n", 247 nt_errstr(status))); 285 248 goto cleanup; 286 }287 288 289 if (!cli_receive_nt_trans(cli,290 &rparam, &rparam_count,291 &rdata, &rdata_count)) {292 DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));293 goto cleanup;294 }295 296 if (cli_is_error(cli)) {297 ret = False;298 goto cleanup;299 } else {300 ret = True;301 249 } 302 250 303 251 if (rdata_count == 0) { 304 252 *pqt_list = NULL; 305 return True;253 return NT_STATUS_OK; 306 254 } 307 255 308 256 if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) { 309 257 DEBUG(0,("talloc_init() failed\n")); 310 return (-1);258 return NT_STATUS_NO_MEMORY; 311 259 } 312 260 … … 316 264 curdata +=offset,curdata_count -= offset) { 317 265 ZERO_STRUCT(qt); 318 if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { 266 if (!parse_user_quota_record((uint8_t *)curdata, curdata_count, 267 &offset, &qt)) { 319 268 DEBUG(1,("Failed to parse the quota record\n")); 320 269 goto cleanup; … … 324 273 DEBUG(0,("TALLOC_ZERO() failed\n")); 325 274 talloc_destroy(mem_ctx); 326 return (-1);275 return NT_STATUS_NO_MEMORY; 327 276 } 328 277 … … 330 279 DEBUG(0,("TALLOC_ZERO() failed\n")); 331 280 talloc_destroy(mem_ctx); 332 return (-1);281 return NT_STATUS_NO_MEMORY; 333 282 } 334 283 … … 341 290 SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE); 342 291 while(1) { 343 if (!cli_send_nt_trans(cli, 344 NT_TRANSACT_GET_USER_QUOTA, 345 0, 346 &setup, 1, 0, 347 params, 16, 4, 348 NULL, 0, 2048)) { 349 DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); 292 293 TALLOC_FREE(rparam); 294 TALLOC_FREE(rdata); 295 296 status = cli_trans(talloc_tos(), cli, SMBnttrans, 297 NULL, -1, /* name, fid */ 298 NT_TRANSACT_GET_USER_QUOTA, 0, 299 setup, 1, 0, /* setup */ 300 params, 16, 4, /* params */ 301 NULL, 0, 2048, /* data */ 302 NULL, /* recv_flags2 */ 303 NULL, 0, NULL, /* rsetup */ 304 &rparam, 0, &rparam_count, 305 &rdata, 0, &rdata_count); 306 307 if (!NT_STATUS_IS_OK(status)) { 308 DEBUG(1, ("NT_TRANSACT_GET_USER_QUOTA failed: %s\n", 309 nt_errstr(status))); 350 310 goto cleanup; 351 311 } 352 312 353 SAFE_FREE(rparam);354 SAFE_FREE(rdata);355 if (!cli_receive_nt_trans(cli,356 &rparam, &rparam_count,357 &rdata, &rdata_count)) {358 DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n"));359 goto cleanup;360 }361 362 if (cli_is_error(cli)) {363 ret = False;364 goto cleanup;365 } else {366 ret = True;367 }368 369 313 if (rdata_count == 0) { 370 break; 314 break; 371 315 } 372 316 … … 376 320 curdata +=offset,curdata_count -= offset) { 377 321 ZERO_STRUCT(qt); 378 if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { 322 if (!parse_user_quota_record((uint8_t *)curdata, 323 curdata_count, &offset, 324 &qt)) { 379 325 DEBUG(1,("Failed to parse the quota record\n")); 380 326 goto cleanup; … … 400 346 } 401 347 402 403 ret = True;404 348 cleanup: 405 SAFE_FREE(rparam);406 SAFE_FREE(rdata);407 408 return ret;409 } 410 411 bool cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) 412 { 413 bool ret = False; 414 uint16 setup;415 charparam[2];416 char *rparam=NULL,*rdata=NULL;417 u nsigned int rparam_count=0,rdata_count=0;349 TALLOC_FREE(rparam); 350 TALLOC_FREE(rdata); 351 352 return status; 353 } 354 355 NTSTATUS cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, 356 SMB_NTQUOTA_STRUCT *pqt) 357 { 358 uint16_t setup[1]; 359 uint8_t param[2]; 360 uint8_t *rdata=NULL; 361 uint32_t rdata_count=0; 418 362 SMB_NTQUOTA_STRUCT qt; 363 NTSTATUS status; 364 419 365 ZERO_STRUCT(qt); 420 366 … … 423 369 } 424 370 425 setup = TRANSACT2_QFSINFO;371 SSVAL(setup + 0, 0, TRANSACT2_QFSINFO); 426 372 427 373 SSVAL(param,0,SMB_FS_QUOTA_INFORMATION); 428 374 429 if (!cli_send_trans(cli, SMBtrans2, 430 NULL, 431 0, 0, 432 &setup, 1, 0, 433 param, 2, 0, 434 NULL, 0, 560)) { 435 goto cleanup; 436 } 437 438 if (!cli_receive_trans(cli, SMBtrans2, 439 &rparam, &rparam_count, 440 &rdata, &rdata_count)) { 441 goto cleanup; 442 } 443 444 if (cli_is_error(cli)) { 445 ret = False; 446 goto cleanup; 447 } else { 448 ret = True; 449 } 450 451 if (rdata_count < 48) { 452 goto cleanup; 375 status = cli_trans(talloc_tos(), cli, SMBtrans2, 376 NULL, -1, /* name, fid */ 377 0, 0, /* function, flags */ 378 setup, 1, 0, /* setup */ 379 param, 2, 0, /* param */ 380 NULL, 0, 560, /* data */ 381 NULL, /* recv_flags2 */ 382 NULL, 0, NULL, /* rsetup */ 383 NULL, 0, NULL, /* rparam */ 384 &rdata, 48, &rdata_count); 385 386 if (!NT_STATUS_IS_OK(status)) { 387 DEBUG(1, ("SMB_FS_QUOTA_INFORMATION failed: %s\n", 388 nt_errstr(status))); 389 return status; 453 390 } 454 391 … … 456 393 457 394 /* the soft quotas 8 bytes (uint64_t)*/ 458 qt.softlim = (uint64_t)IVAL(rdata,24); 459 #ifdef LARGE_SMB_OFF_T 460 qt.softlim |= (((uint64_t)IVAL(rdata,28)) << 32); 461 #else /* LARGE_SMB_OFF_T */ 462 if ((IVAL(rdata,28) != 0)&& 463 ((qt.softlim != 0xFFFFFFFF)|| 464 (IVAL(rdata,28)!=0xFFFFFFFF))) { 465 /* more than 32 bits? */ 466 goto cleanup; 467 } 468 #endif /* LARGE_SMB_OFF_T */ 395 qt.softlim = BVAL(rdata,24); 469 396 470 397 /* the hard quotas 8 bytes (uint64_t)*/ 471 qt.hardlim = (uint64_t)IVAL(rdata,32); 472 #ifdef LARGE_SMB_OFF_T 473 qt.hardlim |= (((uint64_t)IVAL(rdata,36)) << 32); 474 #else /* LARGE_SMB_OFF_T */ 475 if ((IVAL(rdata,36) != 0)&& 476 ((qt.hardlim != 0xFFFFFFFF)|| 477 (IVAL(rdata,36)!=0xFFFFFFFF))) { 478 /* more than 32 bits? */ 479 goto cleanup; 480 } 481 #endif /* LARGE_SMB_OFF_T */ 398 qt.hardlim = BVAL(rdata,32); 482 399 483 400 /* quota_flags 2 bytes **/ … … 488 405 *pqt = qt; 489 406 490 ret = True; 491 cleanup: 492 SAFE_FREE(rparam); 493 SAFE_FREE(rdata); 494 495 return ret; 496 } 497 498 bool cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) 499 { 500 bool ret = False; 501 uint16 setup; 502 char param[4]; 503 char data[48]; 504 char *rparam=NULL, *rdata=NULL; 505 unsigned int rparam_count=0, rdata_count=0; 407 TALLOC_FREE(rdata); 408 return status; 409 } 410 411 NTSTATUS cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, 412 SMB_NTQUOTA_STRUCT *pqt) 413 { 414 uint16_t setup[1]; 415 uint8_t param[4]; 416 uint8_t data[48]; 506 417 SMB_NTQUOTA_STRUCT qt; 418 NTSTATUS status; 507 419 ZERO_STRUCT(qt); 508 420 memset(data,'\0',48); … … 512 424 } 513 425 514 setup = TRANSACT2_SETFSINFO;426 SSVAL(setup + 0, 0,TRANSACT2_SETFSINFO); 515 427 516 428 SSVAL(param,0,quota_fnum); … … 530 442 /* Unknown3 6 NULL bytes */ 531 443 532 if (!cli_send_trans(cli, SMBtrans2, 533 NULL, 534 0, 0, 535 &setup, 1, 0, 536 param, 4, 0, 537 data, 48, 0)) { 538 goto cleanup; 539 } 540 541 if (!cli_receive_trans(cli, SMBtrans2, 542 &rparam, &rparam_count, 543 &rdata, &rdata_count)) { 544 goto cleanup; 545 } 546 547 if (cli_is_error(cli)) { 548 ret = False; 549 goto cleanup; 550 } else { 551 ret = True; 552 } 553 554 cleanup: 555 SAFE_FREE(rparam); 556 SAFE_FREE(rdata); 557 558 return ret; 559 } 560 561 static const char *quota_str_static(uint64_t val, bool special, bool _numeric) 562 { 563 const char *result; 564 565 if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) { 566 return "NO LIMIT"; 567 } 568 result = talloc_asprintf(talloc_tos(), "%"PRIu64, val); 569 SMB_ASSERT(result != NULL); 570 return result; 571 } 572 573 void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose, bool _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, bool _numeric)) 574 { 575 TALLOC_CTX *frame = talloc_stackframe(); 576 577 if (!qt) { 578 smb_panic("dump_ntquota() called with NULL pointer"); 579 } 580 581 switch (qt->qtype) { 582 case SMB_USER_FS_QUOTA_TYPE: 583 { 584 d_printf("File System QUOTAS:\n"); 585 d_printf("Limits:\n"); 586 d_printf(" Default Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric)); 587 d_printf(" Default Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric)); 588 d_printf("Quota Flags:\n"); 589 d_printf(" Quotas Enabled: %s\n", 590 ((qt->qflags"AS_ENABLED)||(qt->qflags"AS_DENY_DISK))?"On":"Off"); 591 d_printf(" Deny Disk: %s\n",(qt->qflags"AS_DENY_DISK)?"On":"Off"); 592 d_printf(" Log Soft Limit: %s\n",(qt->qflags"AS_LOG_THRESHOLD)?"On":"Off"); 593 d_printf(" Log Hard Limit: %s\n",(qt->qflags"AS_LOG_LIMIT)?"On":"Off"); 594 } 595 break; 596 case SMB_USER_QUOTA_TYPE: 597 { 598 fstring username_str = {0}; 599 600 if (_sidtostring) { 601 _sidtostring(username_str,&qt->sid,_numeric); 602 } else { 603 sid_to_fstring(username_str, &qt->sid); 604 } 605 606 if (_verbose) { 607 d_printf("Quotas for User: %s\n",username_str); 608 d_printf("Used Space: %15s\n",quota_str_static(qt->usedspace,False,_numeric)); 609 d_printf("Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric)); 610 d_printf("Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric)); 611 } else { 612 d_printf("%-30s: ",username_str); 613 d_printf("%15s/",quota_str_static(qt->usedspace,False,_numeric)); 614 d_printf("%15s/",quota_str_static(qt->softlim,True,_numeric)); 615 d_printf("%15s\n",quota_str_static(qt->hardlim,True,_numeric)); 616 } 617 } 618 break; 619 default: 620 d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype); 621 } 622 TALLOC_FREE(frame); 623 return; 624 } 625 626 void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, bool _verbose, bool _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, bool _numeric)) 627 { 628 SMB_NTQUOTA_LIST *cur; 629 630 for (cur = *qtl;cur;cur = cur->next) { 631 if (cur->quotas) 632 dump_ntquota(cur->quotas,_verbose,_numeric,_sidtostring); 633 } 634 } 444 status = cli_trans(talloc_tos(), cli, SMBtrans2, 445 NULL, -1, /* name, fid */ 446 0, 0, /* function, flags */ 447 setup, 1, 0, /* setup */ 448 param, 8, 0, /* param */ 449 data, 48, 0, /* data */ 450 NULL, /* recv_flags2 */ 451 NULL, 0, NULL, /* rsetup */ 452 NULL, 0, NULL, /* rparam */ 453 NULL, 0, NULL); /* rdata */ 454 455 if (!NT_STATUS_IS_OK(status)) { 456 DEBUG(1, ("SMB_FS_QUOTA_INFORMATION failed: %s\n", 457 nt_errstr(status))); 458 } 459 460 return status; 461 } -
vendor/current/source3/libsmb/clirap.c
r414 r740 22 22 #include "includes.h" 23 23 #include "../libcli/auth/libcli_auth.h" 24 #include "../librpc/gen_ndr/rap.h" 25 #include "../lib/crypto/arcfour.h" 26 #include "../lib/util/tevent_ntstatus.h" 27 #include "async_smb.h" 28 #include "libsmb/libsmb.h" 29 #include "libsmb/clirap.h" 30 #include "trans2.h" 31 32 #define PIPE_LANMAN "\\PIPE\\LANMAN" 24 33 25 34 /**************************************************************************** … … 33 42 char **rdata, unsigned int *rdrcnt) 34 43 { 35 cli_send_trans(cli,SMBtrans, 36 PIPE_LANMAN, /* Name */ 37 0,0, /* fid, flags */ 38 NULL,0,0, /* Setup, length, max */ 39 param, prcnt, mprcnt, /* Params, length, max */ 40 data, drcnt, mdrcnt /* Data, length, max */ 41 ); 42 43 return (cli_receive_trans(cli,SMBtrans, 44 rparam, rprcnt, 45 rdata, rdrcnt)); 44 NTSTATUS status; 45 46 uint8_t *my_rparam, *my_rdata; 47 uint32_t num_my_rparam, num_my_rdata; 48 49 status = cli_trans(talloc_tos(), cli, SMBtrans, 50 PIPE_LANMAN, 0, /* name, fid */ 51 0, 0, /* function, flags */ 52 NULL, 0, 0, /* setup */ 53 (uint8_t *)param, prcnt, mprcnt, /* Params, length, max */ 54 (uint8_t *)data, drcnt, mdrcnt, /* Data, length, max */ 55 NULL, /* recv_flags2 */ 56 NULL, 0, NULL, /* rsetup */ 57 &my_rparam, 0, &num_my_rparam, 58 &my_rdata, 0, &num_my_rdata); 59 if (!NT_STATUS_IS_OK(status)) { 60 return false; 61 } 62 63 /* 64 * I know this memcpy massively hurts, but there are just tons 65 * of callers of cli_api that eventually need changing to 66 * talloc 67 */ 68 69 *rparam = (char *)memdup(my_rparam, num_my_rparam); 70 if (*rparam == NULL) { 71 goto fail; 72 } 73 *rprcnt = num_my_rparam; 74 TALLOC_FREE(my_rparam); 75 76 *rdata = (char *)memdup(my_rdata, num_my_rdata); 77 if (*rdata == NULL) { 78 goto fail; 79 } 80 *rdrcnt = num_my_rdata; 81 TALLOC_FREE(my_rdata); 82 83 return true; 84 fail: 85 TALLOC_FREE(my_rdata); 86 TALLOC_FREE(my_rparam); 87 *rparam = NULL; 88 *rprcnt = 0; 89 *rdata = NULL; 90 *rdrcnt = 0; 91 return false; 46 92 } 47 93 … … 496 542 data_len = 532; 497 543 498 if (cli_send_trans(cli,SMBtrans, 499 PIPE_LANMAN, /* name */ 500 0,0, /* fid, flags */ 501 NULL,0,0, /* setup, length, max */ 502 param,param_len,2, /* param, length, max */ 503 (char *)data,data_len,0 /* data, length, max */ 504 ) == False) { 544 if (!cli_api(cli, 545 param, param_len, 4, /* param, length, max */ 546 (char *)data, data_len, 0, /* data, length, max */ 547 &rparam, &rprcnt, 548 &rdata, &rdrcnt)) { 505 549 DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", 506 550 user )); … … 508 552 } 509 553 510 if (!cli_receive_trans(cli,SMBtrans,511 &rparam, &rprcnt,512 &rdata, &rdrcnt)) {513 DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n",514 user ));515 return False;516 }517 518 554 if (rparam) { 519 555 cli->rap_error = SVAL(rparam,0); … … 530 566 ****************************************************************************/ 531 567 532 bool cli_qpathinfo(struct cli_state *cli, 568 struct cli_qpathinfo1_state { 569 struct cli_state *cli; 570 uint32_t num_data; 571 uint8_t *data; 572 }; 573 574 static void cli_qpathinfo1_done(struct tevent_req *subreq); 575 576 struct tevent_req *cli_qpathinfo1_send(TALLOC_CTX *mem_ctx, 577 struct event_context *ev, 578 struct cli_state *cli, 579 const char *fname) 580 { 581 struct tevent_req *req = NULL, *subreq = NULL; 582 struct cli_qpathinfo1_state *state = NULL; 583 584 req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo1_state); 585 if (req == NULL) { 586 return NULL; 587 } 588 state->cli = cli; 589 subreq = cli_qpathinfo_send(state, ev, cli, fname, SMB_INFO_STANDARD, 590 22, cli->max_xmit); 591 if (tevent_req_nomem(subreq, req)) { 592 return tevent_req_post(req, ev); 593 } 594 tevent_req_set_callback(subreq, cli_qpathinfo1_done, req); 595 return req; 596 } 597 598 static void cli_qpathinfo1_done(struct tevent_req *subreq) 599 { 600 struct tevent_req *req = tevent_req_callback_data( 601 subreq, struct tevent_req); 602 struct cli_qpathinfo1_state *state = tevent_req_data( 603 req, struct cli_qpathinfo1_state); 604 NTSTATUS status; 605 606 status = cli_qpathinfo_recv(subreq, state, &state->data, 607 &state->num_data); 608 TALLOC_FREE(subreq); 609 if (!NT_STATUS_IS_OK(status)) { 610 tevent_req_nterror(req, status); 611 return; 612 } 613 tevent_req_done(req); 614 } 615 616 NTSTATUS cli_qpathinfo1_recv(struct tevent_req *req, 617 time_t *change_time, 618 time_t *access_time, 619 time_t *write_time, 620 SMB_OFF_T *size, 621 uint16 *mode) 622 { 623 struct cli_qpathinfo1_state *state = tevent_req_data( 624 req, struct cli_qpathinfo1_state); 625 NTSTATUS status; 626 627 time_t (*date_fn)(const void *buf, int serverzone); 628 629 if (tevent_req_is_nterror(req, &status)) { 630 return status; 631 } 632 633 if (state->cli->win95) { 634 date_fn = make_unix_date; 635 } else { 636 date_fn = make_unix_date2; 637 } 638 639 if (change_time) { 640 *change_time = date_fn(state->data+0, state->cli->serverzone); 641 } 642 if (access_time) { 643 *access_time = date_fn(state->data+4, state->cli->serverzone); 644 } 645 if (write_time) { 646 *write_time = date_fn(state->data+8, state->cli->serverzone); 647 } 648 if (size) { 649 *size = IVAL(state->data, 12); 650 } 651 if (mode) { 652 *mode = SVAL(state->data, l1_attrFile); 653 } 654 return NT_STATUS_OK; 655 } 656 657 NTSTATUS cli_qpathinfo1(struct cli_state *cli, 533 658 const char *fname, 534 659 time_t *change_time, … … 538 663 uint16 *mode) 539 664 { 540 unsigned int data_len = 0; 541 unsigned int param_len = 0; 542 unsigned int rparam_len, rdata_len; 543 uint16 setup = TRANSACT2_QPATHINFO; 544 char *param; 545 char *rparam=NULL, *rdata=NULL; 546 int count=8; 547 bool ret; 548 time_t (*date_fn)(struct cli_state *, const void *); 549 char *p; 550 size_t nlen = 2*(strlen(fname)+1); 551 552 param = SMB_MALLOC_ARRAY(char, 6+nlen+2); 553 if (!param) { 554 return false; 555 } 556 p = param; 557 memset(p, '\0', 6); 558 SSVAL(p, 0, SMB_INFO_STANDARD); 559 p += 6; 560 p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); 561 param_len = PTR_DIFF(p, param); 562 563 do { 564 ret = (cli_send_trans(cli, SMBtrans2, 565 NULL, /* Name */ 566 -1, 0, /* fid, flags */ 567 &setup, 1, 0, /* setup, length, max */ 568 param, param_len, 10, /* param, length, max */ 569 NULL, data_len, cli->max_xmit /* data, length, max */ 570 ) && 571 cli_receive_trans(cli, SMBtrans2, 572 &rparam, &rparam_len, 573 &rdata, &rdata_len)); 574 if (!cli_is_dos_error(cli)) break; 575 if (!ret) { 576 /* we need to work around a Win95 bug - sometimes 577 it gives ERRSRV/ERRerror temprarily */ 578 uint8 eclass; 579 uint32 ecode; 580 cli_dos_error(cli, &eclass, &ecode); 581 if (eclass != ERRSRV || ecode != ERRerror) break; 582 smb_msleep(100); 583 } 584 } while (count-- && ret==False); 585 586 SAFE_FREE(param); 587 if (!ret || !rdata || rdata_len < 22) { 588 return False; 589 } 590 591 if (cli->win95) { 592 date_fn = cli_make_unix_date; 593 } else { 594 date_fn = cli_make_unix_date2; 595 } 596 597 if (change_time) { 598 *change_time = date_fn(cli, rdata+0); 599 } 600 if (access_time) { 601 *access_time = date_fn(cli, rdata+4); 602 } 603 if (write_time) { 604 *write_time = date_fn(cli, rdata+8); 605 } 606 if (size) { 607 *size = IVAL(rdata, 12); 608 } 609 if (mode) { 610 *mode = SVAL(rdata,l1_attrFile); 611 } 612 613 SAFE_FREE(rdata); 614 SAFE_FREE(rparam); 615 return True; 665 TALLOC_CTX *frame = talloc_stackframe(); 666 struct event_context *ev; 667 struct tevent_req *req; 668 NTSTATUS status = NT_STATUS_NO_MEMORY; 669 670 if (cli_has_async_calls(cli)) { 671 /* 672 * Can't use sync call while an async call is in flight 673 */ 674 status = NT_STATUS_INVALID_PARAMETER; 675 goto fail; 676 } 677 ev = event_context_init(frame); 678 if (ev == NULL) { 679 goto fail; 680 } 681 req = cli_qpathinfo1_send(frame, ev, cli, fname); 682 if (req == NULL) { 683 goto fail; 684 } 685 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 686 goto fail; 687 } 688 status = cli_qpathinfo1_recv(req, change_time, access_time, 689 write_time, size, mode); 690 fail: 691 TALLOC_FREE(frame); 692 if (!NT_STATUS_IS_OK(status)) { 693 cli_set_error(cli, status); 694 } 695 return status; 616 696 } 617 697 … … 620 700 ****************************************************************************/ 621 701 622 bool cli_setpathinfo(struct cli_state *cli, const char *fname,623 624 625 626 627 702 NTSTATUS cli_setpathinfo_basic(struct cli_state *cli, const char *fname, 703 time_t create_time, 704 time_t access_time, 705 time_t write_time, 706 time_t change_time, 707 uint16 mode) 628 708 { 629 709 unsigned int data_len = 0; 630 unsigned int param_len = 0;631 unsigned int rparam_len, rdata_len;632 uint16 setup = TRANSACT2_SETPATHINFO;633 char *param;634 710 char data[40]; 635 char *rparam=NULL, *rdata=NULL;636 int count=8;637 bool ret;638 711 char *p; 639 size_t nlen = 2*(strlen(fname)+1);640 641 param = SMB_MALLOC_ARRAY(char, 6+nlen+2);642 if (!param) {643 return false;644 }645 memset(param, '\0', 6);646 memset(data, 0, sizeof(data));647 648 p = param;649 650 /* Add the information level */651 SSVAL(p, 0, SMB_FILE_BASIC_INFORMATION);652 653 /* Skip reserved */654 p += 6;655 656 /* Add the file name */657 p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);658 659 param_len = PTR_DIFF(p, param);660 712 661 713 p = data; … … 686 738 data_len = PTR_DIFF(p, data); 687 739 688 do { 689 ret = (cli_send_trans(cli, SMBtrans2, 690 NULL, /* Name */ 691 -1, 0, /* fid, flags */ 692 &setup, 1, 0, /* setup, length, max */ 693 param, param_len, 10, /* param, length, max */ 694 data, data_len, cli->max_xmit /* data, length, max */ 695 ) && 696 cli_receive_trans(cli, SMBtrans2, 697 &rparam, &rparam_len, 698 &rdata, &rdata_len)); 699 if (!cli_is_dos_error(cli)) break; 700 if (!ret) { 701 /* we need to work around a Win95 bug - sometimes 702 it gives ERRSRV/ERRerror temprarily */ 703 uint8 eclass; 704 uint32 ecode; 705 cli_dos_error(cli, &eclass, &ecode); 706 if (eclass != ERRSRV || ecode != ERRerror) break; 707 smb_msleep(100); 708 } 709 } while (count-- && ret==False); 710 711 SAFE_FREE(param); 712 if (!ret) { 713 return False; 714 } 715 716 SAFE_FREE(rdata); 717 SAFE_FREE(rparam); 718 return True; 740 return cli_setpathinfo(cli, SMB_FILE_BASIC_INFORMATION, fname, 741 (uint8_t *)data, data_len); 719 742 } 720 743 … … 723 746 ****************************************************************************/ 724 747 725 bool cli_qpathinfo2(struct cli_state *cli, const char *fname, 726 struct timespec *create_time, 727 struct timespec *access_time, 728 struct timespec *write_time, 729 struct timespec *change_time, 730 SMB_OFF_T *size, uint16 *mode, 731 SMB_INO_T *ino) 732 { 733 unsigned int data_len = 0; 734 unsigned int param_len = 0; 735 uint16 setup = TRANSACT2_QPATHINFO; 736 char *param; 737 char *rparam=NULL, *rdata=NULL; 738 char *p; 739 size_t nlen = 2*(strlen(fname)+1); 740 741 param = SMB_MALLOC_ARRAY(char, 6+nlen+2); 742 if (!param) { 743 return false; 744 } 745 p = param; 746 memset(param, '\0', 6); 747 SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); 748 p += 6; 749 p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); 750 751 param_len = PTR_DIFF(p, param); 752 753 if (!cli_send_trans(cli, SMBtrans2, 754 NULL, /* name */ 755 -1, 0, /* fid, flags */ 756 &setup, 1, 0, /* setup, length, max */ 757 param, param_len, 10, /* param, length, max */ 758 NULL, data_len, cli->max_xmit /* data, length, max */ 759 )) { 760 SAFE_FREE(param); 761 return False; 762 } 763 764 SAFE_FREE(param); 765 if (!cli_receive_trans(cli, SMBtrans2, 766 &rparam, ¶m_len, 767 &rdata, &data_len)) { 768 return False; 769 } 770 771 if (!rdata || data_len < 22) { 772 return False; 748 struct cli_qpathinfo2_state { 749 uint32_t num_data; 750 uint8_t *data; 751 }; 752 753 static void cli_qpathinfo2_done(struct tevent_req *subreq); 754 755 struct tevent_req *cli_qpathinfo2_send(TALLOC_CTX *mem_ctx, 756 struct event_context *ev, 757 struct cli_state *cli, 758 const char *fname) 759 { 760 struct tevent_req *req = NULL, *subreq = NULL; 761 struct cli_qpathinfo2_state *state = NULL; 762 763 req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo2_state); 764 if (req == NULL) { 765 return NULL; 766 } 767 subreq = cli_qpathinfo_send(state, ev, cli, fname, 768 SMB_QUERY_FILE_ALL_INFO, 769 68, cli->max_xmit); 770 if (tevent_req_nomem(subreq, req)) { 771 return tevent_req_post(req, ev); 772 } 773 tevent_req_set_callback(subreq, cli_qpathinfo2_done, req); 774 return req; 775 } 776 777 static void cli_qpathinfo2_done(struct tevent_req *subreq) 778 { 779 struct tevent_req *req = tevent_req_callback_data( 780 subreq, struct tevent_req); 781 struct cli_qpathinfo2_state *state = tevent_req_data( 782 req, struct cli_qpathinfo2_state); 783 NTSTATUS status; 784 785 status = cli_qpathinfo_recv(subreq, state, &state->data, 786 &state->num_data); 787 TALLOC_FREE(subreq); 788 if (!NT_STATUS_IS_OK(status)) { 789 tevent_req_nterror(req, status); 790 return; 791 } 792 tevent_req_done(req); 793 } 794 795 NTSTATUS cli_qpathinfo2_recv(struct tevent_req *req, 796 struct timespec *create_time, 797 struct timespec *access_time, 798 struct timespec *write_time, 799 struct timespec *change_time, 800 SMB_OFF_T *size, uint16 *mode, 801 SMB_INO_T *ino) 802 { 803 struct cli_qpathinfo2_state *state = tevent_req_data( 804 req, struct cli_qpathinfo2_state); 805 NTSTATUS status; 806 807 if (tevent_req_is_nterror(req, &status)) { 808 return status; 773 809 } 774 810 775 811 if (create_time) { 776 *create_time = interpret_long_date( rdata+0);812 *create_time = interpret_long_date((char *)state->data+0); 777 813 } 778 814 if (access_time) { 779 *access_time = interpret_long_date( rdata+8);815 *access_time = interpret_long_date((char *)state->data+8); 780 816 } 781 817 if (write_time) { 782 *write_time = interpret_long_date( rdata+16);818 *write_time = interpret_long_date((char *)state->data+16); 783 819 } 784 820 if (change_time) { 785 *change_time = interpret_long_date( rdata+24);821 *change_time = interpret_long_date((char *)state->data+24); 786 822 } 787 823 if (mode) { 788 *mode = SVAL( rdata, 32);824 *mode = SVAL(state->data, 32); 789 825 } 790 826 if (size) { 791 *size = IVAL2_TO_SMB_BIG_UINT( rdata,48);827 *size = IVAL2_TO_SMB_BIG_UINT(state->data,48); 792 828 } 793 829 if (ino) { 794 *ino = IVAL(rdata, 64); 795 } 796 797 SAFE_FREE(rdata); 798 SAFE_FREE(rparam); 799 return True; 830 *ino = IVAL(state->data, 64); 831 } 832 return NT_STATUS_OK; 833 } 834 835 NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname, 836 struct timespec *create_time, 837 struct timespec *access_time, 838 struct timespec *write_time, 839 struct timespec *change_time, 840 SMB_OFF_T *size, uint16 *mode, 841 SMB_INO_T *ino) 842 { 843 TALLOC_CTX *frame = talloc_stackframe(); 844 struct event_context *ev; 845 struct tevent_req *req; 846 NTSTATUS status = NT_STATUS_NO_MEMORY; 847 848 if (cli_has_async_calls(cli)) { 849 /* 850 * Can't use sync call while an async call is in flight 851 */ 852 status = NT_STATUS_INVALID_PARAMETER; 853 goto fail; 854 } 855 ev = event_context_init(frame); 856 if (ev == NULL) { 857 goto fail; 858 } 859 req = cli_qpathinfo2_send(frame, ev, cli, fname); 860 if (req == NULL) { 861 goto fail; 862 } 863 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 864 goto fail; 865 } 866 status = cli_qpathinfo2_recv(req, create_time, access_time, 867 write_time, change_time, size, mode, ino); 868 fail: 869 TALLOC_FREE(frame); 870 if (!NT_STATUS_IS_OK(status)) { 871 cli_set_error(cli, status); 872 } 873 return status; 800 874 } 801 875 … … 804 878 ****************************************************************************/ 805 879 806 bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname, 807 TALLOC_CTX *mem_ctx, 808 unsigned int *pnum_streams, 809 struct stream_struct **pstreams) 810 { 811 unsigned int data_len = 0; 812 unsigned int param_len = 0; 813 uint16 setup = TRANSACT2_QPATHINFO; 814 char *param; 815 char *rparam=NULL, *rdata=NULL; 816 char *p; 880 static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *data, 881 size_t data_len, 882 unsigned int *pnum_streams, 883 struct stream_struct **pstreams); 884 885 struct cli_qpathinfo_streams_state { 886 uint32_t num_data; 887 uint8_t *data; 888 }; 889 890 static void cli_qpathinfo_streams_done(struct tevent_req *subreq); 891 892 struct tevent_req *cli_qpathinfo_streams_send(TALLOC_CTX *mem_ctx, 893 struct tevent_context *ev, 894 struct cli_state *cli, 895 const char *fname) 896 { 897 struct tevent_req *req = NULL, *subreq = NULL; 898 struct cli_qpathinfo_streams_state *state = NULL; 899 900 req = tevent_req_create(mem_ctx, &state, 901 struct cli_qpathinfo_streams_state); 902 if (req == NULL) { 903 return NULL; 904 } 905 subreq = cli_qpathinfo_send(state, ev, cli, fname, 906 SMB_FILE_STREAM_INFORMATION, 907 0, cli->max_xmit); 908 if (tevent_req_nomem(subreq, req)) { 909 return tevent_req_post(req, ev); 910 } 911 tevent_req_set_callback(subreq, cli_qpathinfo_streams_done, req); 912 return req; 913 } 914 915 static void cli_qpathinfo_streams_done(struct tevent_req *subreq) 916 { 917 struct tevent_req *req = tevent_req_callback_data( 918 subreq, struct tevent_req); 919 struct cli_qpathinfo_streams_state *state = tevent_req_data( 920 req, struct cli_qpathinfo_streams_state); 921 NTSTATUS status; 922 923 status = cli_qpathinfo_recv(subreq, state, &state->data, 924 &state->num_data); 925 TALLOC_FREE(subreq); 926 if (!NT_STATUS_IS_OK(status)) { 927 tevent_req_nterror(req, status); 928 return; 929 } 930 tevent_req_done(req); 931 } 932 933 NTSTATUS cli_qpathinfo_streams_recv(struct tevent_req *req, 934 TALLOC_CTX *mem_ctx, 935 unsigned int *pnum_streams, 936 struct stream_struct **pstreams) 937 { 938 struct cli_qpathinfo_streams_state *state = tevent_req_data( 939 req, struct cli_qpathinfo_streams_state); 940 NTSTATUS status; 941 942 if (tevent_req_is_nterror(req, &status)) { 943 return status; 944 } 945 if (!parse_streams_blob(mem_ctx, state->data, state->num_data, 946 pnum_streams, pstreams)) { 947 return NT_STATUS_INVALID_NETWORK_RESPONSE; 948 } 949 return NT_STATUS_OK; 950 } 951 952 NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname, 953 TALLOC_CTX *mem_ctx, 954 unsigned int *pnum_streams, 955 struct stream_struct **pstreams) 956 { 957 TALLOC_CTX *frame = talloc_stackframe(); 958 struct event_context *ev; 959 struct tevent_req *req; 960 NTSTATUS status = NT_STATUS_NO_MEMORY; 961 962 if (cli_has_async_calls(cli)) { 963 /* 964 * Can't use sync call while an async call is in flight 965 */ 966 status = NT_STATUS_INVALID_PARAMETER; 967 goto fail; 968 } 969 ev = event_context_init(frame); 970 if (ev == NULL) { 971 goto fail; 972 } 973 req = cli_qpathinfo_streams_send(frame, ev, cli, fname); 974 if (req == NULL) { 975 goto fail; 976 } 977 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 978 goto fail; 979 } 980 status = cli_qpathinfo_streams_recv(req, mem_ctx, pnum_streams, 981 pstreams); 982 fail: 983 TALLOC_FREE(frame); 984 if (!NT_STATUS_IS_OK(status)) { 985 cli_set_error(cli, status); 986 } 987 return status; 988 } 989 990 static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata, 991 size_t data_len, 992 unsigned int *pnum_streams, 993 struct stream_struct **pstreams) 994 { 817 995 unsigned int num_streams; 818 996 struct stream_struct *streams; 819 997 unsigned int ofs; 820 size_t namelen = 2*(strlen(fname)+1);821 822 param = SMB_MALLOC_ARRAY(char, 6+namelen+2);823 if (param == NULL) {824 return false;825 }826 p = param;827 memset(p, 0, 6);828 SSVAL(p, 0, SMB_FILE_STREAM_INFORMATION);829 p += 6;830 p += clistr_push(cli, p, fname, namelen, STR_TERMINATE);831 832 param_len = PTR_DIFF(p, param);833 834 if (!cli_send_trans(cli, SMBtrans2,835 NULL, /* name */836 -1, 0, /* fid, flags */837 &setup, 1, 0, /* setup, len, max */838 param, param_len, 10, /* param, len, max */839 NULL, data_len, cli->max_xmit /* data, len, max */840 )) {841 return false;842 }843 844 if (!cli_receive_trans(cli, SMBtrans2,845 &rparam, ¶m_len,846 &rdata, &data_len)) {847 return false;848 }849 850 if (!rdata) {851 SAFE_FREE(rparam);852 return false;853 }854 998 855 999 num_streams = 0; … … 917 1061 } 918 1062 919 SAFE_FREE(rdata);920 SAFE_FREE(rparam);921 922 1063 *pnum_streams = num_streams; 923 1064 *pstreams = streams; … … 926 1067 fail: 927 1068 TALLOC_FREE(streams); 928 SAFE_FREE(rdata);929 SAFE_FREE(rparam);930 1069 return false; 931 1070 } … … 935 1074 ****************************************************************************/ 936 1075 937 bool cli_qfilename(struct cli_state *cli, uint16_t fnum, char *name, size_t namelen) 938 { 939 unsigned int data_len = 0; 940 unsigned int param_len = 0; 941 uint16 setup = TRANSACT2_QFILEINFO; 942 char param[4]; 943 char *rparam=NULL, *rdata=NULL; 944 945 param_len = 4; 946 SSVAL(param, 0, fnum); 947 SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO); 948 949 if (!cli_send_trans(cli, SMBtrans2, 950 NULL, /* name */ 951 -1, 0, /* fid, flags */ 952 &setup, 1, 0, /* setup, length, max */ 953 param, param_len, 2, /* param, length, max */ 954 NULL, data_len, cli->max_xmit /* data, length, max */ 955 )) { 956 return False; 957 } 958 959 if (!cli_receive_trans(cli, SMBtrans2, 960 &rparam, ¶m_len, 961 &rdata, &data_len)) { 962 return False; 963 } 964 965 if (!rdata || data_len < 4) { 966 SAFE_FREE(rparam); 967 SAFE_FREE(rdata); 968 return False; 1076 NTSTATUS cli_qfilename(struct cli_state *cli, uint16_t fnum, char *name, 1077 size_t namelen) 1078 { 1079 uint8_t *rdata; 1080 uint32_t num_rdata; 1081 NTSTATUS status; 1082 1083 status = cli_qfileinfo(talloc_tos(), cli, fnum, 1084 SMB_QUERY_FILE_NAME_INFO, 1085 4, cli->max_xmit, 1086 &rdata, &num_rdata); 1087 if (!NT_STATUS_IS_OK(status)) { 1088 return status; 969 1089 } 970 1090 971 1091 clistr_pull(cli->inbuf, name, rdata+4, namelen, IVAL(rdata, 0), 972 1092 STR_UNICODE); 973 974 SAFE_FREE(rparam); 975 SAFE_FREE(rdata); 976 977 return True; 1093 TALLOC_FREE(rdata); 1094 return NT_STATUS_OK; 978 1095 } 979 1096 … … 982 1099 ****************************************************************************/ 983 1100 984 bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum, 985 uint16 *mode, SMB_OFF_T *size, 986 struct timespec *create_time, 987 struct timespec *access_time, 988 struct timespec *write_time, 989 struct timespec *change_time, 990 SMB_INO_T *ino) 991 { 992 unsigned int data_len = 0; 993 unsigned int param_len = 0; 994 uint16 setup; 995 uint8_t param[4]; 996 uint8_t *rparam=NULL, *rdata=NULL; 1101 NTSTATUS cli_qfileinfo_basic(struct cli_state *cli, uint16_t fnum, 1102 uint16 *mode, SMB_OFF_T *size, 1103 struct timespec *create_time, 1104 struct timespec *access_time, 1105 struct timespec *write_time, 1106 struct timespec *change_time, 1107 SMB_INO_T *ino) 1108 { 1109 uint8_t *rdata; 1110 uint32_t num_rdata; 997 1111 NTSTATUS status; 998 1112 999 1113 /* if its a win95 server then fail this - win95 totally screws it 1000 1114 up */ 1001 if (cli->win95) return False; 1002 1003 param_len = 4; 1004 1005 SSVAL(param, 0, fnum); 1006 SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); 1007 1008 SSVAL(&setup, 0, TRANSACT2_QFILEINFO); 1009 1010 status = cli_trans(talloc_tos(), cli, SMBtrans2, 1011 NULL, -1, 0, 0, /* name, fid, function, flags */ 1012 &setup, 1, 0, /* setup, length, max */ 1013 param, param_len, 2, /* param, length, max */ 1014 NULL, 0, MIN(cli->max_xmit, 0xffff), /* data, length, max */ 1015 NULL, NULL, /* rsetup, length */ 1016 &rparam, ¶m_len, /* rparam, length */ 1017 &rdata, &data_len); 1018 1115 if (cli->win95) { 1116 return NT_STATUS_NOT_SUPPORTED; 1117 } 1118 1119 status = cli_qfileinfo(talloc_tos(), cli, fnum, 1120 SMB_QUERY_FILE_ALL_INFO, 1121 68, MIN(cli->max_xmit, 0xffff), 1122 &rdata, &num_rdata); 1019 1123 if (!NT_STATUS_IS_OK(status)) { 1020 return false; 1021 } 1022 1023 if (!rdata || data_len < 68) { 1024 return False; 1124 return status; 1025 1125 } 1026 1126 … … 1048 1148 1049 1149 TALLOC_FREE(rdata); 1050 TALLOC_FREE(rparam); 1051 return True; 1150 return NT_STATUS_OK; 1052 1151 } 1053 1152 … … 1056 1155 ****************************************************************************/ 1057 1156 1058 bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, 1059 SMB_STRUCT_STAT *sbuf, uint32 *attributes ) 1060 { 1061 unsigned int param_len = 0; 1062 unsigned int data_len = 0; 1063 uint16 setup = TRANSACT2_QPATHINFO; 1064 char *param; 1065 char *rparam=NULL, *rdata=NULL; 1066 char *p; 1067 char *path; 1068 int len; 1069 size_t nlen; 1157 struct cli_qpathinfo_basic_state { 1158 uint32_t num_data; 1159 uint8_t *data; 1160 }; 1161 1162 static void cli_qpathinfo_basic_done(struct tevent_req *subreq); 1163 1164 struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx, 1165 struct event_context *ev, 1166 struct cli_state *cli, 1167 const char *fname) 1168 { 1169 struct tevent_req *req = NULL, *subreq = NULL; 1170 struct cli_qpathinfo_basic_state *state = NULL; 1171 1172 req = tevent_req_create(mem_ctx, &state, 1173 struct cli_qpathinfo_basic_state); 1174 if (req == NULL) { 1175 return NULL; 1176 } 1177 subreq = cli_qpathinfo_send(state, ev, cli, fname, 1178 SMB_QUERY_FILE_BASIC_INFO, 1179 36, cli->max_xmit); 1180 if (tevent_req_nomem(subreq, req)) { 1181 return tevent_req_post(req, ev); 1182 } 1183 tevent_req_set_callback(subreq, cli_qpathinfo_basic_done, req); 1184 return req; 1185 } 1186 1187 static void cli_qpathinfo_basic_done(struct tevent_req *subreq) 1188 { 1189 struct tevent_req *req = tevent_req_callback_data( 1190 subreq, struct tevent_req); 1191 struct cli_qpathinfo_basic_state *state = tevent_req_data( 1192 req, struct cli_qpathinfo_basic_state); 1193 NTSTATUS status; 1194 1195 status = cli_qpathinfo_recv(subreq, state, &state->data, 1196 &state->num_data); 1197 TALLOC_FREE(subreq); 1198 if (!NT_STATUS_IS_OK(status)) { 1199 tevent_req_nterror(req, status); 1200 return; 1201 } 1202 tevent_req_done(req); 1203 } 1204 1205 NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req, 1206 SMB_STRUCT_STAT *sbuf, uint32 *attributes) 1207 { 1208 struct cli_qpathinfo_basic_state *state = tevent_req_data( 1209 req, struct cli_qpathinfo_basic_state); 1210 NTSTATUS status; 1211 1212 if (tevent_req_is_nterror(req, &status)) { 1213 return status; 1214 } 1215 1216 sbuf->st_ex_atime = interpret_long_date((char *)state->data+8); 1217 sbuf->st_ex_mtime = interpret_long_date((char *)state->data+16); 1218 sbuf->st_ex_ctime = interpret_long_date((char *)state->data+24); 1219 *attributes = IVAL(state->data, 32); 1220 return NT_STATUS_OK; 1221 } 1222 1223 NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name, 1224 SMB_STRUCT_STAT *sbuf, uint32 *attributes) 1225 { 1070 1226 TALLOC_CTX *frame = talloc_stackframe(); 1071 1072 path = talloc_strdup(frame, name); 1073 if (!path) { 1074 TALLOC_FREE(frame); 1075 return false; 1076 } 1077 /* cleanup */ 1078 1079 len = strlen(path); 1080 if ( path[len-1] == '\\' || path[len-1] == '/') { 1081 path[len-1] = '\0'; 1082 } 1083 nlen = 2*(strlen(path)+1); 1084 1085 param = TALLOC_ARRAY(frame,char,6+nlen+2); 1086 if (!param) { 1087 return false; 1088 } 1089 p = param; 1090 memset(param, '\0', 6); 1091 1092 SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO); 1093 p += 6; 1094 p += clistr_push(cli, p, path, nlen, STR_TERMINATE); 1095 param_len = PTR_DIFF(p, param); 1096 1097 1098 if (!cli_send_trans(cli, SMBtrans2, 1099 NULL, /* name */ 1100 -1, 0, /* fid, flags */ 1101 &setup, 1, 0, /* setup, length, max */ 1102 param, param_len, 2, /* param, length, max */ 1103 NULL, 0, cli->max_xmit /* data, length, max */ 1104 )) { 1105 TALLOC_FREE(frame); 1106 return False; 1107 } 1108 1227 struct event_context *ev; 1228 struct tevent_req *req; 1229 NTSTATUS status = NT_STATUS_NO_MEMORY; 1230 1231 if (cli_has_async_calls(cli)) { 1232 /* 1233 * Can't use sync call while an async call is in flight 1234 */ 1235 status = NT_STATUS_INVALID_PARAMETER; 1236 goto fail; 1237 } 1238 ev = event_context_init(frame); 1239 if (ev == NULL) { 1240 goto fail; 1241 } 1242 req = cli_qpathinfo_basic_send(frame, ev, cli, name); 1243 if (req == NULL) { 1244 goto fail; 1245 } 1246 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1247 goto fail; 1248 } 1249 status = cli_qpathinfo_basic_recv(req, sbuf, attributes); 1250 fail: 1109 1251 TALLOC_FREE(frame); 1110 1111 if (!cli_receive_trans(cli, SMBtrans2, 1112 &rparam, ¶m_len, 1113 &rdata, &data_len)) { 1114 return False; 1115 } 1116 1117 if (data_len < 36) { 1118 SAFE_FREE(rdata); 1119 SAFE_FREE(rparam); 1120 return False; 1121 } 1122 1123 sbuf->st_ex_atime = interpret_long_date( rdata+8 ); /* Access time. */ 1124 sbuf->st_ex_mtime = interpret_long_date( rdata+16 ); /* Write time. */ 1125 sbuf->st_ex_ctime = interpret_long_date( rdata+24 ); /* Change time. */ 1126 1127 *attributes = IVAL( rdata, 32 ); 1128 1129 SAFE_FREE(rparam); 1130 SAFE_FREE(rdata); 1131 1132 return True; 1133 } 1134 1135 /**************************************************************************** 1136 Send a qfileinfo call. 1137 ****************************************************************************/ 1138 1139 bool cli_qfileinfo_test(struct cli_state *cli, uint16_t fnum, int level, char **poutdata, uint32 *poutlen) 1140 { 1141 unsigned int data_len = 0; 1142 unsigned int param_len = 0; 1143 uint16 setup = TRANSACT2_QFILEINFO; 1144 char param[4]; 1145 char *rparam=NULL, *rdata=NULL; 1146 1147 *poutdata = NULL; 1148 *poutlen = 0; 1149 1150 /* if its a win95 server then fail this - win95 totally screws it 1151 up */ 1152 if (cli->win95) 1153 return False; 1154 1155 param_len = 4; 1156 1157 SSVAL(param, 0, fnum); 1158 SSVAL(param, 2, level); 1159 1160 if (!cli_send_trans(cli, SMBtrans2, 1161 NULL, /* name */ 1162 -1, 0, /* fid, flags */ 1163 &setup, 1, 0, /* setup, length, max */ 1164 param, param_len, 2, /* param, length, max */ 1165 NULL, data_len, cli->max_xmit /* data, length, max */ 1166 )) { 1167 return False; 1168 } 1169 1170 if (!cli_receive_trans(cli, SMBtrans2, 1171 &rparam, ¶m_len, 1172 &rdata, &data_len)) { 1173 return False; 1174 } 1175 1176 *poutdata = (char *)memdup(rdata, data_len); 1177 if (!*poutdata) { 1178 SAFE_FREE(rdata); 1179 SAFE_FREE(rparam); 1180 return False; 1181 } 1182 1183 *poutlen = data_len; 1184 1185 SAFE_FREE(rdata); 1186 SAFE_FREE(rparam); 1187 return True; 1252 if (!NT_STATUS_IS_OK(status)) { 1253 cli_set_error(cli, status); 1254 } 1255 return status; 1188 1256 } 1189 1257 … … 1194 1262 NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) 1195 1263 { 1196 unsigned int data_len = 0; 1197 unsigned int param_len = 0; 1198 uint16 setup = TRANSACT2_QPATHINFO; 1199 char *param; 1200 char *rparam=NULL, *rdata=NULL; 1201 int count=8; 1202 char *p; 1203 bool ret; 1264 uint8_t *rdata; 1265 uint32_t num_rdata; 1204 1266 unsigned int len; 1205 size_t nlen = 2*(strlen(fname)+1); 1206 1207 param = SMB_MALLOC_ARRAY(char, 6+nlen+2); 1208 if (!param) { 1267 char *converted = NULL; 1268 size_t converted_size = 0; 1269 NTSTATUS status; 1270 1271 status = cli_qpathinfo(talloc_tos(), cli, fname, 1272 SMB_QUERY_FILE_ALT_NAME_INFO, 1273 4, cli->max_xmit, &rdata, &num_rdata); 1274 if (!NT_STATUS_IS_OK(status)) { 1275 return status; 1276 } 1277 1278 len = IVAL(rdata, 0); 1279 1280 if (len > num_rdata - 4) { 1281 return NT_STATUS_INVALID_NETWORK_RESPONSE; 1282 } 1283 1284 /* The returned data is a pushed string, not raw data. */ 1285 if (!convert_string_talloc(talloc_tos(), 1286 cli_ucs2(cli) ? CH_UTF16LE : CH_DOS, 1287 CH_UNIX, 1288 rdata + 4, 1289 len, 1290 &converted, 1291 &converted_size, 1292 true)) { 1209 1293 return NT_STATUS_NO_MEMORY; 1210 1294 } 1211 p = param; 1212 memset(param, '\0', 6); 1213 SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO); 1214 p += 6; 1215 p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); 1216 param_len = PTR_DIFF(p, param); 1217 1218 do { 1219 ret = (cli_send_trans(cli, SMBtrans2, 1220 NULL, /* Name */ 1221 -1, 0, /* fid, flags */ 1222 &setup, 1, 0, /* setup, length, max */ 1223 param, param_len, 10, /* param, length, max */ 1224 NULL, data_len, cli->max_xmit /* data, length, max */ 1225 ) && 1226 cli_receive_trans(cli, SMBtrans2, 1227 &rparam, ¶m_len, 1228 &rdata, &data_len)); 1229 if (!ret && cli_is_dos_error(cli)) { 1230 /* we need to work around a Win95 bug - sometimes 1231 it gives ERRSRV/ERRerror temprarily */ 1232 uint8 eclass; 1233 uint32 ecode; 1234 cli_dos_error(cli, &eclass, &ecode); 1235 if (eclass != ERRSRV || ecode != ERRerror) break; 1236 smb_msleep(100); 1237 } 1238 } while (count-- && ret==False); 1239 1240 SAFE_FREE(param); 1241 1242 if (!ret || !rdata || data_len < 4) { 1243 return NT_STATUS_UNSUCCESSFUL; 1244 } 1245 1246 len = IVAL(rdata, 0); 1247 1248 if (len > data_len - 4) { 1249 return NT_STATUS_INVALID_NETWORK_RESPONSE; 1250 } 1251 1252 clistr_pull(cli->inbuf, alt_name, rdata+4, sizeof(fstring), len, 1253 STR_UNICODE); 1254 1255 SAFE_FREE(rdata); 1256 SAFE_FREE(rparam); 1295 fstrcpy(alt_name, converted); 1296 1297 TALLOC_FREE(converted); 1298 TALLOC_FREE(rdata); 1257 1299 1258 1300 return NT_STATUS_OK; -
vendor/current/source3/libsmb/clirap2.c
r597 r740 77 77 78 78 #include "includes.h" 79 #include "libsmb/libsmb.h" 80 #include "../librpc/gen_ndr/rap.h" 81 #include "../librpc/gen_ndr/svcctl.h" 82 #include "libsmb/clirap.h" 79 83 80 84 #define WORDSIZE 2 … … 285 289 ****************************************************************************/ 286 290 287 int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 *grinfo)291 int cli_NetGroupAdd(struct cli_state *cli, struct rap_group_info_1 *grinfo) 288 292 { 289 293 char *rparam = NULL; … … 321 325 322 326 p = data; 323 PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN);327 PUTSTRINGF(p, (const char *)grinfo->group_name, RAP_GROUPNAME_LEN); 324 328 PUTBYTE(p, 0); /* pad byte 0 */ 325 329 PUTSTRINGP(p, grinfo->comment, data, soffset); … … 831 835 ****************************************************************************/ 832 836 833 int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo )837 int cli_NetUserAdd(struct cli_state *cli, struct rap_user_info_1 * userinfo ) 834 838 { 835 839 char *rparam = NULL; … … 864 868 PUTWORD(p, 0); /* pwencrypt */ 865 869 if(userinfo->passwrd) 866 PUTWORD(p,MIN(strlen( userinfo->passwrd), RAP_UPASSWD_LEN));870 PUTWORD(p,MIN(strlen((const char *)userinfo->passwrd), RAP_UPASSWD_LEN)); 867 871 else 868 872 PUTWORD(p, 0); /* password length */ … … 871 875 memset(data, '\0', soffset); 872 876 873 PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN);877 PUTSTRINGF(p, (const char *)userinfo->user_name, RAP_USERNAME_LEN); 874 878 PUTBYTE(p, 0); /* pad byte 0 */ 875 PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN);879 PUTSTRINGF(p, (const char *)userinfo->passwrd, RAP_UPASSWD_LEN); 876 880 PUTDWORD(p, 0); /* pw age - n.a. on user add */ 877 881 PUTWORD(p, userinfo->priv); … … 1334 1338 ****************************************************************************/ 1335 1339 1336 int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo )1340 int cli_NetShareAdd(struct cli_state *cli, struct rap_share_info_2 * sinfo ) 1337 1341 { 1338 1342 char *rparam = NULL; … … 1366 1370 1367 1371 p = data; 1368 PUTSTRINGF(p, sinfo->share_name, RAP_SHARENAME_LEN);1372 PUTSTRINGF(p, (const char *)sinfo->share_name, RAP_SHARENAME_LEN); 1369 1373 PUTBYTE(p, 0); /* pad byte 0 */ 1370 1374 … … 1375 1379 PUTWORD(p, sinfo->active_users); 1376 1380 PUTSTRINGP(p, sinfo->path, data, soffset); 1377 PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN);1381 PUTSTRINGF(p, (const char *)sinfo->password, RAP_SPASSWD_LEN); 1378 1382 SCVAL(p,-1,0x0A); /* required 0x0A at end of password */ 1379 1383 … … 1900 1904 int cli_NetPrintQEnum(struct cli_state *cli, 1901 1905 void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), 1902 void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,u int_t,uint_t,const char*))1906 void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,unsigned int,unsigned int,const char*)) 1903 1907 { 1904 1908 char param[WORDSIZE /* api number */ … … 2076 2080 int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, 2077 2081 void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), 2078 void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,u int_t,uint_t,const char*))2082 void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,unsigned int,unsigned int,const char*)) 2079 2083 { 2080 2084 char param[WORDSIZE /* api number */ … … 2336 2340 ****************************************************************************/ 2337 2341 2338 int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, uint16, uint16, u int_t, uint_t, uint_t, char *))2342 int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, uint16, uint16, unsigned int, unsigned int, unsigned int, char *)) 2339 2343 { 2340 2344 char param[WORDSIZE /* api number */ … … 2436 2440 2437 2441 int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, 2438 void (*fn)(const char *, const char *, uint16, uint16, uint16, u int_t, uint_t, uint_t, const char *))2442 void (*fn)(const char *, const char *, uint16, uint16, uint16, unsigned int, unsigned int, unsigned int, const char *)) 2439 2443 { 2440 2444 char param[WORDSIZE /* api number */ -
vendor/current/source3/libsmb/clireadwrite.c
r594 r740 19 19 20 20 #include "includes.h" 21 #include "libsmb/libsmb.h" 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "async_smb.h" 24 #include "trans2.h" 21 25 22 26 /**************************************************************************** … … 25 29 static size_t cli_read_max_bufsize(struct cli_state *cli) 26 30 { 31 size_t data_offset = smb_size - 4; 32 size_t wct = 12; 33 34 size_t useable_space; 35 27 36 if (!client_is_signing_on(cli) && !cli_encryption_on(cli) 28 && (cli-> posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {37 && (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { 29 38 return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; 30 39 } … … 34 43 : CLI_WINDOWS_MAX_LARGE_READX_SIZE; 35 44 } 36 return (cli->max_xmit - (smb_size+32)) & ~1023; 45 46 data_offset += wct * sizeof(uint16_t); 47 data_offset += 1; /* pad */ 48 49 useable_space = cli->max_xmit - data_offset; 50 51 return useable_space; 37 52 } 38 53 … … 40 55 Calculate the recommended write buffer size 41 56 ****************************************************************************/ 42 static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode) 57 static size_t cli_write_max_bufsize(struct cli_state *cli, 58 uint16_t write_mode, 59 uint8_t wct) 43 60 { 44 61 if (write_mode == 0 && 45 62 !client_is_signing_on(cli) && 46 63 !cli_encryption_on(cli) && 47 (cli-> posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) &&64 (cli->server_posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) && 48 65 (cli->capabilities & CAP_LARGE_FILES)) { 49 66 /* Only do massive writes if we can do them direct … … 59 76 || client_is_signing_on(cli) 60 77 || strequal(cli->dev, "LPT1:")) { 61 62 /* 63 * Printer devices are restricted to max_xmit writesize in 64 * Vista and XPSP3 as are signing connections. 65 */ 66 67 return (cli->max_xmit - (smb_size+32)) & ~1023; 78 size_t data_offset = smb_size - 4; 79 size_t useable_space; 80 81 data_offset += wct * sizeof(uint16_t); 82 data_offset += 1; /* pad */ 83 84 useable_space = cli->max_xmit - data_offset; 85 86 return useable_space; 68 87 } 69 88 … … 89 108 struct tevent_req *req, *subreq; 90 109 struct cli_read_andx_state *state; 91 bool bigoffset = False;92 110 uint8_t wct = 10; 93 111 … … 117 135 118 136 if ((uint64_t)offset >> 32) { 119 bigoffset = true;120 137 SIVAL(state->vwv + 10, 0, 121 138 (((uint64_t)offset)>>32) & 0xffffffff); … … 149 166 150 167 status = cli_smb_req_send(subreq); 151 if (!NT_STATUS_IS_OK(status)) { 152 tevent_req_nterror(req, status); 168 if (tevent_req_nterror(req, status)) { 153 169 return tevent_req_post(req, ev); 154 170 } … … 168 184 uint8_t *bytes; 169 185 170 state->status = cli_smb_recv(subreq, 12, &wct, &vwv, &num_bytes, 171 &bytes); 186 state->status = cli_smb_recv(subreq, state, &inbuf, 12, &wct, &vwv, 187 &num_bytes, &bytes); 188 TALLOC_FREE(subreq); 172 189 if (NT_STATUS_IS_ERR(state->status)) { 173 190 tevent_req_nterror(req, state->status); … … 197 214 } 198 215 199 inbuf = cli_smb_inbuf(subreq);200 216 state->buf = (uint8_t *)smb_base(inbuf) + SVAL(vwv+6, 0); 201 217 … … 283 299 284 300 status = cli_read_andx_recv(subreq, &received, &buf); 285 if (!NT_STATUS_IS_OK(status)) { 286 tevent_req_nterror(req, status); 301 if (tevent_req_nterror(req, status)) { 287 302 return; 288 303 } … … 411 426 char *result; 412 427 413 result = tevent_req_ print(mem_ctx, req);428 result = tevent_req_default_print(req, mem_ctx); 414 429 if (result == NULL) { 415 430 return NULL; … … 570 585 status = state->sink((char *)top_subreq->buf, 571 586 top_subreq->received, state->priv); 572 if (!NT_STATUS_IS_OK(status)) { 573 tevent_req_nterror(state->req, status); 587 if (tevent_req_nterror(state->req, status)) { 574 588 return; 575 589 } … … 697 711 698 712 /**************************************************************************** 699 Issue a single SMBwrite and don't wait for a reply.700 ****************************************************************************/701 702 static bool cli_issue_write(struct cli_state *cli,703 uint16_t fnum,704 off_t offset,705 uint16 mode,706 const char *buf,707 size_t size)708 {709 char *p;710 bool large_writex = false;711 /* We can only do direct writes if not signing and not encrypting. */712 bool direct_writes = !client_is_signing_on(cli) && !cli_encryption_on(cli);713 714 if (!direct_writes && size + 1 > cli->bufsize) {715 cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024);716 if (!cli->outbuf) {717 return False;718 }719 cli->inbuf = (char *)SMB_REALLOC(cli->inbuf, size + 1024);720 if (cli->inbuf == NULL) {721 SAFE_FREE(cli->outbuf);722 return False;723 }724 cli->bufsize = size + 1024;725 }726 727 memset(cli->outbuf,'\0',smb_size);728 memset(cli->inbuf,'\0',smb_size);729 730 if (cli->capabilities & CAP_LARGE_FILES) {731 large_writex = True;732 }733 734 if (large_writex) {735 cli_set_message(cli->outbuf,14,0,True);736 } else {737 cli_set_message(cli->outbuf,12,0,True);738 }739 740 SCVAL(cli->outbuf,smb_com,SMBwriteX);741 SSVAL(cli->outbuf,smb_tid,cli->cnum);742 cli_setup_packet(cli);743 744 SCVAL(cli->outbuf,smb_vwv0,0xFF);745 SSVAL(cli->outbuf,smb_vwv2,fnum);746 747 SIVAL(cli->outbuf,smb_vwv3,offset);748 SIVAL(cli->outbuf,smb_vwv5,0);749 SSVAL(cli->outbuf,smb_vwv7,mode);750 751 SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0);752 /*753 * According to CIFS-TR-1p00, this following field should only754 * be set if CAP_LARGE_WRITEX is set. We should check this755 * locally. However, this check might already have been756 * done by our callers.757 */758 SSVAL(cli->outbuf,smb_vwv9,(size>>16));759 SSVAL(cli->outbuf,smb_vwv10,size);760 /* +1 is pad byte. */761 SSVAL(cli->outbuf,smb_vwv11,762 smb_buf(cli->outbuf) - smb_base(cli->outbuf) + 1);763 764 if (large_writex) {765 SIVAL(cli->outbuf,smb_vwv12,(((uint64_t)offset)>>32) & 0xffffffff);766 }767 768 p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11) -1;769 *p++ = '\0'; /* pad byte. */770 if (!direct_writes) {771 memcpy(p, buf, size);772 }773 if (size > 0x1FFFF) {774 /* This is a POSIX 14 word large write. */775 set_message_bcc(cli->outbuf, 0); /* Set bcc to zero. */776 _smb_setlen_large(cli->outbuf,smb_size + 28 + 1 /* pad */ + size - 4);777 } else {778 cli_setup_bcc(cli, p+size);779 }780 781 show_msg(cli->outbuf);782 if (direct_writes) {783 /* For direct writes we now need to write the data784 * directly out of buf. */785 return cli_send_smb_direct_writeX(cli, buf, size);786 } else {787 return cli_send_smb(cli);788 }789 }790 791 /****************************************************************************792 write to a file793 write_mode: 0x0001 disallow write cacheing794 0x0002 return bytes remaining795 0x0004 use raw named pipe protocol796 0x0008 start of message mode named pipe protocol797 ****************************************************************************/798 799 ssize_t cli_write(struct cli_state *cli,800 uint16_t fnum, uint16 write_mode,801 const char *buf, off_t offset, size_t size)802 {803 ssize_t bwritten = 0;804 unsigned int issued = 0;805 unsigned int received = 0;806 int mpx = 1;807 size_t writesize;808 int blocks;809 810 if(cli->max_mux > 1) {811 mpx = cli->max_mux-1;812 } else {813 mpx = 1;814 }815 816 writesize = cli_write_max_bufsize(cli, write_mode);817 818 blocks = (size + (writesize-1)) / writesize;819 820 while (received < blocks) {821 822 while ((issued - received < mpx) && (issued < blocks)) {823 ssize_t bsent = issued * writesize;824 ssize_t size1 = MIN(writesize, size - bsent);825 826 if (!cli_issue_write(cli, fnum, offset + bsent,827 write_mode,828 buf + bsent,829 size1))830 return -1;831 issued++;832 }833 834 if (!cli_receive_smb(cli)) {835 return bwritten;836 }837 838 received++;839 840 if (cli_is_error(cli))841 break;842 843 bwritten += SVAL(cli->inbuf, smb_vwv2);844 if (writesize > 0xFFFF) {845 bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16);846 }847 }848 849 while (received < issued && cli_receive_smb(cli)) {850 received++;851 }852 853 return bwritten;854 }855 856 /****************************************************************************857 713 write to a file using a SMBwrite and not bypassing 0 byte writes 858 714 ****************************************************************************/ 859 715 860 ssize_t cli_smbwrite(struct cli_state *cli,861 uint16_t fnum, char *buf, off_t offset, size_t size1)862 { 863 char *p;716 NTSTATUS cli_smbwrite(struct cli_state *cli, uint16_t fnum, char *buf, 717 off_t offset, size_t size1, size_t *ptotal) 718 { 719 uint8_t *bytes; 864 720 ssize_t total = 0; 721 722 /* 723 * 3 bytes prefix 724 */ 725 726 bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 3); 727 if (bytes == NULL) { 728 return NT_STATUS_NO_MEMORY; 729 } 730 bytes[0] = 1; 865 731 866 732 do { 867 733 size_t size = MIN(size1, cli->max_xmit - 48); 868 869 memset(cli->outbuf,'\0',smb_size); 870 memset(cli->inbuf,'\0',smb_size); 871 872 cli_set_message(cli->outbuf,5, 0,True); 873 874 SCVAL(cli->outbuf,smb_com,SMBwrite); 875 SSVAL(cli->outbuf,smb_tid,cli->cnum); 876 cli_setup_packet(cli); 877 878 SSVAL(cli->outbuf,smb_vwv0,fnum); 879 SSVAL(cli->outbuf,smb_vwv1,size); 880 SIVAL(cli->outbuf,smb_vwv2,offset); 881 SSVAL(cli->outbuf,smb_vwv4,0); 882 883 p = smb_buf(cli->outbuf); 884 *p++ = 1; 885 SSVAL(p, 0, size); p += 2; 886 memcpy(p, buf + total, size); p += size; 887 888 cli_setup_bcc(cli, p); 889 890 if (!cli_send_smb(cli)) 891 return -1; 892 893 if (!cli_receive_smb(cli)) 894 return -1; 895 896 if (cli_is_error(cli)) 897 return -1; 898 899 size = SVAL(cli->inbuf,smb_vwv0); 900 if (size == 0) 734 struct tevent_req *req; 735 uint16_t vwv[5]; 736 uint16_t *ret_vwv; 737 NTSTATUS status; 738 739 SSVAL(vwv+0, 0, fnum); 740 SSVAL(vwv+1, 0, size); 741 SIVAL(vwv+2, 0, offset); 742 SSVAL(vwv+4, 0, 0); 743 744 bytes = TALLOC_REALLOC_ARRAY(talloc_tos(), bytes, uint8_t, 745 size+3); 746 if (bytes == NULL) { 747 return NT_STATUS_NO_MEMORY; 748 } 749 SSVAL(bytes, 1, size); 750 memcpy(bytes + 3, buf + total, size); 751 752 status = cli_smb(talloc_tos(), cli, SMBwrite, 0, 5, vwv, 753 size+3, bytes, &req, 1, NULL, &ret_vwv, 754 NULL, NULL); 755 if (!NT_STATUS_IS_OK(status)) { 756 TALLOC_FREE(bytes); 757 return status; 758 } 759 760 size = SVAL(ret_vwv+0, 0); 761 TALLOC_FREE(req); 762 if (size == 0) { 901 763 break; 902 764 } 903 765 size1 -= size; 904 766 total += size; … … 907 769 } while (size1); 908 770 909 return total; 771 TALLOC_FREE(bytes); 772 773 if (ptotal != NULL) { 774 *ptotal = total; 775 } 776 return NT_STATUS_OK; 910 777 } 911 778 … … 937 804 bool bigoffset = ((cli->capabilities & CAP_LARGE_FILES) != 0); 938 805 uint8_t wct = bigoffset ? 14 : 12; 939 size_t max_write = cli_write_max_bufsize(cli, mode );806 size_t max_write = cli_write_max_bufsize(cli, mode, wct); 940 807 uint16_t *vwv; 941 808 … … 1003 870 1004 871 status = cli_smb_req_send(subreq); 1005 if (!NT_STATUS_IS_OK(status)) { 1006 tevent_req_nterror(req, status); 872 if (tevent_req_nterror(req, status)) { 1007 873 return tevent_req_post(req, ev); 1008 874 } … … 1018 884 uint8_t wct; 1019 885 uint16_t *vwv; 1020 NTSTATUS status; 1021 1022 status = cli_smb_recv(subreq, 6, &wct, &vwv, NULL, NULL); 886 uint8_t *inbuf; 887 NTSTATUS status; 888 889 status = cli_smb_recv(subreq, state, &inbuf, 6, &wct, &vwv, 890 NULL, NULL); 891 TALLOC_FREE(subreq); 1023 892 if (NT_STATUS_IS_ERR(status)) { 1024 TALLOC_FREE(subreq);1025 893 tevent_req_nterror(req, status); 1026 894 return; … … 1102 970 status = cli_write_andx_recv(subreq, &written); 1103 971 TALLOC_FREE(subreq); 1104 if (!NT_STATUS_IS_OK(status)) { 1105 tevent_req_nterror(req, status); 972 if (tevent_req_nterror(req, status)) { 1106 973 return; 1107 974 } … … 1131 998 } 1132 999 1133 static NTSTATUS cli_writeall_recv(struct tevent_req *req) 1134 { 1135 return tevent_req_simple_recv_ntstatus(req); 1000 static NTSTATUS cli_writeall_recv(struct tevent_req *req, 1001 size_t *pwritten) 1002 { 1003 struct cli_writeall_state *state = tevent_req_data( 1004 req, struct cli_writeall_state); 1005 NTSTATUS status; 1006 1007 if (tevent_req_is_nterror(req, &status)) { 1008 return status; 1009 } 1010 if (pwritten != NULL) { 1011 *pwritten = state->written; 1012 } 1013 return NT_STATUS_OK; 1014 } 1015 1016 NTSTATUS cli_writeall(struct cli_state *cli, uint16_t fnum, uint16_t mode, 1017 const uint8_t *buf, off_t offset, size_t size, 1018 size_t *pwritten) 1019 { 1020 TALLOC_CTX *frame = talloc_stackframe(); 1021 struct event_context *ev; 1022 struct tevent_req *req; 1023 NTSTATUS status = NT_STATUS_NO_MEMORY; 1024 1025 if (cli_has_async_calls(cli)) { 1026 /* 1027 * Can't use sync call while an async call is in flight 1028 */ 1029 status = NT_STATUS_INVALID_PARAMETER; 1030 goto fail; 1031 } 1032 ev = event_context_init(frame); 1033 if (ev == NULL) { 1034 goto fail; 1035 } 1036 req = cli_writeall_send(frame, ev, cli, fnum, mode, buf, offset, size); 1037 if (req == NULL) { 1038 goto fail; 1039 } 1040 if (!tevent_req_poll(req, ev)) { 1041 status = map_nt_error_from_unix(errno); 1042 goto fail; 1043 } 1044 status = cli_writeall_recv(req, pwritten); 1045 fail: 1046 TALLOC_FREE(frame); 1047 if (!NT_STATUS_IS_OK(status)) { 1048 cli_set_error(cli, status); 1049 } 1050 return status; 1136 1051 } 1137 1052 … … 1245 1160 state->next_offset = start_offset; 1246 1161 1247 state->chunk_size = cli_write_max_bufsize(cli, mode );1162 state->chunk_size = cli_write_max_bufsize(cli, mode, 14); 1248 1163 1249 1164 if (window_size == 0) { … … 1298 1213 state->pending -= 1; 1299 1214 1300 status = cli_writeall_recv(subreq );1215 status = cli_writeall_recv(subreq, NULL); 1301 1216 TALLOC_FREE(subreq); 1302 1217 TALLOC_FREE(substate); 1303 if (!NT_STATUS_IS_OK(status)) { 1304 tevent_req_nterror(req, status); 1218 if (tevent_req_nterror(req, status)) { 1305 1219 return; 1306 1220 } -
vendor/current/source3/libsmb/clisecdesc.c
r414 r740 3 3 client security descriptor functions 4 4 Copyright (C) Andrew Tridgell 2000 5 5 6 6 This program is free software; you can redistribute it and/or modify 7 7 it under the terms of the GNU General Public License as published by 8 8 the Free Software Foundation; either version 3 of the License, or 9 9 (at your option) any later version. 10 10 11 11 This program is distributed in the hope that it will be useful, 12 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 GNU General Public License for more details. 15 15 16 16 You should have received a copy of the GNU General Public License 17 17 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 19 19 20 20 #include "includes.h" 21 #include "libsmb/libsmb.h" 21 22 22 23 /**************************************************************************** 23 24 query the security descriptor for a open file 24 25 ****************************************************************************/ 25 SEC_DESC *cli_query_secdesc(struct cli_state *cli, uint16_t fnum, 26 struct security_descriptor *cli_query_secdesc(struct cli_state *cli, uint16_t fnum, 26 27 TALLOC_CTX *mem_ctx) 27 28 { 28 29 uint8_t param[8]; 29 uint8_t *r param=NULL, *rdata=NULL;30 u nsigned int rparam_count=0,rdata_count=0;31 SEC_DESC*psd = NULL;30 uint8_t *rdata=NULL; 31 uint32_t rdata_count=0; 32 struct security_descriptor *psd = NULL; 32 33 NTSTATUS status; 33 34 … … 41 42 param, 8, 4, /* param, length, max */ 42 43 NULL, 0, 0x10000, /* data, length, max */ 43 NULL, NULL, /* rsetup, length */ 44 &rparam, &rparam_count, 45 &rdata, &rdata_count); 44 NULL, /* recv_flags2 */ 45 NULL, 0, NULL, /* rsetup, length */ 46 NULL, 0, NULL, 47 &rdata, 0, &rdata_count); 46 48 47 49 if (!NT_STATUS_IS_OK(status)) { … … 62 64 cleanup: 63 65 64 TALLOC_FREE(rparam);65 66 TALLOC_FREE(rdata); 66 67 … … 71 72 set the security descriptor for a open file 72 73 ****************************************************************************/ 73 bool cli_set_secdesc(struct cli_state *cli, uint16_t fnum, SEC_DESC *sd) 74 NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, 75 struct security_descriptor *sd) 74 76 { 75 char param[8]; 76 char *rparam=NULL, *rdata=NULL; 77 unsigned int rparam_count=0, rdata_count=0; 77 uint8_t param[8]; 78 78 uint32 sec_info = 0; 79 TALLOC_CTX *frame = talloc_stackframe();80 bool ret = False;81 79 uint8 *data; 82 80 size_t len; … … 87 85 DEBUG(10, ("marshall_sec_desc failed: %s\n", 88 86 nt_errstr(status))); 89 goto cleanup;87 return status; 90 88 } 91 89 … … 93 91 94 92 if (sd->dacl) 95 sec_info |= DACL_SECURITY_INFORMATION;93 sec_info |= SECINFO_DACL; 96 94 if (sd->owner_sid) 97 sec_info |= OWNER_SECURITY_INFORMATION;95 sec_info |= SECINFO_OWNER; 98 96 if (sd->group_sid) 99 sec_info |= GROUP_SECURITY_INFORMATION;97 sec_info |= SECINFO_GROUP; 100 98 SSVAL(param, 4, sec_info); 101 99 102 if (!cli_send_nt_trans(cli, 103 NT_TRANSACT_SET_SECURITY_DESC, 104 0, 105 NULL, 0, 0, 106 param, 8, 0, 107 (char *)data, len, 0)) { 108 DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); 109 goto cleanup; 100 status = cli_trans(talloc_tos(), cli, SMBnttrans, 101 NULL, -1, /* name, fid */ 102 NT_TRANSACT_SET_SECURITY_DESC, 0, 103 NULL, 0, 0, /* setup */ 104 param, 8, 0, /* param */ 105 data, len, 0, /* data */ 106 NULL, /* recv_flags2 */ 107 NULL, 0, NULL, /* rsetup */ 108 NULL, 0, NULL, /* rparam */ 109 NULL, 0, NULL); /* rdata */ 110 TALLOC_FREE(data); 111 if (!NT_STATUS_IS_OK(status)) { 112 DEBUG(1, ("Failed to send NT_TRANSACT_SET_SECURITY_DESC: %s\n", 113 nt_errstr(status))); 110 114 } 111 112 113 if (!cli_receive_nt_trans(cli, 114 &rparam, &rparam_count, 115 &rdata, &rdata_count)) { 116 DEBUG(1,("NT_TRANSACT_SET_SECURITY_DESC failed\n")); 117 goto cleanup; 118 } 119 120 ret = True; 121 122 cleanup: 123 124 SAFE_FREE(rparam); 125 SAFE_FREE(rdata); 126 127 TALLOC_FREE(frame); 128 129 return ret; 115 return status; 130 116 } -
vendor/current/source3/libsmb/clisigning.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "libsmb/libsmb.h" 24 #include "smb_signing.h" 23 25 24 26 bool cli_simple_set_signing(struct cli_state *cli, -
vendor/current/source3/libsmb/clispnego.c
r587 r740 5 5 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 6 6 Copyright (C) Luke Howard 2003 7 Copyright (C) Jeremy Allison 2010 7 8 8 9 This program is free software; you can redistribute it and/or modify … … 23 24 #include "../libcli/auth/spnego.h" 24 25 #include "smb_krb5.h" 25 26 /* 27 generate a negTokenInit packet given a GUID, a list of supported 28 OIDs (the mechanisms) and a principal name string 29 */ 30 DATA_BLOB spnego_gen_negTokenInit(char guid[16], 31 const char *OIDs[], 26 #include "../lib/util/asn1.h" 27 28 /* 29 generate a negTokenInit packet given a list of supported 30 OIDs (the mechanisms) a blob, and a principal name string 31 */ 32 33 DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx, 34 const char *OIDs[], 35 DATA_BLOB *psecblob, 32 36 const char *principal) 33 37 { … … 41 45 } 42 46 43 asn1_write(data, guid, 16);44 47 asn1_push_tag(data,ASN1_APPLICATION(0)); 45 48 asn1_write_OID(data,OID_SPNEGO); … … 55 58 asn1_pop_tag(data); 56 59 57 asn1_push_tag(data, ASN1_CONTEXT(3)); 58 asn1_push_tag(data, ASN1_SEQUENCE(0)); 59 asn1_push_tag(data, ASN1_CONTEXT(0)); 60 asn1_write_GeneralString(data,principal); 61 asn1_pop_tag(data); 62 asn1_pop_tag(data); 63 asn1_pop_tag(data); 60 if (psecblob && psecblob->length && psecblob->data) { 61 asn1_push_tag(data, ASN1_CONTEXT(2)); 62 asn1_write_OctetString(data,psecblob->data, 63 psecblob->length); 64 asn1_pop_tag(data); 65 } 66 67 if (principal) { 68 asn1_push_tag(data, ASN1_CONTEXT(3)); 69 asn1_push_tag(data, ASN1_SEQUENCE(0)); 70 asn1_push_tag(data, ASN1_CONTEXT(0)); 71 asn1_write_GeneralString(data,principal); 72 asn1_pop_tag(data); 73 asn1_pop_tag(data); 74 asn1_pop_tag(data); 75 } 64 76 65 77 asn1_pop_tag(data); … … 72 84 } 73 85 74 ret = data_blob(data->data, data->length); 75 asn1_free(data); 76 77 return ret; 78 } 79 80 /* 81 Generate a negTokenInit as used by the client side ... It has a mechType 82 (OID), and a mechToken (a security blob) ... 83 84 Really, we need to break out the NTLMSSP stuff as well, because it could be 85 raw in the packets! 86 */ 87 DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) 88 { 89 ASN1_DATA *data; 90 DATA_BLOB ret; 91 92 data = asn1_init(talloc_tos()); 93 if (data == NULL) { 94 return data_blob_null; 95 } 96 97 asn1_push_tag(data, ASN1_APPLICATION(0)); 98 asn1_write_OID(data,OID_SPNEGO); 99 asn1_push_tag(data, ASN1_CONTEXT(0)); 100 asn1_push_tag(data, ASN1_SEQUENCE(0)); 101 102 asn1_push_tag(data, ASN1_CONTEXT(0)); 103 asn1_push_tag(data, ASN1_SEQUENCE(0)); 104 asn1_write_OID(data, OID); 105 asn1_pop_tag(data); 106 asn1_pop_tag(data); 107 108 asn1_push_tag(data, ASN1_CONTEXT(2)); 109 asn1_write_OctetString(data,blob.data,blob.length); 110 asn1_pop_tag(data); 111 112 asn1_pop_tag(data); 113 asn1_pop_tag(data); 114 115 asn1_pop_tag(data); 116 117 if (data->has_error) { 118 DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs)); 119 } 120 121 ret = data_blob(data->data, data->length); 86 ret = data_blob_talloc(ctx, data->data, data->length); 122 87 asn1_free(data); 123 88 … … 129 94 OIDs (the mechanisms) and a principal name string 130 95 */ 131 bool spnego_parse_negTokenInit(DATA_BLOB blob, 96 bool spnego_parse_negTokenInit(TALLOC_CTX *ctx, 97 DATA_BLOB blob, 132 98 char *OIDs[ASN1_MAX_OIDS], 133 char **principal) 99 char **principal, 100 DATA_BLOB *secblob) 134 101 { 135 102 int i; … … 160 127 asn1_start_tag(data,ASN1_SEQUENCE(0)); 161 128 for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { 162 const char *oid_str = NULL; 163 asn1_read_OID(data,talloc_autofree_context(),&oid_str); 164 OIDs[i] = CONST_DISCARD(char *, oid_str); 129 asn1_read_OID(data,ctx, &OIDs[i]); 165 130 } 166 131 OIDs[i] = NULL; … … 168 133 asn1_end_tag(data); 169 134 170 *principal = NULL; 135 if (principal) { 136 *principal = NULL; 137 } 138 if (secblob) { 139 *secblob = data_blob_null; 140 } 171 141 172 142 /* … … 191 161 192 162 if (asn1_peek_tag(data, ASN1_CONTEXT(2))) { 163 DATA_BLOB sblob = data_blob_null; 193 164 /* mechToken [2] OCTET STRING OPTIONAL */ 194 DATA_BLOB token;195 165 asn1_start_tag(data, ASN1_CONTEXT(2)); 196 asn1_read_OctetString(data, talloc_autofree_context(), 197 &token); 198 asn1_end_tag(data); 199 /* Throw away the token - not used. */ 200 data_blob_free(&token); 166 asn1_read_OctetString(data, ctx, &sblob); 167 asn1_end_tag(data); 168 if (secblob) { 169 *secblob = sblob; 170 } else { 171 data_blob_free(&sblob); 172 } 201 173 } 202 174 203 175 if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { 176 char *princ = NULL; 204 177 /* mechListMIC [3] OCTET STRING OPTIONAL */ 205 178 asn1_start_tag(data, ASN1_CONTEXT(3)); 206 179 asn1_start_tag(data, ASN1_SEQUENCE(0)); 207 180 asn1_start_tag(data, ASN1_CONTEXT(0)); 208 asn1_read_GeneralString(data,talloc_autofree_context(), 209 principal); 210 asn1_end_tag(data); 211 asn1_end_tag(data); 212 asn1_end_tag(data); 181 asn1_read_GeneralString(data, ctx, &princ); 182 asn1_end_tag(data); 183 asn1_end_tag(data); 184 asn1_end_tag(data); 185 if (principal) { 186 *principal = princ; 187 } else { 188 TALLOC_FREE(princ); 189 } 213 190 } 214 191 … … 221 198 if (data->has_error) { 222 199 int j; 223 TALLOC_FREE(*principal); 200 if (principal) { 201 TALLOC_FREE(*principal); 202 } 203 if (secblob) { 204 data_blob_free(secblob); 205 } 224 206 for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { 225 207 TALLOC_FREE(OIDs[j]); … … 232 214 233 215 /* 234 generate a negTokenTarg packet given a list of OIDs and a security blob235 */236 DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob)237 {238 int i;239 ASN1_DATA *data;240 DATA_BLOB ret;241 242 data = asn1_init(talloc_tos());243 if (data == NULL) {244 return data_blob_null;245 }246 247 asn1_push_tag(data, ASN1_APPLICATION(0));248 asn1_write_OID(data,OID_SPNEGO);249 asn1_push_tag(data, ASN1_CONTEXT(0));250 asn1_push_tag(data, ASN1_SEQUENCE(0));251 252 asn1_push_tag(data, ASN1_CONTEXT(0));253 asn1_push_tag(data, ASN1_SEQUENCE(0));254 for (i=0; OIDs[i]; i++) {255 asn1_write_OID(data,OIDs[i]);256 }257 asn1_pop_tag(data);258 asn1_pop_tag(data);259 260 asn1_push_tag(data, ASN1_CONTEXT(2));261 asn1_write_OctetString(data,blob.data,blob.length);262 asn1_pop_tag(data);263 264 asn1_pop_tag(data);265 asn1_pop_tag(data);266 267 asn1_pop_tag(data);268 269 if (data->has_error) {270 DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data->ofs));271 }272 273 ret = data_blob(data->data, data->length);274 asn1_free(data);275 276 return ret;277 }278 279 /*280 parse a negTokenTarg packet giving a list of OIDs and a security blob281 */282 bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob)283 {284 int i;285 ASN1_DATA *data;286 287 data = asn1_init(talloc_tos());288 if (data == NULL) {289 return false;290 }291 292 asn1_load(data, blob);293 asn1_start_tag(data, ASN1_APPLICATION(0));294 asn1_check_OID(data,OID_SPNEGO);295 asn1_start_tag(data, ASN1_CONTEXT(0));296 asn1_start_tag(data, ASN1_SEQUENCE(0));297 298 asn1_start_tag(data, ASN1_CONTEXT(0));299 asn1_start_tag(data, ASN1_SEQUENCE(0));300 for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {301 const char *oid_str = NULL;302 asn1_read_OID(data,talloc_autofree_context(),&oid_str);303 OIDs[i] = CONST_DISCARD(char *, oid_str);304 }305 OIDs[i] = NULL;306 asn1_end_tag(data);307 asn1_end_tag(data);308 309 /* Skip any optional req_flags that are sent per RFC 4178 */310 if (asn1_peek_tag(data, ASN1_CONTEXT(1))) {311 uint8 flags;312 313 asn1_start_tag(data, ASN1_CONTEXT(1));314 asn1_start_tag(data, ASN1_BIT_STRING);315 while (asn1_tag_remaining(data) > 0)316 asn1_read_uint8(data, &flags);317 asn1_end_tag(data);318 asn1_end_tag(data);319 }320 321 asn1_start_tag(data, ASN1_CONTEXT(2));322 asn1_read_OctetString(data,talloc_autofree_context(),secblob);323 asn1_end_tag(data);324 325 asn1_end_tag(data);326 asn1_end_tag(data);327 328 asn1_end_tag(data);329 330 if (data->has_error) {331 int j;332 data_blob_free(secblob);333 for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) {334 TALLOC_FREE(OIDs[j]);335 }336 DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data->ofs));337 asn1_free(data);338 return False;339 }340 341 asn1_free(data);342 return True;343 }344 345 /*346 216 generate a krb5 GSS-API wrapper packet given a ticket 347 217 */ 348 DATA_BLOB spnego_gen_krb5_wrap( const DATA_BLOB ticket, const uint8 tok_id[2])218 DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2]) 349 219 { 350 220 ASN1_DATA *data; … … 367 237 } 368 238 369 ret = data_blob (data->data, data->length);239 ret = data_blob_talloc(ctx, data->data, data->length); 370 240 asn1_free(data); 371 241 … … 376 246 parse a krb5 GSS-API wrapper packet giving a ticket 377 247 */ 378 bool spnego_parse_krb5_wrap( DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])248 bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) 379 249 { 380 250 bool ret; … … 398 268 asn1_read(data, tok_id, 2); 399 269 data_remaining -= 2; 400 *ticket = data_blob (NULL, data_remaining);270 *ticket = data_blob_talloc(ctx, NULL, data_remaining); 401 271 asn1_read(data, ticket->data, ticket->length); 402 272 } … … 417 287 418 288 /* 419 generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY 420 kerberos session setup 421 */ 422 int spnego_gen_negTokenTarg(const char *principal, int time_offset, 423 DATA_BLOB *targ, 289 generate a SPNEGO krb5 negTokenInit packet, ready for a EXTENDED_SECURITY 290 kerberos session setup 291 */ 292 int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx, 293 const char *principal, int time_offset, 294 DATA_BLOB *targ, 424 295 DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, 425 296 time_t *expire_time) … … 430 301 431 302 /* get a kerberos ticket for the service and extract the session key */ 432 retval = cli_krb5_get_ticket( principal, time_offset,433 &tkt, session_key_krb5, extra_ap_opts, NULL,434 expire_time, NULL);435 436 if (retval) 303 retval = cli_krb5_get_ticket(ctx, principal, time_offset, 304 &tkt, session_key_krb5, 305 extra_ap_opts, NULL, 306 expire_time, NULL); 307 if (retval) { 437 308 return retval; 309 } 438 310 439 311 /* wrap that up in a nice GSS-API wrapping */ 440 tkt_wrapped = spnego_gen_krb5_wrap( tkt, TOK_ID_KRB_AP_REQ);312 tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ); 441 313 442 314 /* and wrap that in a shiny SPNEGO wrapper */ 443 *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped);315 *targ = spnego_gen_negTokenInit(ctx, krb_mechs, &tkt_wrapped, NULL); 444 316 445 317 data_blob_free(&tkt_wrapped); … … 453 325 parse a spnego NTLMSSP challenge packet giving two security blobs 454 326 */ 455 bool spnego_parse_challenge( const DATA_BLOB blob,327 bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob, 456 328 DATA_BLOB *chal1, DATA_BLOB *chal2) 457 329 { … … 480 352 481 353 asn1_start_tag(data,ASN1_CONTEXT(2)); 482 asn1_read_OctetString(data, talloc_autofree_context(), chal1);354 asn1_read_OctetString(data, ctx, chal1); 483 355 asn1_end_tag(data); 484 356 … … 486 358 if (asn1_tag_remaining(data)) { 487 359 asn1_start_tag(data,ASN1_CONTEXT(3)); 488 asn1_read_OctetString(data, talloc_autofree_context(), chal2);360 asn1_read_OctetString(data, ctx, chal2); 489 361 asn1_end_tag(data); 490 362 } … … 508 380 generate a SPNEGO auth packet. This will contain the encrypted passwords 509 381 */ 510 DATA_BLOB spnego_gen_auth( DATA_BLOB blob)382 DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob) 511 383 { 512 384 ASN1_DATA *data; … … 526 398 asn1_pop_tag(data); 527 399 528 ret = data_blob (data->data, data->length);400 ret = data_blob_talloc(ctx, data->data, data->length); 529 401 530 402 asn1_free(data); … … 536 408 parse a SPNEGO auth packet. This contains the encrypted passwords 537 409 */ 538 bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) 410 bool spnego_parse_auth_and_mic(TALLOC_CTX *ctx, DATA_BLOB blob, 411 DATA_BLOB *auth, DATA_BLOB *signature) 539 412 { 540 413 ssize_t len; … … 554 427 } 555 428 556 *auth = data_blob_talloc( talloc_tos(),429 *auth = data_blob_talloc(ctx, 557 430 token.negTokenTarg.responseToken.data, 558 431 token.negTokenTarg.responseToken.length); 432 433 if (!signature) { 434 goto done; 435 } 436 437 *signature = data_blob_talloc(ctx, 438 token.negTokenTarg.mechListMIC.data, 439 token.negTokenTarg.mechListMIC.length); 440 441 done: 559 442 spnego_free_data(&token); 560 443 … … 562 445 } 563 446 447 bool spnego_parse_auth(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *auth) 448 { 449 return spnego_parse_auth_and_mic(ctx, blob, auth, NULL); 450 } 451 564 452 /* 565 453 generate a minimal SPNEGO response packet. Doesn't contain much. 566 454 */ 567 DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, 568 const char *mechOID) 455 DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx, 456 NTSTATUS nt_status, 457 const char *mechOID, 458 DATA_BLOB *reply, 459 DATA_BLOB *mechlistMIC) 569 460 { 570 461 ASN1_DATA *data; … … 603 494 } 604 495 605 asn1_pop_tag(data); 606 asn1_pop_tag(data); 607 608 ret = data_blob(data->data, data->length); 496 if (mechlistMIC && mechlistMIC->data != NULL) { 497 asn1_push_tag(data, ASN1_CONTEXT(3)); 498 asn1_write_OctetString(data, 499 mechlistMIC->data, 500 mechlistMIC->length); 501 asn1_pop_tag(data); 502 } 503 504 asn1_pop_tag(data); 505 asn1_pop_tag(data); 506 507 ret = data_blob_talloc(ctx, data->data, data->length); 609 508 asn1_free(data); 610 509 return ret; 611 510 } 612 511 512 DATA_BLOB spnego_gen_auth_response(TALLOC_CTX *ctx, DATA_BLOB *reply, 513 NTSTATUS nt_status, const char *mechOID) 514 { 515 return spnego_gen_auth_response_and_mic(ctx, nt_status, 516 mechOID, reply, NULL); 517 } 518 613 519 /* 614 520 parse a SPNEGO auth packet. This contains the encrypted passwords 615 521 */ 616 bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, 522 bool spnego_parse_auth_response(TALLOC_CTX *ctx, 523 DATA_BLOB blob, NTSTATUS nt_status, 617 524 const char *mechOID, 618 525 DATA_BLOB *auth) … … 650 557 if (asn1_tag_remaining(data)) { 651 558 asn1_start_tag(data,ASN1_CONTEXT(2)); 652 asn1_read_OctetString(data, talloc_autofree_context(), auth);559 asn1_read_OctetString(data, ctx, auth); 653 560 asn1_end_tag(data); 654 561 } … … 664 571 DATA_BLOB mechList = data_blob_null; 665 572 asn1_start_tag(data, ASN1_CONTEXT(3)); 666 asn1_read_OctetString(data, talloc_autofree_context(), &mechList);573 asn1_read_OctetString(data, ctx, &mechList); 667 574 asn1_end_tag(data); 668 575 data_blob_free(&mechList); … … 684 591 return True; 685 592 } 593 594 bool spnego_mech_list_blob(TALLOC_CTX *mem_ctx, 595 char **oid_list, DATA_BLOB *raw_data) 596 { 597 ASN1_DATA *data; 598 unsigned int idx; 599 600 if (!oid_list || !oid_list[0] || !raw_data) { 601 return false; 602 } 603 604 data = asn1_init(talloc_tos()); 605 if (data == NULL) { 606 return false; 607 } 608 609 asn1_push_tag(data, ASN1_SEQUENCE(0)); 610 for (idx = 0; oid_list[idx]; idx++) { 611 asn1_write_OID(data, oid_list[idx]); 612 } 613 asn1_pop_tag(data); 614 615 if (data->has_error) { 616 DEBUG(3, (__location__ " failed at %d\n", (int)data->ofs)); 617 asn1_free(data); 618 return false; 619 } 620 621 *raw_data = data_blob_talloc(mem_ctx, data->data, data->length); 622 if (!raw_data->data) { 623 DEBUG(3, (__location__": data_blob_talloc() failed!\n")); 624 asn1_free(data); 625 return false; 626 } 627 628 asn1_free(data); 629 return true; 630 } -
vendor/current/source3/libsmb/clistr.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "libsmb/libsmb.h" 22 23 23 24 size_t clistr_push_fn(const char *function, … … 35 36 return push_string_base(function, line, 36 37 cli->outbuf, 37 SVAL(cli->outbuf, smb_flg2),38 (uint16_t)(cli_ucs2(cli) ? FLAGS2_UNICODE_STRINGS : 0), 38 39 dest, src, -1, flags); 39 40 } 40 41 return push_string_base(function, line, 41 42 cli->outbuf, 42 SVAL(cli->outbuf, smb_flg2),43 (uint16_t)(cli_ucs2(cli) ? FLAGS2_UNICODE_STRINGS : 0), 43 44 dest, src, cli->bufsize - buf_used, 44 45 flags); … … 48 49 return push_string_base(function, line, 49 50 cli->outbuf, 50 SVAL(cli->outbuf, smb_flg2),51 (uint16_t)(cli_ucs2(cli) ? FLAGS2_UNICODE_STRINGS : 0), 51 52 dest, src, dest_len, flags); 52 53 } … … 69 70 unsigned int line, 70 71 TALLOC_CTX *ctx, 71 const char *inbuf, 72 const char *base, 73 uint16_t flags2, 72 74 char **pp_dest, 73 75 const void *src, … … 78 80 line, 79 81 ctx, 80 inbuf,81 SVAL(inbuf, smb_flg2),82 base, 83 flags2, 82 84 pp_dest, 83 85 src, … … 90 92 return align_string(cli->outbuf, (const char *)p, flags); 91 93 } 92 93 size_t clistr_align_in(struct cli_state *cli, const void *p, int flags)94 {95 return align_string(cli->inbuf, (const char *)p, flags);96 } -
vendor/current/source3/libsmb/clitrans.c
r414 r740 19 19 20 20 #include "includes.h" 21 22 23 /**************************************************************************** 24 Send a SMB trans or trans2 request. 25 ****************************************************************************/ 26 27 bool cli_send_trans(struct cli_state *cli, int trans, 28 const char *pipe_name, 29 int fid, int flags, 30 uint16 *setup, unsigned int lsetup, unsigned int msetup, 31 const char *param, unsigned int lparam, unsigned int mparam, 32 const char *data, unsigned int ldata, unsigned int mdata) 33 { 34 unsigned int i; 35 unsigned int this_ldata,this_lparam; 36 unsigned int tot_data=0,tot_param=0; 37 char *outdata,*outparam; 38 char *p; 39 int pipe_name_len=0; 40 uint16 mid; 41 42 this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ 43 this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); 44 45 memset(cli->outbuf,'\0',smb_size); 46 cli_set_message(cli->outbuf,14+lsetup,0,True); 47 SCVAL(cli->outbuf,smb_com,trans); 48 SSVAL(cli->outbuf,smb_tid, cli->cnum); 49 cli_setup_packet(cli); 50 51 /* 52 * Save the mid we're using. We need this for finding 53 * signing replies. 54 */ 55 56 mid = cli->mid; 57 58 if (pipe_name) { 59 pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); 60 } 61 62 outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); 63 outdata = outparam+this_lparam; 64 65 /* primary request */ 66 SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ 67 SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ 68 SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ 69 SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ 70 SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ 71 SSVAL(cli->outbuf,smb_flags,flags); /* flags */ 72 SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ 73 SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ 74 SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ 75 SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ 76 SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ 77 SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ 78 for (i=0;i<lsetup;i++) /* setup[] */ 79 SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); 80 p = smb_buf(cli->outbuf); 81 if (trans != SMBtrans) { 82 *p++ = 0; /* put in a null smb_name */ 83 *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ 84 } 85 if (this_lparam) /* param[] */ 86 memcpy(outparam,param,this_lparam); 87 if (this_ldata) /* data[] */ 88 memcpy(outdata,data,this_ldata); 89 cli_setup_bcc(cli, outdata+this_ldata); 90 91 show_msg(cli->outbuf); 92 93 if (!cli_send_smb(cli)) { 94 return False; 95 } 96 97 cli_state_seqnum_persistent(cli, mid); 98 99 if (this_ldata < ldata || this_lparam < lparam) { 100 /* receive interim response */ 101 if (!cli_receive_smb(cli) || cli_is_error(cli)) { 102 cli_state_seqnum_remove(cli, mid); 103 return(False); 104 } 105 106 tot_data = this_ldata; 107 tot_param = this_lparam; 108 109 while (tot_data < ldata || tot_param < lparam) { 110 this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ 111 this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); 112 113 cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); 114 SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); 115 116 outparam = smb_buf(cli->outbuf); 117 outdata = outparam+this_lparam; 118 119 /* secondary request */ 120 SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ 121 SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ 122 SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ 123 SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ 124 SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ 125 SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ 126 SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ 127 SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ 128 if (trans==SMBtrans2) 129 SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ 130 if (this_lparam) /* param[] */ 131 memcpy(outparam,param+tot_param,this_lparam); 132 if (this_ldata) /* data[] */ 133 memcpy(outdata,data+tot_data,this_ldata); 134 cli_setup_bcc(cli, outdata+this_ldata); 135 136 show_msg(cli->outbuf); 137 138 cli->mid = mid; 139 if (!cli_send_smb(cli)) { 140 cli_state_seqnum_remove(cli, mid); 141 return False; 142 } 143 144 tot_data += this_ldata; 145 tot_param += this_lparam; 146 } 147 } 148 149 return(True); 150 } 151 152 /**************************************************************************** 153 Receive a SMB trans or trans2 response allocating the necessary memory. 154 ****************************************************************************/ 155 156 bool cli_receive_trans(struct cli_state *cli,int trans, 157 char **param, unsigned int *param_len, 158 char **data, unsigned int *data_len) 159 { 160 unsigned int total_data=0; 161 unsigned int total_param=0; 162 unsigned int this_data,this_param; 163 NTSTATUS status; 164 bool ret = False; 165 uint16_t mid; 166 167 *data_len = *param_len = 0; 168 169 mid = SVAL(cli->outbuf,smb_mid); 170 171 if (!cli_receive_smb(cli)) { 172 cli_state_seqnum_remove(cli, mid); 173 return False; 174 } 175 176 show_msg(cli->inbuf); 177 178 /* sanity check */ 179 if (CVAL(cli->inbuf,smb_com) != trans) { 180 DEBUG(0,("Expected %s response, got command 0x%02x\n", 181 trans==SMBtrans?"SMBtrans":"SMBtrans2", 182 CVAL(cli->inbuf,smb_com))); 183 cli_state_seqnum_remove(cli, mid); 184 return False; 185 } 186 187 /* 188 * An NT RPC pipe call can return ERRDOS, ERRmoredata 189 * to a trans call. This is not an error and should not 190 * be treated as such. Note that STATUS_NO_MORE_FILES is 191 * returned when a trans2 findfirst/next finishes. 192 * When setting up an encrypted transport we can also 193 * see NT_STATUS_MORE_PROCESSING_REQUIRED here. 194 * 195 * Vista returns NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT if the folder 196 * "<share>/Users/All Users" is enumerated. This is a special pseudo 197 * folder, and the response does not have parameters (nor a parameter 198 * length). 199 */ 200 status = cli_nt_error(cli); 201 202 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 203 if (NT_STATUS_IS_ERR(status) || 204 NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES) || 205 NT_STATUS_EQUAL(status,NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) { 206 goto out; 207 } 208 } 209 210 /* parse out the lengths */ 211 total_data = SVAL(cli->inbuf,smb_tdrcnt); 212 total_param = SVAL(cli->inbuf,smb_tprcnt); 213 214 /* allocate it */ 215 if (total_data!=0) { 216 /* We know adding 2 is safe as total_data is an 217 * SVAL <= 0xFFFF. */ 218 *data = (char *)SMB_REALLOC(*data,total_data+2); 219 if (!(*data)) { 220 DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); 221 goto out; 222 } 223 } 224 225 if (total_param!=0) { 226 /* We know adding 2 is safe as total_param is an 227 * SVAL <= 0xFFFF. */ 228 *param = (char *)SMB_REALLOC(*param,total_param+2); 229 if (!(*param)) { 230 DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); 231 goto out; 232 } 233 } 234 235 for (;;) { 236 this_data = SVAL(cli->inbuf,smb_drcnt); 237 this_param = SVAL(cli->inbuf,smb_prcnt); 238 239 if (this_data + *data_len > total_data || 240 this_param + *param_len > total_param) { 241 DEBUG(1,("Data overflow in cli_receive_trans\n")); 242 goto out; 243 } 244 245 if (this_data + *data_len < this_data || 246 this_data + *data_len < *data_len || 247 this_param + *param_len < this_param || 248 this_param + *param_len < *param_len) { 249 DEBUG(1,("Data overflow in cli_receive_trans\n")); 250 goto out; 251 } 252 253 if (this_data) { 254 unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); 255 unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); 256 257 if (data_offset_out > total_data || 258 data_offset_out + this_data > total_data || 259 data_offset_out + this_data < data_offset_out || 260 data_offset_out + this_data < this_data) { 261 DEBUG(1,("Data overflow in cli_receive_trans\n")); 262 goto out; 263 } 264 if (data_offset_in > cli->bufsize || 265 data_offset_in + this_data > cli->bufsize || 266 data_offset_in + this_data < data_offset_in || 267 data_offset_in + this_data < this_data) { 268 DEBUG(1,("Data overflow in cli_receive_trans\n")); 269 goto out; 270 } 271 272 memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); 273 } 274 if (this_param) { 275 unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); 276 unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); 277 278 if (param_offset_out > total_param || 279 param_offset_out + this_param > total_param || 280 param_offset_out + this_param < param_offset_out || 281 param_offset_out + this_param < this_param) { 282 DEBUG(1,("Param overflow in cli_receive_trans\n")); 283 goto out; 284 } 285 if (param_offset_in > cli->bufsize || 286 param_offset_in + this_param > cli->bufsize || 287 param_offset_in + this_param < param_offset_in || 288 param_offset_in + this_param < this_param) { 289 DEBUG(1,("Param overflow in cli_receive_trans\n")); 290 goto out; 291 } 292 293 memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); 294 } 295 *data_len += this_data; 296 *param_len += this_param; 297 298 if (total_data <= *data_len && total_param <= *param_len) { 299 ret = True; 300 break; 301 } 302 303 if (!cli_receive_smb(cli)) { 304 goto out; 305 } 306 307 show_msg(cli->inbuf); 308 309 /* sanity check */ 310 if (CVAL(cli->inbuf,smb_com) != trans) { 311 DEBUG(0,("Expected %s response, got command 0x%02x\n", 312 trans==SMBtrans?"SMBtrans":"SMBtrans2", 313 CVAL(cli->inbuf,smb_com))); 314 goto out; 315 } 316 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 317 if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { 318 goto out; 319 } 320 } 321 322 /* parse out the total lengths again - they can shrink! */ 323 if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) 324 total_data = SVAL(cli->inbuf,smb_tdrcnt); 325 if (SVAL(cli->inbuf,smb_tprcnt) < total_param) 326 total_param = SVAL(cli->inbuf,smb_tprcnt); 327 328 if (total_data <= *data_len && total_param <= *param_len) { 329 ret = True; 330 break; 331 } 332 } 333 334 out: 335 336 cli_state_seqnum_remove(cli, mid); 337 338 if (ret) { 339 /* Ensure the last 2 bytes of param and data are 2 null 340 * bytes. These are malloc'ed, but not included in any 341 * length counts. This allows cli_XX string reading functions 342 * to safely null terminate. */ 343 if (total_data) { 344 SSVAL(*data,total_data,0); 345 } 346 if (total_param) { 347 SSVAL(*param,total_param,0); 348 } 349 } 350 351 return ret; 352 } 353 354 /**************************************************************************** 355 Send a SMB nttrans request. 356 ****************************************************************************/ 357 358 bool cli_send_nt_trans(struct cli_state *cli, 359 int function, 360 int flags, 361 uint16 *setup, unsigned int lsetup, unsigned int msetup, 362 char *param, unsigned int lparam, unsigned int mparam, 363 char *data, unsigned int ldata, unsigned int mdata) 364 { 365 unsigned int i; 366 unsigned int this_ldata,this_lparam; 367 unsigned int tot_data=0,tot_param=0; 368 uint16 mid; 369 char *outdata,*outparam; 370 371 this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ 372 this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); 373 374 memset(cli->outbuf,'\0',smb_size); 375 cli_set_message(cli->outbuf,19+lsetup,0,True); 376 SCVAL(cli->outbuf,smb_com,SMBnttrans); 377 SSVAL(cli->outbuf,smb_tid, cli->cnum); 378 cli_setup_packet(cli); 379 380 /* 381 * Save the mid we're using. We need this for finding 382 * signing replies. 383 */ 384 385 mid = cli->mid; 386 387 outparam = smb_buf(cli->outbuf)+3; 388 outdata = outparam+this_lparam; 389 390 /* primary request */ 391 SCVAL(cli->outbuf,smb_nt_MaxSetupCount,msetup); 392 SCVAL(cli->outbuf,smb_nt_Flags,flags); 393 SIVAL(cli->outbuf,smb_nt_TotalParameterCount, lparam); 394 SIVAL(cli->outbuf,smb_nt_TotalDataCount, ldata); 395 SIVAL(cli->outbuf,smb_nt_MaxParameterCount, mparam); 396 SIVAL(cli->outbuf,smb_nt_MaxDataCount, mdata); 397 SIVAL(cli->outbuf,smb_nt_ParameterCount, this_lparam); 398 SIVAL(cli->outbuf,smb_nt_ParameterOffset, smb_offset(outparam,cli->outbuf)); 399 SIVAL(cli->outbuf,smb_nt_DataCount, this_ldata); 400 SIVAL(cli->outbuf,smb_nt_DataOffset, smb_offset(outdata,cli->outbuf)); 401 SIVAL(cli->outbuf,smb_nt_SetupCount, lsetup); 402 SIVAL(cli->outbuf,smb_nt_Function, function); 403 for (i=0;i<lsetup;i++) /* setup[] */ 404 SSVAL(cli->outbuf,smb_nt_SetupStart+i*2,setup[i]); 405 406 if (this_lparam) /* param[] */ 407 memcpy(outparam,param,this_lparam); 408 if (this_ldata) /* data[] */ 409 memcpy(outdata,data,this_ldata); 410 411 cli_setup_bcc(cli, outdata+this_ldata); 412 413 show_msg(cli->outbuf); 414 if (!cli_send_smb(cli)) { 415 return False; 416 } 417 418 cli_state_seqnum_persistent(cli, mid); 419 420 if (this_ldata < ldata || this_lparam < lparam) { 421 /* receive interim response */ 422 if (!cli_receive_smb(cli) || cli_is_error(cli)) { 423 cli_state_seqnum_remove(cli, mid); 424 return(False); 425 } 426 427 tot_data = this_ldata; 428 tot_param = this_lparam; 429 430 while (tot_data < ldata || tot_param < lparam) { 431 this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ 432 this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); 433 434 cli_set_message(cli->outbuf,18,0,True); 435 SCVAL(cli->outbuf,smb_com,SMBnttranss); 436 437 /* XXX - these should probably be aligned */ 438 outparam = smb_buf(cli->outbuf); 439 outdata = outparam+this_lparam; 440 441 /* secondary request */ 442 SIVAL(cli->outbuf,smb_nts_TotalParameterCount,lparam); 443 SIVAL(cli->outbuf,smb_nts_TotalDataCount,ldata); 444 SIVAL(cli->outbuf,smb_nts_ParameterCount,this_lparam); 445 SIVAL(cli->outbuf,smb_nts_ParameterOffset,smb_offset(outparam,cli->outbuf)); 446 SIVAL(cli->outbuf,smb_nts_ParameterDisplacement,tot_param); 447 SIVAL(cli->outbuf,smb_nts_DataCount,this_ldata); 448 SIVAL(cli->outbuf,smb_nts_DataOffset,smb_offset(outdata,cli->outbuf)); 449 SIVAL(cli->outbuf,smb_nts_DataDisplacement,tot_data); 450 if (this_lparam) /* param[] */ 451 memcpy(outparam,param+tot_param,this_lparam); 452 if (this_ldata) /* data[] */ 453 memcpy(outdata,data+tot_data,this_ldata); 454 cli_setup_bcc(cli, outdata+this_ldata); 455 456 show_msg(cli->outbuf); 457 458 cli->mid = mid; 459 if (!cli_send_smb(cli)) { 460 cli_state_seqnum_remove(cli, mid); 461 return False; 462 } 463 464 tot_data += this_ldata; 465 tot_param += this_lparam; 466 } 467 } 468 469 return(True); 470 } 471 472 /**************************************************************************** 473 Receive a SMB nttrans response allocating the necessary memory. 474 ****************************************************************************/ 475 476 bool cli_receive_nt_trans(struct cli_state *cli, 477 char **param, unsigned int *param_len, 478 char **data, unsigned int *data_len) 479 { 480 unsigned int total_data=0; 481 unsigned int total_param=0; 482 unsigned int this_data,this_param; 483 uint8 eclass; 484 uint32 ecode; 485 bool ret = False; 486 uint16_t mid; 487 488 *data_len = *param_len = 0; 489 490 mid = SVAL(cli->outbuf,smb_mid); 491 492 if (!cli_receive_smb(cli)) { 493 cli_state_seqnum_remove(cli, mid); 494 return False; 495 } 496 497 show_msg(cli->inbuf); 498 499 /* sanity check */ 500 if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { 501 DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", 502 CVAL(cli->inbuf,smb_com))); 503 cli_state_seqnum_remove(cli, mid); 504 return(False); 505 } 506 507 /* 508 * An NT RPC pipe call can return ERRDOS, ERRmoredata 509 * to a trans call. This is not an error and should not 510 * be treated as such. 511 */ 512 if (cli_is_dos_error(cli)) { 513 cli_dos_error(cli, &eclass, &ecode); 514 if (!(eclass == ERRDOS && ecode == ERRmoredata)) { 515 goto out; 516 } 517 } 518 519 /* 520 * Likewise for NT_STATUS_BUFFER_TOO_SMALL 521 */ 522 if (cli_is_nt_error(cli)) { 523 if (!NT_STATUS_EQUAL(cli_nt_error(cli), 524 NT_STATUS_BUFFER_TOO_SMALL)) { 525 goto out; 526 } 527 } 528 529 /* parse out the lengths */ 530 total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount); 531 total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount); 532 /* Only allow 16 megs. */ 533 if (total_param > 16*1024*1024) { 534 DEBUG(0,("cli_receive_nt_trans: param buffer too large %d\n", 535 total_param)); 536 goto out; 537 } 538 if (total_data > 16*1024*1024) { 539 DEBUG(0,("cli_receive_nt_trans: data buffer too large %d\n", 540 total_data)); 541 goto out; 542 } 543 544 /* allocate it */ 545 if (total_data) { 546 /* We know adding 2 is safe as total_data is less 547 * than 16mb (above). */ 548 *data = (char *)SMB_REALLOC(*data,total_data+2); 549 if (!(*data)) { 550 DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); 551 goto out; 552 } 553 } 554 555 if (total_param) { 556 /* We know adding 2 is safe as total_param is less 557 * than 16mb (above). */ 558 *param = (char *)SMB_REALLOC(*param,total_param+2); 559 if (!(*param)) { 560 DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); 561 goto out; 562 } 563 } 564 565 while (1) { 566 this_data = SVAL(cli->inbuf,smb_ntr_DataCount); 567 this_param = SVAL(cli->inbuf,smb_ntr_ParameterCount); 568 569 if (this_data + *data_len > total_data || 570 this_param + *param_len > total_param) { 571 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 572 goto out; 573 } 574 575 if (this_data + *data_len < this_data || 576 this_data + *data_len < *data_len || 577 this_param + *param_len < this_param || 578 this_param + *param_len < *param_len) { 579 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 580 goto out; 581 } 582 583 if (this_data) { 584 unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); 585 unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); 586 587 if (data_offset_out > total_data || 588 data_offset_out + this_data > total_data || 589 data_offset_out + this_data < data_offset_out || 590 data_offset_out + this_data < this_data) { 591 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 592 goto out; 593 } 594 if (data_offset_in > cli->bufsize || 595 data_offset_in + this_data > cli->bufsize || 596 data_offset_in + this_data < data_offset_in || 597 data_offset_in + this_data < this_data) { 598 DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); 599 goto out; 600 } 601 602 memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); 603 } 604 605 if (this_param) { 606 unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); 607 unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); 608 609 if (param_offset_out > total_param || 610 param_offset_out + this_param > total_param || 611 param_offset_out + this_param < param_offset_out || 612 param_offset_out + this_param < this_param) { 613 DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); 614 goto out; 615 } 616 if (param_offset_in > cli->bufsize || 617 param_offset_in + this_param > cli->bufsize || 618 param_offset_in + this_param < param_offset_in || 619 param_offset_in + this_param < this_param) { 620 DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); 621 goto out; 622 } 623 624 memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); 625 } 626 627 *data_len += this_data; 628 *param_len += this_param; 629 630 if (total_data <= *data_len && total_param <= *param_len) { 631 ret = True; 632 break; 633 } 634 635 if (!cli_receive_smb(cli)) { 636 goto out; 637 } 638 639 show_msg(cli->inbuf); 640 641 /* sanity check */ 642 if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { 643 DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", 644 CVAL(cli->inbuf,smb_com))); 645 goto out; 646 } 647 if (cli_is_dos_error(cli)) { 648 cli_dos_error(cli, &eclass, &ecode); 649 if(!(eclass == ERRDOS && ecode == ERRmoredata)) { 650 goto out; 651 } 652 } 653 /* 654 * Likewise for NT_STATUS_BUFFER_TOO_SMALL 655 */ 656 if (cli_is_nt_error(cli)) { 657 if (!NT_STATUS_EQUAL(cli_nt_error(cli), 658 NT_STATUS_BUFFER_TOO_SMALL)) { 659 goto out; 660 } 661 } 662 663 /* parse out the total lengths again - they can shrink! */ 664 if (IVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) 665 total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount); 666 if (IVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) 667 total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount); 668 669 if (total_data <= *data_len && total_param <= *param_len) { 670 ret = True; 671 break; 672 } 673 } 674 675 out: 676 677 cli_state_seqnum_remove(cli, mid); 678 679 if (ret) { 680 /* Ensure the last 2 bytes of param and data are 2 null 681 * bytes. These are malloc'ed, but not included in any 682 * length counts. This allows cli_XX string reading functions 683 * to safely null terminate. */ 684 if (total_data) { 685 SSVAL(*data,total_data,0); 686 } 687 if (total_param) { 688 SSVAL(*param,total_param,0); 689 } 690 } 691 692 return ret; 693 } 21 #include "libsmb/libsmb.h" 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "async_smb.h" 694 24 695 25 struct trans_recvblob { … … 703 33 uint8_t cmd; 704 34 uint16_t mid; 705 uint32_t seqnum;706 35 const char *pipe_name; 707 36 uint8_t *pipe_name_conv; … … 721 50 struct trans_recvblob rparam; 722 51 struct trans_recvblob rdata; 723 724 TALLOC_CTX *secondary_request_ctx; 725 726 struct iovec iov[4]; 52 uint16_t recv_flags2; 53 54 struct iovec iov[6]; 727 55 uint8_t pad[4]; 56 uint8_t zero_pad[4]; 728 57 uint16_t vwv[32]; 58 59 struct tevent_req *primary_subreq; 729 60 }; 61 62 static void cli_trans_cleanup_primary(struct cli_trans_state *state) 63 { 64 if (state->primary_subreq) { 65 cli_smb_req_set_mid(state->primary_subreq, 0); 66 cli_smb_req_unset_pending(state->primary_subreq); 67 TALLOC_FREE(state->primary_subreq); 68 } 69 } 70 71 static int cli_trans_state_destructor(struct cli_trans_state *state) 72 { 73 cli_trans_cleanup_primary(state); 74 return 0; 75 } 730 76 731 77 static NTSTATUS cli_pull_trans(uint8_t *inbuf, … … 843 189 uint8_t *pad = state->pad; 844 190 uint16_t *vwv = state->vwv; 845 uint16_t param_offset; 846 uint16_t this_param = 0; 847 uint16_t this_data = 0; 191 uint32_t param_offset; 192 uint32_t this_param = 0; 193 uint32_t param_pad; 194 uint32_t data_offset; 195 uint32_t this_data = 0; 196 uint32_t data_pad; 848 197 uint32_t useable_space; 849 198 uint8_t cmd; … … 893 242 } 894 243 895 useable_space = state->cli->max_xmit - smb_size - sizeof(uint16_t)*wct; 244 param_offset += wct * sizeof(uint16_t); 245 useable_space = state->cli->max_xmit - param_offset; 246 247 param_pad = param_offset % 4; 248 if (param_pad > 0) { 249 param_pad = MIN(param_pad, useable_space); 250 iov[0].iov_base = (void *)state->zero_pad; 251 iov[0].iov_len = param_pad; 252 iov += 1; 253 param_offset += param_pad; 254 } 255 useable_space = state->cli->max_xmit - param_offset; 896 256 897 257 if (state->param_sent < state->num_param) { … … 903 263 } 904 264 265 data_offset = param_offset + this_param; 266 useable_space = state->cli->max_xmit - data_offset; 267 268 data_pad = data_offset % 4; 269 if (data_pad > 0) { 270 data_pad = MIN(data_pad, useable_space); 271 iov[0].iov_base = (void *)state->zero_pad; 272 iov[0].iov_len = data_pad; 273 iov += 1; 274 data_offset += data_pad; 275 } 276 useable_space = state->cli->max_xmit - data_offset; 277 905 278 if (state->data_sent < state->num_data) { 906 279 this_data = MIN(state->num_data - state->data_sent, 907 useable_space - this_param);280 useable_space); 908 281 iov[0].iov_base = (void *)(state->data + state->data_sent); 909 282 iov[0].iov_len = this_data; … … 911 284 } 912 285 913 param_offset += wct * sizeof(uint16_t);914 915 286 DEBUG(10, ("num_setup=%u, max_setup=%u, " 916 287 "param_total=%u, this_param=%u, max_param=%u, " 917 288 "data_total=%u, this_data=%u, max_data=%u, " 918 "param_offset=%u, param_disp=%u, data_disp=%u\n", 289 "param_offset=%u, param_pad=%u, param_disp=%u, " 290 "data_offset=%u, data_pad=%u, data_disp=%u\n", 919 291 (unsigned)state->num_setup, (unsigned)state->max_setup, 920 292 (unsigned)state->num_param, (unsigned)this_param, … … 922 294 (unsigned)state->num_data, (unsigned)this_data, 923 295 (unsigned)state->rdata.max, 924 (unsigned)param_offset, 925 (unsigned)state->param_sent, (unsigned)state->data_sent)); 296 (unsigned)param_offset, (unsigned)param_pad, 297 (unsigned)state->param_sent, 298 (unsigned)data_offset, (unsigned)data_pad, 299 (unsigned)state->data_sent)); 926 300 927 301 switch (cmd) { … … 940 314 SSVAL(vwv +10, 0, param_offset); 941 315 SSVAL(vwv +11, 0, this_data); 942 SSVAL(vwv +12, 0, param_offset + this_param);316 SSVAL(vwv +12, 0, data_offset); 943 317 SCVAL(vwv +13, 0, state->num_setup); 944 318 SCVAL(vwv +13, 1, 0); /* reserved */ … … 954 328 SSVAL(vwv + 4, 0, state->param_sent); 955 329 SSVAL(vwv + 5, 0, this_data); 956 SSVAL(vwv + 6, 0, param_offset + this_param);330 SSVAL(vwv + 6, 0, data_offset); 957 331 SSVAL(vwv + 7, 0, state->data_sent); 958 332 if (cmd == SMBtranss2) { … … 961 335 break; 962 336 case SMBnttrans: 963 SCVAL(vwv ,0, state->max_setup);964 SSVAL(vwv ,1, 0); /* reserved */965 SIVAL(vwv , 3, state->num_param);966 SIVAL(vwv , 7, state->num_data);967 SIVAL(vwv , 11, state->rparam.max);968 SIVAL(vwv , 15, state->rdata.max);969 SIVAL(vwv , 19, this_param);970 SIVAL(vwv , 23, param_offset);971 SIVAL(vwv , 27, this_data);972 SIVAL(vwv , 31, param_offset + this_param);973 SCVAL(vwv , 35, state->num_setup);974 SSVAL(vwv , 36, state->function);337 SCVAL(vwv + 0, 0, state->max_setup); 338 SSVAL(vwv + 0, 1, 0); /* reserved */ 339 SIVAL(vwv + 1, 1, state->num_param); 340 SIVAL(vwv + 3, 1, state->num_data); 341 SIVAL(vwv + 5, 1, state->rparam.max); 342 SIVAL(vwv + 7, 1, state->rdata.max); 343 SIVAL(vwv + 9, 1, this_param); 344 SIVAL(vwv +11, 1, param_offset); 345 SIVAL(vwv +13, 1, this_data); 346 SIVAL(vwv +15, 1, data_offset); 347 SCVAL(vwv +17, 1, state->num_setup); 348 SSVAL(vwv +18, 0, state->function); 975 349 memcpy(vwv + 19, state->setup, 976 350 sizeof(uint16_t) * state->num_setup); 977 351 break; 978 352 case SMBnttranss: 979 SSVAL(vwv ,0, 0); /* reserved */980 SCVAL(vwv , 2, 0); /* reserved */981 SIVAL(vwv , 3, state->num_param);982 SIVAL(vwv , 7, state->num_data);983 SIVAL(vwv , 11, this_param);984 SIVAL(vwv , 15, param_offset);985 SIVAL(vwv , 19, state->param_sent);986 SIVAL(vwv , 23, this_data);987 SIVAL(vwv , 27, param_offset + this_param);988 SIVAL(vwv , 31, state->data_sent);989 SCVAL(vwv , 35, 0); /* reserved */353 SSVAL(vwv + 0, 0, 0); /* reserved */ 354 SCVAL(vwv + 1, 0, 0); /* reserved */ 355 SIVAL(vwv + 1, 1, state->num_param); 356 SIVAL(vwv + 3, 1, state->num_data); 357 SIVAL(vwv + 5, 1, this_param); 358 SIVAL(vwv + 7, 1, param_offset); 359 SIVAL(vwv + 9, 1, state->param_sent); 360 SIVAL(vwv +11, 1, this_data); 361 SIVAL(vwv +13, 1, data_offset); 362 SIVAL(vwv +15, 1, state->data_sent); 363 SCVAL(vwv +17, 1, 0); /* reserved */ 990 364 break; 991 365 } … … 1084 458 return tevent_req_post(req, ev); 1085 459 } 1086 state->mid = cli_smb_req_mid(subreq);1087 460 status = cli_smb_req_send(subreq); 1088 461 if (!NT_STATUS_IS_OK(status)) { … … 1090 463 return tevent_req_post(req, state->ev); 1091 464 } 1092 cli_state_seqnum_persistent(cli, state->mid);1093 465 tevent_req_set_callback(subreq, cli_trans_done, req); 466 467 /* 468 * Now get the MID of the primary request 469 * and mark it as persistent. This means 470 * we will able to send and receive multiple 471 * SMB pdus using this MID in both directions 472 * (including correct SMB signing). 473 */ 474 state->mid = cli_smb_req_mid(subreq); 475 cli_smb_req_set_mid(subreq, state->mid); 476 state->primary_subreq = subreq; 477 talloc_set_destructor(state, cli_trans_state_destructor); 478 1094 479 return req; 1095 480 } 481 482 static void cli_trans_done2(struct tevent_req *subreq); 1096 483 1097 484 static void cli_trans_done(struct tevent_req *subreq) … … 1107 494 uint32_t num_bytes; 1108 495 uint8_t *bytes; 496 uint8_t *inbuf; 1109 497 uint8_t num_setup = 0; 1110 498 uint16_t *setup = NULL; … … 1118 506 uint8_t *data = NULL; 1119 507 1120 status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes); 508 status = cli_smb_recv(subreq, state, &inbuf, 0, &wct, &vwv, 509 &num_bytes, &bytes); 510 /* 511 * Do not TALLOC_FREE(subreq) here, we might receive more than 512 * one response for the same mid. 513 */ 1121 514 1122 515 /* … … 1133 526 1134 527 status = cli_pull_trans( 1135 cli_smb_inbuf(subreq), wct, vwv, num_bytes, bytes,528 inbuf, wct, vwv, num_bytes, bytes, 1136 529 state->cmd, !sent_all, &num_setup, &setup, 1137 530 &total_param, &num_param, ¶m_disp, ¶m, … … 1144 537 if (!sent_all) { 1145 538 int iov_count; 1146 1147 TALLOC_FREE(subreq); 539 struct tevent_req *subreq2; 1148 540 1149 541 cli_trans_format(state, &wct, &iov_count); 1150 542 1151 subreq = cli_smb_req_create(state, state->ev, state->cli,1152 state->cmd + 1, 0, wct, state->vwv,1153 iov_count, state->iov);1154 if (tevent_req_nomem(subreq , req)) {543 subreq2 = cli_smb_req_create(state, state->ev, state->cli, 544 state->cmd + 1, 0, wct, state->vwv, 545 iov_count, state->iov); 546 if (tevent_req_nomem(subreq2, req)) { 1155 547 return; 1156 548 } 1157 cli_smb_req_set_mid(subreq , state->mid);1158 1159 status = cli_smb_req_send(subreq );549 cli_smb_req_set_mid(subreq2, state->mid); 550 551 status = cli_smb_req_send(subreq2); 1160 552 1161 553 if (!NT_STATUS_IS_OK(status)) { 1162 554 goto fail; 1163 555 } 1164 tevent_req_set_callback(subreq, cli_trans_done, req); 556 tevent_req_set_callback(subreq2, cli_trans_done2, req); 557 1165 558 return; 1166 559 } … … 1186 579 if ((state->rparam.total == state->rparam.received) 1187 580 && (state->rdata.total == state->rdata.received)) { 1188 TALLOC_FREE(subreq);1189 cli_ state_seqnum_remove(state->cli, state->mid);581 state->recv_flags2 = SVAL(inbuf, smb_flg2); 582 cli_trans_cleanup_primary(state); 1190 583 tevent_req_done(req); 1191 584 return; 1192 585 } 1193 586 1194 if (!cli_smb_req_set_pending(subreq)) { 1195 status = NT_STATUS_NO_MEMORY; 1196 goto fail; 1197 } 587 TALLOC_FREE(inbuf); 588 1198 589 return; 1199 590 1200 591 fail: 1201 cli_state_seqnum_remove(state->cli, state->mid); 1202 TALLOC_FREE(subreq); 592 cli_trans_cleanup_primary(state); 1203 593 tevent_req_nterror(req, status); 1204 594 } 1205 595 1206 NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 1207 uint16_t **setup, uint8_t *num_setup, 1208 uint8_t **param, uint32_t *num_param, 1209 uint8_t **data, uint32_t *num_data) 1210 { 596 static void cli_trans_done2(struct tevent_req *subreq2) 597 { 598 struct tevent_req *req = tevent_req_callback_data( 599 subreq2, struct tevent_req); 1211 600 struct cli_trans_state *state = tevent_req_data( 1212 601 req, struct cli_trans_state); 1213 602 NTSTATUS status; 603 bool sent_all; 604 uint8_t wct; 605 uint32_t seqnum; 606 607 /* 608 * First backup the seqnum of the secondary request 609 * and attach it to the primary request. 610 */ 611 seqnum = cli_smb_req_seqnum(subreq2); 612 cli_smb_req_set_seqnum(state->primary_subreq, seqnum); 613 614 status = cli_smb_recv(subreq2, state, NULL, 0, &wct, NULL, 615 NULL, NULL); 616 TALLOC_FREE(subreq2); 617 618 if (!NT_STATUS_IS_OK(status)) { 619 goto fail; 620 } 621 622 if (wct != 0) { 623 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 624 goto fail; 625 } 626 627 sent_all = ((state->param_sent == state->num_param) 628 && (state->data_sent == state->num_data)); 629 630 if (!sent_all) { 631 int iov_count; 632 633 cli_trans_format(state, &wct, &iov_count); 634 635 subreq2 = cli_smb_req_create(state, state->ev, state->cli, 636 state->cmd + 1, 0, wct, state->vwv, 637 iov_count, state->iov); 638 if (tevent_req_nomem(subreq2, req)) { 639 return; 640 } 641 cli_smb_req_set_mid(subreq2, state->mid); 642 643 status = cli_smb_req_send(subreq2); 644 645 if (!NT_STATUS_IS_OK(status)) { 646 goto fail; 647 } 648 tevent_req_set_callback(subreq2, cli_trans_done2, req); 649 return; 650 } 651 652 return; 653 654 fail: 655 cli_trans_cleanup_primary(state); 656 tevent_req_nterror(req, status); 657 } 658 659 NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 660 uint16_t *recv_flags2, 661 uint16_t **setup, uint8_t min_setup, 662 uint8_t *num_setup, 663 uint8_t **param, uint32_t min_param, 664 uint32_t *num_param, 665 uint8_t **data, uint32_t min_data, 666 uint32_t *num_data) 667 { 668 struct cli_trans_state *state = tevent_req_data( 669 req, struct cli_trans_state); 670 NTSTATUS status; 671 672 cli_trans_cleanup_primary(state); 1214 673 1215 674 if (tevent_req_is_nterror(req, &status)) { 1216 675 return status; 676 } 677 678 if ((state->num_rsetup < min_setup) 679 || (state->rparam.total < min_param) 680 || (state->rdata.total < min_data)) { 681 return NT_STATUS_INVALID_NETWORK_RESPONSE; 682 } 683 684 if (recv_flags2 != NULL) { 685 *recv_flags2 = state->recv_flags2; 1217 686 } 1218 687 … … 1248 717 uint8_t *param, uint32_t num_param, uint32_t max_param, 1249 718 uint8_t *data, uint32_t num_data, uint32_t max_data, 1250 uint16_t **rsetup, uint8_t *num_rsetup, 1251 uint8_t **rparam, uint32_t *num_rparam, 1252 uint8_t **rdata, uint32_t *num_rdata) 719 uint16_t *recv_flags2, 720 uint16_t **rsetup, uint8_t min_rsetup, uint8_t *num_rsetup, 721 uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam, 722 uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata) 1253 723 { 1254 724 TALLOC_CTX *frame = talloc_stackframe(); … … 1286 756 } 1287 757 1288 status = cli_trans_recv(req, mem_ctx, rsetup, num_rsetup, 1289 rparam, num_rparam, rdata, num_rdata); 758 status = cli_trans_recv(req, mem_ctx, recv_flags2, 759 rsetup, min_rsetup, num_rsetup, 760 rparam, min_rparam, num_rparam, 761 rdata, min_rdata, num_rdata); 1290 762 fail: 1291 763 TALLOC_FREE(frame); -
vendor/current/source3/libsmb/conncache.c
r414 r740 98 98 static NTSTATUS negative_conn_cache_valuedecode(const char *value) 99 99 { 100 unsigned int v = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR); ;100 unsigned int v = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR); 101 101 102 102 if (value != NULL) { -
vendor/current/source3/libsmb/dsgetdcname.c
r414 r740 22 22 23 23 #include "includes.h" 24 25 #define DSGETDCNAME_FMT "DSGETDCNAME/DOMAIN/%s" 24 #include "libads/sitename_cache.h" 25 #include "../librpc/gen_ndr/ndr_netlogon.h" 26 #include "libads/cldap.h" 27 #include "libads/dns.h" 28 #include "libsmb/clidgram.h" 29 26 30 /* 15 minutes */ 27 31 #define DSGETDCNAME_CACHE_TTL 60*15 … … 123 127 } 124 128 125 return talloc_asprintf_strupper_m(mem_ctx, DSGETDCNAME_FMT, domain); 129 return talloc_asprintf_strupper_m(mem_ctx, "DSGETDCNAME/DOMAIN/%s", 130 domain); 126 131 } 127 132 … … 190 195 r->sockaddr.pdc_ip = talloc_strdup(mem_ctx, addr); 191 196 192 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL,r,197 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, r, 193 198 (ndr_push_flags_fn_t)ndr_push_NETLOGON_SAM_LOGON_RESPONSE_EX); 194 199 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 196 201 } 197 202 198 if (r->domain ) {199 status = dsgetdcname_cache_store(mem_ctx, r->domain , &blob);203 if (r->domain_name) { 204 status = dsgetdcname_cache_store(mem_ctx, r->domain_name, &blob); 200 205 if (!NT_STATUS_IS_OK(status)) { 201 206 goto done; 202 207 } 203 208 if (r->client_site) { 204 sitename_store(r->domain , r->client_site);209 sitename_store(r->domain_name, r->client_site); 205 210 } 206 211 } … … 341 346 } 342 347 343 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL,&r,348 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, 344 349 (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX); 345 350 … … 497 502 dclist = TALLOC_ZERO_ARRAY(mem_ctx, struct ip_service_name, count); 498 503 if (!dclist) { 504 SAFE_FREE(iplist); 499 505 return NT_STATUS_NO_MEMORY; 500 506 } … … 512 518 r->hostname = talloc_strdup(mem_ctx, addr); 513 519 if (!r->hostname) { 520 SAFE_FREE(iplist); 514 521 return NT_STATUS_NO_MEMORY; 515 522 } … … 519 526 *returned_dclist = dclist; 520 527 *returned_count = count; 528 SAFE_FREE(iplist); 521 529 522 530 return NT_STATUS_OK; … … 622 630 * anything about the DC's -- jerry */ 623 631 624 if (!is_zero_addr( (struct sockaddr *)(void *)&r->ss)) {632 if (!is_zero_addr(&r->ss)) { 625 633 count++; 626 634 continue; … … 687 695 info->forest_name = talloc_strdup(mem_ctx, forest_name); 688 696 NT_STATUS_HAVE_NO_MEMORY(info->forest_name); 689 flags |= DS_DNS_FOREST ;697 flags |= DS_DNS_FOREST_ROOT; 690 698 } 691 699 … … 783 791 map_dc_and_domain_names(flags, 784 792 r->pdc_name, 785 r->domain ,793 r->domain_name, 786 794 r->pdc_dns_name, 787 795 r->dns_domain, … … 892 900 /**************************************************************** 893 901 ****************************************************************/ 894 895 static struct event_context *ev_context(void)896 {897 static struct event_context *ctx;898 899 if (!ctx && !(ctx = event_context_init(NULL))) {900 smb_panic("Could not init event context");901 }902 return ctx;903 }904 905 /****************************************************************906 ****************************************************************/907 908 static struct messaging_context *msg_context(TALLOC_CTX *mem_ctx)909 {910 static struct messaging_context *ctx;911 912 if (!ctx && !(ctx = messaging_init(mem_ctx, server_id_self(),913 ev_context()))) {914 smb_panic("Could not init messaging context");915 }916 return ctx;917 }918 902 919 903 /**************************************************************** … … 941 925 NETLOGON_NT_VERSION_5EX_WITH_IP; 942 926 943 if ( !msg_ctx) {944 msg_ctx = msg_context(mem_ctx);927 if (msg_ctx == NULL) { 928 return NT_STATUS_INVALID_PARAMETER; 945 929 } 946 930 … … 954 938 955 939 for (i=0; i<num_dcs; i++) { 940 uint16_t val; 941 int dgm_id; 942 943 generate_random_buffer((uint8_t *)&val, 2); 944 dgm_id = val; 956 945 957 946 ip_list.ss = dclist[i].ss; … … 962 951 } 963 952 964 if (send_getdc_request(mem_ctx, msg_ctx, 965 &dclist[i].ss, domain_name, 966 NULL, nt_version)) 967 { 968 int k; 969 smb_msleep(300); 970 for (k=0; k<5; k++) { 971 if (receive_getdc_response(mem_ctx, 972 &dclist[i].ss, 973 domain_name, 974 &nt_version, 975 &dc_name, 976 &r)) { 977 store_cache = true; 978 namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); 979 goto make_reply; 980 } 981 smb_msleep(1500); 982 } 953 status = nbt_getdc(msg_ctx, &dclist[i].ss, domain_name, 954 NULL, nt_version, 955 mem_ctx, &nt_version, &dc_name, &r); 956 if (NT_STATUS_IS_OK(status)) { 957 store_cache = true; 958 namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); 959 goto make_reply; 983 960 } 984 961 … … 999 976 1000 977 logon1.nt_version = nt_version; 1001 logon1. server= tmp_dc_name;1002 logon1.domain = talloc_strdup_upper(mem_ctx, domain_name);1003 NT_STATUS_HAVE_NO_MEMORY(logon1.domain );978 logon1.pdc_name = tmp_dc_name; 979 logon1.domain_name = talloc_strdup_upper(mem_ctx, domain_name); 980 NT_STATUS_HAVE_NO_MEMORY(logon1.domain_name); 1004 981 1005 982 r->data.nt4 = logon1; -
vendor/current/source3/libsmb/errormap.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "nsswitch/libwbclient/wbclient.h" 23 24 #if HAVE_GSSAPI_GSSAPI_H 25 #include <gssapi/gssapi.h> 26 #elif HAVE_GSSAPI_GSSAPI_GENERIC_H 27 #include <gssapi/gssapi_generic.h> 28 #elif HAVE_GSSAPI_H 29 #include <gssapi.h> 30 #endif 24 31 25 32 /* This map was extracted by the ERRMAPEXTRACT smbtorture command. … … 183 190 */ 184 191 {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, 192 {ERRSRV, ERRbaduid, NT_STATUS_USER_SESSION_DELETED}, 185 193 {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, 186 194 {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, … … 737 745 {ERRDOS, 1022, NT_STATUS(0x0000010c)}, 738 746 {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, 747 {ERRSRV, ERRbaduid, NT_STATUS_USER_SESSION_DELETED}, 739 748 {ERRSRV, ERRbadtype, NT_STATUS_BAD_DEVICE_TYPE}, 740 749 {ERRSRV, ERRaccess, NT_STATUS_NETWORK_ACCESS_DENIED}, … … 1426 1435 { 1427 1436 int i; 1428 if (eclass == 0 && ecode == 0) return NT_STATUS_OK;1437 if (eclass == 0) return NT_STATUS_OK; 1429 1438 for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) { 1430 1439 if (eclass == dos_to_ntstatus_map[i].dos_class && … … 1505 1514 } 1506 1515 1507 /*******************************************************************************1508 Map between wbcErr and NT status.1509 *******************************************************************************/1510 1511 static const struct {1512 wbcErr wbc_err;1513 NTSTATUS nt_status;1514 } wbcErr_ntstatus_map[] = {1515 { WBC_ERR_SUCCESS, NT_STATUS_OK },1516 { WBC_ERR_NOT_IMPLEMENTED, NT_STATUS_NOT_IMPLEMENTED },1517 { WBC_ERR_UNKNOWN_FAILURE, NT_STATUS_UNSUCCESSFUL },1518 { WBC_ERR_NO_MEMORY, NT_STATUS_NO_MEMORY },1519 { WBC_ERR_INVALID_SID, NT_STATUS_INVALID_SID },1520 { WBC_ERR_INVALID_PARAM, NT_STATUS_INVALID_PARAMETER },1521 { WBC_ERR_WINBIND_NOT_AVAILABLE, NT_STATUS_SERVER_DISABLED },1522 { WBC_ERR_DOMAIN_NOT_FOUND, NT_STATUS_NO_SUCH_DOMAIN },1523 { WBC_ERR_INVALID_RESPONSE, NT_STATUS_INVALID_NETWORK_RESPONSE },1524 { WBC_ERR_NSS_ERROR, NT_STATUS_INTERNAL_ERROR },1525 { WBC_ERR_AUTH_ERROR, NT_STATUS_LOGON_FAILURE },1526 { WBC_ERR_UNKNOWN_USER, NT_STATUS_NO_SUCH_USER },1527 { WBC_ERR_UNKNOWN_GROUP, NT_STATUS_NO_SUCH_GROUP },1528 { WBC_ERR_PWD_CHANGE_FAILED, NT_STATUS_PASSWORD_RESTRICTION }1529 };1530 1531 NTSTATUS map_nt_error_from_wbcErr(wbcErr wbc_err)1532 {1533 int i;1534 1535 /* Look through list */1536 for (i=0;i<ARRAY_SIZE(wbcErr_ntstatus_map);i++) {1537 if (wbcErr_ntstatus_map[i].wbc_err == wbc_err) {1538 return wbcErr_ntstatus_map[i].nt_status;1539 }1540 }1541 1542 /* Default return */1543 return NT_STATUS_UNSUCCESSFUL;1544 }1545 1546 1516 1547 1517 #if defined(HAVE_GSSAPI) -
vendor/current/source3/libsmb/libsmb_cache.c
r414 r740 6 6 Copyright (C) John Terpstra 2000 7 7 Copyright (C) Tom Jansen (Ninja ISD) 2002 8 8 9 9 This program is free software; you can redistribute it and/or modify 10 10 it under the terms of the GNU General Public License as published by 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 22 22 23 23 #include "includes.h" 24 #include "libsmb/libsmb.h" 24 25 #include "libsmbclient.h" 25 26 #include "libsmb_internal.h" … … 35 36 char *username; 36 37 SMBCSRV *server; 37 38 38 39 struct smbc_server_cache *next, *prev; 39 40 }; … … 54 55 { 55 56 struct smbc_server_cache * srvcache = NULL; 56 57 57 58 if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) { 58 59 errno = ENOMEM; … … 60 61 return 1; 61 62 } 62 63 63 64 ZERO_STRUCTP(srvcache); 64 65 65 66 srvcache->server = newsrv; 66 67 67 68 srvcache->server_name = SMB_STRDUP(server); 68 69 if (!srvcache->server_name) { … … 70 71 goto failed; 71 72 } 72 73 73 74 srvcache->share_name = SMB_STRDUP(share); 74 75 if (!srvcache->share_name) { … … 76 77 goto failed; 77 78 } 78 79 79 80 srvcache->workgroup = SMB_STRDUP(workgroup); 80 81 if (!srvcache->workgroup) { … … 82 83 goto failed; 83 84 } 84 85 85 86 srvcache->username = SMB_STRDUP(username); 86 87 if (!srvcache->username) { … … 88 89 goto failed; 89 90 } 90 91 91 92 DLIST_ADD(context->internal->server_cache, srvcache); 92 93 return 0; 93 94 94 95 failed: 95 96 SAFE_FREE(srvcache->server_name); … … 98 99 SAFE_FREE(srvcache->username); 99 100 SAFE_FREE(srvcache); 100 101 101 102 return 1; 102 103 } … … 117 118 { 118 119 struct smbc_server_cache * srv = NULL; 119 120 120 121 /* Search the cache lines */ 121 122 for (srv = context->internal->server_cache; srv; srv = srv->next) { 122 123 123 124 if (strcmp(server,srv->server_name) == 0 && 124 125 strcmp(workgroup,srv->workgroup) == 0 && 125 126 strcmp(user, srv->username) == 0) { 126 127 127 128 /* If the share name matches, we're cool */ 128 129 if (strcmp(share, srv->share_name) == 0) { 129 130 return srv->server; 130 131 } 131 132 132 133 /* 133 134 * We only return an empty share name or the attribute … … 137 138 if (*share == '\0' || strcmp(share, "*IPC$") == 0) 138 139 continue; 139 140 140 141 /* 141 142 * Never return an empty share name or the attribute … … 145 146 strcmp(srv->share_name, "*IPC$") == 0) 146 147 continue; 147 148 148 149 /* 149 150 * If we're only allowing one share per server, then … … 152 153 */ 153 154 if (smbc_getOptionOneSharePerServer(context)) { 155 NTSTATUS status; 154 156 /* 155 157 * The currently connected share name … … 157 159 * disconnect from the current share. 158 160 */ 159 if (! cli_tdis(srv->server->cli)) { 161 status = cli_tdis(srv->server->cli); 162 if (!NT_STATUS_IS_OK(status)) { 160 163 /* Sigh. Couldn't disconnect. */ 161 164 cli_shutdown(srv->server->cli); … … 164 167 continue; 165 168 } 166 169 167 170 /* 168 171 * Save the new share name. We've … … 179 182 continue; 180 183 } 181 182 184 183 185 return srv->server; 184 186 } 185 187 } 186 188 } 187 189 188 190 return NULL; 189 191 } … … 200 202 { 201 203 struct smbc_server_cache * srv = NULL; 202 204 203 205 for (srv = context->internal->server_cache; srv; srv = srv->next) { 204 206 if (server == srv->server) { 205 207 206 208 /* remove this sucker */ 207 209 DLIST_REMOVE(context->internal->server_cache, srv); … … 229 231 struct smbc_server_cache * next; 230 232 int could_not_purge_all = 0; 231 233 232 234 for (srv = context->internal->server_cache, 233 235 next = (srv ? srv->next :NULL); … … 235 237 srv = next, 236 238 next = (srv ? srv->next : NULL)) { 237 239 238 240 if (SMBC_remove_unused_server(context, srv->server)) { 239 241 /* could not be removed */ -
vendor/current/source3/libsmb/libsmb_compat.c
r414 r740 7 7 Copyright (C) Tom Jansen (Ninja ISD) 2002 8 8 Copyright (C) Derrell Lipman 2003, 2008 9 9 10 10 This program is free software; you can redistribute it and/or modify 11 11 it under the terms of the GNU General Public License as published by 12 12 the Free Software Foundation; either version 3 of the License, or 13 13 (at your option) any later version. 14 14 15 15 This program is distributed in the hope that it will be useful, 16 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 18 GNU General Public License for more details. 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 56 56 { 57 57 struct smbc_compat_fdlist * f = smbc_compat_fd_avail; 58 58 59 59 if (f) { 60 60 /* We found one that's available */ 61 61 DLIST_REMOVE(smbc_compat_fd_avail, f); 62 63 62 } else { 64 63 /* … … 73 72 return -1; 74 73 } 75 74 76 75 f = SMB_MALLOC_P(struct smbc_compat_fdlist); 77 76 if (!f) { … … 79 78 return -1; 80 79 } 81 80 82 81 f->fd = SMBC_BASE_FD + smbc_compat_nextfd++; 83 82 } 84 83 85 84 f->file = file; 86 85 DLIST_ADD(smbc_compat_fd_in_use, f); 87 86 88 87 return f->fd; 89 88 } … … 96 95 { 97 96 struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; 98 97 99 98 while (f) { 100 99 if (f->fd == fd) … … 102 101 f = f->next; 103 102 } 104 103 105 104 if (f) { 106 105 /* found */ … … 123 122 if (!statcont) 124 123 return -1; 125 124 126 125 smbc_setDebug(statcont, debug); 127 126 smbc_setFunctionAuthData(statcont, fn); 128 127 129 128 if (!smbc_init_context(statcont)) { 130 129 smbc_free_context(statcont, False); 131 130 return -1; 132 131 } 133 132 134 133 smbc_compat_initialized = 1; 135 134 136 135 return 0; 137 136 } … … 144 143 { 145 144 SMBCCTX *old_context = statcont; 146 145 147 146 if (context) { 148 147 /* Save provided context. It must have been initialized! */ 149 148 statcont = context; 150 149 151 150 /* You'd better know what you're doing. We won't help you. */ 152 151 smbc_compat_initialized = 1; 153 152 } 154 153 155 154 return old_context; 156 155 } … … 164 163 SMBCFILE * file; 165 164 int fd; 166 165 167 166 file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode); 168 167 if (!file) 169 168 return -1; 170 169 171 170 fd = add_fd(file); 172 171 if (fd == -1) … … 182 181 SMBCFILE * file; 183 182 int fd; 184 183 185 184 file = smbc_getFunctionCreat(statcont)(statcont, furl, mode); 186 185 if (!file) 187 186 return -1; 188 187 189 188 fd = add_fd(file); 190 189 if (fd == -1) { … … 251 250 SMBCFILE * file; 252 251 int fd; 253 252 254 253 file = smbc_getFunctionOpendir(statcont)(statcont, durl); 255 254 if (!file) 256 255 return -1; 257 256 258 257 fd = add_fd(file); 259 258 if (fd == -1) 260 259 smbc_getFunctionClosedir(statcont)(statcont, file); 261 260 262 261 return fd; 263 262 } … … 373 372 { 374 373 struct timeval tv[2]; 375 374 376 375 if (utbuf == NULL) 377 376 return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL); 378 377 379 378 tv[0].tv_sec = utbuf->actime; 380 379 tv[1].tv_sec = utbuf->modtime; 381 380 tv[0].tv_usec = tv[1].tv_usec = 0; 382 381 383 382 return smbc_getFunctionUtimes(statcont)(statcont, fname, tv); 384 383 } … … 535 534 { 536 535 SMBCFILE * file; 537 536 538 537 file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname); 539 538 if (!file) return -1; -
vendor/current/source3/libsmb/libsmb_context.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" 29 #include "secrets.h" 28 30 29 31 … … 44 46 char *home = NULL; 45 47 TALLOC_CTX *frame = talloc_stackframe(); 46 47 load_case_tables ();48 49 setup_logging("libsmbclient", True);48 49 load_case_tables_library(); 50 51 setup_logging("libsmbclient", DEBUG_STDOUT); 50 52 51 53 /* Here we would open the smb.conf file if needed ... */ 52 54 53 55 lp_set_in_client(True); 54 56 55 57 home = getenv("HOME"); 56 58 if (home) { … … 66 68 } 67 69 } 68 70 69 71 if (!conf_loaded) { 70 72 /* … … 74 76 * defaults ... 75 77 */ 76 78 77 79 if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { 78 80 DEBUG(5, ("Could not load config file: %s\n", … … 98 100 } 99 101 } 100 102 101 103 load_interfaces(); /* Load the list of interfaces ... */ 102 104 103 105 reopen_logs(); /* Get logging working ... */ 104 106 105 107 /* 106 108 * Block SIGPIPE (from lib/util_sock.c: write()) … … 108 110 */ 109 111 BlockSignals(True, SIGPIPE); 110 112 111 113 /* Create the mutex we'll use to protect initialized_ctx_count */ 112 114 if (SMB_THREAD_CREATE_MUTEX("initialized_ctx_count_mutex", … … 137 139 { 138 140 SMBCCTX *context; 139 141 140 142 /* The first call to this function should initialize the module */ 141 143 SMB_THREAD_ONCE(&SMBC_initialized, SMBC_module_init, NULL); … … 150 152 return NULL; 151 153 } 152 154 153 155 ZERO_STRUCTP(context); 154 156 155 157 context->internal = SMB_MALLOC_P(struct SMBC_internal_data); 156 158 if (!context->internal) { … … 159 161 return NULL; 160 162 } 161 163 162 164 /* Initialize the context and establish reasonable defaults */ 163 165 ZERO_STRUCTP(context->internal); 164 166 165 167 smbc_setDebug(context, 0); 166 168 smbc_setTimeout(context, 20000); 167 169 168 170 smbc_setOptionFullTimeNames(context, False); 169 171 smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); … … 177 179 smbc_setOptionUseCCache(context, true); 178 180 } 179 181 180 182 smbc_setFunctionAuthData(context, SMBC_get_auth_data); 181 183 smbc_setFunctionCheckServer(context, SMBC_check_server); 182 184 smbc_setFunctionRemoveUnusedServer(context, SMBC_remove_unused_server); 183 185 184 186 smbc_setOptionUserData(context, NULL); 185 187 smbc_setFunctionAddCachedServer(context, SMBC_add_cached_server); … … 187 189 smbc_setFunctionRemoveCachedServer(context, SMBC_remove_cached_server); 188 190 smbc_setFunctionPurgeCachedServers(context, SMBC_purge_cached_servers); 189 191 190 192 smbc_setFunctionOpen(context, SMBC_open_ctx); 191 193 smbc_setFunctionCreat(context, SMBC_creat_ctx); … … 216 218 smbc_setFunctionRemovexattr(context, SMBC_removexattr_ctx); 217 219 smbc_setFunctionListxattr(context, SMBC_listxattr_ctx); 218 220 219 221 smbc_setFunctionOpenPrintJob(context, SMBC_open_print_job_ctx); 220 222 smbc_setFunctionPrintFile(context, SMBC_print_file_ctx); 221 223 smbc_setFunctionListPrintJobs(context, SMBC_list_print_jobs_ctx); 222 224 smbc_setFunctionUnlinkPrintJob(context, SMBC_unlink_print_job_ctx); 223 225 224 226 return context; 225 227 } … … 240 242 return 1; 241 243 } 242 244 243 245 if (shutdown_ctx) { 244 246 SMBCFILE * f; 245 247 DEBUG(1,("Performing aggressive shutdown.\n")); 246 248 247 249 f = context->internal->files; 248 250 while (f) { … … 251 253 } 252 254 context->internal->files = NULL; 253 255 254 256 /* First try to remove the servers the nice way. */ 255 257 if (smbc_getFunctionPurgeCachedServers(context)(context)) { … … 294 296 } 295 297 } 296 298 297 299 /* Things we have to clean up */ 298 300 smbc_setWorkgroup(context, NULL); 299 301 smbc_setNetbiosName(context, NULL); 300 302 smbc_setUser(context, NULL); 301 303 302 304 DEBUG(3, ("Context %p successfully freed\n", context)); 303 305 … … 325 327 smb_panic("error unlocking 'initialized_ctx_count'"); 326 328 } 327 329 328 330 return 0; 329 331 } … … 347 349 const char *s; 348 350 } option_value; 349 351 350 352 va_start(ap, option_name); 351 353 352 354 if (strcmp(option_name, "debug_to_stderr") == 0) { 353 355 option_value.b = (bool) va_arg(ap, int); 354 356 smbc_setOptionDebugToStderr(context, option_value.b); 355 357 356 358 } else if (strcmp(option_name, "full_time_names") == 0) { 357 359 option_value.b = (bool) va_arg(ap, int); 358 360 smbc_setOptionFullTimeNames(context, option_value.b); 359 361 360 362 } else if (strcmp(option_name, "open_share_mode") == 0) { 361 363 option_value.i = va_arg(ap, int); 362 364 smbc_setOptionOpenShareMode(context, option_value.i); 363 365 364 366 } else if (strcmp(option_name, "auth_function") == 0) { 365 367 option_value.auth_fn = 366 368 va_arg(ap, smbc_get_auth_data_with_context_fn); 367 369 smbc_setFunctionAuthDataWithContext(context, option_value.auth_fn); 368 370 369 371 } else if (strcmp(option_name, "user_data") == 0) { 370 372 option_value.v = va_arg(ap, void *); 371 373 smbc_setOptionUserData(context, option_value.v); 372 374 373 375 } else if (strcmp(option_name, "smb_encrypt_level") == 0) { 374 376 option_value.s = va_arg(ap, const char *); … … 383 385 SMBC_ENCRYPTLEVEL_REQUIRE); 384 386 } 385 387 386 388 } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { 387 389 option_value.i = va_arg(ap, int); 388 390 smbc_setOptionBrowseMaxLmbCount(context, option_value.i); 389 391 390 392 } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { 391 393 option_value.b = (bool) va_arg(ap, int); 392 394 smbc_setOptionUrlEncodeReaddirEntries(context, option_value.b); 393 395 394 396 } else if (strcmp(option_name, "one_share_per_server") == 0) { 395 397 option_value.b = (bool) va_arg(ap, int); 396 398 smbc_setOptionOneSharePerServer(context, option_value.b); 397 399 398 400 } else if (strcmp(option_name, "use_kerberos") == 0) { 399 401 option_value.b = (bool) va_arg(ap, int); 400 402 smbc_setOptionUseKerberos(context, option_value.b); 401 403 402 404 } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { 403 405 option_value.b = (bool) va_arg(ap, int); 404 406 smbc_setOptionFallbackAfterKerberos(context, option_value.b); 405 407 406 408 } else if (strcmp(option_name, "use_ccache") == 0) { 407 409 option_value.b = (bool) va_arg(ap, int); … … 412 414 smbc_setOptionNoAutoAnonymousLogin(context, option_value.b); 413 415 } 414 416 415 417 va_end(ap); 416 418 } … … 431 433 return (void *) smbc_getOptionDebugToStderr(context); 432 434 #endif 433 435 434 436 } else if (strcmp(option_name, "full_time_names") == 0) { 435 437 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 438 440 return (void *) smbc_getOptionFullTimeNames(context); 439 441 #endif 440 442 441 443 } else if (strcmp(option_name, "open_share_mode") == 0) { 442 444 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 445 447 return (void *) smbc_getOptionOpenShareMode(context); 446 448 #endif 447 449 448 450 } else if (strcmp(option_name, "auth_function") == 0) { 449 451 return (void *) smbc_getFunctionAuthDataWithContext(context); 450 452 451 453 } else if (strcmp(option_name, "user_data") == 0) { 452 454 return smbc_getOptionUserData(context); 453 455 454 456 } else if (strcmp(option_name, "smb_encrypt_level") == 0) { 455 457 switch(smbc_getOptionSmbEncryptionLevel(context)) … … 462 464 return (void *) "require"; 463 465 } 464 466 465 467 } else if (strcmp(option_name, "smb_encrypt_on") == 0) { 466 468 SMBCSRV *s; 467 469 unsigned int num_servers = 0; 468 470 469 471 for (s = context->internal->servers; s; s = s->next) { 470 472 num_servers++; … … 478 480 return (void *) (bool) (num_servers > 0); 479 481 #endif 480 482 481 483 } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { 482 484 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 485 487 return (void *) smbc_getOptionBrowseMaxLmbCount(context); 486 488 #endif 487 489 488 490 } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { 489 491 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 492 494 return (void *) (bool) smbc_getOptionUrlEncodeReaddirEntries(context); 493 495 #endif 494 496 495 497 } else if (strcmp(option_name, "one_share_per_server") == 0) { 496 498 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 499 501 return (void *) (bool) smbc_getOptionOneSharePerServer(context); 500 502 #endif 501 503 502 504 } else if (strcmp(option_name, "use_kerberos") == 0) { 503 505 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 506 508 return (void *) (bool) smbc_getOptionUseKerberos(context); 507 509 #endif 508 510 509 511 } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { 510 512 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 513 515 return (void *) (bool) smbc_getOptionFallbackAfterKerberos(context); 514 516 #endif 515 517 516 518 } else if (strcmp(option_name, "use_ccache") == 0) { 517 519 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) … … 528 530 #endif 529 531 } 530 532 531 533 return NULL; 532 534 } … … 544 546 { 545 547 int pid; 546 548 547 549 if (!context) { 548 550 errno = EBADF; 549 551 return NULL; 550 552 } 551 553 552 554 /* Do not initialise the same client twice */ 553 555 if (context->internal->initialized) { 554 556 return NULL; 555 557 } 556 557 if (context->internal->debug_stderr) { 558 /* 559 * Hmmm... Do we want a unique dbf per-thread? For now, we'll just 560 * leave it up to the user. If any one context spefies debug to 561 * stderr then all will be. 562 */ 563 dbf = x_stderr; 564 x_setbuf(x_stderr, NULL); 565 } 566 558 567 559 if ((!smbc_getFunctionAuthData(context) && 568 560 !smbc_getFunctionAuthDataWithContext(context)) || 569 561 smbc_getDebug(context) < 0 || 570 562 smbc_getDebug(context) > 100) { 571 563 572 564 errno = EINVAL; 573 565 return NULL; 574 575 } 576 566 567 } 568 577 569 if (!smbc_getUser(context)) { 578 570 /* 579 571 * FIXME: Is this the best way to get the user info? 580 572 */ 581 573 char *user = getenv("USER"); 582 574 /* walk around as "guest" if no username can be found */ 583 575 if (!user) { … … 595 587 SAFE_FREE(user); 596 588 597 589 if (!smbc_getUser(context)) { 598 590 errno = ENOMEM; 599 591 return NULL; 600 592 } 601 593 } 602 594 603 595 if (!smbc_getNetbiosName(context)) { 604 596 /* … … 629 621 return NULL; 630 622 } 631 623 632 624 smbc_setNetbiosName(context, netbios_name); 633 625 SAFE_FREE(netbios_name); … … 638 630 } 639 631 } 640 632 641 633 DEBUG(1, ("Using netbios name %s.\n", smbc_getNetbiosName(context))); 642 634 643 635 if (!smbc_getWorkgroup(context)) { 644 636 char *workgroup; … … 665 657 } 666 658 } 667 659 668 660 DEBUG(1, ("Using workgroup %s.\n", smbc_getWorkgroup(context))); 669 661 670 662 /* shortest timeout is 1 second */ 671 663 if (smbc_getTimeout(context) > 0 && smbc_getTimeout(context) < 1000) 672 664 smbc_setTimeout(context, 1000); 673 665 674 666 context->internal->initialized = True; 675 667 … … 685 677 smb_panic("error unlocking 'initialized_ctx_count'"); 686 678 } 687 679 688 680 return context; 689 681 } -
vendor/current/source3/libsmb/libsmb_dir.c
r414 r740 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 27 #include "popt_common.h" 26 28 #include "libsmbclient.h" 27 29 #include "libsmb_internal.h" 28 #include "../librpc/gen_ndr/cli_srvsvc.h" 30 #include "rpc_client/cli_pipe.h" 31 #include "../librpc/gen_ndr/ndr_srvsvc_c.h" 32 #include "libsmb/nmblib.h" 29 33 30 34 /* … … 147 151 148 152 if (add_dirent(dir, name, comment, dirent_type) < 0) { 149 150 153 /* An error occurred, what do we do? */ 151 154 /* FIXME: Add some code here */ 155 /* Change cli_NetServerEnum to take a fn 156 returning NTSTATUS... JRA. */ 152 157 } 153 158 … … 227 232 228 233 if (add_dirent(dir, name, comment, dirent_type) < 0) { 229 230 234 /* An error occurred, what do we do? */ 231 235 /* FIXME: Add some code here */ 232 233 } 234 } 235 236 static void 236 /* Change cli_NetServerEnum to take a fn 237 returning NTSTATUS... JRA. */ 238 } 239 } 240 241 static NTSTATUS 237 242 dir_list_fn(const char *mnt, 238 file_info *finfo,243 struct file_info *finfo, 239 244 const char *mask, 240 245 void *state) … … 242 247 243 248 if (add_dirent((SMBCFILE *)state, finfo->name, "", 244 (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { 245 246 /* Handle an error ... */ 247 248 /* FIXME: Add some code ... */ 249 250 } 251 249 (finfo->mode&FILE_ATTRIBUTE_DIRECTORY?SMBC_DIR:SMBC_FILE)) < 0) { 250 SMBCFILE *dir = (SMBCFILE *)state; 251 return map_nt_error_from_unix(dir->dir_error); 252 } 253 return NT_STATUS_OK; 252 254 } 253 255 … … 272 274 uint32_t resume_handle = 0; 273 275 uint32_t total_entries = 0; 276 struct dcerpc_binding_handle *b; 274 277 275 278 /* Open the server service pipe */ … … 287 290 info_ctr.ctr.ctr1 = &ctr1; 288 291 292 b = pipe_hnd->binding_handle; 293 289 294 /* Issue the NetShareEnum RPC call and retrieve the response */ 290 nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(),295 nt_status = dcerpc_srvsvc_NetShareEnumAll(b, talloc_tos(), 291 296 pipe_hnd->desthost, 292 297 &info_ctr, … … 297 302 298 303 /* Was it successful? */ 299 if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result) || 300 total_entries == 0) { 304 if (!NT_STATUS_IS_OK(nt_status)) { 305 /* Nope. Go clean up. */ 306 result = ntstatus_to_werror(nt_status); 307 goto done; 308 } 309 310 if (!W_ERROR_IS_OK(result)) { 301 311 /* Nope. Go clean up. */ 302 312 goto done; 303 313 } 314 315 if (total_entries == 0) { 316 /* Nope. Go clean up. */ 317 result = WERR_GENERAL_FAILURE; 318 goto done; 319 } 304 320 305 321 /* For each returned entry... */ … … 370 386 if (!context || !context->internal->initialized) { 371 387 DEBUG(4, ("no valid context\n")); 388 TALLOC_FREE(frame); 372 389 errno = EINVAL + 8192; 373 TALLOC_FREE(frame);374 390 return NULL; 375 391 … … 378 394 if (!fname) { 379 395 DEBUG(4, ("no valid fname\n")); 396 TALLOC_FREE(frame); 380 397 errno = EINVAL + 8193; 381 TALLOC_FREE(frame);382 398 return NULL; 383 399 } … … 394 410 &options)) { 395 411 DEBUG(4, ("no valid path\n")); 412 TALLOC_FREE(frame); 396 413 errno = EINVAL + 8194; 397 TALLOC_FREE(frame);398 414 return NULL; 399 415 } … … 406 422 if (SMBC_check_options(server, share, path, options)) { 407 423 DEBUG(4, ("unacceptable options (%s)\n", options)); 424 TALLOC_FREE(frame); 408 425 errno = EINVAL + 8195; 409 TALLOC_FREE(frame);410 426 return NULL; 411 427 } … … 414 430 user = talloc_strdup(frame, smbc_getUser(context)); 415 431 if (!user) { 432 TALLOC_FREE(frame); 416 433 errno = ENOMEM; 417 TALLOC_FREE(frame);418 434 return NULL; 419 435 } … … 423 439 424 440 if (!dir) { 441 TALLOC_FREE(frame); 425 442 errno = ENOMEM; 426 TALLOC_FREE(frame);427 443 return NULL; 428 444 } … … 442 458 int count; 443 459 int max_lmb_count; 444 struct ip_service *ip_list;445 struct ip_service server_addr;460 struct sockaddr_storage *ip_list; 461 struct sockaddr_storage server_addr; 446 462 struct user_auth_info u_info; 463 NTSTATUS status; 447 464 448 465 if (share[0] != (char)0 || path[0] != (char)0) { 449 466 450 errno = EINVAL + 8196;451 467 if (dir) { 452 468 SAFE_FREE(dir->fname); … … 454 470 } 455 471 TALLOC_FREE(frame); 472 errno = EINVAL + 8196; 456 473 return NULL; 457 474 } … … 484 501 485 502 ip_list = NULL; 486 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, 487 &count))) 503 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(), 504 &ip_list, &count); 505 if (!NT_STATUS_IS_OK(status)) 488 506 { 489 507 490 SAFE_FREE(ip_list);491 492 if (!find_master_ip(workgroup, &server_addr .ss)) {508 TALLOC_FREE(ip_list); 509 510 if (!find_master_ip(workgroup, &server_addr)) { 493 511 494 512 if (dir) { … … 496 514 SAFE_FREE(dir); 497 515 } 516 TALLOC_FREE(frame); 498 517 errno = ENOENT; 499 TALLOC_FREE(frame);500 518 return NULL; 501 519 } 502 520 503 ip_list = (struct ip_service *)memdup( 504 &server_addr, sizeof(server_addr)); 521 ip_list = (struct sockaddr_storage *)talloc_memdup( 522 talloc_tos(), &server_addr, 523 sizeof(server_addr)); 505 524 if (ip_list == NULL) { 525 if (dir) { 526 SAFE_FREE(dir->fname); 527 SAFE_FREE(dir); 528 } 529 TALLOC_FREE(frame); 506 530 errno = ENOMEM; 507 TALLOC_FREE(frame);508 531 return NULL; 509 532 } … … 516 539 struct cli_state *cli = NULL; 517 540 518 print_sockaddr(addr, sizeof(addr), &ip_list[i] .ss);541 print_sockaddr(addr, sizeof(addr), &ip_list[i]); 519 542 DEBUG(99, ("Found master browser %d of %d: %s\n", 520 543 i+1, MAX(count, max_lmb_count), … … 537 560 538 561 if (!workgroup || !server) { 562 if (dir) { 563 SAFE_FREE(dir->fname); 564 SAFE_FREE(dir); 565 } 566 TALLOC_FREE(frame); 539 567 errno = ENOMEM; 540 TALLOC_FREE(frame);541 568 return NULL; 542 569 } … … 572 599 } 573 600 574 SAFE_FREE(ip_list);601 TALLOC_FREE(ip_list); 575 602 } else { 576 603 /* … … 582 609 583 610 /* Should not have empty share with path */ 584 errno = EINVAL + 8197;585 611 if (dir) { 586 612 SAFE_FREE(dir->fname); … … 588 614 } 589 615 TALLOC_FREE(frame); 616 errno = EINVAL + 8197; 590 617 return NULL; 591 618 … … 645 672 SAFE_FREE(dir); 646 673 } 674 TALLOC_FREE(frame); 647 675 errno = EPERM; 648 TALLOC_FREE(frame);649 676 return NULL; 650 677 … … 749 776 char *targetpath; 750 777 struct cli_state *targetcli; 778 NTSTATUS status; 751 779 752 780 /* We connect to the server and list the directory */ … … 792 820 } 793 821 794 if (cli_list(targetcli, targetpath,795 aDIR | aSYSTEM | aHIDDEN,796 dir_list_fn, (void *)dir) < 0) { 797 822 status = cli_list(targetcli, targetpath, 823 FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, 824 dir_list_fn, (void *)dir); 825 if (!NT_STATUS_IS_OK(status)) { 798 826 if (dir) { 799 827 SAFE_FREE(dir->fname); … … 845 873 } 846 874 875 TALLOC_FREE(frame); 847 876 errno = saved_errno; 848 TALLOC_FREE(frame);849 877 return NULL; 850 878 } … … 1049 1077 while ((dirlist = dir->dir_next)) { 1050 1078 struct smbc_dirent *dirent; 1079 struct smbc_dirent *currentEntry = (struct smbc_dirent *)ndir; 1051 1080 1052 1081 if (!dirlist->dirent) { … … 1085 1114 } 1086 1115 1087 memcpy(ndir, dirent, reqd); /* Copy the data in ... */ 1088 1089 ((struct smbc_dirent *)ndir)->comment = 1090 (char *)(&((struct smbc_dirent *)ndir)->name + 1091 dirent->namelen + 1092 1); 1116 memcpy(currentEntry, dirent, reqd); /* Copy the data in ... */ 1117 1118 currentEntry->comment = ¤tEntry->name[0] + 1119 dirent->namelen + 1; 1093 1120 1094 1121 ndir += reqd; 1095 1096 1122 rem -= reqd; 1123 1124 /* Try and align the struct for the next entry 1125 on a valid pointer boundary by appending zeros */ 1126 while((rem > 0) && ((unsigned long long)ndir & (sizeof(void*) - 1))) { 1127 *ndir = '\0'; 1128 rem--; 1129 ndir++; 1130 currentEntry->dirlen++; 1131 } 1097 1132 1098 1133 dir->dir_next = dirlist = dirlist -> next; … … 1203 1238 */ 1204 1239 1205 static void1240 static NTSTATUS 1206 1241 rmdir_list_fn(const char *mnt, 1207 file_info *finfo,1242 struct file_info *finfo, 1208 1243 const char *mask, 1209 1244 void *state) … … 1214 1249 *smbc_rmdir_dirempty = false; 1215 1250 } 1251 return NT_STATUS_OK; 1216 1252 } 1217 1253 … … 1303 1339 char *lpath; 1304 1340 bool smbc_rmdir_dirempty = true; 1341 NTSTATUS status; 1305 1342 1306 1343 lpath = talloc_asprintf(frame, "%s\\*", … … 1312 1349 } 1313 1350 1314 if (cli_list(targetcli, lpath, 1315 aDIR | aSYSTEM | aHIDDEN, 1316 rmdir_list_fn, 1317 &smbc_rmdir_dirempty) < 0) { 1318 1351 status = cli_list(targetcli, lpath, 1352 FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, 1353 rmdir_list_fn, 1354 &smbc_rmdir_dirempty); 1355 1356 if (!NT_STATUS_IS_OK(status)) { 1319 1357 /* Fix errno to ignore latest error ... */ 1320 1358 DEBUG(5, ("smbc_rmdir: " … … 1578 1616 mode = 0; 1579 1617 1580 if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY;1581 if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH;1582 if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;1583 if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;1618 if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= FILE_ATTRIBUTE_READONLY; 1619 if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= FILE_ATTRIBUTE_ARCHIVE; 1620 if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= FILE_ATTRIBUTE_SYSTEM; 1621 if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= FILE_ATTRIBUTE_HIDDEN; 1584 1622 1585 1623 if (!NT_STATUS_IS_OK(cli_setatr(targetcli, targetpath, mode, 0))) { … … 1770 1808 /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ 1771 1809 1772 if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetpath, aSYSTEM | aHIDDEN))) {1810 if (!NT_STATUS_IS_OK(cli_unlink(targetcli, targetpath, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) { 1773 1811 1774 1812 errno = SMBC_errno(context, targetcli); … … 1976 2014 1977 2015 if (eno != EEXIST || 1978 !NT_STATUS_IS_OK(cli_unlink(targetcli1, targetpath2, aSYSTEM | aHIDDEN)) ||2016 !NT_STATUS_IS_OK(cli_unlink(targetcli1, targetpath2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) || 1979 2017 !NT_STATUS_IS_OK(cli_rename(targetcli1, targetpath1, targetpath2))) { 1980 2018 -
vendor/current/source3/libsmb/libsmb_file.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" … … 51 52 NTSTATUS status = NT_STATUS_OBJECT_PATH_INVALID; 52 53 TALLOC_CTX *frame = talloc_stackframe(); 53 54 54 55 if (!context || !context->internal->initialized) { 55 56 56 errno = EINVAL; /* Best I can think of ... */ 57 57 TALLOC_FREE(frame); 58 58 return NULL; 59 60 } 61 59 } 60 62 61 if (!fname) { 63 64 62 errno = EINVAL; 65 63 TALLOC_FREE(frame); 66 64 return NULL; 67 68 } 69 65 } 66 70 67 if (SMBC_parse_path(frame, 71 68 context, … … 82 79 return NULL; 83 80 } 84 81 85 82 if (!user || user[0] == (char)0) { 86 83 user = talloc_strdup(frame, smbc_getUser(context)); … … 91 88 } 92 89 } 93 90 94 91 srv = SMBC_server(frame, context, True, 95 92 server, share, &workgroup, &user, &password); 96 97 93 if (!srv) { 98 94 if (errno == EPERM) errno = EACCES; … … 100 96 return NULL; /* SMBC_server sets errno */ 101 97 } 102 98 103 99 /* Hmmm, the test for a directory is suspect here ... FIXME */ 104 100 105 101 if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { 106 102 status = NT_STATUS_OBJECT_PATH_INVALID; 107 103 } else { 108 104 file = SMB_MALLOC_P(SMBCFILE); 109 110 105 if (!file) { 111 106 errno = ENOMEM; … … 113 108 return NULL; 114 109 } 115 110 116 111 ZERO_STRUCTP(file); 117 112 118 113 /*d_printf(">>>open: resolving %s\n", path);*/ 119 114 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 127 122 } 128 123 /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ 129 124 130 125 status = cli_open(targetcli, targetpath, flags, 131 126 context->internal->share_mode, &fd); 132 127 if (!NT_STATUS_IS_OK(status)) { 133 128 134 129 /* Handle the error ... */ 135 130 136 131 SAFE_FREE(file); 137 132 errno = SMBC_errno(context, targetcli); 138 133 TALLOC_FREE(frame); 139 134 return NULL; 140 141 135 } 142 136 143 137 /* Fill in file struct */ 144 138 145 139 file->cli_fd = fd; 146 140 file->fname = SMB_STRDUP(fname); … … 148 142 file->offset = 0; 149 143 file->file = True; 150 144 151 145 DLIST_ADD(context->internal->files, file); 152 146 153 147 /* 154 148 * If the file was opened in O_APPEND mode, all write … … 181 175 } 182 176 } 183 177 184 178 TALLOC_FREE(frame); 185 179 return file; 186 187 } 188 180 } 181 189 182 /* Check if opendir needed ... */ 190 183 191 184 if (!NT_STATUS_IS_OK(status)) { 192 185 int eno = 0; 193 186 194 187 eno = SMBC_errno(context, srv->cli); 195 188 file = smbc_getFunctionOpendir(context)(context, fname); … … 197 190 TALLOC_FREE(frame); 198 191 return file; 199 200 } 201 192 } 193 202 194 errno = EINVAL; /* FIXME, correct errno ? */ 203 195 TALLOC_FREE(frame); 204 196 return NULL; 205 206 197 } 207 198 … … 215 206 mode_t mode) 216 207 { 217 218 208 if (!context || !context->internal->initialized) { 219 220 209 errno = EINVAL; 221 210 return NULL; 222 223 } 224 211 } 212 225 213 return SMBC_open_ctx(context, path, 226 214 O_WRONLY | O_CREAT | O_TRUNC, mode); … … 243 231 struct cli_state *targetcli = NULL; 244 232 TALLOC_CTX *frame = talloc_stackframe(); 245 233 246 234 /* 247 235 * offset: … … 254 242 */ 255 243 off_t offset; 256 244 257 245 if (!context || !context->internal->initialized) { 258 259 errno = EINVAL; 260 TALLOC_FREE(frame); 261 return -1; 262 263 } 264 246 errno = EINVAL; 247 TALLOC_FREE(frame); 248 return -1; 249 } 250 265 251 DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); 266 252 267 253 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 268 254 errno = EBADF; 269 255 TALLOC_FREE(frame); 270 256 return -1; 271 272 } 273 257 } 258 274 259 offset = file->offset; 275 260 276 261 /* Check that the buffer exists ... */ 277 262 278 263 if (buf == NULL) { 279 264 errno = EINVAL; 280 265 TALLOC_FREE(frame); 281 266 return -1; 282 283 } 284 267 } 268 285 269 /*d_printf(">>>read: parsing %s\n", file->fname);*/ 286 270 if (SMBC_parse_path(frame, … … 298 282 return -1; 299 283 } 300 284 301 285 /*d_printf(">>>read: resolving %s\n", path);*/ 302 286 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 309 293 } 310 294 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 311 295 312 296 ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); 313 297 314 298 if (ret < 0) { 315 316 299 errno = SMBC_errno(context, targetcli); 317 300 TALLOC_FREE(frame); 318 301 return -1; 319 320 } 321 302 } 303 322 304 file->offset += ret; 323 305 324 306 DEBUG(4, (" --> %d\n", ret)); 325 307 326 308 TALLOC_FREE(frame); 327 309 return ret; /* Success, ret bytes of data ... */ 328 329 310 } 330 311 … … 339 320 size_t count) 340 321 { 341 int ret;342 322 off_t offset; 343 323 char *server = NULL, *share = NULL, *user = NULL, *password = NULL; … … 346 326 struct cli_state *targetcli = NULL; 347 327 TALLOC_CTX *frame = talloc_stackframe(); 348 328 NTSTATUS status; 329 349 330 /* First check all pointers before dereferencing them */ 350 331 351 332 if (!context || !context->internal->initialized) { 352 353 errno = EINVAL; 354 TALLOC_FREE(frame); 355 return -1; 356 357 } 358 333 errno = EINVAL; 334 TALLOC_FREE(frame); 335 return -1; 336 } 337 359 338 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 360 339 errno = EBADF; … … 362 341 return -1; 363 342 } 364 343 365 344 /* Check that the buffer exists ... */ 366 345 367 346 if (buf == NULL) { 368 347 errno = EINVAL; 369 348 TALLOC_FREE(frame); 370 349 return -1; 371 372 } 373 350 } 351 374 352 offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ 375 353 376 354 /*d_printf(">>>write: parsing %s\n", file->fname);*/ 377 355 if (SMBC_parse_path(frame, … … 400 378 } 401 379 /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ 402 403 ret = cli_write(targetcli, file->cli_fd, 404 0, (char *)buf, offset, count); 405 406 if (ret <= 0) { 407 errno = SMBC_errno(context, targetcli); 408 TALLOC_FREE(frame); 409 return -1; 410 411 } 412 413 file->offset += ret; 414 380 381 status = cli_writeall(targetcli, file->cli_fd, 382 0, (uint8_t *)buf, offset, count, NULL); 383 if (!NT_STATUS_IS_OK(status)) { 384 errno = map_errno_from_nt_status(status); 385 TALLOC_FREE(frame); 386 return -1; 387 } 388 389 file->offset += count; 390 415 391 TALLOC_FREE(frame); 416 return ret; /* Success, 0 bytes of data ... */392 return count; /* Success, 0 bytes of data ... */ 417 393 } 418 394 … … 431 407 struct cli_state *targetcli = NULL; 432 408 TALLOC_CTX *frame = talloc_stackframe(); 433 409 434 410 if (!context || !context->internal->initialized) { 435 436 errno = EINVAL; 437 TALLOC_FREE(frame); 438 return -1; 439 } 440 411 errno = EINVAL; 412 TALLOC_FREE(frame); 413 return -1; 414 } 415 441 416 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 442 417 errno = EBADF; … … 444 419 return -1; 445 420 } 446 421 447 422 /* IS a dir ... */ 448 423 if (!file->file) { … … 450 425 return smbc_getFunctionClosedir(context)(context, file); 451 426 } 452 427 453 428 /*d_printf(">>>close: parsing %s\n", file->fname);*/ 454 429 if (SMBC_parse_path(frame, … … 466 441 return -1; 467 442 } 468 443 469 444 /*d_printf(">>>close: resolving %s\n", path);*/ 470 445 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 477 452 } 478 453 /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ 479 454 480 455 if (!NT_STATUS_IS_OK(cli_close(targetcli, file->cli_fd))) { 481 482 456 DEBUG(3, ("cli_close failed on %s. purging server.\n", 483 457 file->fname)); … … 492 466 TALLOC_FREE(frame); 493 467 return -1; 494 495 } 496 468 } 469 497 470 DLIST_REMOVE(context->internal->files, file); 498 471 SAFE_FREE(file->fname); 499 472 SAFE_FREE(file); 500 473 TALLOC_FREE(frame); 501 502 474 return 0; 503 475 } … … 524 496 time_t write_time; 525 497 TALLOC_CTX *frame = talloc_stackframe(); 526 498 527 499 if (!context || !context->internal->initialized) { 528 529 500 errno = EINVAL; 530 501 TALLOC_FREE(frame); 531 502 return False; 532 503 } 533 504 534 505 /* path fixup for . and .. */ 535 506 if (strequal(path, ".") || strequal(path, "..")) { … … 551 522 } 552 523 DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); 553 524 554 525 if (!cli_resolve_path(frame, "", context->internal->auth_info, 555 526 srv->cli, fixedpath, … … 560 531 return False; 561 532 } 562 533 563 534 if (!srv->no_pathinfo2 && 564 cli_qpathinfo2(targetcli, targetpath,535 NT_STATUS_IS_OK(cli_qpathinfo2(targetcli, targetpath, 565 536 create_time_ts, 566 537 access_time_ts, 567 538 write_time_ts, 568 539 change_time_ts, 569 size, mode, ino)) {540 size, mode, ino))) { 570 541 TALLOC_FREE(frame); 571 542 return True; 572 543 } 573 544 574 545 /* if this is NT then don't bother with the getatr */ 575 546 if (targetcli->capabilities & CAP_NT_SMBS) { … … 578 549 return False; 579 550 } 580 551 581 552 if (NT_STATUS_IS_OK(cli_getatr(targetcli, targetpath, mode, size, &write_time))) { 582 583 553 struct timespec w_time_ts; 584 554 585 555 w_time_ts = convert_time_t_to_timespec(write_time); 586 587 556 if (write_time_ts != NULL) { 588 557 *write_time_ts = w_time_ts; 589 558 } 590 591 559 if (create_time_ts != NULL) { 592 560 *create_time_ts = w_time_ts; 593 561 } 594 595 562 if (access_time_ts != NULL) { 596 563 *access_time_ts = w_time_ts; 597 564 } 598 599 565 if (change_time_ts != NULL) { 600 566 *change_time_ts = w_time_ts; 601 567 } 602 603 568 srv->no_pathinfo2 = True; 604 569 TALLOC_FREE(frame); 605 570 return True; 606 571 } 607 572 608 573 errno = EPERM; 609 574 TALLOC_FREE(frame); 610 575 return False; 611 612 576 } 613 577 … … 633 597 int ret; 634 598 TALLOC_CTX *frame = talloc_stackframe(); 635 599 636 600 /* 637 601 * First, try setpathinfo (if qpathinfo succeeded), for it is the … … 641 605 */ 642 606 if (srv->no_pathinfo || 643 ! cli_setpathinfo(srv->cli, path,644 645 646 647 648 mode)) {649 607 !NT_STATUS_IS_OK(cli_setpathinfo_basic(srv->cli, path, 608 create_time, 609 access_time, 610 write_time, 611 change_time, 612 mode))) { 613 650 614 /* 651 615 * setpathinfo is not supported; go to plan B. … … 657 621 * supports both times. 658 622 */ 659 623 660 624 /* Don't try {q,set}pathinfo() again, with this server */ 661 625 srv->no_pathinfo = True; 662 626 663 627 /* Open the file */ 664 628 if (!NT_STATUS_IS_OK(cli_open(srv->cli, path, O_RDWR, DENY_NONE, &fd))) { 665 666 629 errno = SMBC_errno(context, srv->cli); 667 630 TALLOC_FREE(frame); 668 631 return -1; 669 632 } 670 633 671 634 /* Set the new attributes */ 672 635 ret = NT_STATUS_IS_OK(cli_setattrE(srv->cli, fd, … … 674 637 access_time, 675 638 write_time)); 676 639 677 640 /* Close the file */ 678 641 cli_close(srv->cli, fd); 679 642 680 643 /* 681 644 * Unfortunately, setattrE() doesn't have a provision for … … 687 650 ret = NT_STATUS_IS_OK(cli_setatr(srv->cli, path, mode, 0)); 688 651 } 689 652 690 653 if (! ret) { 691 654 errno = SMBC_errno(context, srv->cli); … … 694 657 } 695 658 } 696 659 697 660 TALLOC_FREE(frame); 698 661 return True; … … 715 678 struct cli_state *targetcli = NULL; 716 679 TALLOC_CTX *frame = talloc_stackframe(); 717 680 718 681 if (!context || !context->internal->initialized) { 719 720 errno = EINVAL; 721 TALLOC_FREE(frame); 722 return -1; 723 } 724 682 errno = EINVAL; 683 TALLOC_FREE(frame); 684 return -1; 685 } 686 725 687 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 726 727 688 errno = EBADF; 728 689 TALLOC_FREE(frame); 729 690 return -1; 730 731 } 732 691 } 692 733 693 if (!file->file) { 734 735 694 errno = EINVAL; 736 695 TALLOC_FREE(frame); 737 696 return -1; /* Can't lseek a dir ... */ 738 739 } 740 697 } 698 741 699 switch (whence) { 742 700 case SEEK_SET: 743 701 file->offset = offset; 744 702 break; 745 746 703 case SEEK_CUR: 747 704 file->offset += offset; 748 705 break; 749 750 706 case SEEK_END: 751 707 /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ … … 764 720 return -1; 765 721 } 766 722 767 723 /*d_printf(">>>lseek: resolving %s\n", path);*/ 768 724 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 774 730 return -1; 775 731 } 732 776 733 /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ 777 778 if (!cli_qfileinfo(targetcli, file->cli_fd, NULL,779 &size, NULL, NULL, NULL, NULL, NULL)) 780 {734 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic( 735 targetcli, file->cli_fd, NULL, 736 &size, NULL, NULL, NULL, NULL, 737 NULL))) { 781 738 SMB_OFF_T b_size = size; 782 739 if (!NT_STATUS_IS_OK(cli_getattrE(targetcli, file->cli_fd, … … 790 747 file->offset = size + offset; 791 748 break; 792 793 749 default: 794 750 errno = EINVAL; 795 751 break; 796 797 } 798 752 } 753 799 754 TALLOC_FREE(frame); 800 755 return file->offset; 801 802 756 } 803 757 … … 821 775 struct cli_state *targetcli = NULL; 822 776 TALLOC_CTX *frame = talloc_stackframe(); 823 777 824 778 if (!context || !context->internal->initialized) { 825 826 errno = EINVAL; 827 TALLOC_FREE(frame); 828 return -1; 829 } 830 779 errno = EINVAL; 780 TALLOC_FREE(frame); 781 return -1; 782 } 783 831 784 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 832 785 errno = EBADF; … … 834 787 return -1; 835 788 } 836 789 837 790 if (!file->file) { 838 791 errno = EINVAL; … … 840 793 return -1; 841 794 } 842 795 843 796 /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ 844 797 if (SMBC_parse_path(frame, … … 856 809 return -1; 857 810 } 858 811 859 812 /*d_printf(">>>fstat: resolving %s\n", path);*/ 860 813 if (!cli_resolve_path(frame, "", context->internal->auth_info, … … 867 820 } 868 821 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 869 822 870 823 if (!NT_STATUS_IS_OK(cli_ftruncate(targetcli, file->cli_fd, (uint64_t)size))) { 871 824 errno = EINVAL; … … 873 826 return -1; 874 827 } 875 828 876 829 TALLOC_FREE(frame); 877 830 return 0; 878 879 831 } -
vendor/current/source3/libsmb/libsmb_misc.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" … … 51 52 { 52 53 int ret = cli_errno(c); 53 54 54 55 if (cli_is_dos_error(c)) { 55 56 uint8 eclass; 56 57 uint32 ecode; 57 58 58 59 cli_dos_error(c, &eclass, &ecode); 59 60 60 61 DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", 61 62 (int)eclass, (int)ecode, (int)ecode, ret)); 62 63 } else { 63 64 NTSTATUS status; 64 65 65 66 status = cli_nt_error(c); 66 67 67 68 DEBUG(3,("smbc errno %s -> %d\n", 68 69 nt_errstr(status), ret)); 69 70 } 70 71 71 72 return ret; 72 73 } -
vendor/current/source3/libsmb/libsmb_path.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 61 61 size_t newlen = 1; 62 62 char *p, *dest; 63 63 64 64 if (old_length == 0) { 65 65 return 0; 66 66 } 67 67 68 68 *pp_dest = NULL; 69 69 for (i = 0; i < old_length; ) { 70 70 unsigned char character = src[i++]; 71 71 72 72 if (character == '%') { 73 73 int a = i+1 < old_length ? hex2int(src[i]) : -1; 74 74 int b = i+1 < old_length ? hex2int(src[i+1]) : -1; 75 75 76 76 /* Replace valid sequence */ 77 77 if (a != -1 && b != -1) { … … 88 88 newlen++; 89 89 } 90 90 91 91 dest = TALLOC_ARRAY(ctx, char, newlen); 92 92 if (!dest) { 93 93 return err_count; 94 94 } 95 95 96 96 err_count = 0; 97 97 for (p = dest, i = 0; i < old_length; ) { 98 98 unsigned char character = src[i++]; 99 99 100 100 if (character == '%') { 101 101 int a = i+1 < old_length ? hex2int(src[i]) : -1; 102 102 int b = i+1 < old_length ? hex2int(src[i+1]) : -1; 103 103 104 104 /* Replace valid sequence */ 105 105 if (a != -1 && b != -1) { … … 116 116 *p++ = character; 117 117 } 118 118 119 119 *p = '\0'; 120 120 *pp_dest = dest; … … 130 130 char *pdest; 131 131 int ret = urldecode_talloc(frame, &pdest, src); 132 132 133 133 if (pdest) { 134 134 strlcpy(dest, pdest, max_dest_len); … … 152 152 { 153 153 char hex[] = "0123456789ABCDEF"; 154 154 155 155 for (; *src != '\0' && max_dest_len >= 3; src++) { 156 156 157 157 if ((*src < '0' && 158 158 *src != '-' && … … 173 173 } 174 174 } 175 175 176 176 *dest++ = '\0'; 177 177 max_dest_len--; 178 178 179 179 return max_dest_len; 180 180 } … … 236 236 char *workgroup = NULL; 237 237 int len; 238 238 239 239 /* Ensure these returns are at least valid pointers. */ 240 240 *pp_server = talloc_strdup(ctx, ""); … … 243 243 *pp_user = talloc_strdup(ctx, ""); 244 244 *pp_password = talloc_strdup(ctx, ""); 245 245 246 246 if (!*pp_server || !*pp_share || !*pp_path || 247 247 !*pp_user || !*pp_password) { 248 248 return -1; 249 249 } 250 250 251 251 /* 252 252 * Assume we wont find an authentication domain to parse, so default … … 257 257 talloc_strdup(ctx, smbc_getWorkgroup(context)); 258 258 } 259 259 260 260 if (pp_options) { 261 261 *pp_options = talloc_strdup(ctx, ""); 262 262 } 263 263 s = talloc_strdup(ctx, fname); 264 264 265 265 /* see if it has the right prefix */ 266 266 len = strlen(SMBC_PREFIX); … … 268 268 return -1; /* What about no smb: ? */ 269 269 } 270 270 271 271 p = s + len; 272 272 273 273 /* Watch the test below, we are testing to see if we should exit */ 274 274 275 275 if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { 276 276 DEBUG(1, ("Invalid path (does not begin with smb://")); 277 277 return -1; 278 278 } 279 279 280 280 p += 2; /* Skip the double slash */ 281 281 282 282 /* See if any options were specified */ 283 283 if ((q = strrchr(p, '?')) != NULL ) { 284 284 /* There are options. Null terminate here and point to them */ 285 285 *q++ = '\0'; 286 286 287 287 DEBUG(4, ("Found options '%s'", q)); 288 288 289 289 /* Copy the options */ 290 290 if (pp_options && *pp_options != NULL) { … … 293 293 } 294 294 } 295 295 296 296 if (*p == '\0') { 297 297 goto decoding; 298 298 } 299 299 300 300 if (*p == '/') { 301 301 int wl = strlen(smbc_getWorkgroup(context)); 302 302 303 303 if (wl > 16) { 304 304 wl = 16; 305 305 } 306 306 307 307 *pp_server = talloc_strdup(ctx, smbc_getWorkgroup(context)); 308 308 if (!*pp_server) { … … 312 312 return 0; 313 313 } 314 314 315 315 /* 316 316 * ok, its for us. Now parse out the server, share etc. … … 319 319 * exists ... 320 320 */ 321 321 322 322 /* check that '@' occurs before '/', if '/' exists at all */ 323 323 q = strchr_m(p, '@'); … … 326 326 char *userinfo = NULL; 327 327 const char *u; 328 328 329 329 next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); 330 330 if (!userinfo) { … … 332 332 } 333 333 u = userinfo; 334 334 335 335 if (strchr_m(u, ';')) { 336 336 next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); … … 342 342 } 343 343 } 344 344 345 345 if (strchr_m(u, ':')) { 346 346 next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); … … 359 359 } 360 360 } 361 361 362 362 if (!next_token_talloc(ctx, &p, pp_server, "/")) { 363 363 return -1; 364 364 } 365 365 366 366 if (*p == (char)0) { 367 367 goto decoding; /* That's it ... */ 368 368 } 369 369 370 370 if (!next_token_talloc(ctx, &p, pp_share, "/")) { 371 371 return -1; 372 372 } 373 373 374 374 /* 375 375 * Prepend a leading slash if there's a file path, as required by … … 387 387 } 388 388 string_replace(*pp_path, '/', '\\'); 389 389 390 390 decoding: 391 392 391 (void) urldecode_talloc(ctx, pp_path, *pp_path); 393 392 (void) urldecode_talloc(ctx, pp_server, *pp_server); … … 408 407 *pp_user, 409 408 *pp_password); 410 411 409 return 0; 412 410 } -
vendor/current/source3/libsmb/libsmb_printjob.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" … … 42 43 char *path = NULL; 43 44 TALLOC_CTX *frame = talloc_stackframe(); 44 45 45 46 if (!context || !context->internal->initialized) { 46 47 47 errno = EINVAL; 48 48 TALLOC_FREE(frame); 49 49 return NULL; 50 50 } 51 51 52 52 if (!fname) { 53 53 errno = EINVAL; … … 55 55 return NULL; 56 56 } 57 57 58 58 DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname)); 59 59 60 60 if (SMBC_parse_path(frame, 61 61 context, … … 72 72 return NULL; 73 73 } 74 74 75 75 /* What if the path is empty, or the file exists? */ 76 76 77 77 TALLOC_FREE(frame); 78 78 return smbc_getFunctionOpen(context)(context, fname, O_WRONLY, 666); … … 99 99 char buf[4096]; 100 100 TALLOC_CTX *frame = talloc_stackframe(); 101 101 102 102 if (!c_file || !c_file->internal->initialized || 103 103 !c_print || !c_print->internal->initialized) { 104 105 errno = EINVAL; 106 TALLOC_FREE(frame); 107 return -1; 108 109 } 110 104 errno = EINVAL; 105 TALLOC_FREE(frame); 106 return -1; 107 } 108 111 109 if (!fname && !printq) { 112 113 errno = EINVAL; 114 TALLOC_FREE(frame); 115 return -1; 116 117 } 118 110 errno = EINVAL; 111 TALLOC_FREE(frame); 112 return -1; 113 } 114 119 115 /* Try to open the file for reading ... */ 120 116 121 117 if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, 122 118 O_RDONLY, 0666)) < 0) { … … 125 121 return -1; /* smbc_open sets errno */ 126 122 } 127 123 128 124 /* Now, try to open the printer file for writing */ 129 125 130 126 if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, 131 127 printq)) < 0) { 132 133 128 saverr = errno; /* Save errno */ 134 129 smbc_getFunctionClose(c_file)(c_file, fid1); … … 136 131 TALLOC_FREE(frame); 137 132 return -1; 138 139 } 140 133 } 134 141 135 while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1, 142 136 buf, sizeof(buf))) > 0) { 143 144 137 tot_bytes += bytes; 145 138 146 139 if ((smbc_getFunctionWrite(c_print)(c_print, fid2, 147 140 buf, bytes)) < 0) { 148 149 141 saverr = errno; 150 142 smbc_getFunctionClose(c_file)(c_file, fid1); 151 143 smbc_getFunctionClose(c_print)(c_print, fid2); 152 144 errno = saverr; 153 154 145 } 155 156 } 157 146 } 147 158 148 saverr = errno; 159 149 160 150 smbc_getFunctionClose(c_file)(c_file, fid1); 161 151 smbc_getFunctionClose(c_print)(c_print, fid2); 162 152 163 153 if (bytes < 0) { 164 165 154 errno = saverr; 166 155 TALLOC_FREE(frame); 167 156 return -1; 168 169 } 170 157 } 158 171 159 TALLOC_FREE(frame); 172 160 return tot_bytes; 173 174 161 } 175 162 … … 191 178 char *path = NULL; 192 179 TALLOC_CTX *frame = talloc_stackframe(); 193 180 194 181 if (!context || !context->internal->initialized) { 195 196 errno = EINVAL; 197 TALLOC_FREE(frame); 198 return -1; 199 } 200 182 errno = EINVAL; 183 TALLOC_FREE(frame); 184 return -1; 185 } 186 201 187 if (!fname) { 202 188 errno = EINVAL; … … 204 190 return -1; 205 191 } 206 192 207 193 DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); 208 194 209 195 if (SMBC_parse_path(frame, 210 196 context, … … 221 207 return -1; 222 208 } 223 209 224 210 if (!user || user[0] == (char)0) { 225 211 user = talloc_strdup(frame, smbc_getUser(context)); … … 230 216 } 231 217 } 232 218 233 219 srv = SMBC_server(frame, context, True, 234 220 server, share, &workgroup, &user, &password); 235 221 236 222 if (!srv) { 237 223 TALLOC_FREE(frame); 238 224 return -1; /* errno set by SMBC_server */ 239 225 } 240 226 241 227 if (cli_print_queue(srv->cli, 242 228 (void (*)(struct print_job_info *))fn) < 0) { … … 245 231 return -1; 246 232 } 247 233 248 234 TALLOC_FREE(frame); 249 235 return 0; 250 251 236 } 252 237 … … 269 254 int err; 270 255 TALLOC_CTX *frame = talloc_stackframe(); 271 256 272 257 if (!context || !context->internal->initialized) { 273 274 errno = EINVAL; 275 TALLOC_FREE(frame); 276 return -1; 277 } 278 258 errno = EINVAL; 259 TALLOC_FREE(frame); 260 return -1; 261 } 262 279 263 if (!fname) { 280 264 errno = EINVAL; … … 282 266 return -1; 283 267 } 284 268 285 269 DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); 286 270 287 271 if (SMBC_parse_path(frame, 288 272 context, … … 299 283 return -1; 300 284 } 301 285 302 286 if (!user || user[0] == (char)0) { 303 287 user = talloc_strdup(frame, smbc_getUser(context)); … … 308 292 } 309 293 } 310 294 311 295 srv = SMBC_server(frame, context, True, 312 296 server, share, &workgroup, &user, &password); 313 297 314 298 if (!srv) { 315 316 299 TALLOC_FREE(frame); 317 300 return -1; /* errno set by SMBC_server */ 318 319 } 320 301 } 302 321 303 if ((err = cli_printjob_del(srv->cli, id)) != 0) { 322 323 304 if (err < 0) 324 305 errno = SMBC_errno(context, srv->cli); … … 327 308 TALLOC_FREE(frame); 328 309 return -1; 329 330 } 331 310 } 311 332 312 TALLOC_FREE(frame); 333 313 return 0; 334 335 314 } 336 315 -
vendor/current/source3/libsmb/libsmb_server.c
r414 r740 25 25 26 26 #include "includes.h" 27 #include "libsmb/libsmb.h" 27 28 #include "libsmbclient.h" 28 29 #include "libsmb_internal.h" 29 30 #include "../librpc/gen_ndr/ndr_lsa.h" 31 #include "rpc_client/cli_pipe.h" 32 #include "rpc_client/cli_lsarpc.h" 33 #include "libcli/security/security.h" 34 #include "libsmb/nmblib.h" 30 35 31 36 /* … … 331 336 DEBUG(4, 332 337 ("IPC$ so ignore case sensitivity\n")); 333 } else if (! cli_get_fs_attr_info(c, &fs_attrs)) {338 } else if (!NT_STATUS_IS_OK(cli_get_fs_attr_info(c, &fs_attrs))) { 334 339 DEBUG(4, ("Could not retrieve " 335 340 "case sensitivity flag: %s.\n", … … 568 573 if (is_ipc) { 569 574 DEBUG(4, ("IPC$ so ignore case sensitivity\n")); 570 } else if (! cli_get_fs_attr_info(c, &fs_attrs)) {575 } else if (!NT_STATUS_IS_OK(cli_get_fs_attr_info(c, &fs_attrs))) { 571 576 DEBUG(4, ("Could not retrieve case sensitivity flag: %s.\n", 572 577 cli_errstr(c))); … … 776 781 *pp_password, 777 782 flags, 778 Undefined , NULL);783 Undefined); 779 784 if (! NT_STATUS_IS_OK(nt_status)) { 780 785 DEBUG(1,("cli_full_connection failed! (%s)\n", -
vendor/current/source3/libsmb/libsmb_setget.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 91 91 smbc_setDebug(SMBCCTX *c, int debug) 92 92 { 93 char buf[32]; 94 snprintf(buf, sizeof(buf), "%d", debug); 93 95 c->debug = debug; 94 DEBUGLEVEL = debug; 96 lp_set_cmdline("log level", buf); 95 97 } 96 98 … … 119 121 smbc_getOptionDebugToStderr(SMBCCTX *c) 120 122 { 121 return c->internal->debug_stderr; 122 } 123 124 /** Set whether to log to standard error instead of standard output */ 123 /* Because this is a global concept, it is better to check 124 * what is really set, rather than what we wanted set 125 * (particularly as you cannot go back to stdout). */ 126 return debug_get_output_is_stderr(); 127 } 128 129 /** Set whether to log to standard error instead of standard output. 130 * This option is 'sticky' - once set to true, it cannot be set to 131 * false again, as it is global to the process, as once we have been 132 * told that it is not safe to safe to write to stdout, we shouldn't 133 * go back as we don't know it was this context that set it that way. 134 */ 125 135 void 126 136 smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) 127 137 { 128 c->internal->debug_stderr = b; 138 if (b) { 139 /* 140 * We do not have a unique per-thread debug state? For 141 * now, we'll just leave it up to the user. If any one 142 * context spefies debug to stderr then all will be (and 143 * will stay that way, as it is unsafe to flip back if 144 * stdout is in use for other things) 145 */ 146 setup_logging("libsmbclient", DEBUG_STDERR); 147 } 129 148 } 130 149 -
vendor/current/source3/libsmb/libsmb_stat.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" … … 37 38 { 38 39 if (!context || !context->internal->initialized) { 39 40 40 errno = EINVAL; 41 41 return -1; 42 43 } 44 42 } 43 45 44 if (!*name) return 2; /* FIXME, why 2 ??? */ 46 45 return (ino_t)str_checksum(name); 47 48 46 } 49 47 … … 61 59 { 62 60 TALLOC_CTX *frame = talloc_stackframe(); 63 61 64 62 st->st_mode = 0; 65 63 66 64 if (IS_DOS_DIR(mode)) { 67 65 st->st_mode = SMBC_DIR_MODE; … … 69 67 st->st_mode = SMBC_FILE_MODE; 70 68 } 71 69 72 70 if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; 73 71 if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; 74 72 if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; 75 73 if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; 76 74 77 75 st->st_size = size; 78 76 #ifdef HAVE_STAT_ST_BLKSIZE … … 87 85 st->st_uid = getuid(); 88 86 st->st_gid = getgid(); 89 87 90 88 if (IS_DOS_DIR(mode)) { 91 89 st->st_nlink = 2; … … 93 91 st->st_nlink = 1; 94 92 } 95 93 96 94 if (st->st_ino == 0) { 97 95 st->st_ino = generate_inode(context, fname); 98 96 } 99 97 100 98 TALLOC_FREE(frame); 101 99 return True; /* FIXME: Is this needed ? */ 102 103 100 } 104 101 … … 126 123 SMB_INO_T ino = 0; 127 124 TALLOC_CTX *frame = talloc_stackframe(); 128 125 129 126 if (!context || !context->internal->initialized) { 130 131 127 errno = EINVAL; /* Best I can think of ... */ 132 128 TALLOC_FREE(frame); 133 129 return -1; 134 130 } 135 131 136 132 if (!fname) { 137 133 errno = EINVAL; … … 139 135 return -1; 140 136 } 141 137 142 138 DEBUG(4, ("smbc_stat(%s)\n", fname)); 143 139 144 140 if (SMBC_parse_path(frame, 145 141 context, … … 165 161 } 166 162 } 167 163 168 164 srv = SMBC_server(frame, context, True, 169 165 server, share, &workgroup, &user, &password); 170 171 166 if (!srv) { 172 167 TALLOC_FREE(frame); 173 168 return -1; /* errno set by SMBC_server */ 174 169 } 175 170 176 171 if (!SMBC_getatr(context, srv, path, &mode, &size, 177 172 NULL, … … 184 179 return -1; 185 180 } 186 181 187 182 st->st_ino = ino; 188 183 189 184 setup_stat(context, st, (char *) fname, size, mode); 190 185 191 186 st->st_atime = convert_timespec_to_time_t(access_time_ts); 192 187 st->st_ctime = convert_timespec_to_time_t(change_time_ts); 193 188 st->st_mtime = convert_timespec_to_time_t(write_time_ts); 194 189 st->st_dev = srv->dev; 195 190 196 191 TALLOC_FREE(frame); 197 192 return 0; 198 199 193 } 200 194 … … 222 216 SMB_INO_T ino = 0; 223 217 TALLOC_CTX *frame = talloc_stackframe(); 224 218 225 219 if (!context || !context->internal->initialized) { 226 227 220 errno = EINVAL; 228 221 TALLOC_FREE(frame); 229 222 return -1; 230 223 } 231 224 232 225 if (!file || !SMBC_dlist_contains(context->internal->files, file)) { 233 226 errno = EBADF; … … 235 228 return -1; 236 229 } 237 230 238 231 if (!file->file) { 239 232 TALLOC_FREE(frame); 240 233 return smbc_getFunctionFstatdir(context)(context, file, st); 241 234 } 242 235 243 236 /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ 244 237 if (SMBC_parse_path(frame, … … 256 249 return -1; 257 250 } 258 251 259 252 /*d_printf(">>>fstat: resolving %s\n", path);*/ 260 253 if (!cli_resolve_path(frame, "", context->internal->auth_info, 261 file->srv->cli, path,262 &targetcli, &targetpath)) {254 file->srv->cli, path, 255 &targetcli, &targetpath)) { 263 256 d_printf("Could not resolve %s\n", path); 264 257 errno = ENOENT; … … 267 260 } 268 261 /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ 269 270 if (! cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,271 NULL,272 &access_time_ts,273 &write_time_ts,274 &change_time_ts,275 &ino)) { 276 262 263 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic( 264 targetcli, file->cli_fd, &mode, &size, 265 NULL, 266 &access_time_ts, 267 &write_time_ts, 268 &change_time_ts, 269 &ino))) { 277 270 time_t change_time, access_time, write_time; 278 271 279 272 if (!NT_STATUS_IS_OK(cli_getattrE(targetcli, file->cli_fd, &mode, &size, 280 273 &change_time, &access_time, &write_time))) { 281 282 274 errno = EINVAL; 283 275 TALLOC_FREE(frame); 284 276 return -1; 285 277 } 286 287 278 change_time_ts = convert_time_t_to_timespec(change_time); 288 279 access_time_ts = convert_time_t_to_timespec(access_time); 289 280 write_time_ts = convert_time_t_to_timespec(write_time); 290 281 } 291 282 292 283 st->st_ino = ino; 293 284 294 285 setup_stat(context, st, file->fname, size, mode); 295 286 296 287 st->st_atime = convert_timespec_to_time_t(access_time_ts); 297 288 st->st_ctime = convert_timespec_to_time_t(change_time_ts); 298 289 st->st_mtime = convert_timespec_to_time_t(write_time_ts); 299 290 st->st_dev = file->srv->dev; 300 291 301 292 TALLOC_FREE(frame); 302 293 return 0; 303 304 294 } 305 295 … … 369 359 uint32 fs_attrs = 0; 370 360 struct cli_state *cli = file->srv->cli; 371 372 361 373 362 /* Initialize all fields (at least until we actually use them) */ … … 390 379 uint64_t sectors_per_allocation_unit; 391 380 uint64_t bytes_per_sector; 392 381 NTSTATUS status; 382 393 383 /* Nope. If size data is available... */ 394 if (cli_get_fs_full_size_info(cli, 395 &total_allocation_units, 396 &caller_allocation_units, 397 &actual_allocation_units, 398 §ors_per_allocation_unit, 399 &bytes_per_sector)) { 384 status = cli_get_fs_full_size_info(cli, 385 &total_allocation_units, 386 &caller_allocation_units, 387 &actual_allocation_units, 388 §ors_per_allocation_unit, 389 &bytes_per_sector); 390 if (NT_STATUS_IS_OK(status)) { 400 391 401 392 /* ... then provide it */ … … 422 413 uint64_t free_file_nodes; 423 414 uint64_t fs_identifier; 415 NTSTATUS status; 424 416 425 417 /* Has UNIXCIFS. If POSIX filesystem info is available... */ 426 if (cli_get_posix_fs_info(cli, 427 &optimal_transfer_size, 428 &block_size, 429 &total_blocks, 430 &blocks_available, 431 &user_blocks_available, 432 &total_file_nodes, 433 &free_file_nodes, 434 &fs_identifier)) { 418 status = cli_get_posix_fs_info(cli, 419 &optimal_transfer_size, 420 &block_size, 421 &total_blocks, 422 &blocks_available, 423 &user_blocks_available, 424 &total_file_nodes, 425 &free_file_nodes, 426 &fs_identifier); 427 if (NT_STATUS_IS_OK(status)) { 435 428 436 429 /* ... then what's provided here takes precedence. */ … … 455 448 456 449 /* See if the share is case sensitive */ 457 if (! cli_get_fs_attr_info(cli, &fs_attrs)) {450 if (!NT_STATUS_IS_OK(cli_get_fs_attr_info(cli, &fs_attrs))) { 458 451 /* 459 452 * We can't determine the case sensitivity of -
vendor/current/source3/libsmb/libsmb_xattr.c
r414 r740 8 8 Copyright (C) Derrell Lipman 2003-2008 9 9 Copyright (C) Jeremy Allison 2007, 2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libsmb/libsmb.h" 26 27 #include "libsmbclient.h" 27 28 #include "libsmb_internal.h" 28 29 #include "../librpc/gen_ndr/ndr_lsa.h" 30 #include "rpc_client/rpc_client.h" 31 #include "rpc_client/cli_lsarpc.h" 32 #include "../libcli/security/security.h" 29 33 30 34 /* … … 35 39 { 36 40 struct rpc_pipe_client *pipe_hnd; 37 41 38 42 for (pipe_hnd = ipc_cli->pipe_list; 39 43 pipe_hnd; 40 44 pipe_hnd = pipe_hnd->next) { 41 42 45 if (ndr_syntax_id_equal(&pipe_hnd->abstract_syntax, 43 46 &ndr_table_lsarpc.syntax_id)) { … … 45 48 } 46 49 } 47 48 50 return NULL; 49 51 } … … 56 58 57 59 static int 58 ace_compare( SEC_ACE*ace1,59 SEC_ACE*ace2)60 ace_compare(struct security_ace *ace1, 61 struct security_ace *ace2) 60 62 { 61 63 bool b1; 62 64 bool b2; 63 65 64 66 /* If the ACEs are equal, we have nothing more to do. */ 65 67 if (sec_ace_equal(ace1, ace2)) { 66 68 return 0; 67 69 } 68 70 69 71 /* Inherited follow non-inherited */ 70 72 b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); … … 73 75 return (b1 ? 1 : -1); 74 76 } 75 77 76 78 /* 77 79 * What shall we do with AUDITs and ALARMs? It's undefined. We'll … … 89 91 return (b1 ? 1 : -1); 90 92 } 91 93 92 94 /* Allowed ACEs follow denied ACEs */ 93 95 b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || … … 98 100 return (b1 ? 1 : -1); 99 101 } 100 102 101 103 /* 102 104 * ACEs applying to an entity's object follow those applying to the … … 110 112 return (b1 ? 1 : -1); 111 113 } 112 114 113 115 /* 114 116 * If we get this far, the ACEs are similar as far as the … … 117 119 * just seems reasonable. 118 120 */ 119 121 120 122 if (ace1->type != ace2->type) { 121 123 return ace2->type - ace1->type; 122 124 } 123 124 if ( sid_compare(&ace1->trustee, &ace2->trustee)) {125 return sid_compare(&ace1->trustee, &ace2->trustee);126 } 127 125 126 if (dom_sid_compare(&ace1->trustee, &ace2->trustee)) { 127 return dom_sid_compare(&ace1->trustee, &ace2->trustee); 128 } 129 128 130 if (ace1->flags != ace2->flags) { 129 131 return ace1->flags - ace2->flags; 130 132 } 131 133 132 134 if (ace1->access_mask != ace2->access_mask) { 133 135 return ace1->access_mask - ace2->access_mask; 134 136 } 135 137 136 138 if (ace1->size != ace2->size) { 137 139 return ace1->size - ace2->size; 138 140 } 139 140 return memcmp(ace1, ace2, sizeof( SEC_ACE));141 142 return memcmp(ace1, ace2, sizeof(struct security_ace)); 141 143 } 142 144 143 145 144 146 static void 145 sort_acl( SEC_ACL*the_acl)147 sort_acl(struct security_acl *the_acl) 146 148 { 147 149 uint32 i; 148 150 if (!the_acl) return; 149 150 qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), 151 QSORT_CAST ace_compare); 152 151 152 TYPESAFE_QSORT(the_acl->aces, the_acl->num_aces, ace_compare); 153 153 154 for (i=1;i<the_acl->num_aces;) { 154 155 if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { … … 170 171 fstring str, 171 172 bool numeric, 172 DOM_SID*sid)173 struct dom_sid *sid) 173 174 { 174 175 char **domains = NULL; … … 177 178 struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); 178 179 TALLOC_CTX *ctx; 179 180 180 181 sid_to_fstring(str, sid); 181 182 182 183 if (numeric) { 183 184 return; /* no lookup desired */ 184 185 } 185 186 186 187 if (!pipe_hnd) { 187 188 return; 188 189 } 189 190 190 191 /* Ask LSA to convert the sid to a name */ 191 192 192 193 ctx = talloc_stackframe(); 193 194 194 195 if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, 195 196 pol, 1, sid, &domains, … … 199 200 return; 200 201 } 201 202 202 203 /* Converted OK */ 203 204 204 205 slprintf(str, sizeof(fstring) - 1, "%s%s%s", 205 206 domains[0], lp_winbind_separator(), … … 214 215 struct policy_handle *pol, 215 216 bool numeric, 216 DOM_SID*sid,217 struct dom_sid *sid, 217 218 const char *str) 218 219 { 219 220 enum lsa_SidType *types = NULL; 220 DOM_SID*sids = NULL;221 struct dom_sid *sids = NULL; 221 222 bool result = True; 222 223 TALLOC_CTX *ctx = NULL; 223 224 struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); 224 225 225 226 if (!pipe_hnd) { 226 227 return False; 227 228 } 228 229 229 230 if (numeric) { 230 231 if (strncmp(str, "S-", 2) == 0) { 231 232 return string_to_sid(sid, str); 232 233 } 233 234 234 235 result = False; 235 236 goto done; 236 237 } 237 238 238 239 ctx = talloc_stackframe(); 239 240 if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, … … 244 245 goto done; 245 246 } 246 247 247 248 sid_copy(sid, &sids[0]); 248 249 done: 249 250 250 TALLOC_FREE(ctx); 251 251 return result; … … 253 253 254 254 255 /* parse an ACEin the same format as print_ace() */255 /* parse an struct security_ace in the same format as print_ace() */ 256 256 static bool 257 257 parse_ace(struct cli_state *ipc_cli, 258 258 struct policy_handle *pol, 259 SEC_ACE*ace,259 struct security_ace *ace, 260 260 bool numeric, 261 261 char *str) … … 267 267 unsigned int aflags; 268 268 unsigned int amask; 269 DOM_SIDsid;269 struct dom_sid sid; 270 270 uint32_t mask; 271 271 const struct perm_value *v; … … 275 275 }; 276 276 TALLOC_CTX *frame = talloc_stackframe(); 277 277 278 278 /* These values discovered by inspection */ 279 279 static const struct perm_value special_values[] = { … … 286 286 { "", 0 }, 287 287 }; 288 288 289 289 static const struct perm_value standard_values[] = { 290 290 { "READ", 0x001200a9 }, … … 293 293 { "", 0 }, 294 294 }; 295 296 295 297 296 ZERO_STRUCTP(ace); 298 297 p = strchr_m(str,':'); … … 304 303 p++; 305 304 /* Try to parse numeric form */ 306 305 307 306 if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && 308 307 convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { 309 308 goto done; 310 309 } 311 310 312 311 /* Try to parse text form */ 313 312 314 313 if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { 315 314 TALLOC_FREE(frame); 316 315 return false; 317 316 } 318 317 319 318 cp = p; 320 319 if (!next_token_talloc(frame, &cp, &tok, "/")) { … … 322 321 return false; 323 322 } 324 323 325 324 if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { 326 325 atype = SEC_ACE_TYPE_ACCESS_ALLOWED; … … 331 330 return false; 332 331 } 333 332 334 333 /* Only numeric form accepted for flags at present */ 335 334 336 335 if (!(next_token_talloc(frame, &cp, &tok, "/") && 337 336 sscanf(tok, "%i", &aflags))) { … … 339 338 return false; 340 339 } 341 340 342 341 if (!next_token_talloc(frame, &cp, &tok, "/")) { 343 342 TALLOC_FREE(frame); 344 343 return false; 345 344 } 346 345 347 346 if (strncmp(tok, "0x", 2) == 0) { 348 347 if (sscanf(tok, "%i", &amask) != 1) { … … 352 351 goto done; 353 352 } 354 353 355 354 for (v = standard_values; v->perm; v++) { 356 355 if (strcmp(tok, v->perm) == 0) { … … 359 358 } 360 359 } 361 360 362 361 p = tok; 363 362 364 363 while(*p) { 365 364 bool found = False; 366 365 367 366 for (v = special_values; v->perm; v++) { 368 367 if (v->perm[0] == *p) { … … 371 370 } 372 371 } 373 372 374 373 if (!found) { 375 374 TALLOC_FREE(frame); … … 378 377 p++; 379 378 } 380 379 381 380 if (*p) { 382 381 TALLOC_FREE(frame); 383 382 return false; 384 383 } 385 384 386 385 done: 387 386 mask = amask; … … 391 390 } 392 391 393 /* add an ACE to a list of ACEs in a SEC_ACL*/392 /* add an struct security_ace to a list of struct security_aces in a struct security_acl */ 394 393 static bool 395 add_ace( SEC_ACL**the_acl,396 SEC_ACE*ace,394 add_ace(struct security_acl **the_acl, 395 struct security_ace *ace, 397 396 TALLOC_CTX *ctx) 398 397 { 399 SEC_ACL*newacl;400 SEC_ACE*aces;401 398 struct security_acl *newacl; 399 struct security_ace *aces; 400 402 401 if (! *the_acl) { 403 402 (*the_acl) = make_sec_acl(ctx, 3, 1, ace); 404 403 return True; 405 404 } 406 407 if ((aces = SMB_CALLOC_ARRAY( SEC_ACE,405 406 if ((aces = SMB_CALLOC_ARRAY(struct security_ace, 408 407 1+(*the_acl)->num_aces)) == NULL) { 409 408 return False; 410 409 } 411 memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof( SEC_ACE));412 memcpy(aces+(*the_acl)->num_aces, ace, sizeof( SEC_ACE));410 memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(struct security_ace)); 411 memcpy(aces+(*the_acl)->num_aces, ace, sizeof(struct security_ace)); 413 412 newacl = make_sec_acl(ctx, (*the_acl)->revision, 414 413 1+(*the_acl)->num_aces, aces); … … 420 419 421 420 /* parse a ascii version of a security descriptor */ 422 static SEC_DESC*421 static struct security_descriptor * 423 422 sec_desc_parse(TALLOC_CTX *ctx, 424 423 struct cli_state *ipc_cli, … … 429 428 const char *p = str; 430 429 char *tok; 431 SEC_DESC*ret = NULL;430 struct security_descriptor *ret = NULL; 432 431 size_t sd_size; 433 DOM_SID*group_sid=NULL;434 DOM_SID*owner_sid=NULL;435 SEC_ACL*dacl=NULL;432 struct dom_sid *group_sid=NULL; 433 struct dom_sid *owner_sid=NULL; 434 struct security_acl *dacl=NULL; 436 435 int revision=1; 437 436 438 437 while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { 439 438 440 439 if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { 441 440 revision = strtol(tok+9, NULL, 16); 442 441 continue; 443 442 } 444 443 445 444 if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { 446 445 if (owner_sid) { … … 448 447 goto done; 449 448 } 450 owner_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);449 owner_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 451 450 if (!owner_sid || 452 451 !convert_string_to_sid(ipc_cli, pol, … … 458 457 continue; 459 458 } 460 459 461 460 if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { 462 461 if (owner_sid) { … … 464 463 goto done; 465 464 } 466 owner_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);465 owner_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 467 466 if (!owner_sid || 468 467 !convert_string_to_sid(ipc_cli, pol, … … 474 473 continue; 475 474 } 476 475 477 476 if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { 478 477 if (group_sid) { … … 480 479 goto done; 481 480 } 482 group_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);481 group_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 483 482 if (!group_sid || 484 483 !convert_string_to_sid(ipc_cli, pol, … … 490 489 continue; 491 490 } 492 491 493 492 if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { 494 493 if (group_sid) { … … 496 495 goto done; 497 496 } 498 group_sid = SMB_CALLOC_ARRAY( DOM_SID, 1);497 group_sid = SMB_CALLOC_ARRAY(struct dom_sid, 1); 499 498 if (!group_sid || 500 499 !convert_string_to_sid(ipc_cli, pol, … … 506 505 continue; 507 506 } 508 507 509 508 if (StrnCaseCmp(tok,"ACL:", 4) == 0) { 510 SEC_ACEace;509 struct security_ace ace; 511 510 if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { 512 511 DEBUG(5, ("Failed to parse ACL %s\n", tok)); … … 519 518 continue; 520 519 } 521 520 522 521 if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { 523 SEC_ACEace;522 struct security_ace ace; 524 523 if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { 525 524 DEBUG(5, ("Failed to parse ACL %s\n", tok)); … … 532 531 continue; 533 532 } 534 533 535 534 DEBUG(5, ("Failed to parse security descriptor\n")); 536 535 goto done; 537 536 } 538 537 539 538 ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, 540 539 owner_sid, group_sid, NULL, dacl, &sd_size); 541 540 542 541 done: 543 542 SAFE_FREE(group_sid); 544 543 SAFE_FREE(owner_sid); 545 546 544 return ret; 547 545 } … … 563 561 SMB_INO_T inode = 0; 564 562 DOS_ATTR_DESC *ret; 565 563 566 564 ret = TALLOC_P(ctx, DOS_ATTR_DESC); 567 565 if (!ret) { … … 569 567 return NULL; 570 568 } 571 569 572 570 /* Obtain the DOS attributes */ 573 571 if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), … … 582 580 return NULL; 583 581 } 584 582 585 583 ret->mode = mode; 586 584 ret->size = size; … … 590 588 ret->change_time = convert_timespec_to_time_t(change_time_ts); 591 589 ret->inode = inode; 592 590 593 591 return ret; 594 592 } … … 612 610 const char * change_time_attr; 613 611 } attr_strings; 614 612 615 613 /* Determine whether to use old-style or new-style attribute names */ 616 614 if (context->internal->full_time_names) { … … 627 625 attr_strings.change_time_attr = "C_TIME"; 628 626 } 629 627 630 628 /* if this is to set the entire ACL... */ 631 629 if (*str == '*') { … … 637 635 } 638 636 } 639 637 640 638 frame = talloc_stackframe(); 641 639 while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { … … 652 650 continue; 653 651 } 654 652 655 653 if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { 656 654 dad->size = (SMB_OFF_T)atof(tok+5); 657 655 continue; 658 656 } 659 657 660 658 n = strlen(attr_strings.access_time_attr); 661 659 if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { … … 663 661 continue; 664 662 } 665 663 666 664 n = strlen(attr_strings.change_time_attr); 667 665 if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { … … 669 667 continue; 670 668 } 671 669 672 670 n = strlen(attr_strings.write_time_attr); 673 671 if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { … … 675 673 continue; 676 674 } 677 675 678 676 if (attr_strings.create_time_attr != NULL) { 679 677 n = strlen(attr_strings.create_time_attr); … … 685 683 } 686 684 } 687 685 688 686 if (StrnCaseCmp(tok, "INODE:", 6) == 0) { 689 687 dad->inode = (SMB_INO_T)atof(tok+6); … … 732 730 bool determine_size = (bufsize == 0); 733 731 uint16_t fnum; 734 SEC_DESC*sd;732 struct security_descriptor *sd; 735 733 fstring sidstr; 736 734 fstring name_sandbox; … … 762 760 const char * change_time_attr; 763 761 } excl_attr_strings; 764 762 765 763 /* Determine whether to use old-style or new-style attribute names */ 766 764 if (context->internal->full_time_names) { … … 770 768 attr_strings.write_time_attr = "WRITE_TIME"; 771 769 attr_strings.change_time_attr = "CHANGE_TIME"; 772 770 773 771 excl_attr_strings.create_time_attr = "CREATE_TIME"; 774 772 excl_attr_strings.access_time_attr = "ACCESS_TIME"; … … 781 779 attr_strings.write_time_attr = "M_TIME"; 782 780 attr_strings.change_time_attr = "C_TIME"; 783 781 784 782 excl_attr_strings.create_time_attr = NULL; 785 783 excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; … … 787 785 excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; 788 786 } 789 787 790 788 /* Copy name so we can strip off exclusions (if any are specified) */ 791 789 strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); 792 790 793 791 /* Ensure name is null terminated */ 794 792 name_sandbox[sizeof(name_sandbox) - 1] = '\0'; 795 793 796 794 /* Play in the sandbox */ 797 795 name = name_sandbox; 798 796 799 797 /* If there are any exclusions, point to them and mask them from name */ 800 798 if ((pExclude = strchr(name, '!')) != NULL) … … 802 800 *pExclude++ = '\0'; 803 801 } 804 802 805 803 all = (StrnCaseCmp(name, "system.*", 8) == 0); 806 804 all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); … … 810 808 some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); 811 809 numeric = (* (name + strlen(name) - 1) != '+'); 812 810 813 811 /* Look for exclusions from "all" requests */ 814 812 if (all || all_nt || all_dos) { 815 816 813 /* Exclusions are delimited by '!' */ 817 814 for (; 818 815 pExclude != NULL; 819 816 pExclude = (p == NULL ? NULL : p + 1)) { 820 817 821 818 /* Find end of this exclusion name */ 822 819 if ((p = strchr(pExclude, '!')) != NULL) … … 824 821 *p = '\0'; 825 822 } 826 823 827 824 /* Which exclusion name is this? */ 828 825 if (StrCaseCmp(pExclude, … … 878 875 } 879 876 } 880 877 881 878 n_used = 0; 882 879 883 880 /* 884 881 * If we are (possibly) talking to an NT or new system and some NT … … 951 948 } 952 949 } 953 950 954 951 if (!determine_size && n > bufsize) { 955 952 errno = ERANGE; … … 961 958 n = 0; 962 959 } 963 960 964 961 if (! exclude_nt_owner) { 965 962 /* Get owner and group sid */ … … 972 969 fstrcpy(sidstr, ""); 973 970 } 974 971 975 972 if (all || all_nt) { 976 973 if (determine_size) { … … 999 996 } 1000 997 } 1001 998 1002 999 if (!determine_size && n > bufsize) { 1003 1000 errno = ERANGE; … … 1009 1006 n = 0; 1010 1007 } 1011 1008 1012 1009 if (! exclude_nt_group) { 1013 1010 if (sd->group_sid) { … … 1018 1015 fstrcpy(sidstr, ""); 1019 1016 } 1020 1017 1021 1018 if (all || all_nt) { 1022 1019 if (determine_size) { … … 1045 1042 } 1046 1043 } 1047 1044 1048 1045 if (!determine_size && n > bufsize) { 1049 1046 errno = ERANGE; … … 1055 1052 n = 0; 1056 1053 } 1057 1054 1058 1055 if (! exclude_nt_acl) { 1059 1056 /* Add aces to value buffer */ 1060 1057 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { 1061 1062 SEC_ACE*ace = &sd->dacl->aces[i];1058 1059 struct security_ace *ace = &sd->dacl->aces[i]; 1063 1060 convert_sid_to_string(ipc_cli, pol, 1064 1061 sidstr, numeric, 1065 1062 &ace->trustee); 1066 1063 1067 1064 if (all || all_nt) { 1068 1065 if (determine_size) { … … 1147 1144 } 1148 1145 } 1149 1146 1150 1147 /* Restore name pointer to its original value */ 1151 1148 name -= 19; 1152 1149 } 1153 1150 1154 1151 if (all || some_dos) { 1155 1152 /* Point to the portion after "system.dos_attr." */ 1156 1153 name += 16; /* if (all) this will be invalid but unused */ 1157 1154 1158 1155 /* Obtain the DOS attributes */ 1159 1156 if (!SMBC_getatr(context, srv, filename, &mode, &size, … … 1163 1160 &change_time_ts, 1164 1161 &ino)) { 1165 1162 1166 1163 errno = SMBC_errno(context, srv->cli); 1167 1164 return -1; 1168 1169 } 1170 1165 } 1166 1171 1167 create_time = convert_timespec_to_time_t(create_time_ts); 1172 1168 access_time = convert_timespec_to_time_t(access_time_ts); 1173 1169 write_time = convert_timespec_to_time_t(write_time_ts); 1174 1170 change_time = convert_timespec_to_time_t(change_time_ts); 1175 1171 1176 1172 if (! exclude_dos_mode) { 1177 1173 if (all || all_dos) { … … 1211 1207 } 1212 1208 } 1213 1209 1214 1210 if (!determine_size && n > bufsize) { 1215 1211 errno = ERANGE; … … 1221 1217 n = 0; 1222 1218 } 1223 1219 1224 1220 if (! exclude_dos_size) { 1225 1221 if (all || all_dos) { … … 1256 1252 } 1257 1253 } 1258 1254 1259 1255 if (!determine_size && n > bufsize) { 1260 1256 errno = ERANGE; … … 1266 1262 n = 0; 1267 1263 } 1268 1264 1269 1265 if (! exclude_dos_create_time && 1270 1266 attr_strings.create_time_attr != NULL) { … … 1299 1295 } 1300 1296 } 1301 1297 1302 1298 if (!determine_size && n > bufsize) { 1303 1299 errno = ERANGE; … … 1309 1305 n = 0; 1310 1306 } 1311 1307 1312 1308 if (! exclude_dos_access_time) { 1313 1309 if (all || all_dos) { … … 1341 1337 } 1342 1338 } 1343 1339 1344 1340 if (!determine_size && n > bufsize) { 1345 1341 errno = ERANGE; … … 1351 1347 n = 0; 1352 1348 } 1353 1349 1354 1350 if (! exclude_dos_write_time) { 1355 1351 if (all || all_dos) { … … 1383 1379 } 1384 1380 } 1385 1381 1386 1382 if (!determine_size && n > bufsize) { 1387 1383 errno = ERANGE; … … 1393 1389 n = 0; 1394 1390 } 1395 1391 1396 1392 if (! exclude_dos_change_time) { 1397 1393 if (all || all_dos) { … … 1425 1421 } 1426 1422 } 1427 1423 1428 1424 if (!determine_size && n > bufsize) { 1429 1425 errno = ERANGE; … … 1435 1431 n = 0; 1436 1432 } 1437 1433 1438 1434 if (! exclude_dos_inode) { 1439 1435 if (all || all_dos) { … … 1470 1466 } 1471 1467 } 1472 1468 1473 1469 if (!determine_size && n > bufsize) { 1474 1470 errno = ERANGE; … … 1480 1476 n = 0; 1481 1477 } 1482 1478 1483 1479 /* Restore name pointer to its original value */ 1484 1480 name -= 16; 1485 1481 } 1486 1482 1487 1483 if (n_used == 0) { 1488 1484 errno = ENOATTR; 1489 1485 return -1; 1490 1486 } 1491 1487 1492 1488 return n_used; 1493 1489 } … … 1509 1505 uint16_t fnum = (uint16_t)-1; 1510 1506 int err = 0; 1511 SEC_DESC*sd = NULL, *old;1512 SEC_ACL*dacl = NULL;1513 DOM_SID*owner_sid = NULL;1514 DOM_SID*group_sid = NULL;1507 struct security_descriptor *sd = NULL, *old; 1508 struct security_acl *dacl = NULL; 1509 struct dom_sid *owner_sid = NULL; 1510 struct dom_sid *group_sid = NULL; 1515 1511 uint32 i, j; 1516 1512 size_t sd_size; … … 1520 1516 char *targetpath = NULL; 1521 1517 struct cli_state *targetcli = NULL; 1518 NTSTATUS status; 1522 1519 1523 1520 /* the_acl will be null for REMOVE_ALL operations */ … … 1526 1523 p > the_acl && 1527 1524 p[-1] != '+'); 1528 1525 1529 1526 /* if this is to set the entire ACL... */ 1530 1527 if (*the_acl == '*') { … … 1532 1529 the_acl = p + 1; 1533 1530 } 1534 1531 1535 1532 sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl); 1536 1537 1533 if (!sd) { 1538 1534 errno = EINVAL; … … 1540 1536 } 1541 1537 } 1542 1538 1543 1539 /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller 1544 1540 that doesn't deref sd */ 1545 1541 1546 1542 if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { 1547 1543 errno = EINVAL; … … 1602 1598 } 1603 1599 } 1604 1600 1605 1601 if (!found) { 1606 1602 err = ENOATTR; … … 1610 1606 } 1611 1607 break; 1612 1608 1613 1609 case SMBC_XATTR_MODE_ADD: 1614 1610 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 1615 1611 bool found = False; 1616 1612 1617 1613 for (j=0;old->dacl && j<old->dacl->num_aces;j++) { 1618 if ( sid_equal(&sd->dacl->aces[i].trustee,1614 if (dom_sid_equal(&sd->dacl->aces[i].trustee, 1619 1615 &old->dacl->aces[j].trustee)) { 1620 1616 if (!(flags & SMBC_XATTR_FLAG_CREATE)) { … … 1628 1624 } 1629 1625 } 1630 1626 1631 1627 if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { 1632 1628 err = ENOATTR; … … 1634 1630 goto failed; 1635 1631 } 1636 1632 1637 1633 for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { 1638 1634 add_ace(&old->dacl, &sd->dacl->aces[i], ctx); … … 1641 1637 dacl = old->dacl; 1642 1638 break; 1643 1639 1644 1640 case SMBC_XATTR_MODE_SET: 1645 1641 old = sd; … … 1648 1644 dacl = old->dacl; 1649 1645 break; 1650 1646 1651 1647 case SMBC_XATTR_MODE_CHOWN: 1652 1648 owner_sid = sd->owner_sid; 1653 1649 break; 1654 1650 1655 1651 case SMBC_XATTR_MODE_CHGRP: 1656 1652 group_sid = sd->group_sid; 1657 1653 break; 1658 1654 } 1659 1655 1660 1656 /* Denied ACE entries must come before allowed ones */ 1661 1657 sort_acl(old->dacl); 1662 1658 1663 1659 /* Create new security descriptor and set it */ 1664 1660 sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, 1665 1661 owner_sid, group_sid, NULL, dacl, &sd_size); 1666 1662 1667 1663 if (!NT_STATUS_IS_OK(cli_ntcreate(targetcli, targetpath, 0, 1668 1664 WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS, 0, … … 1673 1669 return -1; 1674 1670 } 1675 1676 if (!cli_set_secdesc(targetcli, fnum, sd)) { 1671 1672 status = cli_set_secdesc(targetcli, fnum, sd); 1673 if (!NT_STATUS_IS_OK(status)) { 1677 1674 DEBUG(5, ("ERROR: secdesc set failed: %s\n", 1678 cli_errstr(targetcli)));1675 nt_errstr(status))); 1679 1676 ret = -1; 1680 1677 } 1681 1678 1682 1679 /* Clean up */ 1683 1680 1684 1681 failed: 1685 1682 cli_close(targetcli, fnum); 1686 1683 1687 1684 if (err != 0) { 1688 1685 errno = err; 1689 1686 } 1690 1687 1691 1688 return ret; 1692 1689 } … … 1719 1716 } attr_strings; 1720 1717 TALLOC_CTX *frame = talloc_stackframe(); 1721 1718 1722 1719 if (!context || !context->internal->initialized) { 1723 1724 1720 errno = EINVAL; /* Best I can think of ... */ 1725 1721 TALLOC_FREE(frame); 1726 1722 return -1; 1727 1723 } 1728 1724 1729 1725 if (!fname) { 1730 1726 errno = EINVAL; … … 1732 1728 return -1; 1733 1729 } 1734 1730 1735 1731 DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", 1736 1732 fname, name, (int) size, (const char*)value)); 1737 1733 1738 1734 if (SMBC_parse_path(frame, 1739 1735 context, … … 1750 1746 return -1; 1751 1747 } 1752 1748 1753 1749 if (!user || user[0] == (char)0) { 1754 1750 user = talloc_strdup(frame, smbc_getUser(context)); … … 1759 1755 } 1760 1756 } 1761 1757 1762 1758 srv = SMBC_server(frame, context, True, 1763 1759 server, share, &workgroup, &user, &password); … … 1766 1762 return -1; /* errno set by SMBC_server */ 1767 1763 } 1768 1764 1769 1765 if (! srv->no_nt_session) { 1770 1766 ipc_srv = SMBC_attr_server(frame, context, server, share, … … 1776 1772 ipc_srv = NULL; 1777 1773 } 1778 1774 1779 1775 /* 1780 1776 * Are they asking to set the entire set of known attributes? … … 1792 1788 return -1; 1793 1789 } 1794 1790 1795 1791 if (ipc_srv) { 1796 1792 ret = cacl_set(context, talloc_tos(), srv->cli, … … 1804 1800 ret = 0; 1805 1801 } 1806 1802 1807 1803 /* get a DOS Attribute Descriptor with current attributes */ 1808 1804 dad = dos_attr_query(context, talloc_tos(), path, srv); … … 1810 1806 /* Overwrite old with new, using what was provided */ 1811 1807 dos_attr_parse(context, dad, srv, namevalue); 1812 1808 1813 1809 /* Set the new DOS attributes */ 1814 1810 if (! SMBC_setatr(context, srv, path, … … 1818 1814 dad->change_time, 1819 1815 dad->mode)) { 1820 1816 1821 1817 /* cause failure if NT failed too */ 1822 1818 dad = NULL; 1823 1819 } 1824 1820 } 1825 1821 1826 1822 /* we only fail if both NT and DOS sets failed */ 1827 1823 if (ret < 0 && ! dad) { … … 1831 1827 ret = 0; 1832 1828 } 1833 1829 1834 1830 TALLOC_FREE(frame); 1835 1831 return ret; 1836 1832 } 1837 1833 1838 1834 /* 1839 1835 * Are they asking to set an access control element or to set … … 1845 1841 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 1846 1842 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { 1847 1843 1848 1844 /* Yup. */ 1849 1845 char *namevalue = 1850 1846 talloc_asprintf(talloc_tos(), "%s:%s", 1851 1847 name+19, (const char *) value); 1852 1848 1853 1849 if (! ipc_srv) { 1854 1850 ret = -1; /* errno set by SMBC_server() */ … … 1869 1865 return ret; 1870 1866 } 1871 1867 1872 1868 /* 1873 1869 * Are they asking to set the owner? … … 1875 1871 if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || 1876 1872 StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { 1877 1873 1878 1874 /* Yup. */ 1879 1875 char *namevalue = 1880 1876 talloc_asprintf(talloc_tos(), "%s:%s", 1881 1877 name+19, (const char *) value); 1882 1878 1883 1879 if (! ipc_srv) { 1884 1880 ret = -1; /* errno set by SMBC_server() */ … … 1895 1891 return ret; 1896 1892 } 1897 1893 1898 1894 /* 1899 1895 * Are they asking to set the group? … … 1901 1897 if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || 1902 1898 StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { 1903 1899 1904 1900 /* Yup. */ 1905 1901 char *namevalue = 1906 1902 talloc_asprintf(talloc_tos(), "%s:%s", 1907 1903 name+19, (const char *) value); 1908 1904 1909 1905 if (! ipc_srv) { 1910 1906 /* errno set by SMBC_server() */ … … 1922 1918 return ret; 1923 1919 } 1924 1920 1925 1921 /* Determine whether to use old-style or new-style attribute names */ 1926 1922 if (context->internal->full_time_names) { … … 1937 1933 attr_strings.change_time_attr = "system.dos_attr.C_TIME"; 1938 1934 } 1939 1935 1940 1936 /* 1941 1937 * Are they asking to set a DOS attribute? … … 1948 1944 StrCaseCmp(name, attr_strings.write_time_attr) == 0 || 1949 1945 StrCaseCmp(name, attr_strings.change_time_attr) == 0) { 1950 1946 1951 1947 /* get a DOS Attribute Descriptor with current attributes */ 1952 1948 dad = dos_attr_query(context, talloc_tos(), path, srv); … … 1961 1957 /* Overwrite old with provided new params */ 1962 1958 dos_attr_parse(context, dad, srv, namevalue); 1963 1959 1964 1960 /* Set the new DOS attributes */ 1965 1961 ret2 = SMBC_setatr(context, srv, path, … … 1969 1965 dad->change_time, 1970 1966 dad->mode); 1971 1967 1972 1968 /* ret2 has True (success) / False (failure) */ 1973 1969 if (ret2) { … … 1980 1976 ret = -1; 1981 1977 } 1982 1978 1983 1979 TALLOC_FREE(frame); 1984 1980 return ret; 1985 1981 } 1986 1982 1987 1983 /* Unsupported attribute name */ 1988 1984 errno = EINVAL; … … 2014 2010 } attr_strings; 2015 2011 TALLOC_CTX *frame = talloc_stackframe(); 2016 2012 2017 2013 if (!context || !context->internal->initialized) { 2018 2019 2014 errno = EINVAL; /* Best I can think of ... */ 2020 2015 TALLOC_FREE(frame); 2021 2016 return -1; 2022 2017 } 2023 2018 2024 2019 if (!fname) { 2025 2020 errno = EINVAL; … … 2027 2022 return -1; 2028 2023 } 2029 2024 2030 2025 DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); 2031 2026 2032 2027 if (SMBC_parse_path(frame, 2033 2028 context, … … 2044 2039 return -1; 2045 2040 } 2046 2041 2047 2042 if (!user || user[0] == (char)0) { 2048 2043 user = talloc_strdup(frame, smbc_getUser(context)); … … 2053 2048 } 2054 2049 } 2055 2050 2056 2051 srv = SMBC_server(frame, context, True, 2057 2052 server, share, &workgroup, &user, &password); … … 2060 2055 return -1; /* errno set by SMBC_server */ 2061 2056 } 2062 2057 2063 2058 if (! srv->no_nt_session) { 2064 2059 ipc_srv = SMBC_attr_server(frame, context, server, share, … … 2070 2065 ipc_srv = NULL; 2071 2066 } 2072 2067 2073 2068 /* Determine whether to use old-style or new-style attribute names */ 2074 2069 if (context->internal->full_time_names) { … … 2085 2080 attr_strings.change_time_attr = "system.dos_attr.C_TIME"; 2086 2081 } 2087 2082 2088 2083 /* Are they requesting a supported attribute? */ 2089 2084 if (StrCaseCmp(name, "system.*") == 0 || … … 2112 2107 StrCaseCmp(name, attr_strings.change_time_attr) == 0 || 2113 2108 StrCaseCmp(name, "system.dos_attr.inode") == 0) { 2114 2109 2115 2110 /* Yup. */ 2116 2111 char *filename = (char *) name; … … 2127 2122 return ret; 2128 2123 } 2129 2124 2130 2125 /* Unsupported attribute name */ 2131 2126 errno = EINVAL; … … 2150 2145 char *path = NULL; 2151 2146 TALLOC_CTX *frame = talloc_stackframe(); 2152 2147 2153 2148 if (!context || !context->internal->initialized) { 2154 2155 2149 errno = EINVAL; /* Best I can think of ... */ 2156 2150 TALLOC_FREE(frame); 2157 2151 return -1; 2158 2152 } 2159 2153 2160 2154 if (!fname) { 2161 2155 errno = EINVAL; … … 2163 2157 return -1; 2164 2158 } 2165 2159 2166 2160 DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); 2167 2161 2168 2162 if (SMBC_parse_path(frame, 2169 2163 context, … … 2180 2174 return -1; 2181 2175 } 2182 2176 2183 2177 if (!user || user[0] == (char)0) { 2184 2178 user = talloc_strdup(frame, smbc_getUser(context)); … … 2189 2183 } 2190 2184 } 2191 2185 2192 2186 srv = SMBC_server(frame, context, True, 2193 2187 server, share, &workgroup, &user, &password); … … 2196 2190 return -1; /* errno set by SMBC_server */ 2197 2191 } 2198 2192 2199 2193 if (! srv->no_nt_session) { 2200 2194 ipc_srv = SMBC_attr_server(frame, context, server, share, … … 2206 2200 ipc_srv = NULL; 2207 2201 } 2208 2202 2209 2203 if (! ipc_srv) { 2210 2204 TALLOC_FREE(frame); 2211 2205 return -1; /* errno set by SMBC_attr_server */ 2212 2206 } 2213 2207 2214 2208 /* Are they asking to set the entire ACL? */ 2215 2209 if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || 2216 2210 StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { 2217 2211 2218 2212 /* Yup. */ 2219 2213 ret = cacl_set(context, talloc_tos(), srv->cli, … … 2223 2217 return ret; 2224 2218 } 2225 2219 2226 2220 /* 2227 2221 * Are they asking to remove one or more spceific security descriptor … … 2235 2229 StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || 2236 2230 StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { 2237 2231 2238 2232 /* Yup. */ 2239 2233 ret = cacl_set(context, talloc_tos(), srv->cli, … … 2244 2238 return ret; 2245 2239 } 2246 2240 2247 2241 /* Unsupported attribute name */ 2248 2242 errno = EINVAL; … … 2303 2297 ; 2304 2298 const char * supported; 2305 2299 2306 2300 if (context->internal->full_time_names) { 2307 2301 supported = supported_new; … … 2311 2305 retsize = sizeof(supported_old); 2312 2306 } 2313 2307 2314 2308 if (size == 0) { 2315 2309 return retsize; 2316 2310 } 2317 2311 2318 2312 if (retsize > size) { 2319 2313 errno = ERANGE; 2320 2314 return -1; 2321 2315 } 2322 2316 2323 2317 /* this can't be strcpy() because there are embedded null characters */ 2324 2318 memcpy(list, supported, retsize); -
vendor/current/source3/libsmb/namecache.c
r414 r740 25 25 26 26 #define NBTKEY_FMT "NBT/%s#%02X" 27 28 /**29 * Initialise namecache system. Function calls gencache30 * initialisation function to perform necessary actions31 *32 * @return true upon successful initialisation of the cache or33 * false on failure34 **/35 36 bool namecache_enable(void)37 {38 /*39 * Check if name caching disabled by setting the name cache40 * timeout to zero.41 */42 43 if (lp_name_cache_timeout() == 0) {44 DEBUG(5, ("namecache_enable: disabling netbios name cache\n"));45 return False;46 }47 48 /* I leave it for now, though I don't think we really49 * need this (mimir, 27.09.2002) */50 DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "51 "seconds\n", lp_name_cache_timeout()));52 53 return True;54 }55 27 56 28 /** … … 189 161 SAFE_FREE(key); 190 162 return False; 191 } else {192 DEBUG(5, ("name %s#%02X found.\n", name, name_type)); 193 }163 } 164 165 DEBUG(5, ("name %s#%02X found.\n", name, name_type)); 194 166 195 167 /* -
vendor/current/source3/libsmb/namequery.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "libads/sitename_cache.h" 24 #include "libads/dns.h" 25 #include "../libcli/netlogon/netlogon.h" 26 #include "lib/async_req/async_sock.h" 27 #include "libsmb/nmblib.h" 22 28 23 29 /* nmbd.c sets this to True. */ … … 209 215 ****************************************************************************/ 210 216 211 static NODE_STATUS_STRUCT *parse_node_status(char *p,217 static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p, 212 218 int *num_names, 213 219 struct node_status_extra *extra) 214 220 { 215 NODE_STATUS_STRUCT*ret;221 struct node_status *ret; 216 222 int i; 217 223 … … 221 227 return NULL; 222 228 223 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);229 ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names); 224 230 if (!ret) 225 231 return NULL; … … 244 250 } 245 251 252 struct sock_packet_read_state { 253 struct tevent_context *ev; 254 enum packet_type type; 255 int trn_id; 256 257 struct nb_packet_reader *reader; 258 struct tevent_req *reader_req; 259 260 int sock; 261 struct tevent_req *socket_req; 262 uint8_t buf[1024]; 263 struct sockaddr_storage addr; 264 socklen_t addr_len; 265 266 bool (*validator)(struct packet_struct *p, 267 void *private_data); 268 void *private_data; 269 270 struct packet_struct *packet; 271 }; 272 273 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s); 274 static void sock_packet_read_got_packet(struct tevent_req *subreq); 275 static void sock_packet_read_got_socket(struct tevent_req *subreq); 276 277 static struct tevent_req *sock_packet_read_send( 278 TALLOC_CTX *mem_ctx, 279 struct tevent_context *ev, 280 int sock, /* dgram socket */ 281 struct nb_packet_reader *reader, 282 enum packet_type type, 283 int trn_id, 284 bool (*validator)(struct packet_struct *p, void *private_data), 285 void *private_data) 286 { 287 struct tevent_req *req; 288 struct sock_packet_read_state *state; 289 290 req = tevent_req_create(mem_ctx, &state, 291 struct sock_packet_read_state); 292 if (req == NULL) { 293 return NULL; 294 } 295 talloc_set_destructor(state, sock_packet_read_state_destructor); 296 state->ev = ev; 297 state->reader = reader; 298 state->sock = sock; 299 state->type = type; 300 state->trn_id = trn_id; 301 state->validator = validator; 302 state->private_data = private_data; 303 304 if (reader != NULL) { 305 state->reader_req = nb_packet_read_send(state, ev, reader); 306 if (tevent_req_nomem(state->reader_req, req)) { 307 return tevent_req_post(req, ev); 308 } 309 tevent_req_set_callback( 310 state->reader_req, sock_packet_read_got_packet, req); 311 } 312 313 state->addr_len = sizeof(state->addr); 314 state->socket_req = recvfrom_send(state, ev, sock, 315 state->buf, sizeof(state->buf), 0, 316 &state->addr, &state->addr_len); 317 if (tevent_req_nomem(state->socket_req, req)) { 318 return tevent_req_post(req, ev); 319 } 320 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket, 321 req); 322 323 return req; 324 } 325 326 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s) 327 { 328 if (s->packet != NULL) { 329 free_packet(s->packet); 330 s->packet = NULL; 331 } 332 return 0; 333 } 334 335 static void sock_packet_read_got_packet(struct tevent_req *subreq) 336 { 337 struct tevent_req *req = tevent_req_callback_data( 338 subreq, struct tevent_req); 339 struct sock_packet_read_state *state = tevent_req_data( 340 req, struct sock_packet_read_state); 341 NTSTATUS status; 342 343 status = nb_packet_read_recv(subreq, &state->packet); 344 345 TALLOC_FREE(state->reader_req); 346 347 if (!NT_STATUS_IS_OK(status)) { 348 if (state->socket_req != NULL) { 349 /* 350 * Still waiting for socket 351 */ 352 return; 353 } 354 /* 355 * Both socket and packet reader failed 356 */ 357 tevent_req_nterror(req, status); 358 return; 359 } 360 361 if ((state->validator != NULL) && 362 !state->validator(state->packet, state->private_data)) { 363 DEBUG(10, ("validator failed\n")); 364 365 free_packet(state->packet); 366 state->packet = NULL; 367 368 state->reader_req = nb_packet_read_send(state, state->ev, 369 state->reader); 370 if (tevent_req_nomem(state->reader_req, req)) { 371 return; 372 } 373 tevent_req_set_callback( 374 state->reader_req, sock_packet_read_got_packet, req); 375 return; 376 } 377 378 TALLOC_FREE(state->socket_req); 379 tevent_req_done(req); 380 } 381 382 static void sock_packet_read_got_socket(struct tevent_req *subreq) 383 { 384 struct tevent_req *req = tevent_req_callback_data( 385 subreq, struct tevent_req); 386 struct sock_packet_read_state *state = tevent_req_data( 387 req, struct sock_packet_read_state); 388 struct sockaddr_in *in_addr; 389 ssize_t received; 390 int err; 391 392 received = recvfrom_recv(subreq, &err); 393 394 TALLOC_FREE(state->socket_req); 395 396 if (received == -1) { 397 if (state->reader_req != NULL) { 398 /* 399 * Still waiting for reader 400 */ 401 return; 402 } 403 /* 404 * Both socket and reader failed 405 */ 406 tevent_req_nterror(req, map_nt_error_from_unix(err)); 407 return; 408 } 409 if (state->addr.ss_family != AF_INET) { 410 goto retry; 411 } 412 in_addr = (struct sockaddr_in *)(void *)&state->addr; 413 414 state->packet = parse_packet((char *)state->buf, received, state->type, 415 in_addr->sin_addr, in_addr->sin_port); 416 if (state->packet == NULL) { 417 DEBUG(10, ("parse_packet failed\n")); 418 goto retry; 419 } 420 if ((state->trn_id != -1) && 421 (state->trn_id != packet_trn_id(state->packet))) { 422 DEBUG(10, ("Expected transaction id %d, got %d\n", 423 state->trn_id, packet_trn_id(state->packet))); 424 goto retry; 425 } 426 427 if ((state->validator != NULL) && 428 !state->validator(state->packet, state->private_data)) { 429 DEBUG(10, ("validator failed\n")); 430 goto retry; 431 } 432 433 tevent_req_done(req); 434 return; 435 436 retry: 437 if (state->packet != NULL) { 438 free_packet(state->packet); 439 state->packet = NULL; 440 } 441 state->socket_req = recvfrom_send(state, state->ev, state->sock, 442 state->buf, sizeof(state->buf), 0, 443 &state->addr, &state->addr_len); 444 if (tevent_req_nomem(state->socket_req, req)) { 445 return; 446 } 447 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket, 448 req); 449 } 450 451 static NTSTATUS sock_packet_read_recv(struct tevent_req *req, 452 struct packet_struct **ppacket) 453 { 454 struct sock_packet_read_state *state = tevent_req_data( 455 req, struct sock_packet_read_state); 456 NTSTATUS status; 457 458 if (tevent_req_is_nterror(req, &status)) { 459 return status; 460 } 461 *ppacket = state->packet; 462 state->packet = NULL; 463 return NT_STATUS_OK; 464 } 465 466 struct nb_trans_state { 467 struct tevent_context *ev; 468 int sock; 469 struct nb_packet_reader *reader; 470 471 const struct sockaddr_storage *dst_addr; 472 uint8_t *buf; 473 size_t buflen; 474 enum packet_type type; 475 int trn_id; 476 477 bool (*validator)(struct packet_struct *p, 478 void *private_data); 479 void *private_data; 480 481 struct packet_struct *packet; 482 }; 483 484 static int nb_trans_state_destructor(struct nb_trans_state *s); 485 static void nb_trans_got_reader(struct tevent_req *subreq); 486 static void nb_trans_done(struct tevent_req *subreq); 487 static void nb_trans_sent(struct tevent_req *subreq); 488 static void nb_trans_send_next(struct tevent_req *subreq); 489 490 static struct tevent_req *nb_trans_send( 491 TALLOC_CTX *mem_ctx, 492 struct tevent_context *ev, 493 const struct sockaddr_storage *my_addr, 494 const struct sockaddr_storage *dst_addr, 495 bool bcast, 496 uint8_t *buf, size_t buflen, 497 enum packet_type type, int trn_id, 498 bool (*validator)(struct packet_struct *p, 499 void *private_data), 500 void *private_data) 501 { 502 struct tevent_req *req, *subreq; 503 struct nb_trans_state *state; 504 505 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state); 506 if (req == NULL) { 507 return NULL; 508 } 509 talloc_set_destructor(state, nb_trans_state_destructor); 510 state->ev = ev; 511 state->dst_addr = dst_addr; 512 state->buf = buf; 513 state->buflen = buflen; 514 state->type = type; 515 state->trn_id = trn_id; 516 state->validator = validator; 517 state->private_data = private_data; 518 519 state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True); 520 if (state->sock == -1) { 521 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 522 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno))); 523 return tevent_req_post(req, ev); 524 } 525 526 if (bcast) { 527 set_socket_options(state->sock,"SO_BROADCAST"); 528 } 529 530 subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL); 531 if (tevent_req_nomem(subreq, req)) { 532 return tevent_req_post(req, ev); 533 } 534 tevent_req_set_callback(subreq, nb_trans_got_reader, req); 535 return req; 536 } 537 538 static int nb_trans_state_destructor(struct nb_trans_state *s) 539 { 540 if (s->sock != -1) { 541 close(s->sock); 542 s->sock = -1; 543 } 544 if (s->packet != NULL) { 545 free_packet(s->packet); 546 s->packet = NULL; 547 } 548 return 0; 549 } 550 551 static void nb_trans_got_reader(struct tevent_req *subreq) 552 { 553 struct tevent_req *req = tevent_req_callback_data( 554 subreq, struct tevent_req); 555 struct nb_trans_state *state = tevent_req_data( 556 req, struct nb_trans_state); 557 NTSTATUS status; 558 559 status = nb_packet_reader_recv(subreq, state, &state->reader); 560 TALLOC_FREE(subreq); 561 562 if (!NT_STATUS_IS_OK(status)) { 563 DEBUG(10, ("nmbd not around\n")); 564 state->reader = NULL; 565 } 566 567 subreq = sock_packet_read_send( 568 state, state->ev, state->sock, 569 state->reader, state->type, state->trn_id, 570 state->validator, state->private_data); 571 if (tevent_req_nomem(subreq, req)) { 572 return; 573 } 574 tevent_req_set_callback(subreq, nb_trans_done, req); 575 576 subreq = sendto_send(state, state->ev, state->sock, 577 state->buf, state->buflen, 0, state->dst_addr); 578 if (tevent_req_nomem(subreq, req)) { 579 return; 580 } 581 tevent_req_set_callback(subreq, nb_trans_sent, req); 582 } 583 584 static void nb_trans_sent(struct tevent_req *subreq) 585 { 586 struct tevent_req *req = tevent_req_callback_data( 587 subreq, struct tevent_req); 588 struct nb_trans_state *state = tevent_req_data( 589 req, struct nb_trans_state); 590 ssize_t sent; 591 int err; 592 593 sent = sendto_recv(subreq, &err); 594 TALLOC_FREE(subreq); 595 if (sent == -1) { 596 DEBUG(10, ("sendto failed: %s\n", strerror(err))); 597 tevent_req_nterror(req, map_nt_error_from_unix(err)); 598 return; 599 } 600 subreq = tevent_wakeup_send(state, state->ev, 601 timeval_current_ofs(1, 0)); 602 if (tevent_req_nomem(subreq, req)) { 603 return; 604 } 605 tevent_req_set_callback(subreq, nb_trans_send_next, req); 606 } 607 608 static void nb_trans_send_next(struct tevent_req *subreq) 609 { 610 struct tevent_req *req = tevent_req_callback_data( 611 subreq, struct tevent_req); 612 struct nb_trans_state *state = tevent_req_data( 613 req, struct nb_trans_state); 614 bool ret; 615 616 ret = tevent_wakeup_recv(subreq); 617 TALLOC_FREE(subreq); 618 if (!ret) { 619 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 620 return; 621 } 622 subreq = sendto_send(state, state->ev, state->sock, 623 state->buf, state->buflen, 0, state->dst_addr); 624 if (tevent_req_nomem(subreq, req)) { 625 return; 626 } 627 tevent_req_set_callback(subreq, nb_trans_sent, req); 628 } 629 630 static void nb_trans_done(struct tevent_req *subreq) 631 { 632 struct tevent_req *req = tevent_req_callback_data( 633 subreq, struct tevent_req); 634 struct nb_trans_state *state = tevent_req_data( 635 req, struct nb_trans_state); 636 NTSTATUS status; 637 638 status = sock_packet_read_recv(subreq, &state->packet); 639 TALLOC_FREE(subreq); 640 if (tevent_req_nterror(req, status)) { 641 return; 642 } 643 tevent_req_done(req); 644 } 645 646 static NTSTATUS nb_trans_recv(struct tevent_req *req, 647 struct packet_struct **ppacket) 648 { 649 struct nb_trans_state *state = tevent_req_data( 650 req, struct nb_trans_state); 651 NTSTATUS status; 652 653 if (tevent_req_is_nterror(req, &status)) { 654 return status; 655 } 656 *ppacket = state->packet; 657 state->packet = NULL; 658 return NT_STATUS_OK; 659 } 246 660 247 661 /**************************************************************************** … … 250 664 **************************************************************************/ 251 665 252 NODE_STATUS_STRUCT *node_status_query(int fd, 253 struct nmb_name *name, 254 const struct sockaddr_storage *to_ss, 255 int *num_names, 256 struct node_status_extra *extra) 257 { 258 bool found=False; 259 int retries = 2; 260 int retry_time = 2000; 261 struct timeval tval; 666 struct node_status_query_state { 667 struct sockaddr_storage my_addr; 668 struct sockaddr_storage addr; 669 uint8_t buf[1024]; 670 ssize_t buflen; 671 struct packet_struct *packet; 672 }; 673 674 static int node_status_query_state_destructor( 675 struct node_status_query_state *s); 676 static bool node_status_query_validator(struct packet_struct *p, 677 void *private_data); 678 static void node_status_query_done(struct tevent_req *subreq); 679 680 struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx, 681 struct tevent_context *ev, 682 struct nmb_name *name, 683 const struct sockaddr_storage *addr) 684 { 685 struct tevent_req *req, *subreq; 686 struct node_status_query_state *state; 262 687 struct packet_struct p; 263 struct packet_struct *p2;264 688 struct nmb_packet *nmb = &p.packet.nmb; 265 NODE_STATUS_STRUCT *ret; 689 struct sockaddr_in *in_addr; 690 691 req = tevent_req_create(mem_ctx, &state, 692 struct node_status_query_state); 693 if (req == NULL) { 694 return NULL; 695 } 696 talloc_set_destructor(state, node_status_query_state_destructor); 697 698 if (addr->ss_family != AF_INET) { 699 /* Can't do node status to IPv6 */ 700 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS); 701 return tevent_req_post(req, ev); 702 } 703 704 state->addr = *addr; 705 in_addr = (struct sockaddr_in *)(void *)&state->addr; 706 in_addr->sin_port = htons(NMB_PORT); 707 708 if (!interpret_string_addr(&state->my_addr, lp_socket_address(), 709 AI_NUMERICHOST|AI_PASSIVE)) { 710 zero_sockaddr(&state->my_addr); 711 } 266 712 267 713 ZERO_STRUCT(p); 268 269 if (to_ss->ss_family != AF_INET) {270 /* Can't do node status to IPv6 */271 return NULL;272 }273 714 nmb->header.name_trn_id = generate_trn_id(); 274 715 nmb->header.opcode = 0; … … 288 729 nmb->question.question_class = 0x1; 289 730 290 p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr; 291 p.port = NMB_PORT; 292 p.recv_fd = -1; 293 p.send_fd = fd; 294 p.timestamp = time(NULL); 295 p.packet_type = NMB_PACKET; 296 297 GetTimeOfDay(&tval); 298 299 if (!send_packet(&p)) 300 return NULL; 301 302 retries--; 303 304 while (1) { 305 struct timeval tval2; 306 GetTimeOfDay(&tval2); 307 if (TvalDiff(&tval,&tval2) > retry_time) { 308 if (!retries) 309 break; 310 if (!found && !send_packet(&p)) 311 return NULL; 312 GetTimeOfDay(&tval); 313 retries--; 314 } 315 316 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { 317 struct nmb_packet *nmb2 = &p2->packet.nmb; 318 debug_nmb_packet(p2); 319 320 if (nmb2->header.opcode != 0 || 321 nmb2->header.nm_flags.bcast || 322 nmb2->header.rcode || 323 !nmb2->header.ancount || 324 nmb2->answers->rr_type != 0x21) { 325 /* XXXX what do we do with this? could be a 326 redirect, but we'll discard it for the 327 moment */ 328 free_packet(p2); 329 continue; 330 } 331 332 ret = parse_node_status(&nmb2->answers->rdata[0], 333 num_names, extra); 334 free_packet(p2); 335 return ret; 336 } 337 } 338 339 return NULL; 731 state->buflen = build_packet((char *)state->buf, sizeof(state->buf), 732 &p); 733 if (state->buflen == 0) { 734 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 735 DEBUG(10, ("build_packet failed\n")); 736 return tevent_req_post(req, ev); 737 } 738 739 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false, 740 state->buf, state->buflen, 741 NMB_PACKET, nmb->header.name_trn_id, 742 node_status_query_validator, NULL); 743 if (tevent_req_nomem(subreq, req)) { 744 DEBUG(10, ("nb_trans_send failed\n")); 745 return tevent_req_post(req, ev); 746 } 747 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) { 748 return tevent_req_post(req, ev); 749 } 750 tevent_req_set_callback(subreq, node_status_query_done, req); 751 return req; 752 } 753 754 static bool node_status_query_validator(struct packet_struct *p, 755 void *private_data) 756 { 757 struct nmb_packet *nmb = &p->packet.nmb; 758 debug_nmb_packet(p); 759 760 if (nmb->header.opcode != 0 || 761 nmb->header.nm_flags.bcast || 762 nmb->header.rcode || 763 !nmb->header.ancount || 764 nmb->answers->rr_type != 0x21) { 765 /* 766 * XXXX what do we do with this? could be a redirect, 767 * but we'll discard it for the moment 768 */ 769 return false; 770 } 771 return true; 772 } 773 774 static int node_status_query_state_destructor( 775 struct node_status_query_state *s) 776 { 777 if (s->packet != NULL) { 778 free_packet(s->packet); 779 s->packet = NULL; 780 } 781 return 0; 782 } 783 784 static void node_status_query_done(struct tevent_req *subreq) 785 { 786 struct tevent_req *req = tevent_req_callback_data( 787 subreq, struct tevent_req); 788 struct node_status_query_state *state = tevent_req_data( 789 req, struct node_status_query_state); 790 NTSTATUS status; 791 792 status = nb_trans_recv(subreq, &state->packet); 793 TALLOC_FREE(subreq); 794 if (tevent_req_nterror(req, status)) { 795 return; 796 } 797 tevent_req_done(req); 798 } 799 800 NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 801 struct node_status **pnode_status, 802 int *pnum_names, 803 struct node_status_extra *extra) 804 { 805 struct node_status_query_state *state = tevent_req_data( 806 req, struct node_status_query_state); 807 struct node_status *node_status; 808 int num_names; 809 NTSTATUS status; 810 811 if (tevent_req_is_nterror(req, &status)) { 812 return status; 813 } 814 node_status = parse_node_status( 815 mem_ctx, &state->packet->packet.nmb.answers->rdata[0], 816 &num_names, extra); 817 if (node_status == NULL) { 818 return NT_STATUS_NO_MEMORY; 819 } 820 *pnode_status = node_status; 821 *pnum_names = num_names; 822 return NT_STATUS_OK; 823 } 824 825 NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name, 826 const struct sockaddr_storage *addr, 827 struct node_status **pnode_status, 828 int *pnum_names, 829 struct node_status_extra *extra) 830 { 831 TALLOC_CTX *frame = talloc_stackframe(); 832 struct tevent_context *ev; 833 struct tevent_req *req; 834 NTSTATUS status = NT_STATUS_NO_MEMORY; 835 836 ev = tevent_context_init(frame); 837 if (ev == NULL) { 838 goto fail; 839 } 840 req = node_status_query_send(ev, ev, name, addr); 841 if (req == NULL) { 842 goto fail; 843 } 844 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 845 goto fail; 846 } 847 status = node_status_query_recv(req, mem_ctx, pnode_status, 848 pnum_names, extra); 849 fail: 850 TALLOC_FREE(frame); 851 return status; 340 852 } 341 853 … … 353 865 char addr[INET6_ADDRSTRLEN]; 354 866 struct sockaddr_storage ss; 355 NODE_STATUS_STRUCT *status = NULL;867 struct node_status *addrs = NULL; 356 868 struct nmb_name nname; 357 869 int count, i; 358 int sock;359 870 bool result = false; 871 NTSTATUS status; 360 872 361 873 if (lp_disable_netbios()) { … … 386 898 } 387 899 388 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);389 if (sock == -1)390 goto done;391 392 900 /* W2K PDC's seem not to respond to '*'#0. JRA */ 393 901 make_nmb_name(&nname, q_name, q_type); 394 status = node_status_query( sock, &nname, to_ss, &count, NULL);395 close(sock);396 if (! status)902 status = node_status_query(talloc_tos(), &nname, to_ss, 903 &addrs, &count, NULL); 904 if (!NT_STATUS_IS_OK(status)) { 397 905 goto done; 906 } 398 907 399 908 for (i=0;i<count;i++) { 400 909 /* Find first one of the requested type that's not a GROUP. */ 401 if ( status[i].type == type && ! (status[i].flags & 0x80))910 if (addrs[i].type == type && ! (addrs[i].flags & 0x80)) 402 911 break; 403 912 } … … 405 914 goto done; 406 915 407 pull_ascii_nstring(name, sizeof(fstring), status[i].name);916 pull_ascii_nstring(name, sizeof(fstring), addrs[i].name); 408 917 409 918 /* Store the result in the cache. */ … … 418 927 419 928 done: 420 SAFE_FREE(status);929 TALLOC_FREE(addrs); 421 930 422 931 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not ")); … … 434 943 */ 435 944 436 static int addr_compare(const struct sockaddr *ss1,437 const struct sockaddr*ss2)945 static int addr_compare(const struct sockaddr_storage *ss1, 946 const struct sockaddr_storage *ss2) 438 947 { 439 948 int max_bits1=0, max_bits2=0; … … 442 951 443 952 /* Sort IPv4 addresses first. */ 444 if (ss1->s a_family != ss2->sa_family) {445 if (ss2->s a_family == AF_INET) {953 if (ss1->ss_family != ss2->ss_family) { 954 if (ss2->ss_family == AF_INET) { 446 955 return 1; 447 956 } else { … … 461 970 int bits1, bits2; 462 971 463 if (pss->ss_family != ss1->s a_family) {972 if (pss->ss_family != ss1->ss_family) { 464 973 /* Ignore interfaces of the wrong type. */ 465 974 continue; … … 495 1004 496 1005 /* Bias towards directly reachable IPs */ 497 if (iface_local( ss1)) {498 if (ss1->s a_family == AF_INET) {1006 if (iface_local((struct sockaddr *)ss1)) { 1007 if (ss1->ss_family == AF_INET) { 499 1008 max_bits1 += 32; 500 1009 } else { … … 502 1011 } 503 1012 } 504 if (iface_local( ss2)) {505 if (ss2->s a_family == AF_INET) {1013 if (iface_local((struct sockaddr *)ss2)) { 1014 if (ss2->ss_family == AF_INET) { 506 1015 max_bits2 += 32; 507 1016 } else { … … 520 1029 int result; 521 1030 522 if ((result = addr_compare( (struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {1031 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) { 523 1032 return result; 524 1033 } … … 547 1056 } 548 1057 549 qsort(sslist, count, sizeof(struct sockaddr_storage), 550 QSORT_CAST addr_compare); 1058 TYPESAFE_QSORT(sslist, count, addr_compare); 551 1059 } 552 1060 … … 557 1065 } 558 1066 559 qsort(servlist, count, sizeof(struct ip_service), 560 QSORT_CAST ip_service_compare); 1067 TYPESAFE_QSORT(servlist, count, ip_service_compare); 561 1068 } 562 1069 … … 574 1081 /* one loop to remove duplicates */ 575 1082 for ( i=0; i<count; i++ ) { 576 if ( is_zero_addr( (struct sockaddr *)&iplist[i].ss)) {1083 if ( is_zero_addr(&iplist[i].ss)) { 577 1084 continue; 578 1085 } … … 589 1096 /* first ip should never be a zero_ip() */ 590 1097 for (i = 0; i<count; ) { 591 if (is_zero_addr( (struct sockaddr *)&iplist[i].ss) ) {1098 if (is_zero_addr(&iplist[i].ss) ) { 592 1099 if (i != count-1) { 593 1100 memmove(&iplist[i], &iplist[i+1], … … 642 1149 ****************************************************************************/ 643 1150 644 struct sockaddr_storage *name_query(int fd, 645 const char *name, 646 int name_type, 647 bool bcast, 648 bool recurse, 649 const struct sockaddr_storage *to_ss, 650 int *count, 651 int *flags, 652 bool *timed_out) 653 { 654 bool found=false; 655 int i, retries = 3; 656 int retry_time = bcast?250:2000; 657 struct timeval tval; 1151 struct name_query_state { 1152 struct sockaddr_storage my_addr; 1153 struct sockaddr_storage addr; 1154 bool bcast; 1155 1156 1157 uint8_t buf[1024]; 1158 ssize_t buflen; 1159 1160 NTSTATUS validate_error; 1161 uint8_t flags; 1162 1163 struct sockaddr_storage *addrs; 1164 int num_addrs; 1165 }; 1166 1167 static bool name_query_validator(struct packet_struct *p, void *private_data); 1168 static void name_query_done(struct tevent_req *subreq); 1169 1170 struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, 1171 struct tevent_context *ev, 1172 const char *name, int name_type, 1173 bool bcast, bool recurse, 1174 const struct sockaddr_storage *addr) 1175 { 1176 struct tevent_req *req, *subreq; 1177 struct name_query_state *state; 658 1178 struct packet_struct p; 659 struct packet_struct *p2;660 1179 struct nmb_packet *nmb = &p.packet.nmb; 661 struct sockaddr_storage *ss_list = NULL; 1180 struct sockaddr_in *in_addr; 1181 1182 req = tevent_req_create(mem_ctx, &state, struct name_query_state); 1183 if (req == NULL) { 1184 return NULL; 1185 } 1186 state->bcast = bcast; 1187 1188 if (addr->ss_family != AF_INET) { 1189 /* Can't do node status to IPv6 */ 1190 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS); 1191 return tevent_req_post(req, ev); 1192 } 662 1193 663 1194 if (lp_disable_netbios()) { 664 1195 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", 665 1196 name, name_type)); 666 return NULL; 667 } 668 669 if (to_ss->ss_family != AF_INET) { 670 return NULL; 671 } 672 673 if (timed_out) { 674 *timed_out = false; 675 } 676 677 memset((char *)&p,'\0',sizeof(p)); 678 (*count) = 0; 679 (*flags) = 0; 680 1197 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 1198 return tevent_req_post(req, ev); 1199 } 1200 1201 state->addr = *addr; 1202 in_addr = (struct sockaddr_in *)(void *)&state->addr; 1203 in_addr->sin_port = htons(NMB_PORT); 1204 1205 if (!interpret_string_addr(&state->my_addr, lp_socket_address(), 1206 AI_NUMERICHOST|AI_PASSIVE)) { 1207 zero_sockaddr(&state->my_addr); 1208 } 1209 1210 ZERO_STRUCT(p); 681 1211 nmb->header.name_trn_id = generate_trn_id(); 682 1212 nmb->header.opcode = 0; … … 698 1228 nmb->question.question_class = 0x1; 699 1229 700 p.ip = ((struct sockaddr_in *)to_ss)->sin_addr; 701 p.port = NMB_PORT; 702 p.recv_fd = -1; 703 p.send_fd = fd; 704 p.timestamp = time(NULL); 705 p.packet_type = NMB_PACKET; 706 707 GetTimeOfDay(&tval); 708 709 if (!send_packet(&p)) 710 return NULL; 711 712 retries--; 713 714 while (1) { 715 struct timeval tval2; 716 717 GetTimeOfDay(&tval2); 718 if (TvalDiff(&tval,&tval2) > retry_time) { 719 if (!retries) 1230 state->buflen = build_packet((char *)state->buf, sizeof(state->buf), 1231 &p); 1232 if (state->buflen == 0) { 1233 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 1234 DEBUG(10, ("build_packet failed\n")); 1235 return tevent_req_post(req, ev); 1236 } 1237 1238 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast, 1239 state->buf, state->buflen, 1240 NMB_PACKET, nmb->header.name_trn_id, 1241 name_query_validator, state); 1242 if (tevent_req_nomem(subreq, req)) { 1243 DEBUG(10, ("nb_trans_send failed\n")); 1244 return tevent_req_post(req, ev); 1245 } 1246 tevent_req_set_callback(subreq, name_query_done, req); 1247 return req; 1248 } 1249 1250 static bool name_query_validator(struct packet_struct *p, void *private_data) 1251 { 1252 struct name_query_state *state = talloc_get_type_abort( 1253 private_data, struct name_query_state); 1254 struct nmb_packet *nmb = &p->packet.nmb; 1255 struct sockaddr_storage *tmp_addrs; 1256 bool got_unique_netbios_name = false; 1257 int i; 1258 1259 debug_nmb_packet(p); 1260 1261 /* 1262 * If we get a Negative Name Query Response from a WINS 1263 * server, we should report it and give up. 1264 */ 1265 if( 0 == nmb->header.opcode /* A query response */ 1266 && !state->bcast /* from a WINS server */ 1267 && nmb->header.rcode /* Error returned */ 1268 ) { 1269 1270 if( DEBUGLVL( 3 ) ) { 1271 /* Only executed if DEBUGLEVEL >= 3 */ 1272 dbgtext( "Negative name query " 1273 "response, rcode 0x%02x: ", 1274 nmb->header.rcode ); 1275 switch( nmb->header.rcode ) { 1276 case 0x01: 1277 dbgtext("Request was invalidly formatted.\n"); 720 1278 break; 721 if (!found && !send_packet(&p)) 722 return NULL; 723 GetTimeOfDay(&tval); 724 retries--; 725 } 726 727 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { 728 struct nmb_packet *nmb2 = &p2->packet.nmb; 729 debug_nmb_packet(p2); 730 731 /* If we get a Negative Name Query Response from a WINS 732 * server, we should report it and give up. 733 */ 734 if( 0 == nmb2->header.opcode /* A query response */ 735 && !(bcast) /* from a WINS server */ 736 && nmb2->header.rcode /* Error returned */ 737 ) { 738 739 if( DEBUGLVL( 3 ) ) { 740 /* Only executed if DEBUGLEVEL >= 3 */ 741 dbgtext( "Negative name query " 742 "response, rcode 0x%02x: ", 743 nmb2->header.rcode ); 744 switch( nmb2->header.rcode ) { 745 case 0x01: 746 dbgtext( "Request " 747 "was invalidly formatted.\n" ); 748 break; 749 case 0x02: 750 dbgtext( "Problem with NBNS, " 751 "cannot process name.\n"); 752 break; 753 case 0x03: 754 dbgtext( "The name requested " 755 "does not exist.\n" ); 756 break; 757 case 0x04: 758 dbgtext( "Unsupported request " 759 "error.\n" ); 760 break; 761 case 0x05: 762 dbgtext( "Query refused " 763 "error.\n" ); 764 break; 765 default: 766 dbgtext( "Unrecognized error " 767 "code.\n" ); 768 break; 769 } 770 } 771 free_packet(p2); 772 return( NULL ); 1279 case 0x02: 1280 dbgtext("Problem with NBNS, cannot process " 1281 "name.\n"); 1282 break; 1283 case 0x03: 1284 dbgtext("The name requested does not " 1285 "exist.\n"); 1286 break; 1287 case 0x04: 1288 dbgtext("Unsupported request error.\n"); 1289 break; 1290 case 0x05: 1291 dbgtext("Query refused error.\n"); 1292 break; 1293 default: 1294 dbgtext("Unrecognized error code.\n" ); 1295 break; 773 1296 } 774 775 if (nmb2->header.opcode != 0 || 776 nmb2->header.nm_flags.bcast || 777 nmb2->header.rcode || 778 !nmb2->header.ancount) { 779 /* 780 * XXXX what do we do with this? Could be a 781 * redirect, but we'll discard it for the 782 * moment. 783 */ 784 free_packet(p2); 785 continue; 1297 } 1298 1299 /* 1300 * We accept this packet as valid, but tell the upper 1301 * layers that it's a negative response. 1302 */ 1303 state->validate_error = NT_STATUS_NOT_FOUND; 1304 return true; 1305 } 1306 1307 if (nmb->header.opcode != 0 || 1308 nmb->header.nm_flags.bcast || 1309 nmb->header.rcode || 1310 !nmb->header.ancount) { 1311 /* 1312 * XXXX what do we do with this? Could be a redirect, 1313 * but we'll discard it for the moment. 1314 */ 1315 return false; 1316 } 1317 1318 tmp_addrs = TALLOC_REALLOC_ARRAY( 1319 state, state->addrs, struct sockaddr_storage, 1320 state->num_addrs + nmb->answers->rdlength/6); 1321 if (tmp_addrs == NULL) { 1322 state->validate_error = NT_STATUS_NO_MEMORY; 1323 return true; 1324 } 1325 state->addrs = tmp_addrs; 1326 1327 DEBUG(2,("Got a positive name query response " 1328 "from %s ( ", inet_ntoa(p->ip))); 1329 1330 for (i=0; i<nmb->answers->rdlength/6; i++) { 1331 uint16_t flags; 1332 struct in_addr ip; 1333 struct sockaddr_storage addr; 1334 int j; 1335 1336 flags = RSVAL(&nmb->answers->rdata[i*6], 0); 1337 got_unique_netbios_name |= ((flags & 0x8000) == 0); 1338 1339 putip((char *)&ip,&nmb->answers->rdata[2+i*6]); 1340 in_addr_to_sockaddr_storage(&addr, ip); 1341 1342 for (j=0; j<state->num_addrs; j++) { 1343 if (sockaddr_equal( 1344 (struct sockaddr *)&addr, 1345 (struct sockaddr *)&state->addrs[j])) { 1346 break; 786 1347 } 787 788 ss_list = SMB_REALLOC_ARRAY(ss_list, 789 struct sockaddr_storage, 790 (*count) + 791 nmb2->answers->rdlength/6); 792 793 if (!ss_list) { 794 DEBUG(0,("name_query: Realloc failed.\n")); 795 free_packet(p2); 796 return NULL; 797 } 798 799 DEBUG(2,("Got a positive name query response " 800 "from %s ( ", 801 inet_ntoa(p2->ip))); 802 803 for (i=0;i<nmb2->answers->rdlength/6;i++) { 804 struct in_addr ip; 805 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]); 806 in_addr_to_sockaddr_storage(&ss_list[(*count)], 807 ip); 808 DEBUGADD(2,("%s ",inet_ntoa(ip))); 809 (*count)++; 810 } 811 DEBUGADD(2,(")\n")); 812 813 found=true; 814 retries=0; 815 /* We add the flags back ... */ 816 if (nmb2->header.response) 817 (*flags) |= NM_FLAGS_RS; 818 if (nmb2->header.nm_flags.authoritative) 819 (*flags) |= NM_FLAGS_AA; 820 if (nmb2->header.nm_flags.trunc) 821 (*flags) |= NM_FLAGS_TC; 822 if (nmb2->header.nm_flags.recursion_desired) 823 (*flags) |= NM_FLAGS_RD; 824 if (nmb2->header.nm_flags.recursion_available) 825 (*flags) |= NM_FLAGS_RA; 826 if (nmb2->header.nm_flags.bcast) 827 (*flags) |= NM_FLAGS_B; 828 free_packet(p2); 829 /* 830 * If we're doing a unicast lookup we only 831 * expect one reply. Don't wait the full 2 832 * seconds if we got one. JRA. 833 */ 834 if(!bcast && found) 835 break; 836 } 837 } 838 839 /* only set timed_out if we didn't fund what we where looking for*/ 840 841 if ( !found && timed_out ) { 842 *timed_out = true; 843 } 844 845 /* sort the ip list so we choose close servers first if possible */ 846 sort_addr_list(ss_list, *count); 847 848 return ss_list; 1348 } 1349 if (j < state->num_addrs) { 1350 /* Already got it */ 1351 continue; 1352 } 1353 1354 DEBUGADD(2,("%s ",inet_ntoa(ip))); 1355 1356 state->addrs[state->num_addrs] = addr; 1357 state->num_addrs += 1; 1358 } 1359 DEBUGADD(2,(")\n")); 1360 1361 /* We add the flags back ... */ 1362 if (nmb->header.response) 1363 state->flags |= NM_FLAGS_RS; 1364 if (nmb->header.nm_flags.authoritative) 1365 state->flags |= NM_FLAGS_AA; 1366 if (nmb->header.nm_flags.trunc) 1367 state->flags |= NM_FLAGS_TC; 1368 if (nmb->header.nm_flags.recursion_desired) 1369 state->flags |= NM_FLAGS_RD; 1370 if (nmb->header.nm_flags.recursion_available) 1371 state->flags |= NM_FLAGS_RA; 1372 if (nmb->header.nm_flags.bcast) 1373 state->flags |= NM_FLAGS_B; 1374 1375 if (state->bcast) { 1376 /* 1377 * We have to collect all entries coming in from broadcast 1378 * queries. If we got a unique name, we're done. 1379 */ 1380 return got_unique_netbios_name; 1381 } 1382 /* 1383 * WINS responses are accepted when they are received 1384 */ 1385 return true; 1386 } 1387 1388 static void name_query_done(struct tevent_req *subreq) 1389 { 1390 struct tevent_req *req = tevent_req_callback_data( 1391 subreq, struct tevent_req); 1392 struct name_query_state *state = tevent_req_data( 1393 req, struct name_query_state); 1394 NTSTATUS status; 1395 struct packet_struct *p = NULL; 1396 1397 status = nb_trans_recv(subreq, &p); 1398 TALLOC_FREE(subreq); 1399 if (tevent_req_nterror(req, status)) { 1400 return; 1401 } 1402 if (!NT_STATUS_IS_OK(state->validate_error)) { 1403 tevent_req_nterror(req, state->validate_error); 1404 return; 1405 } 1406 if (p != NULL) { 1407 /* 1408 * Free the packet here, we've collected the response in the 1409 * validator 1410 */ 1411 free_packet(p); 1412 } 1413 tevent_req_done(req); 1414 } 1415 1416 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 1417 struct sockaddr_storage **addrs, int *num_addrs, 1418 uint8_t *flags) 1419 { 1420 struct name_query_state *state = tevent_req_data( 1421 req, struct name_query_state); 1422 NTSTATUS status; 1423 1424 if (tevent_req_is_nterror(req, &status) 1425 && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 1426 return status; 1427 } 1428 if (state->num_addrs == 0) { 1429 return NT_STATUS_NOT_FOUND; 1430 } 1431 *addrs = talloc_move(mem_ctx, &state->addrs); 1432 sort_addr_list(*addrs, state->num_addrs); 1433 *num_addrs = state->num_addrs; 1434 if (flags != NULL) { 1435 *flags = state->flags; 1436 } 1437 return NT_STATUS_OK; 1438 } 1439 1440 NTSTATUS name_query(const char *name, int name_type, 1441 bool bcast, bool recurse, 1442 const struct sockaddr_storage *to_ss, 1443 TALLOC_CTX *mem_ctx, 1444 struct sockaddr_storage **addrs, 1445 int *num_addrs, uint8_t *flags) 1446 { 1447 TALLOC_CTX *frame = talloc_stackframe(); 1448 struct tevent_context *ev; 1449 struct tevent_req *req; 1450 struct timeval timeout; 1451 NTSTATUS status = NT_STATUS_NO_MEMORY; 1452 1453 ev = tevent_context_init(frame); 1454 if (ev == NULL) { 1455 goto fail; 1456 } 1457 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss); 1458 if (req == NULL) { 1459 goto fail; 1460 } 1461 if (bcast) { 1462 timeout = timeval_current_ofs(0, 250000); 1463 } else { 1464 timeout = timeval_current_ofs(2, 0); 1465 } 1466 if (!tevent_req_set_endtime(req, ev, timeout)) { 1467 goto fail; 1468 } 1469 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1470 goto fail; 1471 } 1472 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags); 1473 fail: 1474 TALLOC_FREE(frame); 1475 return status; 849 1476 } 850 1477 … … 885 1512 NTSTATUS name_resolve_bcast(const char *name, 886 1513 int name_type, 887 struct ip_service **return_iplist, 1514 TALLOC_CTX *mem_ctx, 1515 struct sockaddr_storage **return_iplist, 888 1516 int *return_count) 889 1517 { 890 int sock,i;1518 int i; 891 1519 int num_interfaces = iface_count(); 892 1520 struct sockaddr_storage *ss_list; 893 struct sockaddr_storage ss; 894 NTSTATUS status; 1521 NTSTATUS status = NT_STATUS_NOT_FOUND; 895 1522 896 1523 if (lp_disable_netbios()) { … … 910 1537 "for name %s<0x%x>\n", name, name_type)); 911 1538 912 if (!interpret_string_addr(&ss, lp_socket_address(),913 AI_NUMERICHOST|AI_PASSIVE)) {914 zero_sockaddr(&ss);915 }916 917 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );918 if (sock == -1) {919 return NT_STATUS_UNSUCCESSFUL;920 }921 922 set_socket_options(sock,"SO_BROADCAST");923 1539 /* 924 1540 * Lookup the name on all the interfaces, return on … … 927 1543 for( i = num_interfaces-1; i >= 0; i--) { 928 1544 const struct sockaddr_storage *pss = iface_n_bcast(i); 929 int flags;930 1545 931 1546 /* Done this way to fix compiler error on IRIX 5.x */ … … 933 1548 continue; 934 1549 } 935 ss_list = name_query(sock, name, name_type, true, 936 true, pss, return_count, &flags, NULL); 937 if (ss_list) { 1550 status = name_query(name, name_type, true, true, pss, 1551 talloc_tos(), &ss_list, return_count, 1552 NULL); 1553 if (NT_STATUS_IS_OK(status)) { 938 1554 goto success; 939 1555 } … … 942 1558 /* failed - no response */ 943 1559 944 close(sock); 945 return NT_STATUS_UNSUCCESSFUL; 1560 return status; 946 1561 947 1562 success: 948 949 status = NT_STATUS_OK; 950 if (!convert_ss2service(return_iplist, ss_list, *return_count) ) 951 status = NT_STATUS_INVALID_PARAMETER; 952 953 SAFE_FREE(ss_list); 954 close(sock); 1563 *return_iplist = ss_list; 955 1564 return status; 956 1565 } … … 965 1574 int *return_count) 966 1575 { 967 int sock,t, i;1576 int t, i; 968 1577 char **wins_tags; 969 1578 struct sockaddr_storage src_ss, *ss_list = NULL; … … 1022 1631 struct sockaddr_storage wins_ss; 1023 1632 struct in_addr wins_ip; 1024 int flags;1025 bool timed_out;1026 1633 1027 1634 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip); … … 1041 1648 inet_ntoa(wins_ip), wins_tags[t])); 1042 1649 1043 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);1044 if (sock == -1) {1045 continue;1046 }1047 1048 1650 in_addr_to_sockaddr_storage(&wins_ss, wins_ip); 1049 ss_list = name_query(sock, 1050 name, 1651 status = name_query(name, 1051 1652 name_type, 1052 1653 false, 1053 1654 true, 1054 1655 &wins_ss, 1656 talloc_tos(), 1657 &ss_list, 1055 1658 return_count, 1056 &flags, 1057 &timed_out); 1659 NULL); 1058 1660 1059 1661 /* exit loop if we got a list of addresses */ 1060 1662 1061 if ( ss_list)1663 if (NT_STATUS_IS_OK(status)) { 1062 1664 goto success; 1063 1064 close(sock); 1065 1066 if (timed_out) { 1067 /* Timed out wating for WINS server to respond. 1665 } 1666 1667 if (NT_STATUS_EQUAL(status, 1668 NT_STATUS_IO_TIMEOUT)) { 1669 /* Timed out waiting for WINS server to 1670 * respond. 1068 1671 * Mark it dead. */ 1069 1672 wins_srv_died(wins_ip, src_ip); 1070 1673 } else { 1071 /* The name defin ately isn't in this1674 /* The name definitely isn't in this 1072 1675 group of WINS servers. 1073 1676 goto the next group */ … … 1086 1689 status = NT_STATUS_INVALID_PARAMETER; 1087 1690 1088 SAFE_FREE(ss_list);1691 TALLOC_FREE(ss_list); 1089 1692 wins_srv_tags_free(wins_tags); 1090 close(sock);1091 1693 1092 1694 return status; … … 1104 1706 * "lmhosts" means parse the local lmhosts file. 1105 1707 */ 1106 1107 XFILE *fp; 1108 char *lmhost_name = NULL; 1109 int name_type2; 1110 struct sockaddr_storage return_ss; 1708 struct sockaddr_storage *ss_list; 1111 1709 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 1112 1710 TALLOC_CTX *ctx = NULL; … … 1119 1717 name, name_type)); 1120 1718 1121 fp = startlmhosts(get_dyn_LMHOSTSFILE());1122 1123 if ( fp == NULL )1124 return NT_STATUS_NO_SUCH_FILE;1125 1126 1719 ctx = talloc_init("resolve_lmhosts"); 1127 1720 if (!ctx) { 1128 endlmhosts(fp);1129 1721 return NT_STATUS_NO_MEMORY; 1130 1722 } 1131 1723 1132 while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) { 1133 1134 if (!strequal(name, lmhost_name)) { 1135 TALLOC_FREE(lmhost_name); 1136 continue; 1137 } 1138 1139 if ((name_type2 != -1) && (name_type != name_type2)) { 1140 TALLOC_FREE(lmhost_name); 1141 continue; 1142 } 1143 1144 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), 1145 struct ip_service, 1146 (*return_count)+1); 1147 1148 if ((*return_iplist) == NULL) { 1149 TALLOC_FREE(ctx); 1150 endlmhosts(fp); 1151 DEBUG(3,("resolve_lmhosts: malloc fail !\n")); 1724 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(), 1725 name, name_type, 1726 ctx, 1727 &ss_list, 1728 return_count); 1729 if (NT_STATUS_IS_OK(status)) { 1730 if (convert_ss2service(return_iplist, 1731 ss_list, 1732 *return_count)) { 1733 talloc_free(ctx); 1734 return NT_STATUS_OK; 1735 } else { 1736 talloc_free(ctx); 1152 1737 return NT_STATUS_NO_MEMORY; 1153 1738 } 1154 1155 (*return_iplist)[*return_count].ss = return_ss; 1156 (*return_iplist)[*return_count].port = PORT_NONE; 1157 *return_count += 1; 1158 1159 /* we found something */ 1160 status = NT_STATUS_OK; 1161 1162 /* Multiple names only for DC lookup */ 1163 if (name_type != 0x1c) 1164 break; 1165 } 1166 1167 TALLOC_FREE(ctx); 1168 endlmhosts(fp); 1739 } 1740 talloc_free(ctx); 1169 1741 return status; 1170 1742 } … … 1257 1829 Resolve via "ADS" method. 1258 1830 *********************************************************/ 1831 1832 /* Special name type used to cause a _kerberos DNS lookup. */ 1833 #define KDC_NAME_TYPE 0xDCDC 1259 1834 1260 1835 static NTSTATUS resolve_ads(const char *name, … … 1361 1936 * doesn't know anything about the DC's -- jerry */ 1362 1937 1363 if (!is_zero_addr( (struct sockaddr *)&r->ss)) {1938 if (!is_zero_addr(&r->ss)) { 1364 1939 (*return_count)++; 1365 1940 } … … 1493 2068 } 1494 2069 } else if(strequal( tok, "bcast")) { 1495 status = name_resolve_bcast(name, name_type, 1496 return_iplist, 1497 return_count); 2070 struct sockaddr_storage *ss_list; 2071 status = name_resolve_bcast( 2072 name, name_type, talloc_tos(), 2073 &ss_list, return_count); 1498 2074 if (NT_STATUS_IS_OK(status)) { 2075 if (!convert_ss2service(return_iplist, 2076 ss_list, 2077 *return_count)) { 2078 status = NT_STATUS_NO_MEMORY; 2079 } 1499 2080 goto done; 1500 2081 } … … 1591 2172 if (prefer_ipv4) { 1592 2173 for (i=0; i<count; i++) { 1593 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2174 if (!is_zero_addr(&ss_list[i].ss) && 1594 2175 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) && 1595 2176 (ss_list[i].ss.ss_family == AF_INET)) { … … 1604 2185 /* only return valid addresses for TCP connections */ 1605 2186 for (i=0; i<count; i++) { 1606 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2187 if (!is_zero_addr(&ss_list[i].ss) && 1607 2188 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { 1608 2189 *return_ss = ss_list[i].ss; … … 1668 2249 /* only return valid addresses for TCP connections */ 1669 2250 for (i=0, num_entries = 0; i<count; i++) { 1670 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2251 if (!is_zero_addr(&ss_list[i].ss) && 1671 2252 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { 1672 2253 num_entries++; … … 1687 2268 1688 2269 for (i=0, num_entries = 0; i<count; i++) { 1689 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2270 if (!is_zero_addr(&ss_list[i].ss) && 1690 2271 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { 1691 2272 (*return_ss_arr)[num_entries++] = ss_list[i].ss; … … 1855 2436 1856 2437 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) { 1857 pserver = talloc_asprintf( NULL, "%s, %s",2438 pserver = talloc_asprintf(ctx, "%s, %s", 1858 2439 saf_servername ? saf_servername : "", 1859 2440 lp_passwordserver()); 1860 2441 } else { 1861 pserver = talloc_asprintf( NULL, "%s, *",2442 pserver = talloc_asprintf(ctx, "%s, *", 1862 2443 saf_servername ? saf_servername : ""); 1863 2444 } -
vendor/current/source3/libsmb/namequery_dc.c
r478 r740 7 7 Copyright (C) Andrew Bartlett 2002 8 8 Copyright (C) Gerald Carter 2003 9 9 10 10 This program is free software; you can redistribute it and/or modify 11 11 it under the terms of the GNU General Public License as published by 12 12 the Free Software Foundation; either version 3 of the License, or 13 13 (at your option) any later version. 14 14 15 15 This program is distributed in the hope that it will be useful, 16 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 18 GNU General Public License for more details. 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 24 25 25 #include "includes.h" 26 #include "libads/sitename_cache.h" 27 #include "ads.h" 28 #include "../librpc/gen_ndr/nbt.h" 26 29 27 30 /********************************************************************** … … 46 49 Find the name and IP address for a server in the realm/domain 47 50 *************************************************************************/ 48 51 49 52 static bool ads_dc_name(const char *domain, 50 53 const char *realm, … … 99 102 } 100 103 101 #ifdef HAVE_ KRB5104 #ifdef HAVE_ADS 102 105 if (is_our_primary_domain(domain) && (ads->config.flags & NBT_SERVER_KDC)) { 103 106 if (ads_closest_dc(ads)) { … … 174 177 175 178 for (i = 0; i < count; i++) { 176 if (is_zero_addr( (struct sockaddr *)&ip_list[i].ss))179 if (is_zero_addr(&ip_list[i].ss)) 177 180 continue; 178 181 -
vendor/current/source3/libsmb/nmblib.c
r594 r740 21 21 22 22 #include "includes.h" 23 #include "libsmb/nmblib.h" 23 24 24 25 static const struct opcode_names { … … 726 727 } 727 728 729 int packet_trn_id(struct packet_struct *p) 730 { 731 int result; 732 switch (p->packet_type) { 733 case NMB_PACKET: 734 result = p->packet.nmb.header.name_trn_id; 735 break; 736 case DGRAM_PACKET: 737 result = p->packet.dgram.header.dgm_id; 738 break; 739 default: 740 result = -1; 741 } 742 return result; 743 } 744 728 745 /******************************************************************* 729 746 Parse a packet buffer into a packet structure. … … 1085 1102 1086 1103 /**************************************************************************** 1087 Receive a packet with timeout on a open UDP filedescriptor.1088 The timeout is in milliseconds1089 ***************************************************************************/1090 1091 struct packet_struct *receive_packet(int fd,enum packet_type type,int t)1092 {1093 fd_set fds;1094 struct timeval timeout;1095 int ret;1096 1097 if (fd < 0 || fd >= FD_SETSIZE) {1098 errno = EBADF;1099 return NULL;1100 }1101 1102 FD_ZERO(&fds);1103 FD_SET(fd,&fds);1104 timeout.tv_sec = t/1000;1105 timeout.tv_usec = 1000*(t%1000);1106 1107 if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {1108 /* errno should be EBADF or EINVAL. */1109 DEBUG(0,("select returned -1, errno = %s (%d)\n",1110 strerror(errno), errno));1111 return NULL;1112 }1113 1114 if (ret == 0) /* timeout */1115 return NULL;1116 1117 if (FD_ISSET(fd,&fds))1118 return(read_packet(fd,type));1119 1120 return(NULL);1121 }1122 1123 /****************************************************************************1124 Receive a UDP/137 packet either via UDP or from the unexpected packet1125 queue. The packet must be a reply packet and have the specified trn_id.1126 The timeout is in milliseconds.1127 ***************************************************************************/1128 1129 struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)1130 {1131 struct packet_struct *p;1132 1133 p = receive_packet(fd, NMB_PACKET, t);1134 1135 if (p && p->packet.nmb.header.response &&1136 p->packet.nmb.header.name_trn_id == trn_id) {1137 return p;1138 }1139 if (p)1140 free_packet(p);1141 1142 /* try the unexpected packet queue */1143 return receive_unexpected(NMB_PACKET, trn_id, NULL);1144 }1145 1146 /****************************************************************************1147 1104 Receive a UDP/138 packet either via UDP or from the unexpected packet 1148 1105 queue. The packet must be a reply packet and have the specified mailslot name 1149 1106 The timeout is in milliseconds. 1150 1107 ***************************************************************************/ 1151 1152 struct packet_struct *receive_dgram_packet(int fd, int t,1153 const char *mailslot_name)1154 {1155 struct packet_struct *p;1156 1157 p = receive_packet(fd, DGRAM_PACKET, t);1158 1159 if (p && match_mailslot_name(p, mailslot_name)) {1160 return p;1161 }1162 if (p)1163 free_packet(p);1164 1165 /* try the unexpected packet queue */1166 return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);1167 }1168 1108 1169 1109 /**************************************************************************** … … 1238 1178 putip(sort_ip, (char *)&ip); 1239 1179 1180 /* TODO: 1181 this can't use TYPESAFE_QSORT() as the types are wrong. 1182 It should be fixed to use a real type instead of char* 1183 */ 1240 1184 qsort(data, n, 6, QSORT_CAST name_query_comp); 1241 1185 } -
vendor/current/source3/libsmb/nterr.c
r414 r740 1 /* 1 /* 2 2 * Unix SMB/CIFS implementation. 3 3 * RPC Pipe client / server routines 4 4 * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. 5 * 5 * 6 6 * This program is free software; you can redistribute it and/or modify 7 7 * it under the terms of the GNU General Public License as published by 8 8 * the Free Software Foundation; either version 3 of the License, or 9 9 * (at your option) any later version. 10 * 10 * 11 11 * This program is distributed in the hope that it will be useful, 12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 * GNU General Public License for more details. 15 * 15 * 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. … … 21 21 22 22 #include "includes.h" 23 #include "smb_ldap.h" 24 #undef strcasecmp 25 26 #if !defined(N_) 27 #define N_(string) string 28 #endif 23 29 24 30 typedef struct … … 31 37 { 32 38 { "NT_STATUS_OK", NT_STATUS_OK }, 39 { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, 40 { "STATUS_NO_MORE_EAS", STATUS_NO_MORE_EAS }, 41 { "STATUS_INVALID_EA_NAME", STATUS_INVALID_EA_NAME }, 42 { "STATUS_EA_LIST_INCONSISTENT", STATUS_EA_LIST_INCONSISTENT }, 43 { "STATUS_INVALID_EA_FLAG", STATUS_INVALID_EA_FLAG }, 33 44 { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, 34 45 { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, … … 535 546 { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS }, 536 547 { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, 548 { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, 549 { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, 550 { "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX }, 551 { "NT_STATUS_RPC_UNKNOWN_IF", NT_STATUS_RPC_UNKNOWN_IF }, 552 { "NT_STATUS_RPC_CALL_FAILED", NT_STATUS_RPC_CALL_FAILED }, 553 { "NT_STATUS_RPC_PROTOCOL_ERROR", NT_STATUS_RPC_PROTOCOL_ERROR }, 554 { "NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE", NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE }, 555 { "NT_STATUS_RPC_CANNOT_SUPPORT", NT_STATUS_RPC_CANNOT_SUPPORT }, 556 { "NT_STATUS_RPC_SEC_PKG_ERROR", NT_STATUS_RPC_SEC_PKG_ERROR }, 557 { "NT_STATUS_RPC_SS_CONTEXT_MISMATCH", NT_STATUS_RPC_SS_CONTEXT_MISMATCH }, 558 { "NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE", NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE }, 559 { "NT_STATUS_RPC_BAD_STUB_DATA", NT_STATUS_RPC_BAD_STUB_DATA }, 560 { "NT_STATUS_RPC_INVALID_PIPE_OBJECT", NT_STATUS_RPC_INVALID_PIPE_OBJECT }, 561 { "NT_STATUS_RPC_INVALID_PIPE_OPERATION", NT_STATUS_RPC_INVALID_PIPE_OPERATION }, 562 { "NT_STATUS_RPC_WRONG_PIPE_VERSION", NT_STATUS_RPC_WRONG_PIPE_VERSION }, 563 { "NT_STATUS_RPC_PIPE_CLOSED", NT_STATUS_RPC_PIPE_CLOSED }, 564 { "NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR", NT_STATUS_RPC_PIPE_DISCIPLINE_ERROR }, 565 { "NT_STATUS_RPC_PIPE_EMPTY", NT_STATUS_RPC_PIPE_EMPTY }, 566 { "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED }, 567 { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, 537 568 { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, 538 { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, 569 { "NT_STATUS_NO_S4U_PROT_SUPPORT", NT_STATUS_NO_S4U_PROT_SUPPORT }, 570 { "NT_STATUS_CROSSREALM_DELEGATION_FAILURE", NT_STATUS_CROSSREALM_DELEGATION_FAILURE }, 571 { "NT_STATUS_INVALID_LOCK_RANGE", NT_STATUS_INVALID_LOCK_RANGE }, 572 { "NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS", NT_STATUS_ERROR_DS_OBJ_STRING_NAME_EXISTS }, 573 { "NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION", NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION }, 539 574 { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, 540 575 { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, 541 { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, 542 { "NT_STATUS_RPC_CANNOT_SUPPORT", NT_STATUS_RPC_CANNOT_SUPPORT }, 543 { "NT_STATUS_RPC_NT_CALL_FAILED", NT_STATUS_RPC_NT_CALL_FAILED }, 544 { "NT_STATUS_RPC_NT_PROTOCOL_ERROR", NT_STATUS_RPC_NT_PROTOCOL_ERROR }, 545 { "NT_STATUS_RPC_NT_PROCNUM_OUT_OF_RANGE", NT_STATUS_RPC_NT_PROCNUM_OUT_OF_RANGE }, 546 { "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED }, 576 { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP }, 577 { "STATUS_NOTIFY_ENUM_DIR", STATUS_NOTIFY_ENUM_DIR }, 578 547 579 { NULL, NT_STATUS(0) } 548 580 }; … … 550 582 /* These need sorting..... */ 551 583 552 nt_err_code_struct nt_err_desc[] =584 static const nt_err_code_struct nt_err_desc[] = 553 585 { 554 { "Success", NT_STATUS_OK }, 555 { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, 556 { "Access denied", NT_STATUS_ACCESS_DENIED }, 557 { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, 558 { "Must change password", NT_STATUS_PASSWORD_MUST_CHANGE }, 559 { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, 560 { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, 561 { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, 562 { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, 563 { "Improperly formed account name", NT_STATUS_INVALID_ACCOUNT_NAME }, 564 { "User exists", NT_STATUS_USER_EXISTS }, 565 { "No such user", NT_STATUS_NO_SUCH_USER }, 566 { "Group exists", NT_STATUS_GROUP_EXISTS }, 567 { "No such group", NT_STATUS_NO_SUCH_GROUP }, 568 { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, 569 { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, 570 { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, 571 { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, 572 { "Logon failure", NT_STATUS_LOGON_FAILURE }, 573 { "Account restriction", NT_STATUS_ACCOUNT_RESTRICTION }, 574 { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, 575 { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, 576 { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, 577 { "Account disabled", NT_STATUS_ACCOUNT_DISABLED }, 578 { "Memory allocation error", NT_STATUS_NO_MEMORY }, 579 { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, 580 { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, 581 { "Not implemented", NT_STATUS_NOT_IMPLEMENTED }, 582 { "Invalid information class", NT_STATUS_INVALID_INFO_CLASS }, 583 { "Information length mismatch", NT_STATUS_INFO_LENGTH_MISMATCH }, 584 { "Access violation", NT_STATUS_ACCESS_VIOLATION }, 585 { "Invalid handle", NT_STATUS_INVALID_HANDLE }, 586 { "Invalid parameter", NT_STATUS_INVALID_PARAMETER }, 587 { "No memory", NT_STATUS_NO_MEMORY }, 588 { "Buffer too small", NT_STATUS_BUFFER_TOO_SMALL }, 589 { "Revision mismatch", NT_STATUS_REVISION_MISMATCH }, 590 { "No such logon session", NT_STATUS_NO_SUCH_LOGON_SESSION }, 591 { "No such privilege", NT_STATUS_NO_SUCH_PRIVILEGE }, 592 { "Procedure not found", NT_STATUS_PROCEDURE_NOT_FOUND }, 593 { "Server disabled", NT_STATUS_SERVER_DISABLED }, 594 { "Invalid pipe state", NT_STATUS_INVALID_PIPE_STATE }, 595 { "Named pipe busy", NT_STATUS_PIPE_BUSY }, 596 { "Illegal function", NT_STATUS_ILLEGAL_FUNCTION }, 597 { "Named pipe dicconnected", NT_STATUS_PIPE_DISCONNECTED }, 598 { "Named pipe closing", NT_STATUS_PIPE_CLOSING }, 599 { "Remote host not listening", NT_STATUS_REMOTE_NOT_LISTENING }, 600 { "Duplicate name on network", NT_STATUS_DUPLICATE_NAME }, 601 { "Print queue is full", NT_STATUS_PRINT_QUEUE_FULL }, 602 { "No print spool space available", NT_STATUS_NO_SPOOL_SPACE }, 603 { "The network name cannot be found", NT_STATUS_BAD_NETWORK_NAME }, 604 { "The connection was refused", NT_STATUS_CONNECTION_REFUSED }, 605 { "Too many names", NT_STATUS_TOO_MANY_NAMES }, 606 { "Too many sessions", NT_STATUS_TOO_MANY_SESSIONS }, 607 { "Invalid server state", NT_STATUS_INVALID_SERVER_STATE }, 608 { "Invalid domain state", NT_STATUS_INVALID_DOMAIN_STATE }, 609 { "Invalid domain role", NT_STATUS_INVALID_DOMAIN_ROLE }, 610 { "No such domain", NT_STATUS_NO_SUCH_DOMAIN }, 611 { "Domain exists", NT_STATUS_DOMAIN_EXISTS }, 612 { "Domain limit exceeded", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, 613 { "Bad logon session state", NT_STATUS_BAD_LOGON_SESSION_STATE }, 614 { "Logon session collision", NT_STATUS_LOGON_SESSION_COLLISION }, 615 { "Invalid logon type", NT_STATUS_INVALID_LOGON_TYPE }, 616 { "Cancelled", NT_STATUS_CANCELLED }, 617 { "Invalid computer name", NT_STATUS_INVALID_COMPUTER_NAME }, 618 { "Logon server conflict", NT_STATUS_LOGON_SERVER_CONFLICT }, 619 { "Time difference at domain controller", NT_STATUS_TIME_DIFFERENCE_AT_DC }, 620 { "Pipe broken", NT_STATUS_PIPE_BROKEN }, 621 { "Registry corrupt", NT_STATUS_REGISTRY_CORRUPT }, 622 { "Too many secrets", NT_STATUS_TOO_MANY_SECRETS }, 623 { "Too many SIDs", NT_STATUS_TOO_MANY_SIDS }, 624 { "Lanmanager cross encryption required", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, 625 { "Log file full", NT_STATUS_LOG_FILE_FULL }, 626 { "No trusted LSA secret", NT_STATUS_NO_TRUST_LSA_SECRET }, 627 { "No trusted SAM account", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, 628 { "Trusted domain failure", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, 629 { "Trust relationship failure", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, 630 { "Trust failure", NT_STATUS_TRUST_FAILURE }, 631 { "Netlogon service not started", NT_STATUS_NETLOGON_NOT_STARTED }, 632 { "Account expired", NT_STATUS_ACCOUNT_EXPIRED }, 633 { "Network credential conflict", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, 634 { "Remote session limit", NT_STATUS_REMOTE_SESSION_LIMIT }, 635 { "No logon interdomain trust account", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, 636 { "No logon workstation trust account", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, 637 { "No logon server trust account", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, 638 { "Domain trust inconsistent", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, 639 { "No user session key available", NT_STATUS_NO_USER_SESSION_KEY }, 640 { "User session deleted", NT_STATUS_USER_SESSION_DELETED }, 641 { "Insufficient server resources", NT_STATUS_INSUFF_SERVER_RESOURCES }, 642 { "Insufficient logon information", NT_STATUS_INSUFFICIENT_LOGON_INFO }, 643 644 { "License quota exceeded", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, 645 { "No more files", STATUS_NO_MORE_FILES }, 586 { N_("Success"), NT_STATUS_OK }, 587 { N_("Undetermined error"), NT_STATUS_UNSUCCESSFUL }, 588 { N_("Access denied"), NT_STATUS_ACCESS_DENIED }, 589 { N_("Account locked out"), NT_STATUS_ACCOUNT_LOCKED_OUT }, 590 { N_("Must change password"), NT_STATUS_PASSWORD_MUST_CHANGE }, 591 { N_("Password is too short"), NT_STATUS_PWD_TOO_SHORT }, 592 { N_("Password is too recent"), NT_STATUS_PWD_TOO_RECENT }, 593 { N_("Password history conflict"), NT_STATUS_PWD_HISTORY_CONFLICT }, 594 { N_("No logon servers"), NT_STATUS_NO_LOGON_SERVERS }, 595 { N_("Improperly formed account name"), NT_STATUS_INVALID_ACCOUNT_NAME }, 596 { N_("User exists"), NT_STATUS_USER_EXISTS }, 597 { N_("No such user"), NT_STATUS_NO_SUCH_USER }, 598 { N_("Group exists"), NT_STATUS_GROUP_EXISTS }, 599 { N_("No such group"), NT_STATUS_NO_SUCH_GROUP }, 600 { N_("Member not in group"), NT_STATUS_MEMBER_NOT_IN_GROUP }, 601 { N_("Wrong Password"), NT_STATUS_WRONG_PASSWORD }, 602 { N_("Ill formed password"), NT_STATUS_ILL_FORMED_PASSWORD }, 603 { N_("Password restriction"), NT_STATUS_PASSWORD_RESTRICTION }, 604 { N_("Logon failure"), NT_STATUS_LOGON_FAILURE }, 605 { N_("Account restriction"), NT_STATUS_ACCOUNT_RESTRICTION }, 606 { N_("Invalid logon hours"), NT_STATUS_INVALID_LOGON_HOURS }, 607 { N_("Invalid workstation"), NT_STATUS_INVALID_WORKSTATION }, 608 { N_("Password expired"), NT_STATUS_PASSWORD_EXPIRED }, 609 { N_("Account disabled"), NT_STATUS_ACCOUNT_DISABLED }, 610 { N_("Unexpected information received"), NT_STATUS_INVALID_PARAMETER }, 611 { N_("Memory allocation error"), NT_STATUS_NO_MEMORY }, 612 { N_("No domain controllers located"), NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, 613 { N_("Account locked out"), NT_STATUS_ACCOUNT_LOCKED_OUT }, 614 { N_("Named pipe not available"), NT_STATUS_PIPE_NOT_AVAILABLE }, 615 { N_("Not implemented"), NT_STATUS_NOT_IMPLEMENTED }, 616 { N_("Invalid information class"), NT_STATUS_INVALID_INFO_CLASS }, 617 { N_("Information length mismatch"), NT_STATUS_INFO_LENGTH_MISMATCH }, 618 { N_("Access violation"), NT_STATUS_ACCESS_VIOLATION }, 619 { N_("Invalid handle"), NT_STATUS_INVALID_HANDLE }, 620 { N_("Invalid parameter"), NT_STATUS_INVALID_PARAMETER }, 621 { N_("No memory"), NT_STATUS_NO_MEMORY }, 622 { N_("Buffer too small"), NT_STATUS_BUFFER_TOO_SMALL }, 623 { N_("Revision mismatch"), NT_STATUS_REVISION_MISMATCH }, 624 { N_("No logon servers"), NT_STATUS_NO_LOGON_SERVERS }, 625 { N_("No such logon session"), NT_STATUS_NO_SUCH_LOGON_SESSION }, 626 { N_("No such privilege"), NT_STATUS_NO_SUCH_PRIVILEGE }, 627 { N_("Procedure not found"), NT_STATUS_PROCEDURE_NOT_FOUND }, 628 { N_("Server disabled"), NT_STATUS_SERVER_DISABLED }, 629 { N_("Invalid pipe state"), NT_STATUS_INVALID_PIPE_STATE }, 630 { N_("Named pipe busy"), NT_STATUS_PIPE_BUSY }, 631 { N_("Illegal function"), NT_STATUS_ILLEGAL_FUNCTION }, 632 { N_("Named pipe disconnected"), NT_STATUS_PIPE_DISCONNECTED }, 633 { N_("Named pipe closing"), NT_STATUS_PIPE_CLOSING }, 634 { N_("Remote host not listening"), NT_STATUS_REMOTE_NOT_LISTENING }, 635 { N_("Duplicate name on network"), NT_STATUS_DUPLICATE_NAME }, 636 { N_("Print queue is full"), NT_STATUS_PRINT_QUEUE_FULL }, 637 { N_("No print spool space available"), NT_STATUS_NO_SPOOL_SPACE }, 638 { N_("The network name cannot be found"), NT_STATUS_BAD_NETWORK_NAME }, 639 { N_("The connection was refused"), NT_STATUS_CONNECTION_REFUSED }, 640 { N_("Too many names"), NT_STATUS_TOO_MANY_NAMES }, 641 { N_("Too many sessions"), NT_STATUS_TOO_MANY_SESSIONS }, 642 { N_("Invalid server state"), NT_STATUS_INVALID_SERVER_STATE }, 643 { N_("Invalid domain state"), NT_STATUS_INVALID_DOMAIN_STATE }, 644 { N_("Invalid domain role"), NT_STATUS_INVALID_DOMAIN_ROLE }, 645 { N_("No such domain"), NT_STATUS_NO_SUCH_DOMAIN }, 646 { N_("Domain exists"), NT_STATUS_DOMAIN_EXISTS }, 647 { N_("Domain limit exceeded"), NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, 648 { N_("Bad logon session state"), NT_STATUS_BAD_LOGON_SESSION_STATE }, 649 { N_("Logon session collision"), NT_STATUS_LOGON_SESSION_COLLISION }, 650 { N_("Invalid logon type"), NT_STATUS_INVALID_LOGON_TYPE }, 651 { N_("Cancelled"), NT_STATUS_CANCELLED }, 652 { N_("Invalid computer name"), NT_STATUS_INVALID_COMPUTER_NAME }, 653 { N_("Logon server conflict"), NT_STATUS_LOGON_SERVER_CONFLICT }, 654 { N_("Time difference at domain controller"), NT_STATUS_TIME_DIFFERENCE_AT_DC }, 655 { N_("Pipe broken"), NT_STATUS_PIPE_BROKEN }, 656 { N_("Registry corrupt"), NT_STATUS_REGISTRY_CORRUPT }, 657 { N_("Too many secrets"), NT_STATUS_TOO_MANY_SECRETS }, 658 { N_("Too many SIDs"), NT_STATUS_TOO_MANY_SIDS }, 659 { N_("Lanmanager cross encryption required"), NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, 660 { N_("Log file full"), NT_STATUS_LOG_FILE_FULL }, 661 { N_("No trusted LSA secret"), NT_STATUS_NO_TRUST_LSA_SECRET }, 662 { N_("No trusted SAM account"), NT_STATUS_NO_TRUST_SAM_ACCOUNT }, 663 { N_("Trusted domain failure"), NT_STATUS_TRUSTED_DOMAIN_FAILURE }, 664 { N_("Trust relationship failure"), NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, 665 { N_("Trust failure"), NT_STATUS_TRUST_FAILURE }, 666 { N_("Netlogon service not started"), NT_STATUS_NETLOGON_NOT_STARTED }, 667 { N_("Account expired"), NT_STATUS_ACCOUNT_EXPIRED }, 668 { N_("Network credential conflict"), NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, 669 { N_("Remote session limit"), NT_STATUS_REMOTE_SESSION_LIMIT }, 670 { N_("No logon interdomain trust account"), NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, 671 { N_("No logon workstation trust account"), NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, 672 { N_("No logon server trust account"), NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, 673 { N_("Domain trust inconsistent"), NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, 674 { N_("No user session key available"), NT_STATUS_NO_USER_SESSION_KEY }, 675 { N_("User session deleted"), NT_STATUS_USER_SESSION_DELETED }, 676 { N_("Insufficient server resources"), NT_STATUS_INSUFF_SERVER_RESOURCES }, 677 { N_("Insufficient logon information"), NT_STATUS_INSUFFICIENT_LOGON_INFO }, 678 679 { N_("License quota exceeded"), NT_STATUS_LICENSE_QUOTA_EXCEEDED }, 680 { N_("No more files"), STATUS_NO_MORE_FILES }, 646 681 647 682 { NULL, NT_STATUS(0) } … … 654 689 const char *nt_errstr(NTSTATUS nt_code) 655 690 { 656 691 int idx = 0; 657 692 char *result; 658 693 659 694 #ifdef HAVE_LDAP 660 661 695 if (NT_STATUS_IS_LDAP(nt_code)) { 696 return ldap_err2string(NT_STATUS_LDAP_CODE(nt_code)); 662 697 } 663 698 #endif … … 669 704 670 705 while (nt_errs[idx].nt_errstr != NULL) { 671 if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { 672 return nt_errs[idx].nt_errstr; 706 if (NT_STATUS_V(nt_errs[idx].nt_errcode) == 707 NT_STATUS_V(nt_code)) { 708 return nt_errs[idx].nt_errstr; 673 709 } 674 710 idx++; … … 684 720 Print friendler version fo NT error code 685 721 ***********************************************************************/ 686 722 687 723 const char *get_friendly_nt_error_msg(NTSTATUS nt_code) 688 724 { 689 725 int idx = 0; 690 726 691 727 while (nt_err_desc[idx].nt_errstr != NULL) { 692 728 if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { 693 729 return nt_err_desc[idx].nt_errstr; 694 730 } 695 731 idx++; 696 732 } 697 733 698 734 /* fall back to NT_STATUS_XXX string */ 699 735 700 736 return nt_errstr(nt_code); 701 737 } … … 708 744 { 709 745 char *result; 710 746 int idx = 0; 711 747 712 748 while (nt_errs[idx].nt_errstr != NULL) { 713 if (NT_STATUS_V(nt_errs[idx].nt_errcode) == 714 715 749 if (NT_STATUS_V(nt_errs[idx].nt_errcode) == 750 NT_STATUS_V(nt_code)) { 751 return nt_errs[idx].nt_errstr; 716 752 } 717 753 idx++; … … 730 766 NTSTATUS nt_status_string_to_code(const char *nt_status_str) 731 767 { 732 768 int idx = 0; 733 769 734 770 while (nt_errs[idx].nt_errstr != NULL) { 735 if (strc mp(nt_errs[idx].nt_errstr, nt_status_str) == 0) {736 771 if (strcasecmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { 772 return nt_errs[idx].nt_errcode; 737 773 } 738 774 idx++; … … 744 780 * Squash an NT_STATUS in line with security requirements. 745 781 * In an attempt to avoid giving the whole game away when users 746 * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 747 * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 782 * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 783 * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 748 784 * (session setups in particular). 749 785 * … … 755 791 { 756 792 if NT_STATUS_IS_OK(nt_status) { 757 return nt_status; 793 return nt_status; 758 794 } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { 759 795 /* Match WinXP and don't give the game away */ 760 796 return NT_STATUS_LOGON_FAILURE; 761 797 762 798 } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { 763 799 /* Match WinXP and don't give the game away */ … … 765 801 } else { 766 802 return nt_status; 767 } 803 } 768 804 } -
vendor/current/source3/libsmb/ntlmssp.c
r414 r740 5 5 6 6 Copyright (C) Andrew Tridgell 2001 7 Copyright (C) Andrew Bartlett 2001-20 038 Copyright (C) Andrew Bartlett 2005 (Updated from gensec).7 Copyright (C) Andrew Bartlett 2001-2010 8 Copyright (C) Stefan Metzmacher 2005 9 9 10 10 This program is free software; you can redistribute it and/or modify … … 23 23 24 24 #include "includes.h" 25 #include "../libcli/auth/ntlmssp.h" 26 #include "../libcli/auth/ntlmssp_private.h" 25 27 #include "../libcli/auth/libcli_auth.h" 26 28 #include "../librpc/gen_ndr/ndr_ntlmssp.h" 27 #include "libsmb/ntlmssp_ndr.h" 29 #include "../libcli/auth/ntlmssp_ndr.h" 30 #include "../lib/crypto/md5.h" 31 #include "../lib/crypto/arcfour.h" 32 #include "../lib/crypto/hmacmd5.h" 33 #include "../nsswitch/libwbclient/wbclient.h" 28 34 29 35 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 36 TALLOC_CTX *out_mem_ctx, /* Unused at this time */ 30 37 DATA_BLOB reply, DATA_BLOB *next_request); 31 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,32 const DATA_BLOB in, DATA_BLOB *out);33 38 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 39 TALLOC_CTX *out_mem_ctx, /* Unused at this time */ 34 40 const DATA_BLOB reply, DATA_BLOB *next_request); 35 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,36 const DATA_BLOB request, DATA_BLOB *reply);37 38 41 /** 39 42 * Callbacks for NTLMSSP - for both client and server operating modes … … 42 45 43 46 static const struct ntlmssp_callbacks { 44 enum NTLMSSP_ROLErole;45 enum NTLM_MESSAGE_TYPEntlmssp_command;47 enum ntlmssp_role role; 48 enum ntlmssp_message_type ntlmssp_command; 46 49 NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 50 TALLOC_CTX *out_mem_ctx, 47 51 DATA_BLOB in, DATA_BLOB *out); 48 52 } ntlmssp_callbacks[] = { … … 57 61 58 62 /** 59 * Print out the NTLMSSP flags for debugging60 * @param neg_flags The flags from the packet61 */62 63 void debug_ntlmssp_flags(uint32 neg_flags)64 {65 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));66 67 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)68 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));69 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)70 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));71 if (neg_flags & NTLMSSP_REQUEST_TARGET)72 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));73 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)74 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));75 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)76 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));77 if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM)78 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM\n"));79 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)80 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));81 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)82 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));83 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)84 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));85 if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED)86 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n"));87 if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)88 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"));89 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)90 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));91 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)92 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));93 if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY)94 DEBUGADD(4, (" NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"));95 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)96 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));97 if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)98 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_TARGET_INFO\n"));99 if (neg_flags & NTLMSSP_NEGOTIATE_VERSION)100 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_VERSION\n"));101 if (neg_flags & NTLMSSP_NEGOTIATE_128)102 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));103 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)104 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));105 if (neg_flags & NTLMSSP_NEGOTIATE_56)106 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n"));107 }108 109 /**110 63 * Default challenge generation code. 111 64 * 112 65 */ 113 66 114 static voidget_challenge(const struct ntlmssp_state *ntlmssp_state,115 uint8_t chal[8])67 static NTSTATUS get_challenge(const struct ntlmssp_state *ntlmssp_state, 68 uint8_t chal[8]) 116 69 { 117 70 generate_random_buffer(chal, 8); 71 return NT_STATUS_OK; 118 72 } 119 73 … … 146 100 */ 147 101 148 NTSTATUS ntlmssp_set_username( NTLMSSP_STATE*ntlmssp_state, const char *user)102 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) 149 103 { 150 104 ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" ); … … 159 113 * 160 114 */ 161 NTSTATUS ntlmssp_set_hashes( NTLMSSP_STATE*ntlmssp_state,162 const unsigned charlm_hash[16],163 const unsigned charnt_hash[16])164 { 165 ntlmssp_state->lm_hash = (u nsigned char*)115 NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state, 116 const uint8_t lm_hash[16], 117 const uint8_t nt_hash[16]) 118 { 119 ntlmssp_state->lm_hash = (uint8_t *) 166 120 TALLOC_MEMDUP(ntlmssp_state, lm_hash, 16); 167 ntlmssp_state->nt_hash = (u nsigned char*)121 ntlmssp_state->nt_hash = (uint8_t *) 168 122 TALLOC_MEMDUP(ntlmssp_state, nt_hash, 16); 169 123 if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) { … … 179 133 * 180 134 */ 181 NTSTATUS ntlmssp_set_password( NTLMSSP_STATE*ntlmssp_state, const char *password)135 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) 182 136 { 183 137 if (!password) { … … 185 139 ntlmssp_state->nt_hash = NULL; 186 140 } else { 187 u nsigned charlm_hash[16];188 u nsigned charnt_hash[16];141 uint8_t lm_hash[16]; 142 uint8_t nt_hash[16]; 189 143 190 144 E_deshash(password, lm_hash); … … 199 153 * 200 154 */ 201 NTSTATUS ntlmssp_set_domain( NTLMSSP_STATE*ntlmssp_state, const char *domain)155 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) 202 156 { 203 157 ntlmssp_state->domain = talloc_strdup(ntlmssp_state, … … 210 164 211 165 /** 212 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed213 *214 */215 NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation)216 {217 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);218 if (!ntlmssp_state->workstation) {219 return NT_STATUS_NO_MEMORY;220 }221 return NT_STATUS_OK;222 }223 224 /**225 * Store a DATA_BLOB containing an NTLMSSP response, for use later.226 * This copies the data blob227 */228 229 NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,230 DATA_BLOB response)231 {232 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,233 response.data,234 response.length);235 return NT_STATUS_OK;236 }237 238 /**239 166 * Request features for the NTLMSSP negotiation 240 167 * … … 242 169 * @param feature_list List of space seperated features requested from NTLMSSP. 243 170 */ 244 void ntlmssp_want_feature_list( NTLMSSP_STATE*ntlmssp_state, char *feature_list)171 void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list) 245 172 { 246 173 /* … … 269 196 * @param feature Bit flag specifying the requested feature 270 197 */ 271 void ntlmssp_want_feature( NTLMSSP_STATE *ntlmssp_state, uint32feature)198 void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature) 272 199 { 273 200 /* As per JRA's comment above */ … … 295 222 */ 296 223 297 NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, 298 const DATA_BLOB in, DATA_BLOB *out) 299 { 300 DATA_BLOB input; 301 uint32 ntlmssp_command; 224 NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state, 225 const DATA_BLOB input, DATA_BLOB *out) 226 { 227 uint32_t ntlmssp_command; 302 228 int i; 303 229 … … 309 235 310 236 *out = data_blob_null; 311 312 if (!in.length && ntlmssp_state->stored_response.length) {313 input = ntlmssp_state->stored_response;314 315 /* we only want to read the stored response once - overwrite it */316 ntlmssp_state->stored_response = data_blob_null;317 } else {318 input = in;319 }320 237 321 238 if (!input.length) { … … 328 245 ntlmssp_command = NTLMSSP_NEGOTIATE; 329 246 break; 247 default: 248 DEBUG(1, ("Invalid role: %d\n", ntlmssp_state->role)); 249 return NT_STATUS_INVALID_PARAMETER; 330 250 } 331 251 } else { … … 347 267 if (ntlmssp_callbacks[i].role == ntlmssp_state->role 348 268 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { 349 return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);269 return ntlmssp_callbacks[i].fn(ntlmssp_state, ntlmssp_state, input, out); 350 270 } 351 271 } … … 358 278 359 279 /** 360 * End an NTLMSSP state machine361 *362 * @param ntlmssp_state NTLMSSP State, free()ed by this function363 */364 365 void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)366 {367 (*ntlmssp_state)->ref_count--;368 369 if ((*ntlmssp_state)->ref_count == 0) {370 data_blob_free(&(*ntlmssp_state)->chal);371 data_blob_free(&(*ntlmssp_state)->lm_resp);372 data_blob_free(&(*ntlmssp_state)->nt_resp);373 TALLOC_FREE(*ntlmssp_state);374 }375 376 *ntlmssp_state = NULL;377 return;378 }379 380 /**381 * Determine correct target name flags for reply, given server role382 * and negotiated flags383 *384 * @param ntlmssp_state NTLMSSP State385 * @param neg_flags The flags from the packet386 * @param chal_flags The flags to be set in the reply packet387 * @return The 'target name' string.388 */389 390 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,391 uint32 neg_flags, uint32 *chal_flags)392 {393 if (neg_flags & NTLMSSP_REQUEST_TARGET) {394 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;395 *chal_flags |= NTLMSSP_REQUEST_TARGET;396 if (ntlmssp_state->server_role == ROLE_STANDALONE) {397 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;398 return ntlmssp_state->get_global_myname();399 } else {400 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;401 return ntlmssp_state->get_domain();402 };403 } else {404 return "";405 }406 }407 408 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,409 uint32 neg_flags, bool allow_lm) {410 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {411 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;412 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;413 ntlmssp_state->unicode = True;414 } else {415 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;416 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;417 ntlmssp_state->unicode = False;418 }419 420 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {421 /* other end forcing us to use LM */422 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;423 ntlmssp_state->use_ntlmv2 = False;424 } else {425 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;426 }427 428 if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {429 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;430 }431 432 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {433 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;434 }435 436 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {437 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;438 }439 440 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {441 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;442 }443 444 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {445 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;446 }447 448 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {449 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;450 }451 452 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {453 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;454 }455 456 /* Woop Woop - unknown flag for Windows compatibility...457 What does this really do ? JRA. */458 if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {459 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;460 }461 462 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {463 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;464 }465 }466 467 /**468 Weaken NTLMSSP keys to cope with down-level clients and servers.469 470 We probably should have some parameters to control this, but as471 it only occours for LM_KEY connections, and this is controlled472 by the client lanman auth/lanman auth parameters, it isn't too bad.473 */474 475 DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx)476 {477 DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,478 ntlmssp_state->session_key.data,479 ntlmssp_state->session_key.length);480 481 /* Nothing to weaken. We certainly don't want to 'extend' the length... */482 if (weakened_key.length < 16) {483 /* perhaps there was no key? */484 return weakened_key;485 }486 487 /* Key weakening not performed on the master key for NTLM2488 and does not occour for NTLM1. Therefore we only need489 to do this for the LM_KEY.490 */491 492 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {493 /* LM key doesn't support 128 bit crypto, so this is494 * the best we can do. If you negotiate 128 bit, but495 * not 56, you end up with 40 bit... */496 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {497 weakened_key.data[7] = 0xa0;498 } else { /* forty bits */499 weakened_key.data[5] = 0xe5;500 weakened_key.data[6] = 0x38;501 weakened_key.data[7] = 0xb0;502 }503 weakened_key.length = 8;504 }505 return weakened_key;506 }507 508 /**509 * Next state function for the Negotiate packet510 *511 * @param ntlmssp_state NTLMSSP State512 * @param request The request, as a DATA_BLOB513 * @param request The reply, as an allocated DATA_BLOB, caller to free.514 * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent.515 */516 517 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,518 const DATA_BLOB request, DATA_BLOB *reply)519 {520 DATA_BLOB struct_blob;521 const char *dnsname;522 char *dnsdomname = NULL;523 uint32 neg_flags = 0;524 uint32 ntlmssp_command, chal_flags;525 uint8_t cryptkey[8];526 const char *target_name;527 struct NEGOTIATE_MESSAGE negotiate;528 struct CHALLENGE_MESSAGE challenge;529 530 /* parse the NTLMSSP packet */531 #if 0532 file_save("ntlmssp_negotiate.dat", request.data, request.length);533 #endif534 535 if (request.length) {536 if ((request.length < 16) || !msrpc_parse(ntlmssp_state, &request, "Cdd",537 "NTLMSSP",538 &ntlmssp_command,539 &neg_flags)) {540 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",541 (unsigned int)request.length));542 dump_data(2, request.data, request.length);543 return NT_STATUS_INVALID_PARAMETER;544 }545 debug_ntlmssp_flags(neg_flags);546 547 if (DEBUGLEVEL >= 10) {548 if (NT_STATUS_IS_OK(ntlmssp_pull_NEGOTIATE_MESSAGE(&request,549 ntlmssp_state,550 NULL,551 &negotiate)))552 {553 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, &negotiate);554 }555 }556 }557 558 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());559 560 /* Ask our caller what challenge they would like in the packet */561 ntlmssp_state->get_challenge(ntlmssp_state, cryptkey);562 563 /* Check if we may set the challenge */564 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {565 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;566 }567 568 /* The flags we send back are not just the negotiated flags,569 * they are also 'what is in this packet'. Therfore, we570 * operate on 'chal_flags' from here on571 */572 573 chal_flags = ntlmssp_state->neg_flags;574 575 /* get the right name to fill in as 'target' */576 target_name = ntlmssp_target_name(ntlmssp_state,577 neg_flags, &chal_flags);578 if (target_name == NULL)579 return NT_STATUS_INVALID_PARAMETER;580 581 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);582 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,583 cryptkey, 8);584 585 /* This should be a 'netbios domain -> DNS domain' mapping */586 dnsdomname = get_mydnsdomname(ntlmssp_state);587 if (!dnsdomname) {588 dnsdomname = talloc_strdup(ntlmssp_state, "");589 }590 if (!dnsdomname) {591 return NT_STATUS_NO_MEMORY;592 }593 strlower_m(dnsdomname);594 595 dnsname = get_mydnsfullname();596 if (!dnsname) {597 dnsname = "";598 }599 600 /* This creates the 'blob' of names that appears at the end of the packet */601 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)602 {603 msrpc_gen(ntlmssp_state, &struct_blob, "aaaaa",604 MsvAvNbDomainName, target_name,605 MsvAvNbComputerName, ntlmssp_state->get_global_myname(),606 MsvAvDnsDomainName, dnsdomname,607 MsvAvDnsComputerName, dnsname,608 MsvAvEOL, "");609 } else {610 struct_blob = data_blob_null;611 }612 613 {614 /* Marshel the packet in the right format, be it unicode or ASCII */615 const char *gen_string;616 if (ntlmssp_state->unicode) {617 gen_string = "CdUdbddB";618 } else {619 gen_string = "CdAdbddB";620 }621 622 msrpc_gen(ntlmssp_state, reply, gen_string,623 "NTLMSSP",624 NTLMSSP_CHALLENGE,625 target_name,626 chal_flags,627 cryptkey, 8,628 0, 0,629 struct_blob.data, struct_blob.length);630 631 if (DEBUGLEVEL >= 10) {632 if (NT_STATUS_IS_OK(ntlmssp_pull_CHALLENGE_MESSAGE(reply,633 ntlmssp_state,634 NULL,635 &challenge)))636 {637 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, &challenge);638 }639 }640 }641 642 data_blob_free(&struct_blob);643 644 ntlmssp_state->expected_state = NTLMSSP_AUTH;645 646 return NT_STATUS_MORE_PROCESSING_REQUIRED;647 }648 649 /**650 * Next state function for the Authenticate packet651 *652 * @param ntlmssp_state NTLMSSP State653 * @param request The request, as a DATA_BLOB654 * @param request The reply, as an allocated DATA_BLOB, caller to free.655 * @return Errors or NT_STATUS_OK.656 */657 658 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,659 const DATA_BLOB request, DATA_BLOB *reply)660 {661 DATA_BLOB encrypted_session_key = data_blob_null;662 DATA_BLOB user_session_key = data_blob_null;663 DATA_BLOB lm_session_key = data_blob_null;664 DATA_BLOB session_key = data_blob_null;665 uint32 ntlmssp_command, auth_flags;666 NTSTATUS nt_status = NT_STATUS_OK;667 struct AUTHENTICATE_MESSAGE authenticate;668 669 /* used by NTLM2 */670 bool doing_ntlm2 = False;671 672 uchar session_nonce[16];673 uchar session_nonce_hash[16];674 675 const char *parse_string;676 677 /* parse the NTLMSSP packet */678 *reply = data_blob_null;679 680 #if 0681 file_save("ntlmssp_auth.dat", request.data, request.length);682 #endif683 684 if (ntlmssp_state->unicode) {685 parse_string = "CdBBUUUBd";686 } else {687 parse_string = "CdBBAAABd";688 }689 690 data_blob_free(&ntlmssp_state->lm_resp);691 data_blob_free(&ntlmssp_state->nt_resp);692 693 ntlmssp_state->user = NULL;694 ntlmssp_state->domain = NULL;695 ntlmssp_state->workstation = NULL;696 697 /* now the NTLMSSP encoded auth hashes */698 if (!msrpc_parse(ntlmssp_state, &request, parse_string,699 "NTLMSSP",700 &ntlmssp_command,701 &ntlmssp_state->lm_resp,702 &ntlmssp_state->nt_resp,703 &ntlmssp_state->domain,704 &ntlmssp_state->user,705 &ntlmssp_state->workstation,706 &encrypted_session_key,707 &auth_flags)) {708 auth_flags = 0;709 710 /* Try again with a shorter string (Win9X truncates this packet) */711 if (ntlmssp_state->unicode) {712 parse_string = "CdBBUUU";713 } else {714 parse_string = "CdBBAAA";715 }716 717 /* now the NTLMSSP encoded auth hashes */718 if (!msrpc_parse(ntlmssp_state, &request, parse_string,719 "NTLMSSP",720 &ntlmssp_command,721 &ntlmssp_state->lm_resp,722 &ntlmssp_state->nt_resp,723 &ntlmssp_state->domain,724 &ntlmssp_state->user,725 &ntlmssp_state->workstation)) {726 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));727 dump_data(2, request.data, request.length);728 729 return NT_STATUS_INVALID_PARAMETER;730 }731 }732 733 if (auth_flags)734 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());735 736 if (DEBUGLEVEL >= 10) {737 if (NT_STATUS_IS_OK(ntlmssp_pull_AUTHENTICATE_MESSAGE(&request,738 ntlmssp_state,739 NULL,740 &authenticate)))741 {742 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, &authenticate);743 }744 }745 746 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",747 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));748 749 #if 0750 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);751 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);752 #endif753 754 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a755 client challenge756 757 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.758 */759 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {760 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {761 struct MD5Context md5_session_nonce_ctx;762 SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);763 764 doing_ntlm2 = True;765 766 memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);767 memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);768 769 MD5Init(&md5_session_nonce_ctx);770 MD5Update(&md5_session_nonce_ctx, session_nonce, 16);771 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);772 773 ntlmssp_state->chal = data_blob_talloc(774 ntlmssp_state, session_nonce_hash, 8);775 776 /* LM response is no longer useful */777 data_blob_free(&ntlmssp_state->lm_resp);778 779 /* We changed the effective challenge - set it */780 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {781 data_blob_free(&encrypted_session_key);782 return nt_status;783 }784 785 /* LM Key is incompatible. */786 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;787 }788 }789 790 /*791 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth792 * is required (by "ntlm auth = no" and "lm auth = no" being set in the793 * smb.conf file) and no NTLMv2 response was sent then the password check794 * will fail here. JRA.795 */796 797 /* Finally, actually ask if the password is OK */798 799 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,800 &user_session_key, &lm_session_key))) {801 data_blob_free(&encrypted_session_key);802 return nt_status;803 }804 805 dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);806 dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);807 808 /* Handle the different session key derivation for NTLM2 */809 if (doing_ntlm2) {810 if (user_session_key.data && user_session_key.length == 16) {811 session_key = data_blob_talloc(ntlmssp_state,812 NULL, 16);813 hmac_md5(user_session_key.data, session_nonce,814 sizeof(session_nonce), session_key.data);815 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));816 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);817 818 } else {819 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));820 session_key = data_blob_null;821 }822 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {823 if (lm_session_key.data && lm_session_key.length >= 8) {824 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {825 session_key = data_blob_talloc(ntlmssp_state,826 NULL, 16);827 if (session_key.data == NULL) {828 return NT_STATUS_NO_MEMORY;829 }830 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,831 session_key.data);832 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));833 } else {834 uint8 zeros[24];835 ZERO_STRUCT(zeros);836 session_key = data_blob_talloc(837 ntlmssp_state, NULL, 16);838 if (session_key.data == NULL) {839 return NT_STATUS_NO_MEMORY;840 }841 SMBsesskeygen_lm_sess_key(842 lm_session_key.data, zeros,843 session_key.data);844 }845 dump_data_pw("LM session key:\n", session_key.data,846 session_key.length);847 } else {848 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));849 session_key = data_blob_null;850 }851 } else if (user_session_key.data) {852 session_key = user_session_key;853 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));854 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);855 } else if (lm_session_key.data) {856 session_key = lm_session_key;857 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));858 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);859 } else {860 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));861 session_key = data_blob_null;862 }863 864 /* With KEY_EXCH, the client supplies the proposed session key,865 but encrypts it with the long-term key */866 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {867 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {868 data_blob_free(&encrypted_session_key);869 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",870 (unsigned int)encrypted_session_key.length));871 return NT_STATUS_INVALID_PARAMETER;872 } else if (!session_key.data || session_key.length != 16) {873 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",874 (unsigned int)session_key.length));875 ntlmssp_state->session_key = session_key;876 } else {877 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);878 arcfour_crypt_blob(encrypted_session_key.data,879 encrypted_session_key.length,880 &session_key);881 ntlmssp_state->session_key = data_blob_talloc(882 ntlmssp_state, encrypted_session_key.data,883 encrypted_session_key.length);884 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data,885 encrypted_session_key.length);886 }887 } else {888 ntlmssp_state->session_key = session_key;889 }890 891 if (!NT_STATUS_IS_OK(nt_status)) {892 ntlmssp_state->session_key = data_blob_null;893 } else if (ntlmssp_state->session_key.length) {894 nt_status = ntlmssp_sign_init(ntlmssp_state);895 }896 897 data_blob_free(&encrypted_session_key);898 899 /* Only one authentication allowed per server state. */900 ntlmssp_state->expected_state = NTLMSSP_DONE;901 902 return nt_status;903 }904 905 /**906 280 * Create an NTLMSSP state machine 907 281 * … … 909 283 */ 910 284 911 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) 912 { 913 *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE); 914 if (!*ntlmssp_state) { 915 DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); 916 talloc_destroy(*ntlmssp_state); 917 return NT_STATUS_NO_MEMORY; 918 } 919 920 (*ntlmssp_state)->role = NTLMSSP_SERVER; 921 922 (*ntlmssp_state)->get_challenge = get_challenge; 923 (*ntlmssp_state)->set_challenge = set_challenge; 924 (*ntlmssp_state)->may_set_challenge = may_set_challenge; 925 926 (*ntlmssp_state)->get_global_myname = global_myname; 927 (*ntlmssp_state)->get_domain = lp_workgroup; 928 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ 929 930 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; 931 932 (*ntlmssp_state)->ref_count = 1; 933 934 (*ntlmssp_state)->neg_flags = 285 NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, 286 bool is_standalone, 287 const char *netbios_name, 288 const char *netbios_domain, 289 const char *dns_name, 290 const char *dns_domain, 291 struct ntlmssp_state **_ntlmssp_state) 292 { 293 struct ntlmssp_state *ntlmssp_state; 294 295 if (!netbios_name) { 296 netbios_name = ""; 297 } 298 299 if (!netbios_domain) { 300 netbios_domain = ""; 301 } 302 303 if (!dns_domain) { 304 dns_domain = ""; 305 } 306 307 if (!dns_name) { 308 dns_name = ""; 309 } 310 311 ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state); 312 if (!ntlmssp_state) { 313 return NT_STATUS_NO_MEMORY; 314 } 315 316 ntlmssp_state->role = NTLMSSP_SERVER; 317 318 ntlmssp_state->get_challenge = get_challenge; 319 ntlmssp_state->set_challenge = set_challenge; 320 ntlmssp_state->may_set_challenge = may_set_challenge; 321 322 ntlmssp_state->server.is_standalone = is_standalone; 323 324 ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; 325 326 ntlmssp_state->allow_lm_key = lp_lanman_auth(); 327 328 ntlmssp_state->neg_flags = 935 329 NTLMSSP_NEGOTIATE_128 | 936 330 NTLMSSP_NEGOTIATE_56 | … … 943 337 NTLMSSP_NEGOTIATE_SEAL; 944 338 339 ntlmssp_state->server.netbios_name = talloc_strdup(ntlmssp_state, netbios_name); 340 if (!ntlmssp_state->server.netbios_name) { 341 talloc_free(ntlmssp_state); 342 return NT_STATUS_NO_MEMORY; 343 } 344 ntlmssp_state->server.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain); 345 if (!ntlmssp_state->server.netbios_domain) { 346 talloc_free(ntlmssp_state); 347 return NT_STATUS_NO_MEMORY; 348 } 349 ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, dns_name); 350 if (!ntlmssp_state->server.dns_name) { 351 talloc_free(ntlmssp_state); 352 return NT_STATUS_NO_MEMORY; 353 } 354 ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain); 355 if (!ntlmssp_state->server.dns_domain) { 356 talloc_free(ntlmssp_state); 357 return NT_STATUS_NO_MEMORY; 358 } 359 360 *_ntlmssp_state = ntlmssp_state; 945 361 return NT_STATUS_OK; 946 362 } … … 960 376 961 377 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 378 TALLOC_CTX *out_mem_ctx, /* Unused at this time */ 962 379 DATA_BLOB reply, DATA_BLOB *next_request) 963 380 { 964 struct NEGOTIATE_MESSAGE negotiate;381 NTSTATUS status; 965 382 966 383 if (ntlmssp_state->unicode) { … … 975 392 976 393 /* generate the ntlmssp negotiate packet */ 977 msrpc_gen(ntlmssp_state, next_request, "CddAA",394 status = msrpc_gen(ntlmssp_state, next_request, "CddAA", 978 395 "NTLMSSP", 979 396 NTLMSSP_NEGOTIATE, 980 397 ntlmssp_state->neg_flags, 981 ntlmssp_state->get_domain(), 982 ntlmssp_state->get_global_myname()); 398 ntlmssp_state->client.netbios_domain, 399 ntlmssp_state->client.netbios_name); 400 if (!NT_STATUS_IS_OK(status)) { 401 DEBUG(0, ("ntlmssp_client_initial: failed to generate " 402 "ntlmssp negotiate packet\n")); 403 return status; 404 } 983 405 984 406 if (DEBUGLEVEL >= 10) { 985 if (NT_STATUS_IS_OK(ntlmssp_pull_NEGOTIATE_MESSAGE(next_request, 986 ntlmssp_state, 987 NULL, 988 &negotiate))) 989 { 990 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, &negotiate); 407 struct NEGOTIATE_MESSAGE *negotiate = talloc( 408 talloc_tos(), struct NEGOTIATE_MESSAGE); 409 if (negotiate != NULL) { 410 status = ntlmssp_pull_NEGOTIATE_MESSAGE( 411 next_request, negotiate, negotiate); 412 if (NT_STATUS_IS_OK(status)) { 413 NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE, 414 negotiate); 415 } 416 TALLOC_FREE(negotiate); 991 417 } 992 418 } … … 1007 433 1008 434 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 435 TALLOC_CTX *out_mem_ctx, /* Unused at this time */ 1009 436 const DATA_BLOB reply, DATA_BLOB *next_request) 1010 437 { 1011 uint32 chal_flags, ntlmssp_command, unkn1, unkn2;438 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; 1012 439 DATA_BLOB server_domain_blob; 1013 440 DATA_BLOB challenge_blob; … … 1021 448 DATA_BLOB encrypted_session_key = data_blob_null; 1022 449 NTSTATUS nt_status = NT_STATUS_OK; 1023 struct CHALLENGE_MESSAGE challenge;1024 struct AUTHENTICATE_MESSAGE authenticate;1025 450 1026 451 if (ntlmssp_state->use_ccache) { … … 1046 471 1047 472 wbc_status = wbcCredentialCache(¶ms, &info, &error); 1048 if (error != NULL) { 1049 wbcFreeMemory(error); 1050 } 473 wbcFreeMemory(error); 1051 474 if (!WBC_ERROR_IS_OK(wbc_status)) { 1052 475 goto noccache; … … 1088 511 1089 512 if (DEBUGLEVEL >= 10) { 1090 if (NT_STATUS_IS_OK(ntlmssp_pull_CHALLENGE_MESSAGE(&reply, 1091 ntlmssp_state, 1092 NULL, 1093 &challenge))) 1094 { 1095 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, &challenge); 513 struct CHALLENGE_MESSAGE *challenge = talloc( 514 talloc_tos(), struct CHALLENGE_MESSAGE); 515 if (challenge != NULL) { 516 NTSTATUS status; 517 challenge->NegotiateFlags = chal_flags; 518 status = ntlmssp_pull_CHALLENGE_MESSAGE( 519 &reply, challenge, challenge); 520 if (NT_STATUS_IS_OK(status)) { 521 NDR_PRINT_DEBUG(CHALLENGE_MESSAGE, 522 challenge); 523 } 524 TALLOC_FREE(challenge); 1096 525 } 1097 526 } … … 1137 566 } 1138 567 1139 ntlmssp_state->server_domain = server_domain; 568 if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) { 569 ntlmssp_state->server.is_standalone = true; 570 } else { 571 ntlmssp_state->server.is_standalone = false; 572 } 573 /* TODO: parse struct_blob and fill in the rest */ 574 ntlmssp_state->server.netbios_name = ""; 575 ntlmssp_state->server.netbios_domain = server_domain; 576 ntlmssp_state->server.dns_name = ""; 577 ntlmssp_state->server.dns_domain = ""; 1140 578 1141 579 if (challenge_blob.length != 8) { … … 1145 583 1146 584 if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) { 1147 uchar zeros[16];585 static const uint8_t zeros[16] = {0, }; 1148 586 /* do nothing - blobs are zero length */ 1149 1150 ZERO_STRUCT(zeros);1151 587 1152 588 /* session key is all zeros */ … … 1178 614 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 1179 615 struct MD5Context md5_session_nonce_ctx; 1180 u charsession_nonce[16];1181 u charsession_nonce_hash[16];1182 u charuser_session_key[16];616 uint8_t session_nonce[16]; 617 uint8_t session_nonce_hash[16]; 618 uint8_t user_session_key[16]; 1183 619 1184 620 lm_response = data_blob_talloc(ntlmssp_state, NULL, 24); … … 1238 674 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { 1239 675 /* Make up a new session key */ 1240 uint8 client_session_key[16];676 uint8_t client_session_key[16]; 1241 677 generate_random_buffer(client_session_key, sizeof(client_session_key)); 1242 678 … … 1255 691 1256 692 /* this generates the actual auth packet */ 1257 if (!msrpc_gen(ntlmssp_state, next_request, auth_gen_string,693 nt_status = msrpc_gen(ntlmssp_state, next_request, auth_gen_string, 1258 694 "NTLMSSP", 1259 695 NTLMSSP_AUTH, … … 1262 698 ntlmssp_state->domain, 1263 699 ntlmssp_state->user, 1264 ntlmssp_state-> get_global_myname(),700 ntlmssp_state->client.netbios_name, 1265 701 encrypted_session_key.data, encrypted_session_key.length, 1266 ntlmssp_state->neg_flags)) { 1267 702 ntlmssp_state->neg_flags); 703 704 if (!NT_STATUS_IS_OK(nt_status)) { 1268 705 return NT_STATUS_NO_MEMORY; 1269 706 } 1270 707 1271 708 if (DEBUGLEVEL >= 10) { 1272 if (NT_STATUS_IS_OK(ntlmssp_pull_AUTHENTICATE_MESSAGE(next_request, 1273 ntlmssp_state, 1274 NULL, 1275 &authenticate))) 1276 { 1277 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, &authenticate); 709 struct AUTHENTICATE_MESSAGE *authenticate = talloc( 710 talloc_tos(), struct AUTHENTICATE_MESSAGE); 711 if (authenticate != NULL) { 712 NTSTATUS status; 713 authenticate->NegotiateFlags = 714 ntlmssp_state->neg_flags; 715 status = ntlmssp_pull_AUTHENTICATE_MESSAGE( 716 next_request, authenticate, authenticate); 717 if (NT_STATUS_IS_OK(status)) { 718 NDR_PRINT_DEBUG(AUTHENTICATE_MESSAGE, 719 authenticate); 720 } 721 TALLOC_FREE(authenticate); 1278 722 } 1279 723 } … … 1300 744 } 1301 745 1302 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) 1303 { 1304 *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE); 1305 if (!*ntlmssp_state) { 1306 DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); 1307 talloc_destroy(*ntlmssp_state); 1308 return NT_STATUS_NO_MEMORY; 1309 } 1310 1311 (*ntlmssp_state)->role = NTLMSSP_CLIENT; 1312 1313 (*ntlmssp_state)->get_global_myname = global_myname; 1314 (*ntlmssp_state)->get_domain = lp_workgroup; 1315 1316 (*ntlmssp_state)->unicode = True; 1317 1318 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); 1319 1320 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL; 1321 1322 (*ntlmssp_state)->ref_count = 1; 1323 1324 (*ntlmssp_state)->neg_flags = 746 NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, 747 const char *netbios_name, 748 const char *netbios_domain, 749 bool use_ntlmv2, 750 struct ntlmssp_state **_ntlmssp_state) 751 { 752 struct ntlmssp_state *ntlmssp_state; 753 754 if (!netbios_name) { 755 netbios_name = ""; 756 } 757 758 if (!netbios_domain) { 759 netbios_domain = ""; 760 } 761 762 ntlmssp_state = talloc_zero(mem_ctx, struct ntlmssp_state); 763 if (!ntlmssp_state) { 764 return NT_STATUS_NO_MEMORY; 765 } 766 767 ntlmssp_state->role = NTLMSSP_CLIENT; 768 769 ntlmssp_state->unicode = True; 770 771 ntlmssp_state->use_ntlmv2 = use_ntlmv2; 772 773 ntlmssp_state->expected_state = NTLMSSP_INITIAL; 774 775 ntlmssp_state->neg_flags = 1325 776 NTLMSSP_NEGOTIATE_128 | 1326 777 NTLMSSP_NEGOTIATE_ALWAYS_SIGN | … … 1330 781 NTLMSSP_REQUEST_TARGET; 1331 782 783 ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name); 784 if (!ntlmssp_state->client.netbios_name) { 785 talloc_free(ntlmssp_state); 786 return NT_STATUS_NO_MEMORY; 787 } 788 ntlmssp_state->client.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain); 789 if (!ntlmssp_state->client.netbios_domain) { 790 talloc_free(ntlmssp_state); 791 return NT_STATUS_NO_MEMORY; 792 } 793 794 *_ntlmssp_state = ntlmssp_state; 1332 795 return NT_STATUS_OK; 1333 796 } -
vendor/current/source3/libsmb/passchange.c
r414 r740 19 19 20 20 #include "includes.h" 21 #include "../librpc/gen_ndr/ndr_samr.h" 22 #include "rpc_client/cli_pipe.h" 23 #include "rpc_client/cli_samr.h" 24 #include "libsmb/libsmb.h" 25 #include "libsmb/clirap.h" 26 #include "libsmb/nmblib.h" 21 27 22 28 /************************************************************* … … 301 307 if (asprintf(err_str, "SAMR connection to machine %s " 302 308 "failed. Error was %s, but LANMAN password " 303 "change dare disabled\n",309 "changes are disabled\n", 304 310 nt_errstr(result), remote_machine) == -1) { 305 311 *err_str = NULL; -
vendor/current/source3/libsmb/samlogon_cache.c
r414 r740 23 23 24 24 #include "includes.h" 25 #include "system/filesys.h" 25 26 #include "librpc/gen_ndr/ndr_krb5pac.h" 27 #include "../libcli/security/security.h" 28 #include "util_tdb.h" 26 29 27 30 #define NETSAMLOGON_TDB "netsamlogon_cache.tdb" … … 46 49 path = cache_path(NETSAMLOGON_TDB); 47 50 again: 48 tdb = tdb_open_log(path, 0, TDB_DEFAULT ,51 tdb = tdb_open_log(path, 0, TDB_DEFAULT|TDB_INCOMPATIBLE_HASH, 49 52 O_RDWR | O_CREAT, 0600); 50 53 if (tdb == NULL) { … … 70 73 71 74 DEBUG(0,("retry after CLEAR_IF_FIRST for '%s'\n", path)); 72 tdb = tdb_open_log(path, 0, TDB_CLEAR_IF_FIRST ,75 tdb = tdb_open_log(path, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, 73 76 O_RDWR | O_CREAT, 0600); 74 77 if (tdb) { … … 99 102 ***********************************************************************/ 100 103 101 void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3) 102 { 103 DOM_SID user_sid; 104 fstring keystr, tmp; 105 106 if (!info3) { 107 return; 108 } 104 void netsamlogon_clear_cached_user(const struct dom_sid *user_sid) 105 { 106 fstring keystr; 109 107 110 108 if (!netsamlogon_cache_init()) { … … 114 112 return; 115 113 } 116 sid_copy(&user_sid, info3->base.domain_sid);117 sid_append_rid(&user_sid, info3->base.rid);118 114 119 115 /* Prepare key as DOMAIN-SID/USER-RID string */ 120 s lprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid));116 sid_to_fstring(keystr, user_sid); 121 117 122 118 DEBUG(10,("netsamlogon_clear_cached_user: SID [%s]\n", keystr)); … … 133 129 { 134 130 TDB_DATA data; 135 fstring keystr , tmp;131 fstring keystr; 136 132 bool result = false; 137 DOM_SIDuser_sid;133 struct dom_sid user_sid; 138 134 time_t t = time(NULL); 139 135 TALLOC_CTX *mem_ctx; … … 152 148 } 153 149 154 sid_copy(&user_sid, info3->base.domain_sid); 155 sid_append_rid(&user_sid, info3->base.rid); 150 sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid); 156 151 157 152 /* Prepare key as DOMAIN-SID/USER-RID string */ 158 s lprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid));153 sid_to_fstring(keystr, &user_sid); 159 154 160 155 DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); … … 181 176 } 182 177 183 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL,&r,178 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r, 184 179 (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry); 185 180 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 206 201 ***********************************************************************/ 207 202 208 struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID*user_sid)203 struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct dom_sid *user_sid) 209 204 { 210 205 struct netr_SamInfo3 *info3 = NULL; … … 237 232 blob = data_blob_const(data.dptr, data.dsize); 238 233 239 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL,&r,234 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, 240 235 (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry); 241 236 … … 279 274 } 280 275 281 bool netsamlogon_cache_have(const DOM_SID*user_sid)276 bool netsamlogon_cache_have(const struct dom_sid *user_sid) 282 277 { 283 278 TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); -
vendor/current/source3/libsmb/smb_seal.c
r414 r740 19 19 20 20 #include "includes.h" 21 #include "../libcli/auth/ntlmssp.h" 22 #include "smb_crypt.h" 23 #include "libsmb/libsmb.h" 21 24 22 25 /****************************************************************************** … … 60 63 ******************************************************************************/ 61 64 62 NTSTATUS common_ntlm_decrypt_buffer( NTLMSSP_STATE*ntlmssp_state, char *buf)65 NTSTATUS common_ntlm_decrypt_buffer(struct ntlmssp_state *ntlmssp_state, char *buf) 63 66 { 64 67 NTSTATUS status; … … 108 111 ******************************************************************************/ 109 112 110 NTSTATUS common_ntlm_encrypt_buffer( NTLMSSP_STATE*ntlmssp_state,113 NTSTATUS common_ntlm_encrypt_buffer(struct ntlmssp_state *ntlmssp_state, 111 114 uint16 enc_ctx_num, 112 115 char *buf, … … 117 120 size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ 118 121 DATA_BLOB sig; 119 122 TALLOC_CTX *frame; 120 123 *ppbuf_out = NULL; 121 124 … … 124 127 } 125 128 129 frame = talloc_stackframe(); 126 130 /* 127 131 * We know smb_len can't return a value > 128k, so no int overflow … … 140 144 141 145 status = ntlmssp_seal_packet(ntlmssp_state, 146 frame, 142 147 (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */ 143 148 data_len, … … 147 152 148 153 if (!NT_STATUS_IS_OK(status)) { 149 data_blob_free(&sig);154 talloc_free(frame); 150 155 SAFE_FREE(buf_out); 151 156 return status; … … 154 159 /* First 16 data bytes are signature for SSPI compatibility. */ 155 160 memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); 156 data_blob_free(&sig);161 talloc_free(frame); 157 162 *ppbuf_out = buf_out; 158 163 return NT_STATUS_OK; … … 369 374 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { 370 375 if (es->s.ntlmssp_state) { 371 ntlmssp_end(&es->s.ntlmssp_state);376 TALLOC_FREE(es->s.ntlmssp_state); 372 377 } 373 378 } -
vendor/current/source3/libsmb/smb_share_modes.c
r414 r740 26 26 27 27 #include "includes.h" 28 #include "system/filesys.h" 28 29 #include "smb_share_modes.h" 30 #include <tdb.h> 29 31 30 32 /* Database context handle. */ … … 68 70 69 71 smb_db->smb_tdb = tdb_open(db_path, 70 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST ,72 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, 71 73 O_RDWR|O_CREAT, 72 74 0644); … … 156 158 157 159 static void create_share_mode_entry(struct share_mode_entry *out, 158 const struct smb_share_mode_entry *in) 160 const struct smb_share_mode_entry *in, 161 uint32_t name_hash) 159 162 { 160 163 memset(out, '\0', sizeof(struct share_mode_entry)); … … 171 174 out->uid = (uint32)geteuid(); 172 175 out->flags = 0; 176 out->name_hash = name_hash; 173 177 } 174 178 … … 256 260 } 257 261 258 *p_delete_on_close = ld->u.s. delete_on_close;262 *p_delete_on_close = ld->u.s.num_delete_token_entries != 0; 259 263 *pp_list = list; 260 264 free(db_data.dptr); 261 265 return list_num; 266 } 267 268 static uint32_t smb_name_hash(const char *sharepath, const char *filename, int *err) 269 { 270 TDB_DATA key; 271 char *fullpath = NULL; 272 size_t sharepath_size = strlen(sharepath); 273 size_t filename_size = strlen(filename); 274 uint32_t name_hash; 275 276 *err = 0; 277 fullpath = (char *)malloc(sharepath_size + filename_size + 2); 278 if (fullpath == NULL) { 279 *err = 1; 280 return 0; 281 } 282 memcpy(fullpath, sharepath, sharepath_size); 283 fullpath[sharepath_size] = '/'; 284 memcpy(&fullpath[sharepath_size + 1], filename, filename_size + 1); 285 286 key.dptr = (uint8_t *)fullpath; 287 key.dsize = strlen(fullpath) + 1; 288 name_hash = tdb_jenkins_hash(&key); 289 free(fullpath); 290 return name_hash; 262 291 } 263 292 … … 282 311 uint8 *new_data_p = NULL; 283 312 size_t new_data_size = 0; 313 int err = 0; 314 uint32_t name_hash = smb_name_hash(sharepath, filename, &err); 315 316 if (err) { 317 return -1; 318 } 284 319 285 320 db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); … … 297 332 memset(ld, '\0', sizeof(struct locking_data)); 298 333 ld->u.s.num_share_mode_entries = 1; 299 ld->u.s.delete_on_close = 0; 300 ld->u.s.delete_token_size = 0; 334 ld->u.s.num_delete_token_entries = 0; 301 335 shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); 302 create_share_mode_entry(shares, new_entry );336 create_share_mode_entry(shares, new_entry, name_hash); 303 337 304 338 memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(struct share_mode_entry), … … 339 373 (orig_num_share_modes * sizeof(struct share_mode_entry))); 340 374 341 create_share_mode_entry(shares, new_entry );375 create_share_mode_entry(shares, new_entry, name_hash); 342 376 343 377 ld = (struct locking_data *)new_data_p; 344 378 ld->u.s.num_share_mode_entries++; 345 379 346 /* Append the original delete_token and filenames. */380 /* Append the original delete_tokens and filenames. */ 347 381 memcpy(new_data_p + sizeof(struct locking_data) + (ld->u.s.num_share_mode_entries * sizeof(struct share_mode_entry)), 348 382 db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(struct share_mode_entry)), … … 461 495 } 462 496 463 /* Copy any delete token plus the terminating filenames. */497 /* Copy any delete tokens plus the terminating filenames. */ 464 498 remaining_ptr = db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(struct share_mode_entry)); 465 499 remaining_size = db_data.dsize - (remaining_ptr - db_data.dptr); … … 522 556 523 557 if (share_mode_entry_equal(set_entry, share)) { 524 create_share_mode_entry(share, new_entry );558 create_share_mode_entry(share, new_entry, share->name_hash); 525 559 found_entry = 1; 526 560 break; -
vendor/current/source3/libsmb/smb_signing.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "../lib/crypto/md5.h" 24 #include "smb_signing.h" 23 25 24 26 /* Used by the SMB signing functions. */ … … 44 46 /* the next expected seqnum */ 45 47 uint32_t seqnum; 48 49 TALLOC_CTX *mem_ctx; 50 void *(*alloc_fn)(TALLOC_CTX *mem_ctx, size_t len); 51 void (*free_fn)(TALLOC_CTX *mem_ctx, void *ptr); 46 52 }; 47 53 … … 50 56 si->active = false; 51 57 si->bsrspyl = false; 52 data_blob_free(&si->mac_key);53 58 si->seqnum = 0; 59 60 if (si->free_fn) { 61 si->free_fn(si->mem_ctx, si->mac_key.data); 62 } else { 63 talloc_free(si->mac_key.data); 64 } 65 si->mac_key.data = NULL; 66 si->mac_key.length = 0; 67 } 68 69 struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx, 70 bool allowed, 71 bool mandatory, 72 void *(*alloc_fn)(TALLOC_CTX *, size_t), 73 void (*free_fn)(TALLOC_CTX *, void *)) 74 { 75 struct smb_signing_state *si; 76 77 if (alloc_fn) { 78 void *p = alloc_fn(mem_ctx, sizeof(struct smb_signing_state)); 79 if (p == NULL) { 80 return NULL; 81 } 82 memset(p, 0, sizeof(struct smb_signing_state)); 83 si = (struct smb_signing_state *)p; 84 si->mem_ctx = mem_ctx; 85 si->alloc_fn = alloc_fn; 86 si->free_fn = free_fn; 87 } else { 88 si = talloc_zero(mem_ctx, struct smb_signing_state); 89 if (si == NULL) { 90 return NULL; 91 } 92 } 93 94 if (mandatory) { 95 allowed = true; 96 } 97 98 si->allowed = allowed; 99 si->mandatory = mandatory; 100 101 return si; 54 102 } 55 103 … … 58 106 bool mandatory) 59 107 { 60 struct smb_signing_state *si; 61 62 si = talloc_zero(mem_ctx, struct smb_signing_state); 63 if (si == NULL) { 64 return NULL; 65 } 66 67 if (mandatory) { 68 allowed = true; 69 } 70 71 si->allowed = allowed; 72 si->mandatory = mandatory; 73 74 return si; 108 return smb_signing_init_ex(mem_ctx, allowed, mandatory, NULL, NULL); 75 109 } 76 110 … … 313 347 314 348 len = response.length + user_session_key.length; 315 si->mac_key = data_blob_talloc(si, NULL, len); 349 if (si->alloc_fn) { 350 si->mac_key.data = (uint8_t *)si->alloc_fn(si->mem_ctx, len); 351 if (si->mac_key.data == NULL) { 352 return false; 353 } 354 } else { 355 si->mac_key.data = (uint8_t *)talloc_size(si, len); 356 if (si->mac_key.data == NULL) { 357 return false; 358 } 359 } 360 si->mac_key.length = len; 316 361 317 362 ofs = 0; -
vendor/current/source3/libsmb/smberr.c
r414 r740 2 2 Unix SMB/CIFS implementation. 3 3 Copyright (C) Andrew Tridgell 1998 4 4 5 5 This program is free software; you can redistribute it and/or modify 6 6 it under the terms of the GNU General Public License as published by 7 7 the Free Software Foundation; either version 3 of the License, or 8 8 (at your option) any later version. 9 9 10 10 This program is distributed in the hope that it will be useful, 11 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 13 GNU General Public License for more details. 14 14 15 15 You should have received a copy of the GNU General Public License 16 16 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 163 163 char *result; 164 164 int i,j; 165 165 166 166 for (i=0;err_classes[i].e_class;i++) 167 167 if (err_classes[i].code == e_class) { … … 177 177 return result; 178 178 } 179 179 180 180 result = talloc_asprintf(talloc_tos(), "Error: Unknown error class " 181 181 "(%d,%d)", e_class,num); -
vendor/current/source3/libsmb/smbsock_connect.c
r600 r740 19 19 20 20 #include "includes.h" 21 #include "../lib/async_req/async_sock.h" 21 #include "../lib/util/tevent_ntstatus.h" 22 #include "client.h" 22 23 #include "async_smb.h" 24 #include "libsmb/nmblib.h" 23 25 24 26 struct nb_connect_state { … … 177 179 const struct sockaddr_storage *addr; 178 180 const char *called_name; 181 uint8_t called_type; 179 182 const char *calling_name; 183 uint8_t calling_type; 180 184 struct tevent_req *req_139; 181 185 struct tevent_req *req_445; … … 192 196 struct tevent_context *ev, 193 197 const struct sockaddr_storage *addr, 198 uint16_t port, 194 199 const char *called_name, 195 const char *calling_name) 200 int called_type, 201 const char *calling_name, 202 int calling_type) 196 203 { 197 204 struct tevent_req *req, *subreq; … … 207 214 state->called_name = 208 215 (called_name != NULL) ? called_name : "*SMBSERVER"; 216 state->called_type = 217 (called_type != -1) ? called_type : 0x20; 209 218 state->calling_name = 210 219 (calling_name != NULL) ? calling_name : global_myname(); 220 state->calling_type = 221 (calling_type != -1) ? calling_type : 0x00; 211 222 212 223 talloc_set_destructor(state, smbsock_connect_state_destructor); 224 225 if (port == 139) { 226 subreq = tevent_wakeup_send(state, ev, timeval_set(0, 0)); 227 if (tevent_req_nomem(subreq, req)) { 228 return tevent_req_post(req, ev); 229 } 230 tevent_req_set_callback(subreq, smbsock_connect_do_139, req); 231 return req; 232 } 233 if (port != 0) { 234 state->req_445 = open_socket_out_send(state, ev, addr, port, 235 5000); 236 if (tevent_req_nomem(state->req_445, req)) { 237 return tevent_req_post(req, ev); 238 } 239 tevent_req_set_callback( 240 state->req_445, smbsock_connect_connected, req); 241 return req; 242 } 243 244 /* 245 * port==0, try both 246 */ 213 247 214 248 state->req_445 = open_socket_out_send(state, ev, addr, 445, 5000); … … 238 272 if (state->sock != -1) { 239 273 close(state->sock); 274 state->sock = -1; 240 275 } 241 276 return 0; … … 257 292 } 258 293 state->req_139 = nb_connect_send(state, state->ev, state->addr, 259 state->called_name, 0x20, 260 state->calling_name, 0x0); 294 state->called_name, 295 state->called_type, 296 state->calling_name, 297 state->calling_type); 261 298 if (tevent_req_nomem(state->req_139, req)) { 262 299 return; … … 314 351 315 352 NTSTATUS smbsock_connect_recv(struct tevent_req *req, int *sock, 316 uint16_t *port)353 uint16_t *ret_port) 317 354 { 318 355 struct smbsock_connect_state *state = tevent_req_data( … … 325 362 *sock = state->sock; 326 363 state->sock = -1; 327 if ( port != NULL) {328 * port = state->port;364 if (ret_port != NULL) { 365 *ret_port = state->port; 329 366 } 330 367 return NT_STATUS_OK; 331 368 } 332 369 333 NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, 334 const char *called_name, const char *calling_name, 335 int *pfd, uint16_t *port) 370 NTSTATUS smbsock_connect(const struct sockaddr_storage *addr, uint16_t port, 371 const char *called_name, int called_type, 372 const char *calling_name, int calling_type, 373 int *pfd, uint16_t *ret_port, int sec_timeout) 336 374 { 337 375 TALLOC_CTX *frame = talloc_stackframe(); … … 344 382 goto fail; 345 383 } 346 req = smbsock_connect_send(frame, ev, addr, called_name, calling_name); 384 req = smbsock_connect_send(frame, ev, addr, port, 385 called_name, called_type, 386 calling_name, calling_type); 347 387 if (req == NULL) { 348 388 goto fail; 349 389 } 390 if ((sec_timeout != 0) && 391 !tevent_req_set_endtime( 392 req, ev, timeval_current_ofs(sec_timeout, 0))) { 393 goto fail; 394 } 350 395 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 351 396 goto fail; 352 397 } 353 status = smbsock_connect_recv(req, pfd, port);398 status = smbsock_connect_recv(req, pfd, ret_port); 354 399 fail: 355 400 TALLOC_FREE(frame); … … 361 406 const struct sockaddr_storage *addrs; 362 407 const char **called_names; 408 int *called_types; 409 const char **calling_names; 410 int *calling_types; 363 411 size_t num_addrs; 412 uint16_t port; 364 413 365 414 struct tevent_req **requests; … … 368 417 369 418 int fd; 370 uint16_t port;419 uint16_t chosen_port; 371 420 size_t chosen_index; 372 421 }; … … 381 430 const struct sockaddr_storage *addrs, 382 431 const char **called_names, 383 size_t num_addrs) 432 int *called_types, 433 const char **calling_names, 434 int *calling_types, 435 size_t num_addrs, uint16_t port) 384 436 { 385 437 struct tevent_req *req, *subreq; … … 395 447 state->num_addrs = num_addrs; 396 448 state->called_names = called_names; 449 state->called_types = called_types; 450 state->calling_names = calling_names; 451 state->calling_types = calling_types; 452 state->port = port; 397 453 398 454 if (num_addrs == 0) { … … 459 515 subreq = smbsock_connect_send( 460 516 state->requests, state->ev, &state->addrs[state->num_sent], 517 state->port, 461 518 (state->called_names != NULL) 462 519 ? state->called_names[state->num_sent] : NULL, 463 NULL); 520 (state->called_types != NULL) 521 ? state->called_types[state->num_sent] : -1, 522 (state->calling_names != NULL) 523 ? state->calling_names[state->num_sent] : NULL, 524 (state->calling_types != NULL) 525 ? state->calling_types[state->num_sent] : -1); 464 526 if (tevent_req_nomem(subreq, req)) { 465 527 return false; … … 481 543 NTSTATUS status; 482 544 int fd; 483 uint16_t port;545 uint16_t chosen_port; 484 546 size_t i; 485 547 size_t chosen_index = 0; … … 496 558 } 497 559 498 status = smbsock_connect_recv(subreq, &fd, & port);560 status = smbsock_connect_recv(subreq, &fd, &chosen_port); 499 561 500 562 TALLOC_FREE(subreq); … … 507 569 TALLOC_FREE(state->requests); 508 570 state->fd = fd; 509 state-> port =port;571 state->chosen_port = chosen_port; 510 572 state->chosen_index = chosen_index; 511 573 tevent_req_done(req); … … 529 591 530 592 NTSTATUS smbsock_any_connect_recv(struct tevent_req *req, int *pfd, 531 size_t *chosen_index, uint16_t *port) 593 size_t *chosen_index, 594 uint16_t *chosen_port) 532 595 { 533 596 struct smbsock_any_connect_state *state = tevent_req_data( … … 542 605 *chosen_index = state->chosen_index; 543 606 } 544 if ( port != NULL) {545 * port = state->port;607 if (chosen_port != NULL) { 608 *chosen_port = state->chosen_port; 546 609 } 547 610 return NT_STATUS_OK; … … 549 612 550 613 NTSTATUS smbsock_any_connect(const struct sockaddr_storage *addrs, 551 const char **called_names, size_t num_addrs, 552 int *pfd, size_t *chosen_index, uint16_t *port) 614 const char **called_names, 615 int *called_types, 616 const char **calling_names, 617 int *calling_types, 618 size_t num_addrs, 619 uint16_t port, 620 int sec_timeout, 621 int *pfd, size_t *chosen_index, 622 uint16_t *chosen_port) 553 623 { 554 624 TALLOC_CTX *frame = talloc_stackframe(); … … 561 631 goto fail; 562 632 } 563 req = smbsock_any_connect_send(frame, ev, addrs, called_names, 564 num_addrs); 633 req = smbsock_any_connect_send(frame, ev, addrs, 634 called_names, called_types, 635 calling_names, calling_types, 636 num_addrs, port); 565 637 if (req == NULL) { 566 638 goto fail; 567 639 } 640 if ((sec_timeout != 0) && 641 !tevent_req_set_endtime( 642 req, ev, timeval_current_ofs(sec_timeout, 0))) { 643 goto fail; 644 } 568 645 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 569 646 goto fail; 570 647 } 571 status = smbsock_any_connect_recv(req, pfd, chosen_index, port);648 status = smbsock_any_connect_recv(req, pfd, chosen_index, chosen_port); 572 649 fail: 573 650 TALLOC_FREE(frame); -
vendor/current/source3/libsmb/trustdom_cache.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "../libcli/security/security.h" 23 24 24 25 #undef DBGC_CLASS … … 96 97 **/ 97 98 98 bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID*sid,99 bool trustdom_cache_store(char* name, char* alt_name, const struct dom_sid *sid, 99 100 time_t timeout) 100 101 { … … 142 143 **/ 143 144 144 bool trustdom_cache_fetch(const char* name, DOM_SID* sid)145 bool trustdom_cache_fetch(const char* name, struct dom_sid* sid) 145 146 { 146 147 char *key = NULL, *value = NULL; … … 165 166 } 166 167 167 /* convert sid string representation into DOM_SIDstructure */168 /* convert sid string representation into struct dom_sid structure */ 168 169 if(! string_to_sid(sid, value)) { 169 170 sid = NULL; … … 253 254 { 254 255 char **domain_names; 255 DOM_SID*dom_sids;256 struct dom_sid *dom_sids; 256 257 uint32 num_domains; 257 258 uint32 last_check; -
vendor/current/source3/libsmb/trusts_util.c
r414 r740 21 21 #include "includes.h" 22 22 #include "../libcli/auth/libcli_auth.h" 23 #include "../librpc/gen_ndr/cli_lsa.h" 23 #include "../librpc/gen_ndr/ndr_lsa_c.h" 24 #include "rpc_client/cli_lsarpc.h" 25 #include "rpc_client/cli_netlogon.h" 26 #include "rpc_client/cli_pipe.h" 27 #include "../librpc/gen_ndr/ndr_netlogon.h" 28 #include "secrets.h" 29 #include "passdb.h" 30 #include "libsmb/libsmb.h" 24 31 25 32 /********************************************************* … … 136 143 bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, 137 144 char ***domain_names, uint32 *num_domains, 138 DOM_SID**sids )145 struct dom_sid **sids ) 139 146 { 140 147 struct policy_handle pol; 141 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;148 NTSTATUS status, result; 142 149 fstring dc_name; 143 150 struct sockaddr_storage dc_ss; … … 145 152 struct cli_state *cli = NULL; 146 153 struct rpc_pipe_client *lsa_pipe = NULL; 147 bool retry;148 154 struct lsa_DomainList dom_list; 149 155 int i; 156 struct dcerpc_binding_handle *b = NULL; 150 157 151 158 *domain_names = NULL; … … 163 170 /* setup the anonymous connection */ 164 171 165 result= cli_full_connection( &cli, global_myname(), dc_name, &dc_ss, 0, "IPC$", "IPC",166 "", "", "", 0, Undefined , &retry);167 if ( !NT_STATUS_IS_OK( result) )172 status = cli_full_connection( &cli, global_myname(), dc_name, &dc_ss, 0, "IPC$", "IPC", 173 "", "", "", 0, Undefined); 174 if ( !NT_STATUS_IS_OK(status) ) 168 175 goto done; 169 176 170 177 /* open the LSARPC_PIPE */ 171 178 172 result= cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,179 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id, 173 180 &lsa_pipe); 174 if (!NT_STATUS_IS_OK(result)) { 175 goto done; 176 } 181 if (!NT_STATUS_IS_OK(status)) { 182 goto done; 183 } 184 185 b = lsa_pipe->binding_handle; 177 186 178 187 /* get a handle */ 179 188 180 result= rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,189 status = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, 181 190 LSA_POLICY_VIEW_LOCAL_INFORMATION, &pol); 182 if ( !NT_STATUS_IS_OK( result) )191 if ( !NT_STATUS_IS_OK(status) ) 183 192 goto done; 184 193 185 194 /* Lookup list of trusted domains */ 186 195 187 result = rpccli_lsa_EnumTrustDom(lsa_pipe, mem_ctx,196 status = dcerpc_lsa_EnumTrustDom(b, mem_ctx, 188 197 &pol, 189 198 &enum_ctx, 190 199 &dom_list, 191 (uint32_t)-1); 192 if ( !NT_STATUS_IS_OK(result) ) 193 goto done; 200 (uint32_t)-1, 201 &result); 202 if ( !NT_STATUS_IS_OK(status) ) 203 goto done; 204 if (!NT_STATUS_IS_OK(result)) { 205 status = result; 206 goto done; 207 } 194 208 195 209 *num_domains = dom_list.count; … … 197 211 *domain_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_domains); 198 212 if (!*domain_names) { 199 result= NT_STATUS_NO_MEMORY;200 goto done; 201 } 202 203 *sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_domains);213 status = NT_STATUS_NO_MEMORY; 214 goto done; 215 } 216 217 *sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_domains); 204 218 if (!*sids) { 205 result= NT_STATUS_NO_MEMORY;219 status = NT_STATUS_NO_MEMORY; 206 220 goto done; 207 221 } … … 219 233 } 220 234 221 return NT_STATUS_IS_OK( result);235 return NT_STATUS_IS_OK(status); 222 236 } 237 238 NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine) 239 { 240 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 241 struct sockaddr_storage pdc_ss; 242 fstring dc_name; 243 struct cli_state *cli = NULL; 244 struct rpc_pipe_client *netlogon_pipe = NULL; 245 246 DEBUG(5,("change_trust_account_password: Attempting to change trust account password in domain %s....\n", 247 domain)); 248 249 if (remote_machine == NULL || !strcmp(remote_machine, "*")) { 250 /* Use the PDC *only* for this */ 251 252 if ( !get_pdc_ip(domain, &pdc_ss) ) { 253 DEBUG(0,("Can't get IP for PDC for domain %s\n", domain)); 254 goto failed; 255 } 256 257 if ( !name_status_find( domain, 0x1b, 0x20, &pdc_ss, dc_name) ) 258 goto failed; 259 } else { 260 /* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */ 261 fstrcpy( dc_name, remote_machine ); 262 } 263 264 /* if this next call fails, then give up. We can't do 265 password changes on BDC's --jerry */ 266 267 if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name, 268 NULL, 0, 269 "IPC$", "IPC", 270 "", "", 271 "", 0, Undefined))) { 272 DEBUG(0,("modify_trust_password: Connection to %s failed!\n", dc_name)); 273 nt_status = NT_STATUS_UNSUCCESSFUL; 274 goto failed; 275 } 276 277 /* 278 * Ok - we have an anonymous connection to the IPC$ share. 279 * Now start the NT Domain stuff :-). 280 */ 281 282 /* Shouldn't we open this with schannel ? JRA. */ 283 284 nt_status = cli_rpc_pipe_open_noauth( 285 cli, &ndr_table_netlogon.syntax_id, &netlogon_pipe); 286 if (!NT_STATUS_IS_OK(nt_status)) { 287 DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n", 288 dc_name, nt_errstr(nt_status))); 289 cli_shutdown(cli); 290 cli = NULL; 291 goto failed; 292 } 293 294 nt_status = trust_pw_find_change_and_store_it( 295 netlogon_pipe, netlogon_pipe, domain); 296 297 cli_shutdown(cli); 298 cli = NULL; 299 300 failed: 301 if (!NT_STATUS_IS_OK(nt_status)) { 302 DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n", 303 current_timestring(talloc_tos(), False), domain)); 304 } 305 else 306 DEBUG(5,("change_trust_account_password: sucess!\n")); 307 308 return nt_status; 309 } -
vendor/current/source3/libsmb/unexpected.c
r414 r740 20 20 21 21 #include "includes.h" 22 23 static TDB_CONTEXT *tdbd = NULL; 24 25 /* the key type used in the unexpected packet database */ 26 struct unexpected_key { 27 enum packet_type packet_type; 28 time_t timestamp; 29 int count; 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "lib/async_req/async_sock.h" 24 #include "libsmb/nmblib.h" 25 26 static const char *nmbd_socket_dir(void) 27 { 28 return lp_parm_const_string(-1, "nmbd", "socket dir", 29 get_dyn_NMBDSOCKETDIR()); 30 } 31 32 struct nb_packet_query { 33 enum packet_type type; 34 size_t mailslot_namelen; 35 int trn_id; 30 36 }; 31 37 32 /**************************************************************************** 33 All unexpected packets are passed in here, to be stored in a unexpected 34 packet database. This allows nmblookup and other tools to receive packets 35 erroneously sent to the wrong port by broken MS systems. 36 **************************************************************************/ 37 38 void unexpected_packet(struct packet_struct *p) 39 { 40 static int count; 41 TDB_DATA kbuf, dbuf; 42 struct unexpected_key key; 43 char buf[1024]; 44 int len=0; 45 uint32_t enc_ip; 46 47 if (!tdbd) { 48 tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, 49 TDB_CLEAR_IF_FIRST|TDB_DEFAULT, 50 O_RDWR | O_CREAT, 0644); 51 if (!tdbd) { 52 DEBUG(0,("Failed to open unexpected.tdb\n")); 38 struct nb_packet_client; 39 40 struct nb_packet_server { 41 struct tevent_context *ev; 42 int listen_sock; 43 int max_clients; 44 int num_clients; 45 struct nb_packet_client *clients; 46 }; 47 48 struct nb_packet_client { 49 struct nb_packet_client *prev, *next; 50 struct nb_packet_server *server; 51 52 enum packet_type type; 53 int trn_id; 54 char *mailslot_name; 55 56 int sock; 57 struct tevent_req *read_req; 58 struct tevent_queue *out_queue; 59 }; 60 61 static int nb_packet_server_destructor(struct nb_packet_server *s); 62 static void nb_packet_server_listener(struct tevent_context *ev, 63 struct tevent_fd *fde, 64 uint16_t flags, 65 void *private_data); 66 67 NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, 68 struct tevent_context *ev, 69 int max_clients, 70 struct nb_packet_server **presult) 71 { 72 struct nb_packet_server *result; 73 struct tevent_fd *fde; 74 NTSTATUS status; 75 76 result = TALLOC_ZERO_P(mem_ctx, struct nb_packet_server); 77 if (result == NULL) { 78 status = NT_STATUS_NO_MEMORY; 79 goto fail; 80 } 81 result->ev = ev; 82 result->max_clients = max_clients; 83 84 result->listen_sock = create_pipe_sock( 85 nmbd_socket_dir(), "unexpected", 0755); 86 if (result->listen_sock == -1) { 87 status = map_nt_error_from_unix(errno); 88 goto fail; 89 } 90 talloc_set_destructor(result, nb_packet_server_destructor); 91 92 fde = tevent_add_fd(ev, result, result->listen_sock, TEVENT_FD_READ, 93 nb_packet_server_listener, result); 94 if (fde == NULL) { 95 status = NT_STATUS_NO_MEMORY; 96 goto fail; 97 } 98 99 *presult = result; 100 return NT_STATUS_OK; 101 fail: 102 TALLOC_FREE(result); 103 return status; 104 } 105 106 static int nb_packet_server_destructor(struct nb_packet_server *s) 107 { 108 if (s->listen_sock != -1) { 109 close(s->listen_sock); 110 s->listen_sock = -1; 111 } 112 return 0; 113 } 114 115 static int nb_packet_client_destructor(struct nb_packet_client *c); 116 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen, 117 void *private_data); 118 static void nb_packet_got_query(struct tevent_req *req); 119 static void nb_packet_client_read_done(struct tevent_req *req); 120 121 static void nb_packet_server_listener(struct tevent_context *ev, 122 struct tevent_fd *fde, 123 uint16_t flags, 124 void *private_data) 125 { 126 struct nb_packet_server *server = talloc_get_type_abort( 127 private_data, struct nb_packet_server); 128 struct nb_packet_client *client; 129 struct tevent_req *req; 130 struct sockaddr_un sunaddr; 131 socklen_t len; 132 int sock; 133 134 len = sizeof(sunaddr); 135 136 sock = accept(server->listen_sock, (struct sockaddr *)(void *)&sunaddr, 137 &len); 138 if (sock == -1) { 139 return; 140 } 141 DEBUG(6,("accepted socket %d\n", sock)); 142 143 client = TALLOC_ZERO_P(server, struct nb_packet_client); 144 if (client == NULL) { 145 DEBUG(10, ("talloc failed\n")); 146 close(sock); 147 return; 148 } 149 client->sock = sock; 150 client->server = server; 151 talloc_set_destructor(client, nb_packet_client_destructor); 152 153 client->out_queue = tevent_queue_create( 154 client, "unexpected packet output"); 155 if (client->out_queue == NULL) { 156 DEBUG(10, ("tevent_queue_create failed\n")); 157 TALLOC_FREE(client); 158 return; 159 } 160 161 req = read_packet_send(client, ev, client->sock, 162 sizeof(struct nb_packet_query), 163 nb_packet_client_more, NULL); 164 if (req == NULL) { 165 DEBUG(10, ("read_packet_send failed\n")); 166 TALLOC_FREE(client); 167 return; 168 } 169 tevent_req_set_callback(req, nb_packet_got_query, client); 170 171 DLIST_ADD(server->clients, client); 172 server->num_clients += 1; 173 174 if (server->num_clients > server->max_clients) { 175 DEBUG(10, ("Too many clients, dropping oldest\n")); 176 177 /* 178 * no TALLOC_FREE here, don't mess with the list structs 179 */ 180 talloc_free(server->clients->prev); 181 } 182 } 183 184 static ssize_t nb_packet_client_more(uint8_t *buf, size_t buflen, 185 void *private_data) 186 { 187 struct nb_packet_query q; 188 if (buflen > sizeof(struct nb_packet_query)) { 189 return 0; 190 } 191 /* Take care of alignment */ 192 memcpy(&q, buf, sizeof(q)); 193 if (q.mailslot_namelen > 1024) { 194 DEBUG(10, ("Got invalid mailslot namelen %d\n", 195 (int)q.mailslot_namelen)); 196 return -1; 197 } 198 return q.mailslot_namelen; 199 } 200 201 static int nb_packet_client_destructor(struct nb_packet_client *c) 202 { 203 if (c->sock != -1) { 204 close(c->sock); 205 c->sock = -1; 206 } 207 DLIST_REMOVE(c->server->clients, c); 208 c->server->num_clients -= 1; 209 return 0; 210 } 211 212 static void nb_packet_got_query(struct tevent_req *req) 213 { 214 struct nb_packet_client *client = tevent_req_callback_data( 215 req, struct nb_packet_client); 216 struct nb_packet_query q; 217 uint8_t *buf; 218 ssize_t nread, nwritten; 219 int err; 220 char c; 221 222 nread = read_packet_recv(req, talloc_tos(), &buf, &err); 223 TALLOC_FREE(req); 224 if (nread < (ssize_t)sizeof(struct nb_packet_query)) { 225 DEBUG(10, ("read_packet_recv returned %d (%s)\n", 226 (int)nread, 227 (nread == -1) ? strerror(err) : "wrong length")); 228 TALLOC_FREE(client); 229 return; 230 } 231 232 /* Take care of alignment */ 233 memcpy(&q, buf, sizeof(q)); 234 235 if (nread != sizeof(struct nb_packet_query) + q.mailslot_namelen) { 236 DEBUG(10, ("nb_packet_got_query: Invalid mailslot namelength\n")); 237 TALLOC_FREE(client); 238 return; 239 } 240 241 client->trn_id = q.trn_id; 242 client->type = q.type; 243 if (q.mailslot_namelen > 0) { 244 client->mailslot_name = talloc_strndup( 245 client, (char *)buf + sizeof(q), 246 q.mailslot_namelen); 247 if (client->mailslot_name == NULL) { 248 TALLOC_FREE(client); 53 249 return; 54 250 } 55 251 } 56 252 57 memset(buf,'\0',sizeof(buf)); 58 59 /* Encode the ip addr and port. */ 60 enc_ip = ntohl(p->ip.s_addr); 61 SIVAL(buf,0,enc_ip); 62 SSVAL(buf,4,p->port); 63 64 len = build_packet(&buf[6], sizeof(buf)-6, p) + 6; 65 66 ZERO_STRUCT(key); /* needed for potential alignment */ 67 68 key.packet_type = p->packet_type; 69 key.timestamp = p->timestamp; 70 key.count = count++; 71 72 kbuf.dptr = (uint8_t *)&key; 73 kbuf.dsize = sizeof(key); 74 dbuf.dptr = (uint8_t *)buf; 75 dbuf.dsize = len; 76 77 tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE); 78 } 79 80 81 static time_t lastt; 82 83 /**************************************************************************** 84 Delete the record if it is too old. 85 **************************************************************************/ 86 87 static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) 88 { 89 struct unexpected_key key; 90 91 if (kbuf.dsize != sizeof(key)) { 92 tdb_delete(ttdb, kbuf); 93 } 94 95 memcpy(&key, kbuf.dptr, sizeof(key)); 96 97 if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) { 98 tdb_delete(ttdb, kbuf); 99 } 100 253 /* 254 * Yes, this is a blocking write of 1 byte into a unix 255 * domain socket that has never been written to. Highly 256 * unlikely that this actually blocks. 257 */ 258 c = 0; 259 nwritten = sys_write(client->sock, &c, sizeof(c)); 260 if (nwritten != sizeof(c)) { 261 DEBUG(10, ("Could not write success indicator to client: %s\n", 262 strerror(errno))); 263 TALLOC_FREE(client); 264 return; 265 } 266 267 client->read_req = read_packet_send(client, client->server->ev, 268 client->sock, 1, NULL, NULL); 269 if (client->read_req == NULL) { 270 DEBUG(10, ("Could not activate reader for client exit " 271 "detection\n")); 272 TALLOC_FREE(client); 273 return; 274 } 275 tevent_req_set_callback(client->read_req, nb_packet_client_read_done, 276 client); 277 } 278 279 static void nb_packet_client_read_done(struct tevent_req *req) 280 { 281 struct nb_packet_client *client = tevent_req_callback_data( 282 req, struct nb_packet_client); 283 ssize_t nread; 284 uint8_t *buf; 285 int err; 286 287 nread = read_packet_recv(req, talloc_tos(), &buf, &err); 288 TALLOC_FREE(req); 289 if (nread == 1) { 290 DEBUG(10, ("Protocol error, received data on write-only " 291 "unexpected socket: 0x%2.2x\n", (*buf))); 292 } 293 TALLOC_FREE(client); 294 } 295 296 static void nb_packet_client_send(struct nb_packet_client *client, 297 struct packet_struct *p); 298 299 void nb_packet_dispatch(struct nb_packet_server *server, 300 struct packet_struct *p) 301 { 302 struct nb_packet_client *c; 303 uint16_t trn_id; 304 305 switch (p->packet_type) { 306 case NMB_PACKET: 307 trn_id = p->packet.nmb.header.name_trn_id; 308 break; 309 case DGRAM_PACKET: 310 trn_id = p->packet.dgram.header.dgm_id; 311 break; 312 default: 313 DEBUG(10, ("Got invalid packet type %d\n", 314 (int)p->packet_type)); 315 return; 316 } 317 for (c = server->clients; c != NULL; c = c->next) { 318 319 if (c->type != p->packet_type) { 320 DEBUG(10, ("client expects packet %d, got %d\n", 321 c->type, p->packet_type)); 322 continue; 323 } 324 325 if (p->packet_type == NMB_PACKET) { 326 /* 327 * See if the client specified transaction 328 * ID. Filter if it did. 329 */ 330 if ((c->trn_id != -1) && 331 (c->trn_id != trn_id)) { 332 DEBUG(10, ("client expects trn %d, got %d\n", 333 c->trn_id, trn_id)); 334 continue; 335 } 336 } else { 337 /* 338 * See if the client specified a mailslot 339 * name. Filter if it did. 340 */ 341 if ((c->mailslot_name != NULL) && 342 !match_mailslot_name(p, c->mailslot_name)) { 343 continue; 344 } 345 } 346 nb_packet_client_send(c, p); 347 } 348 } 349 350 struct nb_packet_client_header { 351 size_t len; 352 enum packet_type type; 353 time_t timestamp; 354 struct in_addr ip; 355 int port; 356 }; 357 358 struct nb_packet_client_state { 359 struct nb_packet_client *client; 360 struct iovec iov[2]; 361 struct nb_packet_client_header hdr; 362 char buf[1024]; 363 }; 364 365 static void nb_packet_client_send_done(struct tevent_req *req); 366 367 static void nb_packet_client_send(struct nb_packet_client *client, 368 struct packet_struct *p) 369 { 370 struct nb_packet_client_state *state; 371 struct tevent_req *req; 372 373 if (tevent_queue_length(client->out_queue) > 10) { 374 /* 375 * Skip clients that don't listen anyway, some form of DoS 376 * protection 377 */ 378 return; 379 } 380 381 state = TALLOC_ZERO_P(client, struct nb_packet_client_state); 382 if (state == NULL) { 383 DEBUG(10, ("talloc failed\n")); 384 return; 385 } 386 387 state->client = client; 388 389 state->hdr.ip = p->ip; 390 state->hdr.port = p->port; 391 state->hdr.timestamp = p->timestamp; 392 state->hdr.type = p->packet_type; 393 state->hdr.len = build_packet(state->buf, sizeof(state->buf), p); 394 395 state->iov[0].iov_base = (char *)&state->hdr; 396 state->iov[0].iov_len = sizeof(state->hdr); 397 state->iov[1].iov_base = state->buf; 398 state->iov[1].iov_len = state->hdr.len; 399 400 TALLOC_FREE(client->read_req); 401 402 req = writev_send(client, client->server->ev, client->out_queue, 403 client->sock, true, state->iov, 2); 404 if (req == NULL) { 405 DEBUG(10, ("writev_send failed\n")); 406 return; 407 } 408 tevent_req_set_callback(req, nb_packet_client_send_done, state); 409 } 410 411 static void nb_packet_client_send_done(struct tevent_req *req) 412 { 413 struct nb_packet_client_state *state = tevent_req_callback_data( 414 req, struct nb_packet_client_state); 415 struct nb_packet_client *client = state->client; 416 ssize_t nwritten; 417 int err; 418 419 nwritten = writev_recv(req, &err); 420 421 TALLOC_FREE(req); 422 TALLOC_FREE(state); 423 424 if (nwritten == -1) { 425 DEBUG(10, ("writev failed: %s\n", strerror(err))); 426 TALLOC_FREE(client); 427 } 428 429 if (tevent_queue_length(client->out_queue) == 0) { 430 client->read_req = read_packet_send(client, client->server->ev, 431 client->sock, 1, 432 NULL, NULL); 433 if (client->read_req == NULL) { 434 DEBUG(10, ("Could not activate reader for client exit " 435 "detection\n")); 436 TALLOC_FREE(client); 437 return; 438 } 439 tevent_req_set_callback(client->read_req, 440 nb_packet_client_read_done, 441 client); 442 } 443 } 444 445 struct nb_packet_reader { 446 int sock; 447 }; 448 449 struct nb_packet_reader_state { 450 struct tevent_context *ev; 451 struct sockaddr_un addr; 452 struct nb_packet_query query; 453 const char *mailslot_name; 454 struct iovec iov[2]; 455 char c; 456 struct nb_packet_reader *reader; 457 }; 458 459 static int nb_packet_reader_destructor(struct nb_packet_reader *r); 460 static void nb_packet_reader_connected(struct tevent_req *subreq); 461 static void nb_packet_reader_sent_query(struct tevent_req *subreq); 462 static void nb_packet_reader_got_ack(struct tevent_req *subreq); 463 464 struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, 465 struct tevent_context *ev, 466 enum packet_type type, 467 int trn_id, 468 const char *mailslot_name) 469 { 470 struct tevent_req *req, *subreq; 471 struct nb_packet_reader_state *state; 472 char *path; 473 474 req = tevent_req_create(mem_ctx, &state, 475 struct nb_packet_reader_state); 476 if (req == NULL) { 477 return NULL; 478 } 479 state->ev = ev; 480 state->query.trn_id = trn_id; 481 state->query.type = type; 482 state->mailslot_name = mailslot_name; 483 484 if (mailslot_name != NULL) { 485 state->query.mailslot_namelen = strlen(mailslot_name); 486 } 487 488 state->reader = TALLOC_ZERO_P(state, struct nb_packet_reader); 489 if (tevent_req_nomem(state->reader, req)) { 490 return tevent_req_post(req, ev); 491 } 492 493 path = talloc_asprintf(talloc_tos(), "%s/%s", nmbd_socket_dir(), 494 "unexpected"); 495 if (tevent_req_nomem(path, req)) { 496 return tevent_req_post(req, ev); 497 } 498 state->addr.sun_family = AF_UNIX; 499 strlcpy(state->addr.sun_path, path, sizeof(state->addr.sun_path)); 500 TALLOC_FREE(path); 501 502 state->reader->sock = socket(AF_UNIX, SOCK_STREAM, 0); 503 if (state->reader->sock == -1) { 504 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 505 return tevent_req_post(req, ev); 506 } 507 talloc_set_destructor(state->reader, nb_packet_reader_destructor); 508 509 subreq = async_connect_send(state, ev, state->reader->sock, 510 (struct sockaddr *)(void *)&state->addr, 511 sizeof(state->addr)); 512 if (tevent_req_nomem(subreq, req)) { 513 return tevent_req_post(req, ev); 514 } 515 tevent_req_set_callback(subreq, nb_packet_reader_connected, req); 516 return req; 517 } 518 519 static int nb_packet_reader_destructor(struct nb_packet_reader *r) 520 { 521 if (r->sock != -1) { 522 close(r->sock); 523 r->sock = -1; 524 } 101 525 return 0; 102 526 } 103 527 104 105 /**************************************************************************** 106 Delete all old unexpected packets. 107 **************************************************************************/ 108 109 void clear_unexpected(time_t t) 110 { 111 if (!tdbd) return; 112 113 if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT)) 114 return; 115 116 lastt = t; 117 118 tdb_traverse(tdbd, traverse_fn, NULL); 119 } 120 121 struct receive_unexpected_state { 122 struct packet_struct *matched_packet; 123 int match_id; 124 enum packet_type match_type; 125 const char *match_name; 528 static void nb_packet_reader_connected(struct tevent_req *subreq) 529 { 530 struct tevent_req *req = tevent_req_callback_data( 531 subreq, struct tevent_req); 532 struct nb_packet_reader_state *state = tevent_req_data( 533 req, struct nb_packet_reader_state); 534 int res, err; 535 int num_iovecs = 1; 536 537 res = async_connect_recv(subreq, &err); 538 TALLOC_FREE(subreq); 539 if (res == -1) { 540 DEBUG(10, ("async_connect failed: %s\n", strerror(err))); 541 tevent_req_nterror(req, map_nt_error_from_unix(err)); 542 return; 543 } 544 545 state->iov[0].iov_base = (char *)&state->query; 546 state->iov[0].iov_len = sizeof(state->query); 547 548 if (state->mailslot_name != NULL) { 549 num_iovecs = 2; 550 state->iov[1].iov_base = discard_const_p( 551 char, state->mailslot_name); 552 state->iov[1].iov_len = state->query.mailslot_namelen; 553 } 554 555 subreq = writev_send(state, state->ev, NULL, state->reader->sock, 556 true, state->iov, num_iovecs); 557 if (tevent_req_nomem(subreq, req)) { 558 return; 559 } 560 tevent_req_set_callback(subreq, nb_packet_reader_sent_query, req); 561 } 562 563 static void nb_packet_reader_sent_query(struct tevent_req *subreq) 564 { 565 struct tevent_req *req = tevent_req_callback_data( 566 subreq, struct tevent_req); 567 struct nb_packet_reader_state *state = tevent_req_data( 568 req, struct nb_packet_reader_state); 569 ssize_t written; 570 int err; 571 572 written = writev_recv(subreq, &err); 573 TALLOC_FREE(subreq); 574 if (written == -1) { 575 tevent_req_nterror(req, map_nt_error_from_unix(err)); 576 return; 577 } 578 if (written != sizeof(state->query) + state->query.mailslot_namelen) { 579 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR); 580 return; 581 } 582 subreq = read_packet_send(state, state->ev, state->reader->sock, 583 sizeof(state->c), NULL, NULL); 584 if (tevent_req_nomem(subreq, req)) { 585 return; 586 } 587 tevent_req_set_callback(subreq, nb_packet_reader_got_ack, req); 588 } 589 590 static void nb_packet_reader_got_ack(struct tevent_req *subreq) 591 { 592 struct tevent_req *req = tevent_req_callback_data( 593 subreq, struct tevent_req); 594 struct nb_packet_reader_state *state = tevent_req_data( 595 req, struct nb_packet_reader_state); 596 ssize_t nread; 597 int err; 598 uint8_t *buf; 599 600 nread = read_packet_recv(subreq, state, &buf, &err); 601 TALLOC_FREE(subreq); 602 if (nread == -1) { 603 DEBUG(10, ("read_packet_recv returned %s\n", 604 strerror(err))); 605 tevent_req_nterror(req, map_nt_error_from_unix(err)); 606 return; 607 } 608 if (nread != sizeof(state->c)) { 609 DEBUG(10, ("read = %d, expected %d\n", (int)nread, 610 (int)sizeof(state->c))); 611 tevent_req_nterror(req, NT_STATUS_UNEXPECTED_IO_ERROR); 612 return; 613 } 614 tevent_req_done(req); 615 } 616 617 NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 618 struct nb_packet_reader **preader) 619 { 620 struct nb_packet_reader_state *state = tevent_req_data( 621 req, struct nb_packet_reader_state); 622 NTSTATUS status; 623 624 if (tevent_req_is_nterror(req, &status)) { 625 return status; 626 } 627 *preader = talloc_move(mem_ctx, &state->reader); 628 return NT_STATUS_OK; 629 } 630 631 struct nb_packet_read_state { 632 struct nb_packet_client_header hdr; 633 uint8_t *buf; 634 size_t buflen; 126 635 }; 127 636 128 /**************************************************************************** 129 tdb traversal fn to find a matching 137 packet. 130 **************************************************************************/ 131 132 static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, 133 void *private_data) 134 { 135 struct receive_unexpected_state *state = 136 (struct receive_unexpected_state *)private_data; 137 struct unexpected_key key; 138 struct in_addr ip; 139 uint32_t enc_ip; 140 int port; 141 struct packet_struct *p; 142 143 if (kbuf.dsize != sizeof(key)) { 637 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p); 638 static void nb_packet_read_done(struct tevent_req *subreq); 639 640 struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx, 641 struct tevent_context *ev, 642 struct nb_packet_reader *reader) 643 { 644 struct tevent_req *req, *subreq; 645 struct nb_packet_read_state *state; 646 647 req = tevent_req_create(mem_ctx, &state, struct nb_packet_read_state); 648 if (req == NULL) { 649 return NULL; 650 } 651 subreq = read_packet_send(state, ev, reader->sock, 652 sizeof(struct nb_packet_client_header), 653 nb_packet_read_more, state); 654 if (tevent_req_nomem(subreq, req)) { 655 return tevent_req_post(req, ev); 656 } 657 tevent_req_set_callback(subreq, nb_packet_read_done, req); 658 return req; 659 } 660 661 static ssize_t nb_packet_read_more(uint8_t *buf, size_t buflen, void *p) 662 { 663 struct nb_packet_read_state *state = talloc_get_type_abort( 664 p, struct nb_packet_read_state); 665 666 if (buflen > sizeof(struct nb_packet_client_header)) { 667 /* 668 * Been here, done 669 */ 144 670 return 0; 145 671 } 146 147 memcpy(&key, kbuf.dptr, sizeof(key)); 148 149 if (key.packet_type != state->match_type) return 0; 150 151 if (dbuf.dsize < 6) { 152 return 0; 153 } 154 155 /* Decode the ip addr and port. */ 156 enc_ip = IVAL(dbuf.dptr,0); 157 ip.s_addr = htonl(enc_ip); 158 port = SVAL(dbuf.dptr,4); 159 160 p = parse_packet((char *)&dbuf.dptr[6], 161 dbuf.dsize-6, 162 state->match_type, 163 ip, 164 port); 165 if (!p) 166 return 0; 167 168 if ((state->match_type == NMB_PACKET && 169 p->packet.nmb.header.name_trn_id == state->match_id) || 170 (state->match_type == DGRAM_PACKET && 171 match_mailslot_name(p, state->match_name))) { 172 state->matched_packet = p; 173 return -1; 174 } 175 176 free_packet(p); 177 178 return 0; 179 } 180 181 /**************************************************************************** 182 Check for a particular packet in the unexpected packet queue. 183 **************************************************************************/ 184 185 struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, 186 const char *mailslot_name) 187 { 188 TDB_CONTEXT *tdb2; 189 struct receive_unexpected_state state; 190 191 tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); 192 if (!tdb2) return NULL; 193 194 state.matched_packet = NULL; 195 state.match_id = id; 196 state.match_type = packet_type; 197 state.match_name = mailslot_name; 198 199 tdb_traverse(tdb2, traverse_match, &state); 200 201 tdb_close(tdb2); 202 203 return state.matched_packet; 204 } 672 memcpy(&state->hdr, buf, sizeof(struct nb_packet_client_header)); 673 return state->hdr.len; 674 } 675 676 static void nb_packet_read_done(struct tevent_req *subreq) 677 { 678 struct tevent_req *req = tevent_req_callback_data( 679 subreq, struct tevent_req); 680 struct nb_packet_read_state *state = tevent_req_data( 681 req, struct nb_packet_read_state); 682 ssize_t nread; 683 int err; 684 685 nread = read_packet_recv(subreq, state, &state->buf, &err); 686 if (nread == -1) { 687 tevent_req_nterror(req, map_nt_error_from_unix(err)); 688 return; 689 } 690 state->buflen = nread; 691 tevent_req_done(req); 692 } 693 694 NTSTATUS nb_packet_read_recv(struct tevent_req *req, 695 struct packet_struct **ppacket) 696 { 697 struct nb_packet_read_state *state = tevent_req_data( 698 req, struct nb_packet_read_state); 699 struct nb_packet_client_header hdr; 700 struct packet_struct *packet; 701 NTSTATUS status; 702 703 if (tevent_req_is_nterror(req, &status)) { 704 return status; 705 } 706 707 memcpy(&hdr, state->buf, sizeof(hdr)); 708 709 packet = parse_packet( 710 (char *)state->buf + sizeof(struct nb_packet_client_header), 711 state->buflen - sizeof(struct nb_packet_client_header), 712 state->hdr.type, state->hdr.ip, state->hdr.port); 713 if (packet == NULL) { 714 return NT_STATUS_INVALID_NETWORK_RESPONSE; 715 } 716 *ppacket = packet; 717 return NT_STATUS_OK; 718 }
Note:
See TracChangeset
for help on using the changeset viewer.