1 /*
2    Unix SMB/CIFS implementation.
3    SMB transaction2 handling
4    Copyright (C) Jeremy Allison			1994-2007
5    Copyright (C) Stefan (metze) Metzmacher	2003
6    Copyright (C) Volker Lendecke		2005-2007
7    Copyright (C) Steve French			2005
8    Copyright (C) James Peach			2006-2007
9 
10    Extensively modified by Andrew Tridgell, 1995
11 
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16 
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25 
26 #include "includes.h"
27 #include "ntioctl.h"
28 #include "system/filesys.h"
29 #include "lib/util/time_basic.h"
30 #include "version.h"
31 #include "smbd/smbd.h"
32 #include "smbd/globals.h"
33 #include "../libcli/auth/libcli_auth.h"
34 #include "../librpc/gen_ndr/xattr.h"
35 #include "../librpc/gen_ndr/ndr_security.h"
36 #include "libcli/security/security.h"
37 #include "trans2.h"
38 #include "auth.h"
39 #include "smbprofile.h"
40 #include "rpc_server/srv_pipe_hnd.h"
41 #include "printing.h"
42 #include "lib/util_ea.h"
43 #include "lib/readdir_attr.h"
44 #include "messages.h"
45 #include "smb1_utils.h"
46 
47 #define DIR_ENTRY_SAFETY_MARGIN 4096
48 
49 static char *store_file_unix_basic(connection_struct *conn,
50 				char *pdata,
51 				files_struct *fsp,
52 				const SMB_STRUCT_STAT *psbuf);
53 
54 static char *store_file_unix_basic_info2(connection_struct *conn,
55 				char *pdata,
56 				files_struct *fsp,
57 				const SMB_STRUCT_STAT *psbuf);
58 
59 /****************************************************************************
60  Check if an open file handle or smb_fname is a symlink.
61 ****************************************************************************/
62 
refuse_symlink(connection_struct * conn,const files_struct * fsp,const struct smb_filename * smb_fname)63 static NTSTATUS refuse_symlink(connection_struct *conn,
64 			const files_struct *fsp,
65 			const struct smb_filename *smb_fname)
66 {
67 	SMB_STRUCT_STAT sbuf;
68 	const SMB_STRUCT_STAT *pst = NULL;
69 
70 	if (fsp) {
71 		pst = &fsp->fsp_name->st;
72 	} else {
73 		pst = &smb_fname->st;
74 	}
75 
76 	if (!VALID_STAT(*pst)) {
77 		int ret = vfs_stat_smb_basename(conn,
78 				smb_fname,
79 				&sbuf);
80 		if (ret == -1 && errno != ENOENT) {
81 			return map_nt_error_from_unix(errno);
82 		} else if (ret == -1) {
83 			/* it's not a symlink.. */
84 			return NT_STATUS_OK;
85 		}
86 		pst = &sbuf;
87 	}
88 
89 	if (S_ISLNK(pst->st_ex_mode)) {
90 		return NT_STATUS_ACCESS_DENIED;
91 	}
92 	return NT_STATUS_OK;
93 }
94 
check_access_fsp(const struct files_struct * fsp,uint32_t access_mask)95 NTSTATUS check_access_fsp(const struct files_struct *fsp,
96 			  uint32_t access_mask)
97 {
98 	if (!(fsp->access_mask & access_mask)) {
99 		return NT_STATUS_ACCESS_DENIED;
100 	}
101 	return NT_STATUS_OK;
102 }
103 
104 #if defined(HAVE_POSIX_ACLS)
105 /****************************************************************************
106  Utility function to open a fsp for a POSIX handle operation.
107 ****************************************************************************/
108 
get_posix_fsp(connection_struct * conn,struct smb_request * req,const struct smb_filename * smb_fname,uint32_t access_mask,files_struct ** ret_fsp)109 static NTSTATUS get_posix_fsp(connection_struct *conn,
110 			struct smb_request *req,
111 			const struct smb_filename *smb_fname,
112 			uint32_t access_mask,
113 			files_struct **ret_fsp)
114 {
115 	NTSTATUS status;
116 	struct smb_filename *smb_fname_tmp = NULL;
117 	uint32_t create_disposition = FILE_OPEN;
118 	uint32_t share_access = FILE_SHARE_READ|
119 				FILE_SHARE_WRITE|
120 				FILE_SHARE_DELETE;
121 	/*
122 	 * Only FILE_FLAG_POSIX_SEMANTICS matters on existing files,
123 	 * but set reasonable defaults.
124 	 */
125 	uint32_t file_attributes = 0664|FILE_FLAG_POSIX_SEMANTICS;
126 	uint32_t oplock = NO_OPLOCK;
127 	uint32_t create_options = FILE_NON_DIRECTORY_FILE;
128 
129 	/* File or directory must exist. */
130 	if (!VALID_STAT(smb_fname->st)) {
131 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
132 	}
133 	/* Cannot be a symlink. */
134 	if (S_ISLNK(smb_fname->st.st_ex_mode)) {
135 		return NT_STATUS_ACCESS_DENIED;
136 	}
137 	/* Set options correctly for directory open. */
138 	if (S_ISDIR(smb_fname->st.st_ex_mode)) {
139 		/*
140 		 * Only FILE_FLAG_POSIX_SEMANTICS matters on existing
141 		 * directories, but set reasonable defaults.
142 		 */
143 		file_attributes = 0775|FILE_FLAG_POSIX_SEMANTICS;
144 		create_options = FILE_DIRECTORY_FILE;
145 	}
146 
147 	/* Createfile uses a non-const smb_fname. */
148 	smb_fname_tmp = cp_smb_filename(talloc_tos(),
149 					smb_fname);
150 	if (smb_fname_tmp == NULL) {
151 		return NT_STATUS_NO_MEMORY;
152 	}
153 
154 	status = SMB_VFS_CREATE_FILE(
155 		conn,           /* conn */
156 		req,            /* req */
157 		0,              /* root_dir_fid */
158 		smb_fname_tmp,  /* fname */
159 		access_mask,    /* access_mask */
160 		share_access,   /* share_access */
161 		create_disposition,/* create_disposition*/
162 		create_options, /* create_options */
163 		file_attributes,/* file_attributes */
164 		oplock,         /* oplock_request */
165 		NULL,           /* lease */
166 		0,              /* allocation_size */
167 		0,              /* private_flags */
168 		NULL,           /* sd */
169 		NULL,           /* ea_list */
170 		ret_fsp,	/* result */
171 		NULL,           /* pinfo */
172 		NULL,           /* in_context */
173 		NULL);          /* out_context */
174 
175 	TALLOC_FREE(smb_fname_tmp);
176 	return status;
177 }
178 #endif
179 
180 /********************************************************************
181  The canonical "check access" based on object handle or path function.
182 ********************************************************************/
183 
check_access(connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,uint32_t access_mask)184 static NTSTATUS check_access(connection_struct *conn,
185 			     files_struct *fsp,
186 			     const struct smb_filename *smb_fname,
187 			     uint32_t access_mask)
188 {
189 	NTSTATUS status;
190 
191 	if (fsp) {
192 		status = check_access_fsp(fsp, access_mask);
193 	} else {
194 		status = smbd_check_access_rights(conn, smb_fname,
195 						  false, access_mask);
196 	}
197 
198 	return status;
199 }
200 
201 /********************************************************************
202  Roundup a value to the nearest allocation roundup size boundary.
203  Only do this for Windows clients.
204 ********************************************************************/
205 
smb_roundup(connection_struct * conn,uint64_t val)206 uint64_t smb_roundup(connection_struct *conn, uint64_t val)
207 {
208 	uint64_t rval = lp_allocation_roundup_size(SNUM(conn));
209 
210 	/* Only roundup for Windows clients. */
211 	enum remote_arch_types ra_type = get_remote_arch();
212 	if (rval && (ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
213 		val = SMB_ROUNDUP(val,rval);
214 	}
215 	return val;
216 }
217 
218 /****************************************************************************
219  Utility functions for dealing with extended attributes.
220 ****************************************************************************/
221 
222 /****************************************************************************
223  Refuse to allow clients to overwrite our private xattrs.
224 ****************************************************************************/
225 
samba_private_attr_name(const char * unix_ea_name)226 bool samba_private_attr_name(const char *unix_ea_name)
227 {
228 	static const char * const prohibited_ea_names[] = {
229 		SAMBA_POSIX_INHERITANCE_EA_NAME,
230 		SAMBA_XATTR_DOS_ATTRIB,
231 		SAMBA_XATTR_MARKER,
232 		XATTR_NTACL_NAME,
233 		NULL
234 	};
235 
236 	int i;
237 
238 	for (i = 0; prohibited_ea_names[i]; i++) {
239 		if (strequal( prohibited_ea_names[i], unix_ea_name))
240 			return true;
241 	}
242 	if (strncasecmp_m(unix_ea_name, SAMBA_XATTR_DOSSTREAM_PREFIX,
243 			strlen(SAMBA_XATTR_DOSSTREAM_PREFIX)) == 0) {
244 		return true;
245 	}
246 	return false;
247 }
248 
249 /****************************************************************************
250  Get one EA value. Fill in a struct ea_struct.
251 ****************************************************************************/
252 
get_ea_value(TALLOC_CTX * mem_ctx,connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,const char * ea_name,struct ea_struct * pea)253 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx,
254 			connection_struct *conn,
255 			files_struct *fsp,
256 			const struct smb_filename *smb_fname,
257 			const char *ea_name,
258 			struct ea_struct *pea)
259 {
260 	/* Get the value of this xattr. Max size is 64k. */
261 	size_t attr_size = 256;
262 	char *val = NULL;
263 	ssize_t sizeret;
264 
265  again:
266 
267 	val = talloc_realloc(mem_ctx, val, char, attr_size);
268 	if (!val) {
269 		return NT_STATUS_NO_MEMORY;
270 	}
271 
272 	if (fsp && fsp->fh->fd != -1) {
273 		sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
274 	} else {
275 		sizeret = SMB_VFS_GETXATTR(conn, smb_fname,
276 				ea_name, val, attr_size);
277 	}
278 
279 	if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
280 		attr_size = 65536;
281 		goto again;
282 	}
283 
284 	if (sizeret == -1) {
285 		return map_nt_error_from_unix(errno);
286 	}
287 
288 	DEBUG(10,("get_ea_value: EA %s is of length %u\n", ea_name, (unsigned int)sizeret));
289 	dump_data(10, (uint8_t *)val, sizeret);
290 
291 	pea->flags = 0;
292 	if (strnequal(ea_name, "user.", 5)) {
293 		pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
294 	} else {
295 		pea->name = talloc_strdup(mem_ctx, ea_name);
296 	}
297 	if (pea->name == NULL) {
298 		TALLOC_FREE(val);
299 		return NT_STATUS_NO_MEMORY;
300 	}
301 	pea->value.data = (unsigned char *)val;
302 	pea->value.length = (size_t)sizeret;
303 	return NT_STATUS_OK;
304 }
305 
get_ea_names_from_file(TALLOC_CTX * mem_ctx,connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,char *** pnames,size_t * pnum_names)306 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
307 				connection_struct *conn,
308 				files_struct *fsp,
309 				const struct smb_filename *smb_fname,
310 				char ***pnames,
311 				size_t *pnum_names)
312 {
313 	char smallbuf[1024];
314 	/* Get a list of all xattrs. Max namesize is 64k. */
315 	size_t ea_namelist_size = 1024;
316 	char *ea_namelist = smallbuf;
317 	char *to_free = NULL;
318 
319 	char *p;
320 	char **names;
321 	size_t num_names;
322 	ssize_t sizeret = -1;
323 	NTSTATUS status;
324 
325 	if (pnames) {
326 		*pnames = NULL;
327 	}
328 	*pnum_names = 0;
329 
330 	status = refuse_symlink(conn, fsp, smb_fname);
331 	if (!NT_STATUS_IS_OK(status)) {
332 		/*
333 		 * Just return no EA's on a symlink.
334 		 */
335 		return NT_STATUS_OK;
336 	}
337 
338 	if (fsp && fsp->fh->fd != -1) {
339 		sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
340 					     ea_namelist_size);
341 	} else {
342 		sizeret = SMB_VFS_LISTXATTR(conn,
343 					    smb_fname,
344 					    ea_namelist,
345 					    ea_namelist_size);
346 	}
347 
348 	if ((sizeret == -1) && (errno == ERANGE)) {
349 		ea_namelist_size = 65536;
350 		ea_namelist = talloc_array(mem_ctx, char, ea_namelist_size);
351 		if (ea_namelist == NULL) {
352 			return NT_STATUS_NO_MEMORY;
353 		}
354 		to_free = ea_namelist;
355 
356 		if (fsp && fsp->fh->fd != -1) {
357 			sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
358 						     ea_namelist_size);
359 		} else {
360 			sizeret = SMB_VFS_LISTXATTR(conn,
361 						    smb_fname,
362 						    ea_namelist,
363 						    ea_namelist_size);
364 		}
365 	}
366 
367 	if (sizeret == -1) {
368 		status = map_nt_error_from_unix(errno);
369 		TALLOC_FREE(to_free);
370 		return status;
371 	}
372 
373 	DBG_DEBUG("ea_namelist size = %zd\n", sizeret);
374 
375 	if (sizeret == 0) {
376 		TALLOC_FREE(to_free);
377 		return NT_STATUS_OK;
378 	}
379 
380 	/*
381 	 * Ensure the result is 0-terminated
382 	 */
383 
384 	if (ea_namelist[sizeret-1] != '\0') {
385 		TALLOC_FREE(to_free);
386 		return NT_STATUS_INTERNAL_ERROR;
387 	}
388 
389 	/*
390 	 * count the names
391 	 */
392 	num_names = 0;
393 
394 	for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
395 		num_names += 1;
396 	}
397 
398 	*pnum_names = num_names;
399 
400 	if (pnames == NULL) {
401 		TALLOC_FREE(to_free);
402 		return NT_STATUS_OK;
403 	}
404 
405 	names = talloc_array(mem_ctx, char *, num_names);
406 	if (names == NULL) {
407 		DEBUG(0, ("talloc failed\n"));
408 		TALLOC_FREE(to_free);
409 		return NT_STATUS_NO_MEMORY;
410 	}
411 
412 	if (ea_namelist == smallbuf) {
413 		ea_namelist = talloc_memdup(names, smallbuf, sizeret);
414 		if (ea_namelist == NULL) {
415 			TALLOC_FREE(names);
416 			return NT_STATUS_NO_MEMORY;
417 		}
418 	} else {
419 		talloc_steal(names, ea_namelist);
420 
421 		ea_namelist = talloc_realloc(names, ea_namelist, char,
422 					     sizeret);
423 		if (ea_namelist == NULL) {
424 			TALLOC_FREE(names);
425 			return NT_STATUS_NO_MEMORY;
426 		}
427 	}
428 
429 	num_names = 0;
430 
431 	for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
432 		names[num_names++] = p;
433 	}
434 
435 	*pnames = names;
436 
437 	return NT_STATUS_OK;
438 }
439 
440 /****************************************************************************
441  Return a linked list of the total EA's. Plus the total size
442 ****************************************************************************/
443 
get_ea_list_from_file_path(TALLOC_CTX * mem_ctx,connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,size_t * pea_total_len,struct ea_list ** ea_list)444 static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
445 				connection_struct *conn,
446 				files_struct *fsp,
447 				const struct smb_filename *smb_fname,
448 				size_t *pea_total_len,
449 				struct ea_list **ea_list)
450 {
451 	/* Get a list of all xattrs. Max namesize is 64k. */
452 	size_t i, num_names;
453 	char **names;
454 	struct ea_list *ea_list_head = NULL;
455 	bool posix_pathnames = false;
456 	NTSTATUS status;
457 
458 	*pea_total_len = 0;
459 	*ea_list = NULL;
460 
461 	if (!lp_ea_support(SNUM(conn))) {
462 		return NT_STATUS_OK;
463 	}
464 
465 	if (fsp) {
466 		posix_pathnames =
467 			(fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
468 	} else {
469 		posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
470 	}
471 
472 	status = get_ea_names_from_file(talloc_tos(),
473 				conn,
474 				fsp,
475 				smb_fname,
476 				&names,
477 				&num_names);
478 
479 	if (!NT_STATUS_IS_OK(status)) {
480 		return status;
481 	}
482 
483 	if (num_names == 0) {
484 		return NT_STATUS_OK;
485 	}
486 
487 	for (i=0; i<num_names; i++) {
488 		struct ea_list *listp;
489 		fstring dos_ea_name;
490 
491 		if (strnequal(names[i], "system.", 7)
492 		    || samba_private_attr_name(names[i]))
493 			continue;
494 
495 		/*
496 		 * Filter out any underlying POSIX EA names
497 		 * that a Windows client can't handle.
498 		 */
499 		if (!posix_pathnames &&
500 				is_invalid_windows_ea_name(names[i])) {
501 			continue;
502 		}
503 
504 		listp = talloc(mem_ctx, struct ea_list);
505 		if (listp == NULL) {
506 			return NT_STATUS_NO_MEMORY;
507 		}
508 
509 		status = get_ea_value(listp,
510 					conn,
511 					fsp,
512 					smb_fname,
513 					names[i],
514 					&listp->ea);
515 
516 		if (!NT_STATUS_IS_OK(status)) {
517 			TALLOC_FREE(listp);
518 			return status;
519 		}
520 
521 		if (listp->ea.value.length == 0) {
522 			/*
523 			 * We can never return a zero length EA.
524 			 * Windows reports the EA's as corrupted.
525 			 */
526 			TALLOC_FREE(listp);
527 			continue;
528 		}
529 
530 		push_ascii_fstring(dos_ea_name, listp->ea.name);
531 
532 		*pea_total_len +=
533 			4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
534 
535 		DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len "
536 			  "= %u\n", (unsigned int)*pea_total_len, dos_ea_name,
537 			  (unsigned int)listp->ea.value.length));
538 
539 		DLIST_ADD_END(ea_list_head, listp);
540 
541 	}
542 
543 	/* Add on 4 for total length. */
544 	if (*pea_total_len) {
545 		*pea_total_len += 4;
546 	}
547 
548 	DEBUG(10, ("get_ea_list_from_file: total_len = %u\n",
549 		   (unsigned int)*pea_total_len));
550 
551 	*ea_list = ea_list_head;
552 	return NT_STATUS_OK;
553 }
554 
get_ea_list_from_file(TALLOC_CTX * mem_ctx,connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,size_t * pea_total_len,struct ea_list ** ea_list)555 static NTSTATUS get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp,
556 				      const struct smb_filename *smb_fname, size_t *pea_total_len, struct ea_list **ea_list)
557 {
558 	*pea_total_len = 0;
559 	*ea_list = NULL;
560 
561 	if (!lp_ea_support(SNUM(conn))) {
562 		return NT_STATUS_OK;
563 	}
564 
565 	if (is_ntfs_stream_smb_fname(smb_fname)) {
566 		return NT_STATUS_INVALID_PARAMETER;
567 	}
568 
569 	return get_ea_list_from_file_path(mem_ctx,
570 				conn,
571 				fsp,
572 				smb_fname,
573 				pea_total_len,
574 				ea_list);
575 }
576 
577 /****************************************************************************
578  Fill a qfilepathinfo buffer with EA's. Returns the length of the buffer
579  that was filled.
580 ****************************************************************************/
581 
fill_ea_buffer(TALLOC_CTX * mem_ctx,char * pdata,unsigned int total_data_size,connection_struct * conn,struct ea_list * ea_list)582 static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned int total_data_size,
583 	connection_struct *conn, struct ea_list *ea_list)
584 {
585 	unsigned int ret_data_size = 4;
586 	char *p = pdata;
587 
588 	SMB_ASSERT(total_data_size >= 4);
589 
590 	if (!lp_ea_support(SNUM(conn))) {
591 		SIVAL(pdata,4,0);
592 		return 4;
593 	}
594 
595 	for (p = pdata + 4; ea_list; ea_list = ea_list->next) {
596 		size_t dos_namelen;
597 		fstring dos_ea_name;
598 		push_ascii_fstring(dos_ea_name, ea_list->ea.name);
599 		dos_namelen = strlen(dos_ea_name);
600 		if (dos_namelen > 255 || dos_namelen == 0) {
601 			break;
602 		}
603 		if (ea_list->ea.value.length > 65535) {
604 			break;
605 		}
606 		if (4 + dos_namelen + 1 + ea_list->ea.value.length > total_data_size) {
607 			break;
608 		}
609 
610 		/* We know we have room. */
611 		SCVAL(p,0,ea_list->ea.flags);
612 		SCVAL(p,1,dos_namelen);
613 		SSVAL(p,2,ea_list->ea.value.length);
614 		strlcpy(p+4, dos_ea_name, dos_namelen+1);
615 		if (ea_list->ea.value.length > 0) {
616 			memcpy(p + 4 + dos_namelen + 1,
617 			       ea_list->ea.value.data,
618 			       ea_list->ea.value.length);
619 		}
620 
621 		total_data_size -= 4 + dos_namelen + 1 + ea_list->ea.value.length;
622 		p += 4 + dos_namelen + 1 + ea_list->ea.value.length;
623 	}
624 
625 	ret_data_size = PTR_DIFF(p, pdata);
626 	DEBUG(10,("fill_ea_buffer: data_size = %u\n", ret_data_size ));
627 	SIVAL(pdata,0,ret_data_size);
628 	return ret_data_size;
629 }
630 
fill_ea_chained_buffer(TALLOC_CTX * mem_ctx,char * pdata,unsigned int total_data_size,unsigned int * ret_data_size,connection_struct * conn,struct ea_list * ea_list)631 static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
632 				       char *pdata,
633 				       unsigned int total_data_size,
634 				       unsigned int *ret_data_size,
635 				       connection_struct *conn,
636 				       struct ea_list *ea_list)
637 {
638 	uint8_t *p = (uint8_t *)pdata;
639 	uint8_t *last_start = NULL;
640 	bool do_store_data = (pdata != NULL);
641 
642 	*ret_data_size = 0;
643 
644 	if (!lp_ea_support(SNUM(conn))) {
645 		return NT_STATUS_NO_EAS_ON_FILE;
646 	}
647 
648 	for (; ea_list; ea_list = ea_list->next) {
649 		size_t dos_namelen;
650 		fstring dos_ea_name;
651 		size_t this_size;
652 		size_t pad = 0;
653 
654 		if (last_start != NULL && do_store_data) {
655 			SIVAL(last_start, 0, PTR_DIFF(p, last_start));
656 		}
657 		last_start = p;
658 
659 		push_ascii_fstring(dos_ea_name, ea_list->ea.name);
660 		dos_namelen = strlen(dos_ea_name);
661 		if (dos_namelen > 255 || dos_namelen == 0) {
662 			return NT_STATUS_INTERNAL_ERROR;
663 		}
664 		if (ea_list->ea.value.length > 65535) {
665 			return NT_STATUS_INTERNAL_ERROR;
666 		}
667 
668 		this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
669 
670 		if (ea_list->next) {
671 			pad = (4 - (this_size % 4)) % 4;
672 			this_size += pad;
673 		}
674 
675 		if (do_store_data) {
676 			if (this_size > total_data_size) {
677 				return NT_STATUS_INFO_LENGTH_MISMATCH;
678 			}
679 
680 			/* We know we have room. */
681 			SIVAL(p, 0x00, 0); /* next offset */
682 			SCVAL(p, 0x04, ea_list->ea.flags);
683 			SCVAL(p, 0x05, dos_namelen);
684 			SSVAL(p, 0x06, ea_list->ea.value.length);
685 			strlcpy((char *)(p+0x08), dos_ea_name, dos_namelen+1);
686 			memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
687 			if (pad) {
688 				memset(p + 0x08 + dos_namelen + 1 + ea_list->ea.value.length,
689 					'\0',
690 					pad);
691 			}
692 			total_data_size -= this_size;
693 		}
694 
695 		p += this_size;
696 	}
697 
698 	*ret_data_size = PTR_DIFF(p, pdata);
699 	DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
700 	return NT_STATUS_OK;
701 }
702 
estimate_ea_size(connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname)703 static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const struct smb_filename *smb_fname)
704 {
705 	size_t total_ea_len = 0;
706 	TALLOC_CTX *mem_ctx;
707 	struct ea_list *ea_list = NULL;
708 
709 	if (!lp_ea_support(SNUM(conn))) {
710 		return 0;
711 	}
712 	mem_ctx = talloc_stackframe();
713 
714 	/* If this is a stream fsp, then we need to instead find the
715 	 * estimated ea len from the main file, not the stream
716 	 * (streams cannot have EAs), but the estimate isn't just 0 in
717 	 * this case! */
718 	if (is_ntfs_stream_smb_fname(smb_fname)) {
719 		fsp = NULL;
720 	}
721 	(void)get_ea_list_from_file_path(mem_ctx,
722 				conn,
723 				fsp,
724 				smb_fname,
725 				&total_ea_len,
726 				&ea_list);
727 	if(conn->sconn->using_smb2) {
728 		NTSTATUS status;
729 		unsigned int ret_data_size;
730 		/*
731 		 * We're going to be using fill_ea_chained_buffer() to
732 		 * marshall EA's - this size is significantly larger
733 		 * than the SMB1 buffer. Re-calculate the size without
734 		 * marshalling.
735 		 */
736 		status = fill_ea_chained_buffer(mem_ctx,
737 						NULL,
738 						0,
739 						&ret_data_size,
740 						conn,
741 						ea_list);
742 		if (!NT_STATUS_IS_OK(status)) {
743 			ret_data_size = 0;
744 		}
745 		total_ea_len = ret_data_size;
746 	}
747 	TALLOC_FREE(mem_ctx);
748 	return total_ea_len;
749 }
750 
751 /****************************************************************************
752  Ensure the EA name is case insensitive by matching any existing EA name.
753 ****************************************************************************/
754 
canonicalize_ea_name(connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,fstring unix_ea_name)755 static void canonicalize_ea_name(connection_struct *conn,
756 			files_struct *fsp,
757 			const struct smb_filename *smb_fname,
758 			fstring unix_ea_name)
759 {
760 	size_t total_ea_len;
761 	TALLOC_CTX *mem_ctx = talloc_tos();
762 	struct ea_list *ea_list;
763 	NTSTATUS status = get_ea_list_from_file_path(mem_ctx,
764 					conn,
765 					fsp,
766 					smb_fname,
767 					&total_ea_len,
768 					&ea_list);
769 	if (!NT_STATUS_IS_OK(status)) {
770 		return;
771 	}
772 
773 	for (; ea_list; ea_list = ea_list->next) {
774 		if (strequal(&unix_ea_name[5], ea_list->ea.name)) {
775 			DEBUG(10,("canonicalize_ea_name: %s -> %s\n",
776 				&unix_ea_name[5], ea_list->ea.name));
777 			strlcpy(&unix_ea_name[5], ea_list->ea.name, sizeof(fstring)-5);
778 			break;
779 		}
780 	}
781 }
782 
783 /****************************************************************************
784  Set or delete an extended attribute.
785 ****************************************************************************/
786 
set_ea(connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,struct ea_list * ea_list)787 NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
788 		const struct smb_filename *smb_fname, struct ea_list *ea_list)
789 {
790 	NTSTATUS status;
791 	bool posix_pathnames = false;
792 
793 	if (!lp_ea_support(SNUM(conn))) {
794 		return NT_STATUS_EAS_NOT_SUPPORTED;
795 	}
796 
797 	if (fsp) {
798 		posix_pathnames =
799 			(fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
800 	} else {
801 		posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
802 	}
803 
804 	status = refuse_symlink(conn, fsp, smb_fname);
805 	if (!NT_STATUS_IS_OK(status)) {
806 		return status;
807 	}
808 
809 	status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA);
810 	if (!NT_STATUS_IS_OK(status)) {
811 		return status;
812 	}
813 
814 	/* Setting EAs on streams isn't supported. */
815 	if (is_ntfs_stream_smb_fname(smb_fname)) {
816 		return NT_STATUS_INVALID_PARAMETER;
817 	}
818 
819 	/*
820 	 * Filter out invalid Windows EA names - before
821 	 * we set *any* of them.
822 	 */
823 
824 	if (!posix_pathnames && ea_list_has_invalid_name(ea_list)) {
825 		return STATUS_INVALID_EA_NAME;
826 	}
827 
828 	for (;ea_list; ea_list = ea_list->next) {
829 		int ret;
830 		fstring unix_ea_name;
831 
832 		fstrcpy(unix_ea_name, "user."); /* All EA's must start with user. */
833 		fstrcat(unix_ea_name, ea_list->ea.name);
834 
835 		canonicalize_ea_name(conn,
836 				fsp,
837 				smb_fname,
838 				unix_ea_name);
839 
840 		DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length));
841 
842 		if (samba_private_attr_name(unix_ea_name)) {
843 			DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name));
844 			return NT_STATUS_ACCESS_DENIED;
845 		}
846 
847 		if (ea_list->ea.value.length == 0) {
848 			/* Remove the attribute. */
849 			if (fsp && (fsp->fh->fd != -1)) {
850 				DEBUG(10,("set_ea: deleting ea name %s on "
851 					  "file %s by file descriptor.\n",
852 					  unix_ea_name, fsp_str_dbg(fsp)));
853 				ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
854 			} else {
855 				DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
856 					unix_ea_name, smb_fname->base_name));
857 				ret = SMB_VFS_REMOVEXATTR(conn,
858 						smb_fname,
859 						unix_ea_name);
860 			}
861 #ifdef ENOATTR
862 			/* Removing a non existent attribute always succeeds. */
863 			if (ret == -1 && errno == ENOATTR) {
864 				DEBUG(10,("set_ea: deleting ea name %s didn't exist - succeeding by default.\n",
865 						unix_ea_name));
866 				ret = 0;
867 			}
868 #endif
869 		} else {
870 			if (fsp && (fsp->fh->fd != -1)) {
871 				DEBUG(10,("set_ea: setting ea name %s on file "
872 					  "%s by file descriptor.\n",
873 					  unix_ea_name, fsp_str_dbg(fsp)));
874 				ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
875 							ea_list->ea.value.data, ea_list->ea.value.length, 0);
876 			} else {
877 				DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
878 					unix_ea_name, smb_fname->base_name));
879 				ret = SMB_VFS_SETXATTR(conn,
880 						smb_fname,
881 						unix_ea_name,
882 						ea_list->ea.value.data,
883 						ea_list->ea.value.length,
884 						0);
885 			}
886 		}
887 
888 		if (ret == -1) {
889 #ifdef ENOTSUP
890 			if (errno == ENOTSUP) {
891 				return NT_STATUS_EAS_NOT_SUPPORTED;
892 			}
893 #endif
894 			return map_nt_error_from_unix(errno);
895 		}
896 
897 	}
898 	return NT_STATUS_OK;
899 }
900 /****************************************************************************
901  Read a list of EA names from an incoming data buffer. Create an ea_list with them.
902 ****************************************************************************/
903 
read_ea_name_list(TALLOC_CTX * ctx,const char * pdata,size_t data_size)904 static struct ea_list *read_ea_name_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
905 {
906 	struct ea_list *ea_list_head = NULL;
907 	size_t converted_size, offset = 0;
908 
909 	while (offset + 2 < data_size) {
910 		struct ea_list *eal = talloc_zero(ctx, struct ea_list);
911 		unsigned int namelen = CVAL(pdata,offset);
912 
913 		offset++; /* Go past the namelen byte. */
914 
915 		/* integer wrap paranioa. */
916 		if ((offset + namelen < offset) || (offset + namelen < namelen) ||
917 				(offset > data_size) || (namelen > data_size) ||
918 				(offset + namelen >= data_size)) {
919 			break;
920 		}
921 		/* Ensure the name is null terminated. */
922 		if (pdata[offset + namelen] != '\0') {
923 			return NULL;
924 		}
925 		if (!pull_ascii_talloc(ctx, &eal->ea.name, &pdata[offset],
926 				       &converted_size)) {
927 			DEBUG(0,("read_ea_name_list: pull_ascii_talloc "
928 				 "failed: %s", strerror(errno)));
929 		}
930 		if (!eal->ea.name) {
931 			return NULL;
932 		}
933 
934 		offset += (namelen + 1); /* Go past the name + terminating zero. */
935 		DLIST_ADD_END(ea_list_head, eal);
936 		DEBUG(10,("read_ea_name_list: read ea name %s\n", eal->ea.name));
937 	}
938 
939 	return ea_list_head;
940 }
941 
942 /****************************************************************************
943  Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
944 ****************************************************************************/
945 
read_ea_list(TALLOC_CTX * ctx,const char * pdata,size_t data_size)946 static struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
947 {
948 	struct ea_list *ea_list_head = NULL;
949 	size_t offset = 0;
950 	size_t bytes_used = 0;
951 
952 	while (offset < data_size) {
953 		struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset, data_size - offset, &bytes_used);
954 
955 		if (!eal) {
956 			return NULL;
957 		}
958 
959 		DLIST_ADD_END(ea_list_head, eal);
960 		offset += bytes_used;
961 	}
962 
963 	return ea_list_head;
964 }
965 
966 /****************************************************************************
967  Count the total EA size needed.
968 ****************************************************************************/
969 
ea_list_size(struct ea_list * ealist)970 static size_t ea_list_size(struct ea_list *ealist)
971 {
972 	fstring dos_ea_name;
973 	struct ea_list *listp;
974 	size_t ret = 0;
975 
976 	for (listp = ealist; listp; listp = listp->next) {
977 		push_ascii_fstring(dos_ea_name, listp->ea.name);
978 		ret += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length;
979 	}
980 	/* Add on 4 for total length. */
981 	if (ret) {
982 		ret += 4;
983 	}
984 
985 	return ret;
986 }
987 
988 /****************************************************************************
989  Return a union of EA's from a file list and a list of names.
990  The TALLOC context for the two lists *MUST* be identical as we steal
991  memory from one list to add to another. JRA.
992 ****************************************************************************/
993 
ea_list_union(struct ea_list * name_list,struct ea_list * file_list,size_t * total_ea_len)994 static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list *file_list, size_t *total_ea_len)
995 {
996 	struct ea_list *nlistp, *flistp;
997 
998 	for (nlistp = name_list; nlistp; nlistp = nlistp->next) {
999 		for (flistp = file_list; flistp; flistp = flistp->next) {
1000 			if (strequal(nlistp->ea.name, flistp->ea.name)) {
1001 				break;
1002 			}
1003 		}
1004 
1005 		if (flistp) {
1006 			/* Copy the data from this entry. */
1007 			nlistp->ea.flags = flistp->ea.flags;
1008 			nlistp->ea.value = flistp->ea.value;
1009 		} else {
1010 			/* Null entry. */
1011 			nlistp->ea.flags = 0;
1012 			ZERO_STRUCT(nlistp->ea.value);
1013 		}
1014 	}
1015 
1016 	*total_ea_len = ea_list_size(name_list);
1017 	return name_list;
1018 }
1019 
1020 /****************************************************************************
1021   Send the required number of replies back.
1022   We assume all fields other than the data fields are
1023   set correctly for the type of call.
1024   HACK ! Always assumes smb_setup field is zero.
1025 ****************************************************************************/
1026 
send_trans2_replies(connection_struct * conn,struct smb_request * req,NTSTATUS status,const char * params,int paramsize,const char * pdata,int datasize,int max_data_bytes)1027 void send_trans2_replies(connection_struct *conn,
1028 			struct smb_request *req,
1029 			NTSTATUS status,
1030 			 const char *params,
1031 			 int paramsize,
1032 			 const char *pdata,
1033 			 int datasize,
1034 			 int max_data_bytes)
1035 {
1036 	/* As we are using a protocol > LANMAN1 then the max_send
1037 	 variable must have been set in the sessetupX call.
1038 	 This takes precedence over the max_xmit field in the
1039 	 global struct. These different max_xmit variables should
1040 	 be merged as this is now too confusing */
1041 
1042 	int data_to_send = datasize;
1043 	int params_to_send = paramsize;
1044 	int useable_space;
1045 	const char *pp = params;
1046 	const char *pd = pdata;
1047 	int params_sent_thistime, data_sent_thistime, total_sent_thistime;
1048 	int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
1049 	int data_alignment_offset = 0;
1050 	bool overflow = False;
1051 	struct smbXsrv_connection *xconn = req->xconn;
1052 	int max_send = xconn->smb1.sessions.max_send;
1053 
1054 	/* Modify the data_to_send and datasize and set the error if
1055 	   we're trying to send more than max_data_bytes. We still send
1056 	   the part of the packet(s) that fit. Strange, but needed
1057 	   for OS/2. */
1058 
1059 	if (max_data_bytes > 0 && datasize > max_data_bytes) {
1060 		DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
1061 			max_data_bytes, datasize ));
1062 		datasize = data_to_send = max_data_bytes;
1063 		overflow = True;
1064 	}
1065 
1066 	/* If there genuinely are no parameters or data to send just send the empty packet */
1067 
1068 	if(params_to_send == 0 && data_to_send == 0) {
1069 		reply_outbuf(req, 10, 0);
1070 		if (NT_STATUS_V(status)) {
1071 			uint8_t eclass;
1072 			uint32_t ecode;
1073 			ntstatus_to_dos(status, &eclass, &ecode);
1074 			error_packet_set((char *)req->outbuf,
1075 					eclass, ecode, status,
1076 					__LINE__,__FILE__);
1077 		}
1078 		show_msg((char *)req->outbuf);
1079 		if (!srv_send_smb(xconn,
1080 				(char *)req->outbuf,
1081 				true, req->seqnum+1,
1082 				IS_CONN_ENCRYPTED(conn),
1083 				&req->pcd)) {
1084 			exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1085 		}
1086 		TALLOC_FREE(req->outbuf);
1087 		return;
1088 	}
1089 
1090 	/* When sending params and data ensure that both are nicely aligned */
1091 	/* Only do this alignment when there is also data to send - else
1092 		can cause NT redirector problems. */
1093 
1094 	if (((params_to_send % 4) != 0) && (data_to_send != 0))
1095 		data_alignment_offset = 4 - (params_to_send % 4);
1096 
1097 	/* Space is bufsize minus Netbios over TCP header minus SMB header */
1098 	/* The alignment_offset is to align the param bytes on an even byte
1099 		boundary. NT 4.0 Beta needs this to work correctly. */
1100 
1101 	useable_space = max_send - (smb_size
1102 				    + 2 * 10 /* wct */
1103 				    + alignment_offset
1104 				    + data_alignment_offset);
1105 
1106 	if (useable_space < 0) {
1107 		DEBUG(0, ("send_trans2_replies failed sanity useable_space "
1108 			  "= %d!!!", useable_space));
1109 		exit_server_cleanly("send_trans2_replies: Not enough space");
1110 	}
1111 
1112 	while (params_to_send || data_to_send) {
1113 		/* Calculate whether we will totally or partially fill this packet */
1114 
1115 		total_sent_thistime = params_to_send + data_to_send;
1116 
1117 		/* We can never send more than useable_space */
1118 		/*
1119 		 * Note that 'useable_space' does not include the alignment offsets,
1120 		 * but we must include the alignment offsets in the calculation of
1121 		 * the length of the data we send over the wire, as the alignment offsets
1122 		 * are sent here. Fix from Marc_Jacobsen@hp.com.
1123 		 */
1124 
1125 		total_sent_thistime = MIN(total_sent_thistime, useable_space);
1126 
1127 		reply_outbuf(req, 10, total_sent_thistime + alignment_offset
1128 			     + data_alignment_offset);
1129 
1130 		/* Set total params and data to be sent */
1131 		SSVAL(req->outbuf,smb_tprcnt,paramsize);
1132 		SSVAL(req->outbuf,smb_tdrcnt,datasize);
1133 
1134 		/* Calculate how many parameters and data we can fit into
1135 		 * this packet. Parameters get precedence
1136 		 */
1137 
1138 		params_sent_thistime = MIN(params_to_send,useable_space);
1139 		data_sent_thistime = useable_space - params_sent_thistime;
1140 		data_sent_thistime = MIN(data_sent_thistime,data_to_send);
1141 
1142 		SSVAL(req->outbuf,smb_prcnt, params_sent_thistime);
1143 
1144 		/* smb_proff is the offset from the start of the SMB header to the
1145 			parameter bytes, however the first 4 bytes of outbuf are
1146 			the Netbios over TCP header. Thus use smb_base() to subtract
1147 			them from the calculation */
1148 
1149 		SSVAL(req->outbuf,smb_proff,
1150 		      ((smb_buf(req->outbuf)+alignment_offset)
1151 		       - smb_base(req->outbuf)));
1152 
1153 		if(params_sent_thistime == 0)
1154 			SSVAL(req->outbuf,smb_prdisp,0);
1155 		else
1156 			/* Absolute displacement of param bytes sent in this packet */
1157 			SSVAL(req->outbuf,smb_prdisp,pp - params);
1158 
1159 		SSVAL(req->outbuf,smb_drcnt, data_sent_thistime);
1160 		if(data_sent_thistime == 0) {
1161 			SSVAL(req->outbuf,smb_droff,0);
1162 			SSVAL(req->outbuf,smb_drdisp, 0);
1163 		} else {
1164 			/* The offset of the data bytes is the offset of the
1165 				parameter bytes plus the number of parameters being sent this time */
1166 			SSVAL(req->outbuf, smb_droff,
1167 			      ((smb_buf(req->outbuf)+alignment_offset)
1168 			       - smb_base(req->outbuf))
1169 			      + params_sent_thistime + data_alignment_offset);
1170 			SSVAL(req->outbuf,smb_drdisp, pd - pdata);
1171 		}
1172 
1173 		/* Initialize the padding for alignment */
1174 
1175 		if (alignment_offset != 0) {
1176 			memset(smb_buf(req->outbuf), 0, alignment_offset);
1177 		}
1178 
1179 		/* Copy the param bytes into the packet */
1180 
1181 		if(params_sent_thistime) {
1182 			memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
1183 			       params_sent_thistime);
1184 		}
1185 
1186 		/* Copy in the data bytes */
1187 		if(data_sent_thistime) {
1188 			if (data_alignment_offset != 0) {
1189 				memset((smb_buf(req->outbuf)+alignment_offset+
1190 					params_sent_thistime), 0,
1191 				       data_alignment_offset);
1192 			}
1193 			memcpy(smb_buf(req->outbuf)+alignment_offset
1194 			       +params_sent_thistime+data_alignment_offset,
1195 			       pd,data_sent_thistime);
1196 		}
1197 
1198 		DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
1199 			params_sent_thistime, data_sent_thistime, useable_space));
1200 		DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
1201 			params_to_send, data_to_send, paramsize, datasize));
1202 
1203 		if (overflow) {
1204 			error_packet_set((char *)req->outbuf,
1205 					 ERRDOS,ERRbufferoverflow,
1206 					 STATUS_BUFFER_OVERFLOW,
1207 					 __LINE__,__FILE__);
1208 		} else if (NT_STATUS_V(status)) {
1209 			uint8_t eclass;
1210 			uint32_t ecode;
1211 			ntstatus_to_dos(status, &eclass, &ecode);
1212 			error_packet_set((char *)req->outbuf,
1213 					eclass, ecode, status,
1214 					__LINE__,__FILE__);
1215 		}
1216 
1217 		/* Send the packet */
1218 		show_msg((char *)req->outbuf);
1219 		if (!srv_send_smb(xconn,
1220 				(char *)req->outbuf,
1221 				true, req->seqnum+1,
1222 				IS_CONN_ENCRYPTED(conn),
1223 				&req->pcd))
1224 			exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
1225 
1226 		TALLOC_FREE(req->outbuf);
1227 
1228 		pp += params_sent_thistime;
1229 		pd += data_sent_thistime;
1230 
1231 		params_to_send -= params_sent_thistime;
1232 		data_to_send -= data_sent_thistime;
1233 
1234 		/* Sanity check */
1235 		if(params_to_send < 0 || data_to_send < 0) {
1236 			DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
1237 				params_to_send, data_to_send));
1238 			return;
1239 		}
1240 	}
1241 
1242 	return;
1243 }
1244 
1245 /****************************************************************************
1246  Reply to a TRANSACT2_OPEN.
1247 ****************************************************************************/
1248 
call_trans2open(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)1249 static void call_trans2open(connection_struct *conn,
1250 			    struct smb_request *req,
1251 			    char **pparams, int total_params,
1252 			    char **ppdata, int total_data,
1253 			    unsigned int max_data_bytes)
1254 {
1255 	struct smb_filename *smb_fname = NULL;
1256 	char *params = *pparams;
1257 	char *pdata = *ppdata;
1258 	int deny_mode;
1259 	int32_t open_attr;
1260 	bool oplock_request;
1261 #if 0
1262 	bool return_additional_info;
1263 	int16 open_sattr;
1264 	time_t open_time;
1265 #endif
1266 	int open_ofun;
1267 	uint32_t open_size;
1268 	char *pname;
1269 	char *fname = NULL;
1270 	off_t size=0;
1271 	int fattr=0,mtime=0;
1272 	SMB_INO_T inode = 0;
1273 	int smb_action = 0;
1274 	files_struct *fsp;
1275 	struct ea_list *ea_list = NULL;
1276 	uint16_t flags = 0;
1277 	NTSTATUS status;
1278 	uint32_t access_mask;
1279 	uint32_t share_mode;
1280 	uint32_t create_disposition;
1281 	uint32_t create_options = 0;
1282 	uint32_t private_flags = 0;
1283 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
1284 	TALLOC_CTX *ctx = talloc_tos();
1285 
1286 	/*
1287 	 * Ensure we have enough parameters to perform the operation.
1288 	 */
1289 
1290 	if (total_params < 29) {
1291 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1292 		goto out;
1293 	}
1294 
1295 	flags = SVAL(params, 0);
1296 	deny_mode = SVAL(params, 2);
1297 	open_attr = SVAL(params,6);
1298         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1299         if (oplock_request) {
1300                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1301         }
1302 
1303 #if 0
1304 	return_additional_info = BITSETW(params,0);
1305 	open_sattr = SVAL(params, 4);
1306 	open_time = make_unix_date3(params+8);
1307 #endif
1308 	open_ofun = SVAL(params,12);
1309 	open_size = IVAL(params,14);
1310 	pname = &params[28];
1311 
1312 	if (IS_IPC(conn)) {
1313 		reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
1314 		goto out;
1315 	}
1316 
1317 	if (req->posix_pathnames) {
1318 		srvstr_get_path_posix(ctx,
1319 			params,
1320 			req->flags2,
1321 			&fname,
1322 			pname,
1323 			total_params - 28,
1324 			STR_TERMINATE,
1325 			&status);
1326 	} else {
1327 		srvstr_get_path(ctx,
1328 			params,
1329 			req->flags2,
1330 			&fname,
1331 			pname,
1332 			total_params - 28,
1333 			STR_TERMINATE,
1334 			&status);
1335 	}
1336 	if (!NT_STATUS_IS_OK(status)) {
1337 		reply_nterror(req, status);
1338 		goto out;
1339 	}
1340 
1341 	DEBUG(3,("call_trans2open %s deny_mode=0x%x attr=%d ofun=0x%x size=%d\n",
1342 		fname, (unsigned int)deny_mode, (unsigned int)open_attr,
1343 		(unsigned int)open_ofun, open_size));
1344 
1345 	status = filename_convert(ctx,
1346 				conn,
1347 				fname,
1348 				ucf_flags,
1349 				NULL,
1350 				NULL,
1351 				&smb_fname);
1352 	if (!NT_STATUS_IS_OK(status)) {
1353 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1354 			reply_botherror(req,
1355 				NT_STATUS_PATH_NOT_COVERED,
1356 				ERRSRV, ERRbadpath);
1357 			goto out;
1358 		}
1359 		reply_nterror(req, status);
1360 		goto out;
1361 	}
1362 
1363 	if (open_ofun == 0) {
1364 		reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
1365 		goto out;
1366 	}
1367 
1368 	if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
1369 					 open_ofun,
1370 					 &access_mask, &share_mode,
1371 					 &create_disposition,
1372 					 &create_options,
1373 					 &private_flags)) {
1374 		reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1375 		goto out;
1376 	}
1377 
1378 	/* Any data in this call is an EA list. */
1379 	if (total_data && (total_data != 4)) {
1380 		if (total_data < 10) {
1381 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1382 			goto out;
1383 		}
1384 
1385 		if (IVAL(pdata,0) > total_data) {
1386 			DEBUG(10,("call_trans2open: bad total data size (%u) > %u\n",
1387 				IVAL(pdata,0), (unsigned int)total_data));
1388 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1389 			goto out;
1390 		}
1391 
1392 		ea_list = read_ea_list(talloc_tos(), pdata + 4,
1393 				       total_data - 4);
1394 		if (!ea_list) {
1395 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1396 			goto out;
1397 		}
1398 
1399 		if (!lp_ea_support(SNUM(conn))) {
1400 			reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1401 			goto out;
1402 		}
1403 
1404 		if (!req->posix_pathnames &&
1405 				ea_list_has_invalid_name(ea_list)) {
1406 			int param_len = 30;
1407 			*pparams = (char *)SMB_REALLOC(*pparams, param_len);
1408 			if(*pparams == NULL ) {
1409 				reply_nterror(req, NT_STATUS_NO_MEMORY);
1410 				goto out;
1411 			}
1412 			params = *pparams;
1413 			memset(params, '\0', param_len);
1414 			send_trans2_replies(conn, req, STATUS_INVALID_EA_NAME,
1415 				params, param_len, NULL, 0, max_data_bytes);
1416 			goto out;
1417 		}
1418 	}
1419 
1420 	status = SMB_VFS_CREATE_FILE(
1421 		conn,					/* conn */
1422 		req,					/* req */
1423 		0,					/* root_dir_fid */
1424 		smb_fname,				/* fname */
1425 		access_mask,				/* access_mask */
1426 		share_mode,				/* share_access */
1427 		create_disposition,			/* create_disposition*/
1428 		create_options,				/* create_options */
1429 		open_attr,				/* file_attributes */
1430 		oplock_request,				/* oplock_request */
1431 		NULL,					/* lease */
1432 		open_size,				/* allocation_size */
1433 		private_flags,
1434 		NULL,					/* sd */
1435 		ea_list,				/* ea_list */
1436 		&fsp,					/* result */
1437 		&smb_action,				/* psbuf */
1438 		NULL, NULL);				/* create context */
1439 
1440 	if (!NT_STATUS_IS_OK(status)) {
1441 		if (open_was_deferred(req->xconn, req->mid)) {
1442 			/* We have re-scheduled this call. */
1443 			goto out;
1444 		}
1445 
1446 		if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
1447 			reply_openerror(req, status);
1448 			goto out;
1449 		}
1450 
1451 		fsp = fcb_or_dos_open(
1452 			req,
1453 			smb_fname,
1454 			access_mask,
1455 			create_options,
1456 			private_flags);
1457 		if (fsp == NULL) {
1458 			bool ok = defer_smb1_sharing_violation(req);
1459 			if (ok) {
1460 				goto out;
1461 			}
1462 			reply_openerror(req, status);
1463 			goto out;
1464 		}
1465 
1466 		smb_action = FILE_WAS_OPENED;
1467 	}
1468 
1469 	size = get_file_size_stat(&smb_fname->st);
1470 	fattr = dos_mode(conn, smb_fname);
1471 	mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
1472 	inode = smb_fname->st.st_ex_ino;
1473 	if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
1474 		close_file(req, fsp, ERROR_CLOSE);
1475 		reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1476 		goto out;
1477 	}
1478 
1479 	/* Realloc the size of parameters and data we will return */
1480 	*pparams = (char *)SMB_REALLOC(*pparams, 30);
1481 	if(*pparams == NULL ) {
1482 		reply_nterror(req, NT_STATUS_NO_MEMORY);
1483 		goto out;
1484 	}
1485 	params = *pparams;
1486 
1487 	SSVAL(params,0,fsp->fnum);
1488 	SSVAL(params,2,fattr);
1489 	srv_put_dos_date2(params,4, mtime);
1490 	SIVAL(params,8, (uint32_t)size);
1491 	SSVAL(params,12,deny_mode);
1492 	SSVAL(params,14,0); /* open_type - file or directory. */
1493 	SSVAL(params,16,0); /* open_state - only valid for IPC device. */
1494 
1495 	if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
1496 		smb_action |= EXTENDED_OPLOCK_GRANTED;
1497 	}
1498 
1499 	SSVAL(params,18,smb_action);
1500 
1501 	/*
1502 	 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
1503 	 */
1504 	SIVAL(params,20,inode);
1505 	SSVAL(params,24,0); /* Padding. */
1506 	if (flags & 8) {
1507 		uint32_t ea_size = estimate_ea_size(conn, fsp,
1508 						  smb_fname);
1509 		SIVAL(params, 26, ea_size);
1510 	} else {
1511 		SIVAL(params, 26, 0);
1512 	}
1513 
1514 	/* Send the required number of replies */
1515 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 30, *ppdata, 0, max_data_bytes);
1516  out:
1517 	TALLOC_FREE(smb_fname);
1518 }
1519 
1520 /*********************************************************
1521  Routine to check if a given string matches exactly.
1522  as a special case a mask of "." does NOT match. That
1523  is required for correct wildcard semantics
1524  Case can be significant or not.
1525 **********************************************************/
1526 
exact_match(bool has_wild,bool case_sensitive,const char * str,const char * mask)1527 static bool exact_match(bool has_wild,
1528 			bool case_sensitive,
1529 			const char *str,
1530 			const char *mask)
1531 {
1532 	if (mask[0] == '.' && mask[1] == 0) {
1533 		return false;
1534 	}
1535 
1536 	if (has_wild) {
1537 		return false;
1538 	}
1539 
1540 	if (case_sensitive) {
1541 		return strcmp(str,mask)==0;
1542 	} else {
1543 		return strcasecmp_m(str,mask) == 0;
1544 	}
1545 }
1546 
1547 /****************************************************************************
1548  Return the filetype for UNIX extensions.
1549 ****************************************************************************/
1550 
unix_filetype(mode_t mode)1551 static uint32_t unix_filetype(mode_t mode)
1552 {
1553 	if(S_ISREG(mode))
1554 		return UNIX_TYPE_FILE;
1555 	else if(S_ISDIR(mode))
1556 		return UNIX_TYPE_DIR;
1557 #ifdef S_ISLNK
1558 	else if(S_ISLNK(mode))
1559 		return UNIX_TYPE_SYMLINK;
1560 #endif
1561 #ifdef S_ISCHR
1562 	else if(S_ISCHR(mode))
1563 		return UNIX_TYPE_CHARDEV;
1564 #endif
1565 #ifdef S_ISBLK
1566 	else if(S_ISBLK(mode))
1567 		return UNIX_TYPE_BLKDEV;
1568 #endif
1569 #ifdef S_ISFIFO
1570 	else if(S_ISFIFO(mode))
1571 		return UNIX_TYPE_FIFO;
1572 #endif
1573 #ifdef S_ISSOCK
1574 	else if(S_ISSOCK(mode))
1575 		return UNIX_TYPE_SOCKET;
1576 #endif
1577 
1578 	DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
1579 	return UNIX_TYPE_UNKNOWN;
1580 }
1581 
1582 /****************************************************************************
1583  Map wire perms onto standard UNIX permissions. Obey share restrictions.
1584 ****************************************************************************/
1585 
1586 enum perm_type { PERM_NEW_FILE, PERM_NEW_DIR, PERM_EXISTING_FILE, PERM_EXISTING_DIR};
1587 
unix_perms_from_wire(connection_struct * conn,const SMB_STRUCT_STAT * psbuf,uint32_t perms,enum perm_type ptype,mode_t * ret_perms)1588 static NTSTATUS unix_perms_from_wire( connection_struct *conn,
1589 				const SMB_STRUCT_STAT *psbuf,
1590 				uint32_t perms,
1591 				enum perm_type ptype,
1592 				mode_t *ret_perms)
1593 {
1594 	mode_t ret = 0;
1595 
1596 	if (perms == SMB_MODE_NO_CHANGE) {
1597 		if (!VALID_STAT(*psbuf)) {
1598 			return NT_STATUS_INVALID_PARAMETER;
1599 		} else {
1600 			*ret_perms = psbuf->st_ex_mode;
1601 			return NT_STATUS_OK;
1602 		}
1603 	}
1604 
1605 	ret = wire_perms_to_unix(perms);
1606 
1607 	if (ptype == PERM_NEW_FILE) {
1608 		/*
1609 		 * "create mask"/"force create mode" are
1610 		 * only applied to new files, not existing ones.
1611 		 */
1612 		ret &= lp_create_mask(SNUM(conn));
1613 		/* Add in force bits */
1614 		ret |= lp_force_create_mode(SNUM(conn));
1615 	} else if (ptype == PERM_NEW_DIR) {
1616 		/*
1617 		 * "directory mask"/"force directory mode" are
1618 		 * only applied to new directories, not existing ones.
1619 		 */
1620 		ret &= lp_directory_mask(SNUM(conn));
1621 		/* Add in force bits */
1622 		ret |= lp_force_directory_mode(SNUM(conn));
1623 	}
1624 
1625 	*ret_perms = ret;
1626 	return NT_STATUS_OK;
1627 }
1628 
1629 /****************************************************************************
1630  Needed to show the msdfs symlinks as directories. Modifies psbuf
1631  to be a directory if it's a msdfs link.
1632 ****************************************************************************/
1633 
check_msdfs_link(connection_struct * conn,struct smb_filename * smb_fname)1634 static bool check_msdfs_link(connection_struct *conn,
1635 				struct smb_filename *smb_fname)
1636 {
1637 	int saved_errno = errno;
1638 	if(lp_host_msdfs() &&
1639 		lp_msdfs_root(SNUM(conn)) &&
1640 		is_msdfs_link(conn, smb_fname)) {
1641 
1642 		DEBUG(5,("check_msdfs_link: Masquerading msdfs link %s "
1643 			"as a directory\n",
1644 			smb_fname->base_name));
1645 		smb_fname->st.st_ex_mode =
1646 			(smb_fname->st.st_ex_mode & 0xFFF) | S_IFDIR;
1647 		errno = saved_errno;
1648 		return true;
1649 	}
1650 	errno = saved_errno;
1651 	return false;
1652 }
1653 
1654 
1655 /****************************************************************************
1656  Get a level dependent lanman2 dir entry.
1657 ****************************************************************************/
1658 
1659 struct smbd_dirptr_lanman2_state {
1660 	connection_struct *conn;
1661 	uint32_t info_level;
1662 	bool check_mangled_names;
1663 	bool has_wild;
1664 	bool got_exact_match;
1665 };
1666 
smbd_dirptr_lanman2_match_fn(TALLOC_CTX * ctx,void * private_data,const char * dname,const char * mask,char ** _fname)1667 static bool smbd_dirptr_lanman2_match_fn(TALLOC_CTX *ctx,
1668 					 void *private_data,
1669 					 const char *dname,
1670 					 const char *mask,
1671 					 char **_fname)
1672 {
1673 	struct smbd_dirptr_lanman2_state *state =
1674 		(struct smbd_dirptr_lanman2_state *)private_data;
1675 	bool ok;
1676 	char mangled_name[13]; /* mangled 8.3 name. */
1677 	bool got_match;
1678 	const char *fname;
1679 
1680 	/* Mangle fname if it's an illegal name. */
1681 	if (mangle_must_mangle(dname, state->conn->params)) {
1682 		/*
1683 		 * Slow path - ensure we can push the original name as UCS2. If
1684 		 * not, then just don't return this name.
1685 		 */
1686 		NTSTATUS status;
1687 		size_t ret_len = 0;
1688 		size_t len = (strlen(dname) + 2) * 4; /* Allow enough space. */
1689 		uint8_t *tmp = talloc_array(talloc_tos(),
1690 					uint8_t,
1691 					len);
1692 
1693 		status = srvstr_push(NULL,
1694 			FLAGS2_UNICODE_STRINGS,
1695 			tmp,
1696 			dname,
1697 			len,
1698 			STR_TERMINATE,
1699 			&ret_len);
1700 
1701 		TALLOC_FREE(tmp);
1702 
1703 		if (!NT_STATUS_IS_OK(status)) {
1704 			return false;
1705 		}
1706 
1707 		ok = name_to_8_3(dname, mangled_name,
1708 				 true, state->conn->params);
1709 		if (!ok) {
1710 			return false;
1711 		}
1712 		fname = mangled_name;
1713 	} else {
1714 		fname = dname;
1715 	}
1716 
1717 	got_match = exact_match(state->has_wild,
1718 				state->conn->case_sensitive,
1719 				fname, mask);
1720 	state->got_exact_match = got_match;
1721 	if (!got_match) {
1722 		got_match = mask_match(fname, mask,
1723 				       state->conn->case_sensitive);
1724 	}
1725 
1726 	if(!got_match && state->check_mangled_names &&
1727 	   !mangle_is_8_3(fname, false, state->conn->params)) {
1728 		/*
1729 		 * It turns out that NT matches wildcards against
1730 		 * both long *and* short names. This may explain some
1731 		 * of the wildcard wierdness from old DOS clients
1732 		 * that some people have been seeing.... JRA.
1733 		 */
1734 		/* Force the mangling into 8.3. */
1735 		ok = name_to_8_3(fname, mangled_name,
1736 				 false, state->conn->params);
1737 		if (!ok) {
1738 			return false;
1739 		}
1740 
1741 		got_match = exact_match(state->has_wild,
1742 					state->conn->case_sensitive,
1743 					mangled_name, mask);
1744 		state->got_exact_match = got_match;
1745 		if (!got_match) {
1746 			got_match = mask_match(mangled_name, mask,
1747 					       state->conn->case_sensitive);
1748 		}
1749 	}
1750 
1751 	if (!got_match) {
1752 		return false;
1753 	}
1754 
1755 	*_fname = talloc_strdup(ctx, fname);
1756 	if (*_fname == NULL) {
1757 		return false;
1758 	}
1759 
1760 	return true;
1761 }
1762 
smbd_dirptr_lanman2_mode_fn(TALLOC_CTX * ctx,void * private_data,struct smb_filename * smb_fname,bool get_dosmode,uint32_t * _mode)1763 static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
1764 					void *private_data,
1765 					struct smb_filename *smb_fname,
1766 					bool get_dosmode,
1767 					uint32_t *_mode)
1768 {
1769 	struct smbd_dirptr_lanman2_state *state =
1770 		(struct smbd_dirptr_lanman2_state *)private_data;
1771 	bool ms_dfs_link = false;
1772 	uint32_t mode = 0;
1773 
1774 	if (INFO_LEVEL_IS_UNIX(state->info_level)) {
1775 		if (SMB_VFS_LSTAT(state->conn, smb_fname) != 0) {
1776 			DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1777 				 "Couldn't lstat [%s] (%s)\n",
1778 				 smb_fname_str_dbg(smb_fname),
1779 				 strerror(errno)));
1780 			return false;
1781 		}
1782 	} else if (!VALID_STAT(smb_fname->st) &&
1783 		   SMB_VFS_STAT(state->conn, smb_fname) != 0) {
1784 		/* Needed to show the msdfs symlinks as
1785 		 * directories */
1786 
1787 		ms_dfs_link = check_msdfs_link(state->conn,
1788 					       smb_fname);
1789 		if (!ms_dfs_link) {
1790 			DEBUG(5,("smbd_dirptr_lanman2_mode_fn: "
1791 				 "Couldn't stat [%s] (%s)\n",
1792 				 smb_fname_str_dbg(smb_fname),
1793 				 strerror(errno)));
1794 			return false;
1795 		}
1796 	}
1797 
1798 	if (ms_dfs_link) {
1799 		mode = dos_mode_msdfs(state->conn, smb_fname);
1800 	} else if (get_dosmode) {
1801 		mode = dos_mode(state->conn, smb_fname);
1802 	}
1803 
1804 	*_mode = mode;
1805 	return true;
1806 }
1807 
smbd_marshall_dir_entry(TALLOC_CTX * ctx,connection_struct * conn,uint16_t flags2,uint32_t info_level,struct ea_list * name_list,bool check_mangled_names,bool requires_resume_key,uint32_t mode,const char * fname,const struct smb_filename * smb_fname,int space_remaining,uint8_t align,bool do_pad,char * base_data,char ** ppdata,char * end_data,uint64_t * last_entry_off)1808 static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
1809 				    connection_struct *conn,
1810 				    uint16_t flags2,
1811 				    uint32_t info_level,
1812 				    struct ea_list *name_list,
1813 				    bool check_mangled_names,
1814 				    bool requires_resume_key,
1815 				    uint32_t mode,
1816 				    const char *fname,
1817 				    const struct smb_filename *smb_fname,
1818 				    int space_remaining,
1819 				    uint8_t align,
1820 				    bool do_pad,
1821 				    char *base_data,
1822 				    char **ppdata,
1823 				    char *end_data,
1824 				    uint64_t *last_entry_off)
1825 {
1826 	char *p, *q, *pdata = *ppdata;
1827 	uint32_t reskey=0;
1828 	uint64_t file_size = 0;
1829 	uint64_t allocation_size = 0;
1830 	uint64_t file_id = 0;
1831 	size_t len = 0;
1832 	struct timespec mdate_ts = {0};
1833 	struct timespec adate_ts = {0};
1834 	struct timespec cdate_ts = {0};
1835 	struct timespec create_date_ts = {0};
1836 	time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
1837 	char *nameptr;
1838 	char *last_entry_ptr;
1839 	bool was_8_3;
1840 	int off;
1841 	int pad = 0;
1842 	NTSTATUS status;
1843 	struct readdir_attr_data *readdir_attr_data = NULL;
1844 
1845 	if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
1846 		file_size = get_file_size_stat(&smb_fname->st);
1847 	}
1848 	allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
1849 
1850 	status = SMB_VFS_READDIR_ATTR(conn, smb_fname, ctx, &readdir_attr_data);
1851 	if (!NT_STATUS_IS_OK(status)) {
1852 		if (!NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED, status)) {
1853 			return status;
1854 		}
1855 	}
1856 
1857 	file_id = SMB_VFS_FS_FILE_ID(conn, &smb_fname->st);
1858 
1859 	mdate_ts = smb_fname->st.st_ex_mtime;
1860 	adate_ts = smb_fname->st.st_ex_atime;
1861 	create_date_ts = get_create_timespec(conn, NULL, smb_fname);
1862 	cdate_ts = get_change_timespec(conn, NULL, smb_fname);
1863 
1864 	if (lp_dos_filetime_resolution(SNUM(conn))) {
1865 		dos_filetime_timespec(&create_date_ts);
1866 		dos_filetime_timespec(&mdate_ts);
1867 		dos_filetime_timespec(&adate_ts);
1868 		dos_filetime_timespec(&cdate_ts);
1869 	}
1870 
1871 	create_date = convert_timespec_to_time_t(create_date_ts);
1872 	mdate = convert_timespec_to_time_t(mdate_ts);
1873 	adate = convert_timespec_to_time_t(adate_ts);
1874 
1875 	/* align the record */
1876 	SMB_ASSERT(align >= 1);
1877 
1878 	off = (int)PTR_DIFF(pdata, base_data);
1879 	pad = (off + (align-1)) & ~(align-1);
1880 	pad -= off;
1881 
1882 	if (pad && pad > space_remaining) {
1883 		DEBUG(9,("smbd_marshall_dir_entry: out of space "
1884 			"for padding (wanted %u, had %d)\n",
1885 			(unsigned int)pad,
1886 			space_remaining ));
1887 		return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
1888 	}
1889 
1890 	off += pad;
1891 	/* initialize padding to 0 */
1892 	if (pad) {
1893 		memset(pdata, 0, pad);
1894 	}
1895 	space_remaining -= pad;
1896 
1897 	DEBUG(10,("smbd_marshall_dir_entry: space_remaining = %d\n",
1898 		space_remaining ));
1899 
1900 	pdata += pad;
1901 	p = pdata;
1902 	last_entry_ptr = p;
1903 
1904 	pad = 0;
1905 	off = 0;
1906 
1907 	switch (info_level) {
1908 	case SMB_FIND_INFO_STANDARD:
1909 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
1910 		if(requires_resume_key) {
1911 			SIVAL(p,0,reskey);
1912 			p += 4;
1913 		}
1914 		srv_put_dos_date2(p,0,create_date);
1915 		srv_put_dos_date2(p,4,adate);
1916 		srv_put_dos_date2(p,8,mdate);
1917 		SIVAL(p,12,(uint32_t)file_size);
1918 		SIVAL(p,16,(uint32_t)allocation_size);
1919 		SSVAL(p,20,mode);
1920 		p += 23;
1921 		nameptr = p;
1922 		if (flags2 & FLAGS2_UNICODE_STRINGS) {
1923 			p += ucs2_align(base_data, p, 0);
1924 		}
1925 		status = srvstr_push(base_data, flags2, p,
1926 				  fname, PTR_DIFF(end_data, p),
1927 				  STR_TERMINATE, &len);
1928 		if (!NT_STATUS_IS_OK(status)) {
1929 			return status;
1930 		}
1931 		if (flags2 & FLAGS2_UNICODE_STRINGS) {
1932 			if (len > 2) {
1933 				SCVAL(nameptr, -1, len - 2);
1934 			} else {
1935 				SCVAL(nameptr, -1, 0);
1936 			}
1937 		} else {
1938 			if (len > 1) {
1939 				SCVAL(nameptr, -1, len - 1);
1940 			} else {
1941 				SCVAL(nameptr, -1, 0);
1942 			}
1943 		}
1944 		p += len;
1945 		break;
1946 
1947 	case SMB_FIND_EA_SIZE:
1948 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
1949 		if (requires_resume_key) {
1950 			SIVAL(p,0,reskey);
1951 			p += 4;
1952 		}
1953 		srv_put_dos_date2(p,0,create_date);
1954 		srv_put_dos_date2(p,4,adate);
1955 		srv_put_dos_date2(p,8,mdate);
1956 		SIVAL(p,12,(uint32_t)file_size);
1957 		SIVAL(p,16,(uint32_t)allocation_size);
1958 		SSVAL(p,20,mode);
1959 		{
1960 			unsigned int ea_size = estimate_ea_size(conn, NULL,
1961 								smb_fname);
1962 			SIVAL(p,22,ea_size); /* Extended attributes */
1963 		}
1964 		p += 27;
1965 		nameptr = p - 1;
1966 		status = srvstr_push(base_data, flags2,
1967 				  p, fname, PTR_DIFF(end_data, p),
1968 				  STR_TERMINATE | STR_NOALIGN, &len);
1969 		if (!NT_STATUS_IS_OK(status)) {
1970 			return status;
1971 		}
1972 		if (flags2 & FLAGS2_UNICODE_STRINGS) {
1973 			if (len > 2) {
1974 				len -= 2;
1975 			} else {
1976 				len = 0;
1977 			}
1978 		} else {
1979 			if (len > 1) {
1980 				len -= 1;
1981 			} else {
1982 				len = 0;
1983 			}
1984 		}
1985 		SCVAL(nameptr,0,len);
1986 		p += len;
1987 		SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
1988 		break;
1989 
1990 	case SMB_FIND_EA_LIST:
1991 	{
1992 		struct ea_list *file_list = NULL;
1993 		size_t ea_len = 0;
1994 
1995 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
1996 		if (!name_list) {
1997 			return NT_STATUS_INVALID_PARAMETER;
1998 		}
1999 		if (requires_resume_key) {
2000 			SIVAL(p,0,reskey);
2001 			p += 4;
2002 		}
2003 		srv_put_dos_date2(p,0,create_date);
2004 		srv_put_dos_date2(p,4,adate);
2005 		srv_put_dos_date2(p,8,mdate);
2006 		SIVAL(p,12,(uint32_t)file_size);
2007 		SIVAL(p,16,(uint32_t)allocation_size);
2008 		SSVAL(p,20,mode);
2009 		p += 22; /* p now points to the EA area. */
2010 
2011 		status = get_ea_list_from_file(ctx, conn, NULL,
2012 					       smb_fname,
2013 					       &ea_len, &file_list);
2014 		if (!NT_STATUS_IS_OK(status)) {
2015 			file_list = NULL;
2016 		}
2017 		name_list = ea_list_union(name_list, file_list, &ea_len);
2018 
2019 		/* We need to determine if this entry will fit in the space available. */
2020 		/* Max string size is 255 bytes. */
2021 		if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
2022 			DEBUG(9,("smbd_marshall_dir_entry: out of space "
2023 				"(wanted %u, had %d)\n",
2024 				(unsigned int)PTR_DIFF(p + 255 + ea_len,pdata),
2025 				space_remaining ));
2026 			return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
2027 		}
2028 
2029 		/* Push the ea_data followed by the name. */
2030 		p += fill_ea_buffer(ctx, p, space_remaining, conn, name_list);
2031 		nameptr = p;
2032 		status = srvstr_push(base_data, flags2,
2033 				  p + 1, fname, PTR_DIFF(end_data, p+1),
2034 				  STR_TERMINATE | STR_NOALIGN, &len);
2035 		if (!NT_STATUS_IS_OK(status)) {
2036 			return status;
2037 		}
2038 		if (flags2 & FLAGS2_UNICODE_STRINGS) {
2039 			if (len > 2) {
2040 				len -= 2;
2041 			} else {
2042 				len = 0;
2043 			}
2044 		} else {
2045 			if (len > 1) {
2046 				len -= 1;
2047 			} else {
2048 				len = 0;
2049 			}
2050 		}
2051 		SCVAL(nameptr,0,len);
2052 		p += len + 1;
2053 		SCVAL(p,0,0); p += 1; /* Extra zero byte ? - why.. */
2054 		break;
2055 	}
2056 
2057 	case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2058 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
2059 		was_8_3 = mangle_is_8_3(fname, True, conn->params);
2060 		p += 4;
2061 		SIVAL(p,0,reskey); p += 4;
2062 		put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2063 		put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2064 		put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2065 		put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2066 		SOFF_T(p,0,file_size); p += 8;
2067 		SOFF_T(p,0,allocation_size); p += 8;
2068 		SIVAL(p,0,mode); p += 4;
2069 		q = p; p += 4; /* q is placeholder for name length. */
2070 		if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2071 			SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2072 		} else {
2073 			unsigned int ea_size = estimate_ea_size(conn, NULL,
2074 								smb_fname);
2075 			SIVAL(p,0,ea_size); /* Extended attributes */
2076 		}
2077 		p += 4;
2078 		/* Clear the short name buffer. This is
2079 		 * IMPORTANT as not doing so will trigger
2080 		 * a Win2k client bug. JRA.
2081 		 */
2082 		if (!was_8_3 && check_mangled_names) {
2083 			char mangled_name[13]; /* mangled 8.3 name. */
2084 			if (!name_to_8_3(fname,mangled_name,True,
2085 					   conn->params)) {
2086 				/* Error - mangle failed ! */
2087 				memset(mangled_name,'\0',12);
2088 			}
2089 			mangled_name[12] = 0;
2090 			status = srvstr_push(base_data, flags2,
2091 					  p+2, mangled_name, 24,
2092 					  STR_UPPER|STR_UNICODE, &len);
2093 			if (!NT_STATUS_IS_OK(status)) {
2094 				return status;
2095 			}
2096 			if (len < 24) {
2097 				memset(p + 2 + len,'\0',24 - len);
2098 			}
2099 			SSVAL(p, 0, len);
2100 		} else {
2101 			memset(p,'\0',26);
2102 		}
2103 		p += 2 + 24;
2104 		status = srvstr_push(base_data, flags2, p,
2105 				  fname, PTR_DIFF(end_data, p),
2106 				  STR_TERMINATE_ASCII, &len);
2107 		if (!NT_STATUS_IS_OK(status)) {
2108 			return status;
2109 		}
2110 		SIVAL(q,0,len);
2111 		p += len;
2112 
2113 		len = PTR_DIFF(p, pdata);
2114 		pad = (len + (align-1)) & ~(align-1);
2115 		/*
2116 		 * offset to the next entry, the caller
2117 		 * will overwrite it for the last entry
2118 		 * that's why we always include the padding
2119 		 */
2120 		SIVAL(pdata,0,pad);
2121 		/*
2122 		 * set padding to zero
2123 		 */
2124 		if (do_pad) {
2125 			memset(p, 0, pad - len);
2126 			p = pdata + pad;
2127 		} else {
2128 			p = pdata + len;
2129 		}
2130 		break;
2131 
2132 	case SMB_FIND_FILE_DIRECTORY_INFO:
2133 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
2134 		p += 4;
2135 		SIVAL(p,0,reskey); p += 4;
2136 		put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2137 		put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2138 		put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2139 		put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2140 		SOFF_T(p,0,file_size); p += 8;
2141 		SOFF_T(p,0,allocation_size); p += 8;
2142 		SIVAL(p,0,mode); p += 4;
2143 		status = srvstr_push(base_data, flags2,
2144 				  p + 4, fname, PTR_DIFF(end_data, p+4),
2145 				  STR_TERMINATE_ASCII, &len);
2146 		if (!NT_STATUS_IS_OK(status)) {
2147 			return status;
2148 		}
2149 		SIVAL(p,0,len);
2150 		p += 4 + len;
2151 
2152 		len = PTR_DIFF(p, pdata);
2153 		pad = (len + (align-1)) & ~(align-1);
2154 		/*
2155 		 * offset to the next entry, the caller
2156 		 * will overwrite it for the last entry
2157 		 * that's why we always include the padding
2158 		 */
2159 		SIVAL(pdata,0,pad);
2160 		/*
2161 		 * set padding to zero
2162 		 */
2163 		if (do_pad) {
2164 			memset(p, 0, pad - len);
2165 			p = pdata + pad;
2166 		} else {
2167 			p = pdata + len;
2168 		}
2169 		break;
2170 
2171 	case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2172 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
2173 		p += 4;
2174 		SIVAL(p,0,reskey); p += 4;
2175 		put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2176 		put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2177 		put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2178 		put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2179 		SOFF_T(p,0,file_size); p += 8;
2180 		SOFF_T(p,0,allocation_size); p += 8;
2181 		SIVAL(p,0,mode); p += 4;
2182 		q = p; p += 4; /* q is placeholder for name length. */
2183 		if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2184 			SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2185 		} else {
2186 			unsigned int ea_size = estimate_ea_size(conn, NULL,
2187 								smb_fname);
2188 			SIVAL(p,0,ea_size); /* Extended attributes */
2189 		}
2190 		p +=4;
2191 		status = srvstr_push(base_data, flags2, p,
2192 				  fname, PTR_DIFF(end_data, p),
2193 				  STR_TERMINATE_ASCII, &len);
2194 		if (!NT_STATUS_IS_OK(status)) {
2195 			return status;
2196 		}
2197 		SIVAL(q, 0, len);
2198 		p += len;
2199 
2200 		len = PTR_DIFF(p, pdata);
2201 		pad = (len + (align-1)) & ~(align-1);
2202 		/*
2203 		 * offset to the next entry, the caller
2204 		 * will overwrite it for the last entry
2205 		 * that's why we always include the padding
2206 		 */
2207 		SIVAL(pdata,0,pad);
2208 		/*
2209 		 * set padding to zero
2210 		 */
2211 		if (do_pad) {
2212 			memset(p, 0, pad - len);
2213 			p = pdata + pad;
2214 		} else {
2215 			p = pdata + len;
2216 		}
2217 		break;
2218 
2219 	case SMB_FIND_FILE_NAMES_INFO:
2220 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
2221 		p += 4;
2222 		SIVAL(p,0,reskey); p += 4;
2223 		p += 4;
2224 		/* this must *not* be null terminated or w2k gets in a loop trying to set an
2225 		   acl on a dir (tridge) */
2226 		status = srvstr_push(base_data, flags2, p,
2227 				  fname, PTR_DIFF(end_data, p),
2228 				  STR_TERMINATE_ASCII, &len);
2229 		if (!NT_STATUS_IS_OK(status)) {
2230 			return status;
2231 		}
2232 		SIVAL(p, -4, len);
2233 		p += len;
2234 
2235 		len = PTR_DIFF(p, pdata);
2236 		pad = (len + (align-1)) & ~(align-1);
2237 		/*
2238 		 * offset to the next entry, the caller
2239 		 * will overwrite it for the last entry
2240 		 * that's why we always include the padding
2241 		 */
2242 		SIVAL(pdata,0,pad);
2243 		/*
2244 		 * set padding to zero
2245 		 */
2246 		if (do_pad) {
2247 			memset(p, 0, pad - len);
2248 			p = pdata + pad;
2249 		} else {
2250 			p = pdata + len;
2251 		}
2252 		break;
2253 
2254 	case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2255 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
2256 		p += 4;
2257 		SIVAL(p,0,reskey); p += 4;
2258 		put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2259 		put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2260 		put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2261 		put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2262 		SOFF_T(p,0,file_size); p += 8;
2263 		SOFF_T(p,0,allocation_size); p += 8;
2264 		SIVAL(p,0,mode); p += 4;
2265 		q = p; p += 4; /* q is placeholder for name length. */
2266 		if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2267 			SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2268 		} else {
2269 			unsigned int ea_size = estimate_ea_size(conn, NULL,
2270 								smb_fname);
2271 			SIVAL(p,0,ea_size); /* Extended attributes */
2272 		}
2273 		p += 4;
2274 		SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
2275 		SBVAL(p,0,file_id); p += 8;
2276 		status = srvstr_push(base_data, flags2, p,
2277 				  fname, PTR_DIFF(end_data, p),
2278 				  STR_TERMINATE_ASCII, &len);
2279 		if (!NT_STATUS_IS_OK(status)) {
2280 			return status;
2281 		}
2282 		SIVAL(q, 0, len);
2283 		p += len;
2284 
2285 		len = PTR_DIFF(p, pdata);
2286 		pad = (len + (align-1)) & ~(align-1);
2287 		/*
2288 		 * offset to the next entry, the caller
2289 		 * will overwrite it for the last entry
2290 		 * that's why we always include the padding
2291 		 */
2292 		SIVAL(pdata,0,pad);
2293 		/*
2294 		 * set padding to zero
2295 		 */
2296 		if (do_pad) {
2297 			memset(p, 0, pad - len);
2298 			p = pdata + pad;
2299 		} else {
2300 			p = pdata + len;
2301 		}
2302 		break;
2303 
2304 	case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2305 		DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
2306 		was_8_3 = mangle_is_8_3(fname, True, conn->params);
2307 		p += 4;
2308 		SIVAL(p,0,reskey); p += 4;
2309 		put_long_date_full_timespec(conn->ts_res,p,&create_date_ts); p += 8;
2310 		put_long_date_full_timespec(conn->ts_res,p,&adate_ts); p += 8;
2311 		put_long_date_full_timespec(conn->ts_res,p,&mdate_ts); p += 8;
2312 		put_long_date_full_timespec(conn->ts_res,p,&cdate_ts); p += 8;
2313 		SOFF_T(p,0,file_size); p += 8;
2314 		SOFF_T(p,0,allocation_size); p += 8;
2315 		SIVAL(p,0,mode); p += 4;
2316 		q = p; p += 4; /* q is placeholder for name length */
2317 		if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
2318 			SIVAL(p, 0, IO_REPARSE_TAG_DFS);
2319 		} else if (readdir_attr_data &&
2320 			   readdir_attr_data->type == RDATTR_AAPL) {
2321 			/*
2322 			 * OS X specific SMB2 extension negotiated via
2323 			 * AAPL create context: return max_access in
2324 			 * ea_size field.
2325 			 */
2326 			SIVAL(p, 0, readdir_attr_data->attr_data.aapl.max_access);
2327 		} else {
2328 			unsigned int ea_size = estimate_ea_size(conn, NULL,
2329 								smb_fname);
2330 			SIVAL(p,0,ea_size); /* Extended attributes */
2331 		}
2332 		p += 4;
2333 
2334 		if (readdir_attr_data &&
2335 		    readdir_attr_data->type == RDATTR_AAPL) {
2336 			/*
2337 			 * OS X specific SMB2 extension negotiated via
2338 			 * AAPL create context: return resource fork
2339 			 * length and compressed FinderInfo in
2340 			 * shortname field.
2341 			 *
2342 			 * According to documentation short_name_len
2343 			 * should be 0, but on the wire behaviour
2344 			 * shows its set to 24 by clients.
2345 			 */
2346 			SSVAL(p, 0, 24);
2347 
2348 			/* Resourefork length */
2349 			SBVAL(p, 2, readdir_attr_data->attr_data.aapl.rfork_size);
2350 
2351 			/* Compressed FinderInfo */
2352 			memcpy(p + 10, &readdir_attr_data->attr_data.aapl.finder_info, 16);
2353 		} else if (!was_8_3 && check_mangled_names) {
2354 			char mangled_name[13]; /* mangled 8.3 name. */
2355 			if (!name_to_8_3(fname,mangled_name,True,
2356 					conn->params)) {
2357 				/* Error - mangle failed ! */
2358 				memset(mangled_name,'\0',12);
2359 			}
2360 			mangled_name[12] = 0;
2361 			status = srvstr_push(base_data, flags2,
2362 					  p+2, mangled_name, 24,
2363 					  STR_UPPER|STR_UNICODE, &len);
2364 			if (!NT_STATUS_IS_OK(status)) {
2365 				return status;
2366 			}
2367 			SSVAL(p, 0, len);
2368 			if (len < 24) {
2369 				memset(p + 2 + len,'\0',24 - len);
2370 			}
2371 			SSVAL(p, 0, len);
2372 		} else {
2373 			/* Clear the short name buffer. This is
2374 			 * IMPORTANT as not doing so will trigger
2375 			 * a Win2k client bug. JRA.
2376 			 */
2377 			memset(p,'\0',26);
2378 		}
2379 		p += 26;
2380 
2381 		/* Reserved ? */
2382 		if (readdir_attr_data &&
2383 		    readdir_attr_data->type == RDATTR_AAPL) {
2384 			/*
2385 			 * OS X specific SMB2 extension negotiated via
2386 			 * AAPL create context: return UNIX mode in
2387 			 * reserved field.
2388 			 */
2389 			uint16_t aapl_mode = (uint16_t)readdir_attr_data->attr_data.aapl.unix_mode;
2390 			SSVAL(p, 0, aapl_mode);
2391 		} else {
2392 			SSVAL(p, 0, 0);
2393 		}
2394 		p += 2;
2395 
2396 		SBVAL(p,0,file_id); p += 8;
2397 		status = srvstr_push(base_data, flags2, p,
2398 				  fname, PTR_DIFF(end_data, p),
2399 				  STR_TERMINATE_ASCII, &len);
2400 		if (!NT_STATUS_IS_OK(status)) {
2401 			return status;
2402 		}
2403 		SIVAL(q,0,len);
2404 		p += len;
2405 
2406 		len = PTR_DIFF(p, pdata);
2407 		pad = (len + (align-1)) & ~(align-1);
2408 		/*
2409 		 * offset to the next entry, the caller
2410 		 * will overwrite it for the last entry
2411 		 * that's why we always include the padding
2412 		 */
2413 		SIVAL(pdata,0,pad);
2414 		/*
2415 		 * set padding to zero
2416 		 */
2417 		if (do_pad) {
2418 			memset(p, 0, pad - len);
2419 			p = pdata + pad;
2420 		} else {
2421 			p = pdata + len;
2422 		}
2423 		break;
2424 
2425 	/* CIFS UNIX Extension. */
2426 
2427 	case SMB_FIND_FILE_UNIX:
2428 	case SMB_FIND_FILE_UNIX_INFO2:
2429 		p+= 4;
2430 		SIVAL(p,0,reskey); p+= 4;    /* Used for continuing search. */
2431 
2432 		/* Begin of SMB_QUERY_FILE_UNIX_BASIC */
2433 
2434 		if (info_level == SMB_FIND_FILE_UNIX) {
2435 			DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
2436 			p = store_file_unix_basic(conn, p,
2437 						NULL, &smb_fname->st);
2438 			status = srvstr_push(base_data, flags2, p,
2439 					  fname, PTR_DIFF(end_data, p),
2440 					  STR_TERMINATE, &len);
2441 			if (!NT_STATUS_IS_OK(status)) {
2442 				return status;
2443 			}
2444 		} else {
2445 			DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
2446 			p = store_file_unix_basic_info2(conn, p,
2447 						NULL, &smb_fname->st);
2448 			nameptr = p;
2449 			p += 4;
2450 			status = srvstr_push(base_data, flags2, p, fname,
2451 					  PTR_DIFF(end_data, p), 0, &len);
2452 			if (!NT_STATUS_IS_OK(status)) {
2453 				return status;
2454 			}
2455 			SIVAL(nameptr, 0, len);
2456 		}
2457 
2458 		p += len;
2459 
2460 		len = PTR_DIFF(p, pdata);
2461 		pad = (len + (align-1)) & ~(align-1);
2462 		/*
2463 		 * offset to the next entry, the caller
2464 		 * will overwrite it for the last entry
2465 		 * that's why we always include the padding
2466 		 */
2467 		SIVAL(pdata,0,pad);
2468 		/*
2469 		 * set padding to zero
2470 		 */
2471 		if (do_pad) {
2472 			memset(p, 0, pad - len);
2473 			p = pdata + pad;
2474 		} else {
2475 			p = pdata + len;
2476 		}
2477 		/* End of SMB_QUERY_FILE_UNIX_BASIC */
2478 
2479 		break;
2480 
2481 	default:
2482 		return NT_STATUS_INVALID_LEVEL;
2483 	}
2484 
2485 	if (PTR_DIFF(p,pdata) > space_remaining) {
2486 		DEBUG(9,("smbd_marshall_dir_entry: out of space "
2487 			"(wanted %u, had %d)\n",
2488 			(unsigned int)PTR_DIFF(p,pdata),
2489 			space_remaining ));
2490 		return STATUS_MORE_ENTRIES; /* Not finished - just out of space */
2491 	}
2492 
2493 	/* Setup the last entry pointer, as an offset from base_data */
2494 	*last_entry_off = PTR_DIFF(last_entry_ptr,base_data);
2495 	/* Advance the data pointer to the next slot */
2496 	*ppdata = p;
2497 
2498 	return NT_STATUS_OK;
2499 }
2500 
smbd_dirptr_lanman2_entry(TALLOC_CTX * ctx,connection_struct * conn,struct dptr_struct * dirptr,uint16_t flags2,const char * path_mask,uint32_t dirtype,int info_level,int requires_resume_key,bool dont_descend,bool ask_sharemode,bool get_dosmode,uint8_t align,bool do_pad,char ** ppdata,char * base_data,char * end_data,int space_remaining,struct smb_filename ** _smb_fname,bool * got_exact_match,int * _last_entry_off,struct ea_list * name_list,struct file_id * file_id)2501 NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
2502 			       connection_struct *conn,
2503 			       struct dptr_struct *dirptr,
2504 			       uint16_t flags2,
2505 			       const char *path_mask,
2506 			       uint32_t dirtype,
2507 			       int info_level,
2508 			       int requires_resume_key,
2509 			       bool dont_descend,
2510 			       bool ask_sharemode,
2511 			       bool get_dosmode,
2512 			       uint8_t align,
2513 			       bool do_pad,
2514 			       char **ppdata,
2515 			       char *base_data,
2516 			       char *end_data,
2517 			       int space_remaining,
2518 			       struct smb_filename **_smb_fname,
2519 			       bool *got_exact_match,
2520 			       int *_last_entry_off,
2521 			       struct ea_list *name_list,
2522 			       struct file_id *file_id)
2523 {
2524 	const char *p;
2525 	const char *mask = NULL;
2526 	long prev_dirpos = 0;
2527 	uint32_t mode = 0;
2528 	char *fname = NULL;
2529 	struct smb_filename *smb_fname = NULL;
2530 	struct smbd_dirptr_lanman2_state state;
2531 	bool ok;
2532 	uint64_t last_entry_off = 0;
2533 	NTSTATUS status;
2534 	enum mangled_names_options mangled_names;
2535 	bool marshall_with_83_names;
2536 
2537 	mangled_names = lp_mangled_names(conn->params);
2538 
2539 	ZERO_STRUCT(state);
2540 	state.conn = conn;
2541 	state.info_level = info_level;
2542 	if (mangled_names != MANGLED_NAMES_NO) {
2543 		state.check_mangled_names = true;
2544 	}
2545 	state.has_wild = dptr_has_wild(dirptr);
2546 	state.got_exact_match = false;
2547 
2548 	*got_exact_match = false;
2549 
2550 	p = strrchr_m(path_mask,'/');
2551 	if(p != NULL) {
2552 		if(p[1] == '\0') {
2553 			mask = "*.*";
2554 		} else {
2555 			mask = p+1;
2556 		}
2557 	} else {
2558 		mask = path_mask;
2559 	}
2560 
2561 	ok = smbd_dirptr_get_entry(ctx,
2562 				   dirptr,
2563 				   mask,
2564 				   dirtype,
2565 				   dont_descend,
2566 				   ask_sharemode,
2567 				   get_dosmode,
2568 				   smbd_dirptr_lanman2_match_fn,
2569 				   smbd_dirptr_lanman2_mode_fn,
2570 				   &state,
2571 				   &fname,
2572 				   &smb_fname,
2573 				   &mode,
2574 				   &prev_dirpos);
2575 	if (!ok) {
2576 		return NT_STATUS_END_OF_FILE;
2577 	}
2578 
2579 	*got_exact_match = state.got_exact_match;
2580 
2581 	marshall_with_83_names = (mangled_names == MANGLED_NAMES_YES);
2582 
2583 	status = smbd_marshall_dir_entry(ctx,
2584 				     conn,
2585 				     flags2,
2586 				     info_level,
2587 				     name_list,
2588 				     marshall_with_83_names,
2589 				     requires_resume_key,
2590 				     mode,
2591 				     fname,
2592 				     smb_fname,
2593 				     space_remaining,
2594 				     align,
2595 				     do_pad,
2596 				     base_data,
2597 				     ppdata,
2598 				     end_data,
2599 				     &last_entry_off);
2600 	if (NT_STATUS_EQUAL(status, NT_STATUS_ILLEGAL_CHARACTER)) {
2601 		DEBUG(1,("Conversion error: illegal character: %s\n",
2602 			 smb_fname_str_dbg(smb_fname)));
2603 	}
2604 
2605 	if (file_id != NULL) {
2606 		*file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
2607 	}
2608 
2609 	if (!NT_STATUS_IS_OK(status) &&
2610 	    !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
2611 	{
2612 		TALLOC_FREE(smb_fname);
2613 		TALLOC_FREE(fname);
2614 		return status;
2615 	}
2616 
2617 	if (_smb_fname != NULL) {
2618 		struct smb_filename *name = NULL;
2619 
2620 		name = synthetic_smb_fname(ctx, fname, NULL, &smb_fname->st, 0);
2621 		if (name == NULL) {
2622 			TALLOC_FREE(smb_fname);
2623 			TALLOC_FREE(fname);
2624 			return NT_STATUS_NO_MEMORY;
2625 		}
2626 		*_smb_fname = name;
2627 	}
2628 
2629 	TALLOC_FREE(smb_fname);
2630 	TALLOC_FREE(fname);
2631 
2632 	if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
2633 		dptr_SeekDir(dirptr, prev_dirpos);
2634 		return status;
2635 	}
2636 
2637 	*_last_entry_off = last_entry_off;
2638 	return NT_STATUS_OK;
2639 }
2640 
get_lanman2_dir_entry(TALLOC_CTX * ctx,connection_struct * conn,struct dptr_struct * dirptr,uint16_t flags2,const char * path_mask,uint32_t dirtype,int info_level,bool requires_resume_key,bool dont_descend,bool ask_sharemode,char ** ppdata,char * base_data,char * end_data,int space_remaining,bool * got_exact_match,int * last_entry_off,struct ea_list * name_list)2641 static NTSTATUS get_lanman2_dir_entry(TALLOC_CTX *ctx,
2642 				connection_struct *conn,
2643 				struct dptr_struct *dirptr,
2644 				uint16_t flags2,
2645 				const char *path_mask,
2646 				uint32_t dirtype,
2647 				int info_level,
2648 				bool requires_resume_key,
2649 				bool dont_descend,
2650 				bool ask_sharemode,
2651 				char **ppdata,
2652 				char *base_data,
2653 				char *end_data,
2654 				int space_remaining,
2655 				bool *got_exact_match,
2656 				int *last_entry_off,
2657 				struct ea_list *name_list)
2658 {
2659 	uint8_t align = 4;
2660 	const bool do_pad = true;
2661 
2662 	if (info_level >= 1 && info_level <= 3) {
2663 		/* No alignment on earlier info levels. */
2664 		align = 1;
2665 	}
2666 
2667 	return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
2668 					 path_mask, dirtype, info_level,
2669 					 requires_resume_key, dont_descend, ask_sharemode,
2670 					 true, align, do_pad,
2671 					 ppdata, base_data, end_data,
2672 					 space_remaining,
2673 					 NULL,
2674 					 got_exact_match,
2675 					 last_entry_off, name_list, NULL);
2676 }
2677 
2678 /****************************************************************************
2679  Reply to a TRANS2_FINDFIRST.
2680 ****************************************************************************/
2681 
call_trans2findfirst(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)2682 static void call_trans2findfirst(connection_struct *conn,
2683 				 struct smb_request *req,
2684 				 char **pparams, int total_params,
2685 				 char **ppdata, int total_data,
2686 				 unsigned int max_data_bytes)
2687 {
2688 	/* We must be careful here that we don't return more than the
2689 		allowed number of data bytes. If this means returning fewer than
2690 		maxentries then so be it. We assume that the redirector has
2691 		enough room for the fixed number of parameter bytes it has
2692 		requested. */
2693 	struct smb_filename *smb_dname = NULL;
2694 	char *params = *pparams;
2695 	char *pdata = *ppdata;
2696 	char *data_end;
2697 	uint32_t dirtype;
2698 	int maxentries;
2699 	uint16_t findfirst_flags;
2700 	bool close_after_first;
2701 	bool close_if_end;
2702 	bool requires_resume_key;
2703 	int info_level;
2704 	char *directory = NULL;
2705 	char *mask = NULL;
2706 	char *p;
2707 	int last_entry_off=0;
2708 	int dptr_num = -1;
2709 	int numentries = 0;
2710 	int i;
2711 	bool finished = False;
2712 	bool dont_descend = False;
2713 	bool out_of_space = False;
2714 	int space_remaining;
2715 	bool mask_contains_wcard = False;
2716 	struct ea_list *ea_list = NULL;
2717 	NTSTATUS ntstatus = NT_STATUS_OK;
2718 	bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
2719 	struct smbd_server_connection *sconn = req->sconn;
2720 	uint32_t ucf_flags = UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP |
2721 			ucf_flags_from_smb_request(req);
2722 	bool backup_priv = false;
2723 	bool as_root = false;
2724 	files_struct *fsp = NULL;
2725 	const struct loadparm_substitution *lp_sub =
2726 		loadparm_s3_global_substitution();
2727 	int ret;
2728 
2729 	if (total_params < 13) {
2730 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2731 		goto out;
2732 	}
2733 
2734 	dirtype = SVAL(params,0);
2735 	maxentries = SVAL(params,2);
2736 	findfirst_flags = SVAL(params,4);
2737 	close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
2738 	close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
2739 	requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
2740 	backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) &&
2741 				security_token_has_privilege(get_current_nttok(conn),
2742 						SEC_PRIV_BACKUP));
2743 
2744 	info_level = SVAL(params,6);
2745 
2746 	DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \
2747 close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n",
2748 		(unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
2749 		(int)backup_priv,
2750 		info_level, max_data_bytes));
2751 
2752 	if (!maxentries) {
2753 		/* W2K3 seems to treat zero as 1. */
2754 		maxentries = 1;
2755 	}
2756 
2757 	switch (info_level) {
2758 		case SMB_FIND_INFO_STANDARD:
2759 		case SMB_FIND_EA_SIZE:
2760 		case SMB_FIND_EA_LIST:
2761 		case SMB_FIND_FILE_DIRECTORY_INFO:
2762 		case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
2763 		case SMB_FIND_FILE_NAMES_INFO:
2764 		case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
2765 		case SMB_FIND_ID_FULL_DIRECTORY_INFO:
2766 		case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
2767 			break;
2768 		case SMB_FIND_FILE_UNIX:
2769 		case SMB_FIND_FILE_UNIX_INFO2:
2770 			/* Always use filesystem for UNIX mtime query. */
2771 			ask_sharemode = false;
2772 			if (!lp_unix_extensions()) {
2773 				reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2774 				goto out;
2775 			}
2776 			ucf_flags |= UCF_UNIX_NAME_LOOKUP;
2777 			break;
2778 		default:
2779 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
2780 			goto out;
2781 	}
2782 
2783 	if (req->posix_pathnames) {
2784 		srvstr_get_path_wcard_posix(talloc_tos(),
2785 				params,
2786 				req->flags2,
2787 				&directory,
2788 				params+12,
2789 				total_params - 12,
2790 				STR_TERMINATE,
2791 				&ntstatus,
2792 				&mask_contains_wcard);
2793 	} else {
2794 		srvstr_get_path_wcard(talloc_tos(),
2795 				params,
2796 				req->flags2,
2797 				&directory,
2798 				params+12,
2799 				total_params - 12,
2800 				STR_TERMINATE,
2801 				&ntstatus,
2802 				&mask_contains_wcard);
2803 	}
2804 	if (!NT_STATUS_IS_OK(ntstatus)) {
2805 		reply_nterror(req, ntstatus);
2806 		goto out;
2807 	}
2808 
2809 	if (backup_priv) {
2810 		become_root();
2811 		as_root = true;
2812 		ntstatus = filename_convert_with_privilege(talloc_tos(),
2813 				conn,
2814 				req,
2815 				directory,
2816 				ucf_flags,
2817 				&mask_contains_wcard,
2818 				&smb_dname);
2819 	} else {
2820 		ntstatus = filename_convert(talloc_tos(), conn,
2821 				    directory,
2822 				    ucf_flags,
2823 				    NULL,
2824 				    &mask_contains_wcard,
2825 				    &smb_dname);
2826 	}
2827 
2828 	if (!NT_STATUS_IS_OK(ntstatus)) {
2829 		if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
2830 			reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2831 					ERRSRV, ERRbadpath);
2832 			goto out;
2833 		}
2834 		reply_nterror(req, ntstatus);
2835 		goto out;
2836 	}
2837 
2838 	mask = smb_dname->original_lcomp;
2839 
2840 	directory = smb_dname->base_name;
2841 
2842 	p = strrchr_m(directory,'/');
2843 	if(p == NULL) {
2844 		/* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
2845 		if((directory[0] == '.') && (directory[1] == '\0')) {
2846 			mask = talloc_strdup(talloc_tos(),"*");
2847 			if (!mask) {
2848 				reply_nterror(req, NT_STATUS_NO_MEMORY);
2849 				goto out;
2850 			}
2851 			mask_contains_wcard = True;
2852 		}
2853 	} else {
2854 		*p = 0;
2855 	}
2856 
2857 	if (p == NULL || p == directory) {
2858 		/* Ensure we don't have a directory name of "". */
2859 		directory = talloc_strdup(talloc_tos(), ".");
2860 		if (!directory) {
2861 			reply_nterror(req, NT_STATUS_NO_MEMORY);
2862 			goto out;
2863 		}
2864 		/* Ensure smb_dname->base_name matches. */
2865 		smb_dname->base_name = directory;
2866 	}
2867 
2868 	DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
2869 
2870 	if (info_level == SMB_FIND_EA_LIST) {
2871 		uint32_t ea_size;
2872 
2873 		if (total_data < 4) {
2874 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2875 			goto out;
2876 		}
2877 
2878 		ea_size = IVAL(pdata,0);
2879 		if (ea_size != total_data) {
2880 			DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
2881 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
2882 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2883 			goto out;
2884 		}
2885 
2886 		if (!lp_ea_support(SNUM(conn))) {
2887 			reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
2888 			goto out;
2889 		}
2890 
2891 		/* Pull out the list of names. */
2892 		ea_list = read_ea_name_list(talloc_tos(), pdata + 4, ea_size - 4);
2893 		if (!ea_list) {
2894 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2895 			goto out;
2896 		}
2897 	}
2898 
2899 	if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
2900 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2901 		goto out;
2902 	}
2903 
2904 	*ppdata = (char *)SMB_REALLOC(
2905 		*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
2906 	if(*ppdata == NULL ) {
2907 		reply_nterror(req, NT_STATUS_NO_MEMORY);
2908 		goto out;
2909 	}
2910 	pdata = *ppdata;
2911 	data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
2912 	/*
2913 	 * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
2914 	 * error.
2915 	 */
2916 	memset(pdata + total_data, 0, ((max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data));
2917 	/* Realloc the params space */
2918 	*pparams = (char *)SMB_REALLOC(*pparams, 10);
2919 	if (*pparams == NULL) {
2920 		reply_nterror(req, NT_STATUS_NO_MEMORY);
2921 		goto out;
2922 	}
2923 	params = *pparams;
2924 
2925 	/*
2926 	 * As we've cut off the last component from
2927 	 * smb_fname we need to re-stat smb_dname
2928 	 * so FILE_OPEN disposition knows the directory
2929 	 * exists.
2930 	 */
2931 	if (req->posix_pathnames) {
2932 		ret = SMB_VFS_LSTAT(conn, smb_dname);
2933 	} else {
2934 		ret = SMB_VFS_STAT(conn, smb_dname);
2935 	}
2936 
2937 	if (ret == -1) {
2938 		ntstatus = map_nt_error_from_unix(errno);
2939 		reply_nterror(req, ntstatus);
2940 		goto out;
2941 	}
2942 
2943 	/*
2944 	 * Open an fsp on this directory for the dptr.
2945 	 */
2946 	ntstatus = SMB_VFS_CREATE_FILE(
2947 			conn, /* conn */
2948 			req, /* req */
2949 			0, /* root_dir_fid */
2950 			smb_dname, /* dname */
2951 			FILE_LIST_DIRECTORY, /* access_mask */
2952 			FILE_SHARE_READ|
2953 			FILE_SHARE_WRITE, /* share_access */
2954 			FILE_OPEN, /* create_disposition*/
2955 			FILE_DIRECTORY_FILE, /* create_options */
2956 			FILE_ATTRIBUTE_DIRECTORY,/* file_attributes */
2957 			NO_OPLOCK, /* oplock_request */
2958 			NULL, /* lease */
2959 			0, /* allocation_size */
2960 			0, /* private_flags */
2961 			NULL, /* sd */
2962 			NULL, /* ea_list */
2963 			&fsp, /* result */
2964 			NULL, /* pinfo */
2965 			NULL, /* in_context */
2966 			NULL);/* out_context */
2967 
2968 	if (!NT_STATUS_IS_OK(ntstatus)) {
2969 		DBG_ERR("failed to open directory %s\n",
2970 			smb_fname_str_dbg(smb_dname));
2971 		reply_nterror(req, ntstatus);
2972 		goto out;
2973 	}
2974 
2975 	/* Save the wildcard match and attribs we are using on this directory -
2976 		needed as lanman2 assumes these are being saved between calls */
2977 
2978 	ntstatus = dptr_create(conn,
2979 				req,
2980 				fsp, /* fsp */
2981 				False,
2982 				True,
2983 				req->smbpid,
2984 				mask,
2985 				mask_contains_wcard,
2986 				dirtype,
2987 				&fsp->dptr);
2988 
2989 	if (!NT_STATUS_IS_OK(ntstatus)) {
2990 		/*
2991 		 * Use NULL here for the first parameter (req)
2992 		 * as this is not a client visible handle so
2993 		 * can'tbe part of an SMB1 chain.
2994 		 */
2995 		close_file(NULL, fsp, NORMAL_CLOSE);
2996 		fsp = NULL;
2997 		reply_nterror(req, ntstatus);
2998 		goto out;
2999 	}
3000 
3001 	if (backup_priv) {
3002 		/* Remember this in case we have
3003 		   to do a findnext. */
3004 		dptr_set_priv(fsp->dptr);
3005 	}
3006 
3007 	dptr_num = dptr_dnum(fsp->dptr);
3008 	DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype));
3009 
3010 	/* We don't need to check for VOL here as this is returned by
3011 		a different TRANS2 call. */
3012 
3013 	DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3014 		 directory,lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn))));
3015 	if (in_list(directory,
3016 		    lp_dont_descend(talloc_tos(), lp_sub, SNUM(conn)),
3017 			conn->case_sensitive)) {
3018 		dont_descend = True;
3019 	}
3020 
3021 	p = pdata;
3022 	space_remaining = max_data_bytes;
3023 	out_of_space = False;
3024 
3025 	for (i=0;(i<maxentries) && !finished && !out_of_space;i++) {
3026 		bool got_exact_match = False;
3027 
3028 		/* this is a heuristic to avoid seeking the dirptr except when
3029 			absolutely necessary. It allows for a filename of about 40 chars */
3030 		if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3031 			out_of_space = True;
3032 			finished = False;
3033 		} else {
3034 			ntstatus = get_lanman2_dir_entry(talloc_tos(),
3035 					conn,
3036 					fsp->dptr,
3037 					req->flags2,
3038 					mask,dirtype,info_level,
3039 					requires_resume_key,dont_descend,
3040 					ask_sharemode,
3041 					&p,pdata,data_end,
3042 					space_remaining,
3043 					&got_exact_match,
3044 					&last_entry_off, ea_list);
3045 			if (NT_STATUS_EQUAL(ntstatus,
3046 					NT_STATUS_ILLEGAL_CHARACTER)) {
3047 				/*
3048 				 * Bad character conversion on name. Ignore this
3049 				 * entry.
3050 				 */
3051 				continue;
3052 			}
3053 			if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3054 				out_of_space = true;
3055 			} else {
3056 				finished = !NT_STATUS_IS_OK(ntstatus);
3057 			}
3058 		}
3059 
3060 		if (!finished && !out_of_space)
3061 			numentries++;
3062 
3063 		/*
3064 		 * As an optimisation if we know we aren't looking
3065 		 * for a wildcard name (ie. the name matches the wildcard exactly)
3066 		 * then we can finish on any (first) match.
3067 		 * This speeds up large directory searches. JRA.
3068 		 */
3069 
3070 		if(got_exact_match)
3071 			finished = True;
3072 
3073 		/* Ensure space_remaining never goes -ve. */
3074 		if (PTR_DIFF(p,pdata) > max_data_bytes) {
3075 			space_remaining = 0;
3076 			out_of_space = true;
3077 		} else {
3078 			space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3079 		}
3080 	}
3081 
3082 	/* Check if we can close the dirptr */
3083 	if(close_after_first || (finished && close_if_end)) {
3084 		DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
3085 		dptr_num = -1;
3086 		close_file(NULL, fsp, NORMAL_CLOSE);
3087 		fsp = NULL;
3088 	}
3089 
3090 	/*
3091 	 * If there are no matching entries we must return ERRDOS/ERRbadfile -
3092 	 * from observation of NT. NB. This changes to ERRDOS,ERRnofiles if
3093 	 * the protocol level is less than NT1. Tested with smbclient. JRA.
3094 	 * This should fix the OS/2 client bug #2335.
3095 	 */
3096 
3097 	if(numentries == 0) {
3098 		dptr_num = -1;
3099 		/*
3100 		 * We may have already closed the file in the
3101 		 * close_after_first or finished case above.
3102 		 */
3103 		if (fsp != NULL) {
3104 			close_file(NULL, fsp, NORMAL_CLOSE);
3105 			fsp = NULL;
3106 		}
3107 		if (get_Protocol() < PROTOCOL_NT1) {
3108 			reply_force_doserror(req, ERRDOS, ERRnofiles);
3109 			goto out;
3110 		} else {
3111 			reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
3112 					ERRDOS, ERRbadfile);
3113 			goto out;
3114 		}
3115 	}
3116 
3117 	/* At this point pdata points to numentries directory entries. */
3118 
3119 	/* Set up the return parameter block */
3120 	SSVAL(params,0,dptr_num);
3121 	SSVAL(params,2,numentries);
3122 	SSVAL(params,4,finished);
3123 	SSVAL(params,6,0); /* Never an EA error */
3124 	SSVAL(params,8,last_entry_off);
3125 
3126 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 10, pdata, PTR_DIFF(p,pdata),
3127 			    max_data_bytes);
3128 
3129 	if ((! *directory) && dptr_path(sconn, dptr_num)) {
3130 		directory = talloc_strdup(talloc_tos(),dptr_path(sconn, dptr_num));
3131 		if (!directory) {
3132 			reply_nterror(req, NT_STATUS_NO_MEMORY);
3133 		}
3134 	}
3135 
3136 	DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3137 		smb_fn_name(req->cmd),
3138 		mask, directory, dirtype, numentries ) );
3139 
3140 	/*
3141 	 * Force a name mangle here to ensure that the
3142 	 * mask as an 8.3 name is top of the mangled cache.
3143 	 * The reasons for this are subtle. Don't remove
3144 	 * this code unless you know what you are doing
3145 	 * (see PR#13758). JRA.
3146 	 */
3147 
3148 	if(!mangle_is_8_3_wildcards( mask, False, conn->params)) {
3149 		char mangled_name[13];
3150 		name_to_8_3(mask, mangled_name, True, conn->params);
3151 	}
3152  out:
3153 
3154 	if (as_root) {
3155 		unbecome_root();
3156 	}
3157 
3158 	TALLOC_FREE(smb_dname);
3159 	return;
3160 }
3161 
3162 /****************************************************************************
3163  Reply to a TRANS2_FINDNEXT.
3164 ****************************************************************************/
3165 
call_trans2findnext(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)3166 static void call_trans2findnext(connection_struct *conn,
3167 				struct smb_request *req,
3168 				char **pparams, int total_params,
3169 				char **ppdata, int total_data,
3170 				unsigned int max_data_bytes)
3171 {
3172 	/* We must be careful here that we don't return more than the
3173 		allowed number of data bytes. If this means returning fewer than
3174 		maxentries then so be it. We assume that the redirector has
3175 		enough room for the fixed number of parameter bytes it has
3176 		requested. */
3177 	char *params = *pparams;
3178 	char *pdata = *ppdata;
3179 	char *data_end;
3180 	int dptr_num;
3181 	int maxentries;
3182 	uint16_t info_level;
3183 	uint32_t resume_key;
3184 	uint16_t findnext_flags;
3185 	bool close_after_request;
3186 	bool close_if_end;
3187 	bool requires_resume_key;
3188 	bool continue_bit;
3189 	bool mask_contains_wcard = False;
3190 	char *resume_name = NULL;
3191 	const char *mask = NULL;
3192 	const char *directory = NULL;
3193 	char *p = NULL;
3194 	uint16_t dirtype;
3195 	int numentries = 0;
3196 	int i, last_entry_off=0;
3197 	bool finished = False;
3198 	bool dont_descend = False;
3199 	bool out_of_space = False;
3200 	int space_remaining;
3201 	struct ea_list *ea_list = NULL;
3202 	NTSTATUS ntstatus = NT_STATUS_OK;
3203 	bool ask_sharemode = lp_smbd_search_ask_sharemode(SNUM(conn));
3204 	TALLOC_CTX *ctx = talloc_tos();
3205 	struct smbd_server_connection *sconn = req->sconn;
3206 	bool backup_priv = false;
3207 	bool as_root = false;
3208 	files_struct *fsp = NULL;
3209 	const struct loadparm_substitution *lp_sub =
3210 		loadparm_s3_global_substitution();
3211 
3212 	if (total_params < 13) {
3213 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3214 		return;
3215 	}
3216 
3217 	dptr_num = SVAL(params,0);
3218 	maxentries = SVAL(params,2);
3219 	info_level = SVAL(params,4);
3220 	resume_key = IVAL(params,6);
3221 	findnext_flags = SVAL(params,10);
3222 	close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
3223 	close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
3224 	requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
3225 	continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
3226 
3227 	if (!continue_bit) {
3228 		/* We only need resume_name if continue_bit is zero. */
3229 		if (req->posix_pathnames) {
3230 			srvstr_get_path_wcard_posix(ctx,
3231 				params,
3232 				req->flags2,
3233 				&resume_name,
3234 				params+12,
3235 				total_params - 12,
3236 				STR_TERMINATE,
3237 				&ntstatus,
3238 				&mask_contains_wcard);
3239 		} else {
3240 			srvstr_get_path_wcard(ctx,
3241 				params,
3242 				req->flags2,
3243 				&resume_name,
3244 				params+12,
3245 				total_params - 12,
3246 				STR_TERMINATE,
3247 				&ntstatus,
3248 				&mask_contains_wcard);
3249 		}
3250 		if (!NT_STATUS_IS_OK(ntstatus)) {
3251 			/* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
3252 			   complain (it thinks we're asking for the directory above the shared
3253 			   path or an invalid name). Catch this as the resume name is only compared, never used in
3254 			   a file access. JRA. */
3255 			srvstr_pull_talloc(ctx, params, req->flags2,
3256 				&resume_name, params+12,
3257 				total_params - 12,
3258 				STR_TERMINATE);
3259 
3260 			if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
3261 				reply_nterror(req, ntstatus);
3262 				return;
3263 			}
3264 		}
3265 	}
3266 
3267 	DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
3268 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
3269 resume_key = %d resume name = %s continue=%d level = %d\n",
3270 		dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
3271 		requires_resume_key, resume_key,
3272 		resume_name ? resume_name : "(NULL)", continue_bit, info_level));
3273 
3274 	if (!maxentries) {
3275 		/* W2K3 seems to treat zero as 1. */
3276 		maxentries = 1;
3277 	}
3278 
3279 	switch (info_level) {
3280 		case SMB_FIND_INFO_STANDARD:
3281 		case SMB_FIND_EA_SIZE:
3282 		case SMB_FIND_EA_LIST:
3283 		case SMB_FIND_FILE_DIRECTORY_INFO:
3284 		case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
3285 		case SMB_FIND_FILE_NAMES_INFO:
3286 		case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
3287 		case SMB_FIND_ID_FULL_DIRECTORY_INFO:
3288 		case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
3289 			break;
3290 		case SMB_FIND_FILE_UNIX:
3291 		case SMB_FIND_FILE_UNIX_INFO2:
3292 			/* Always use filesystem for UNIX mtime query. */
3293 			ask_sharemode = false;
3294 			if (!lp_unix_extensions()) {
3295 				reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3296 				return;
3297 			}
3298 			break;
3299 		default:
3300 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3301 			return;
3302 	}
3303 
3304 	if (info_level == SMB_FIND_EA_LIST) {
3305 		uint32_t ea_size;
3306 
3307 		if (total_data < 4) {
3308 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3309 			return;
3310 		}
3311 
3312 		ea_size = IVAL(pdata,0);
3313 		if (ea_size != total_data) {
3314 			DEBUG(4,("call_trans2findnext: Rejecting EA request with incorrect \
3315 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
3316 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3317 			return;
3318 		}
3319 
3320 		if (!lp_ea_support(SNUM(conn))) {
3321 			reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
3322 			return;
3323 		}
3324 
3325 		/* Pull out the list of names. */
3326 		ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
3327 		if (!ea_list) {
3328 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3329 			return;
3330 		}
3331 	}
3332 
3333 	if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3334 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3335 		return;
3336 	}
3337 
3338 	*ppdata = (char *)SMB_REALLOC(
3339 		*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3340 	if(*ppdata == NULL) {
3341 		reply_nterror(req, NT_STATUS_NO_MEMORY);
3342 		return;
3343 	}
3344 
3345 	pdata = *ppdata;
3346 	data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3347 
3348 	/*
3349 	 * squash valgrind "writev(vector[...]) points to uninitialised byte(s)"
3350 	 * error.
3351 	 */
3352 	memset(pdata + total_data, 0, (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN) - total_data);
3353 	/* Realloc the params space */
3354 	*pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
3355 	if(*pparams == NULL ) {
3356 		reply_nterror(req, NT_STATUS_NO_MEMORY);
3357 		return;
3358 	}
3359 
3360 	params = *pparams;
3361 
3362 	/* Check that the dptr is valid */
3363 	fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
3364 	if (fsp == NULL) {
3365 		reply_nterror(req, STATUS_NO_MORE_FILES);
3366 		return;
3367 	}
3368 
3369 	directory = dptr_path(sconn, dptr_num);
3370 
3371 	/* Get the wildcard mask from the dptr */
3372 	if((mask = dptr_wcard(sconn, dptr_num))== NULL) {
3373 		DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
3374 		reply_nterror(req, STATUS_NO_MORE_FILES);
3375 		return;
3376 	}
3377 
3378 	/* Get the attr mask from the dptr */
3379 	dirtype = dptr_attr(sconn, dptr_num);
3380 
3381 	backup_priv = dptr_get_priv(fsp->dptr);
3382 
3383 	DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) "
3384 		"backup_priv = %d\n",
3385 		dptr_num, mask, dirtype,
3386 		(long)fsp->dptr,
3387 		dptr_TellDir(fsp->dptr),
3388 		(int)backup_priv));
3389 
3390 	/* We don't need to check for VOL here as this is returned by
3391 		a different TRANS2 call. */
3392 
3393 	DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
3394 		 directory,lp_dont_descend(ctx, lp_sub, SNUM(conn))));
3395 	if (in_list(directory,lp_dont_descend(ctx, lp_sub, SNUM(conn)),conn->case_sensitive))
3396 		dont_descend = True;
3397 
3398 	p = pdata;
3399 	space_remaining = max_data_bytes;
3400 	out_of_space = False;
3401 
3402 	if (backup_priv) {
3403 		become_root();
3404 		as_root = true;
3405 	}
3406 
3407 	/*
3408 	 * Seek to the correct position. We no longer use the resume key but
3409 	 * depend on the last file name instead.
3410 	 */
3411 
3412 	if(!continue_bit && resume_name && *resume_name) {
3413 		SMB_STRUCT_STAT st;
3414 
3415 		long current_pos = 0;
3416 		/*
3417 		 * Remember, name_to_8_3 is called by
3418 		 * get_lanman2_dir_entry(), so the resume name
3419 		 * could be mangled. Ensure we check the unmangled name.
3420 		 */
3421 
3422 		if (mangle_is_mangled(resume_name, conn->params)) {
3423 			char *new_resume_name = NULL;
3424 			mangle_lookup_name_from_8_3(ctx,
3425 						resume_name,
3426 						&new_resume_name,
3427 						conn->params);
3428 			if (new_resume_name) {
3429 				resume_name = new_resume_name;
3430 			}
3431 		}
3432 
3433 		/*
3434 		 * Fix for NT redirector problem triggered by resume key indexes
3435 		 * changing between directory scans. We now return a resume key of 0
3436 		 * and instead look for the filename to continue from (also given
3437 		 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
3438 		 * findfirst/findnext (as is usual) then the directory pointer
3439 		 * should already be at the correct place.
3440 		 */
3441 
3442 		finished = !dptr_SearchDir(fsp->dptr, resume_name, &current_pos, &st);
3443 	} /* end if resume_name && !continue_bit */
3444 
3445 	for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
3446 		bool got_exact_match = False;
3447 
3448 		/* this is a heuristic to avoid seeking the fsp->dptr except when
3449 			absolutely necessary. It allows for a filename of about 40 chars */
3450 		if (space_remaining < DIRLEN_GUESS && numentries > 0) {
3451 			out_of_space = True;
3452 			finished = False;
3453 		} else {
3454 			ntstatus = get_lanman2_dir_entry(ctx,
3455 						conn,
3456 						fsp->dptr,
3457 						req->flags2,
3458 						mask,dirtype,info_level,
3459 						requires_resume_key,dont_descend,
3460 						ask_sharemode,
3461 						&p,pdata,data_end,
3462 						space_remaining,
3463 						&got_exact_match,
3464 						&last_entry_off, ea_list);
3465 			if (NT_STATUS_EQUAL(ntstatus,
3466 					NT_STATUS_ILLEGAL_CHARACTER)) {
3467 				/*
3468 				 * Bad character conversion on name. Ignore this
3469 				 * entry.
3470 				 */
3471 				continue;
3472 			}
3473 			if (NT_STATUS_EQUAL(ntstatus, STATUS_MORE_ENTRIES)) {
3474 				out_of_space = true;
3475 			} else {
3476 				finished = !NT_STATUS_IS_OK(ntstatus);
3477 			}
3478 		}
3479 
3480 		if (!finished && !out_of_space)
3481 			numentries++;
3482 
3483 		/*
3484 		 * As an optimisation if we know we aren't looking
3485 		 * for a wildcard name (ie. the name matches the wildcard exactly)
3486 		 * then we can finish on any (first) match.
3487 		 * This speeds up large directory searches. JRA.
3488 		 */
3489 
3490 		if(got_exact_match)
3491 			finished = True;
3492 
3493 		space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
3494 	}
3495 
3496 	DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
3497 		smb_fn_name(req->cmd),
3498 		mask, directory, dirtype, numentries ) );
3499 
3500 	/* Check if we can close the fsp->dptr */
3501 	if(close_after_request || (finished && close_if_end)) {
3502 		DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
3503 		dptr_num = -1;
3504 		close_file(NULL, fsp, NORMAL_CLOSE);
3505 		fsp = NULL;
3506 	}
3507 
3508 	if (as_root) {
3509 		unbecome_root();
3510 	}
3511 
3512 	/* Set up the return parameter block */
3513 	SSVAL(params,0,numentries);
3514 	SSVAL(params,2,finished);
3515 	SSVAL(params,4,0); /* Never an EA error */
3516 	SSVAL(params,6,last_entry_off);
3517 
3518 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 8, pdata, PTR_DIFF(p,pdata),
3519 			    max_data_bytes);
3520 
3521 	return;
3522 }
3523 
create_volume_objectid(connection_struct * conn,unsigned char objid[16])3524 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16])
3525 {
3526 	const struct loadparm_substitution *lp_sub =
3527 		loadparm_s3_global_substitution();
3528 
3529 	E_md4hash(lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),objid);
3530 	return objid;
3531 }
3532 
samba_extended_info_version(struct smb_extended_info * extended_info)3533 static void samba_extended_info_version(struct smb_extended_info *extended_info)
3534 {
3535 	SMB_ASSERT(extended_info != NULL);
3536 
3537 	extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
3538 	extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
3539 				       | ((SAMBA_VERSION_MINOR & 0xff) << 16)
3540 				       | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
3541 #ifdef SAMBA_VERSION_REVISION
3542 	extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
3543 #endif
3544 	extended_info->samba_subversion = 0;
3545 #ifdef SAMBA_VERSION_RC_RELEASE
3546 	extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
3547 #else
3548 #ifdef SAMBA_VERSION_PRE_RELEASE
3549 	extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
3550 #endif
3551 #endif
3552 #ifdef SAMBA_VERSION_VENDOR_PATCH
3553 	extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
3554 #endif
3555 	extended_info->samba_gitcommitdate = 0;
3556 #ifdef SAMBA_VERSION_COMMIT_TIME
3557 	unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_COMMIT_TIME);
3558 #endif
3559 
3560 	memset(extended_info->samba_version_string, 0,
3561 	       sizeof(extended_info->samba_version_string));
3562 
3563 	snprintf (extended_info->samba_version_string,
3564 		  sizeof(extended_info->samba_version_string),
3565 		  "%s", samba_version_string());
3566 }
3567 
smbd_do_qfsinfo(struct smbXsrv_connection * xconn,connection_struct * conn,TALLOC_CTX * mem_ctx,uint16_t info_level,uint16_t flags2,unsigned int max_data_bytes,size_t * fixed_portion,struct smb_filename * fname,char ** ppdata,int * ret_data_len)3568 NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
3569 			 connection_struct *conn,
3570 			 TALLOC_CTX *mem_ctx,
3571 			 uint16_t info_level,
3572 			 uint16_t flags2,
3573 			 unsigned int max_data_bytes,
3574 			 size_t *fixed_portion,
3575 			 struct smb_filename *fname,
3576 			 char **ppdata,
3577 			 int *ret_data_len)
3578 {
3579 	const struct loadparm_substitution *lp_sub =
3580 		loadparm_s3_global_substitution();
3581 	char *pdata, *end_data;
3582 	int data_len = 0;
3583 	size_t len = 0;
3584 	const char *vname = volume_label(talloc_tos(), SNUM(conn));
3585 	int snum = SNUM(conn);
3586 	const char *fstype = lp_fstype(SNUM(conn));
3587 	const char *filename = NULL;
3588 	const uint64_t bytes_per_sector = 512;
3589 	uint32_t additional_flags = 0;
3590 	struct smb_filename smb_fname;
3591 	SMB_STRUCT_STAT st;
3592 	NTSTATUS status = NT_STATUS_OK;
3593 	uint64_t df_ret;
3594 
3595 	if (fname == NULL || fname->base_name == NULL) {
3596 		filename = ".";
3597 	} else {
3598 		filename = fname->base_name;
3599 	}
3600 
3601 	if (IS_IPC(conn)) {
3602 		if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
3603 			DEBUG(0,("smbd_do_qfsinfo: not an allowed "
3604 				"info level (0x%x) on IPC$.\n",
3605 				(unsigned int)info_level));
3606 			return NT_STATUS_ACCESS_DENIED;
3607 		}
3608 	}
3609 
3610 	DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
3611 
3612 	ZERO_STRUCT(smb_fname);
3613 	smb_fname.base_name = discard_const_p(char, filename);
3614 
3615 	if(info_level != SMB_FS_QUOTA_INFORMATION
3616 	   && SMB_VFS_STAT(conn, &smb_fname) != 0) {
3617 		DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
3618 		return map_nt_error_from_unix(errno);
3619 	}
3620 
3621 	st = smb_fname.st;
3622 
3623 	if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
3624 		return NT_STATUS_INVALID_PARAMETER;
3625 	}
3626 
3627 	*ppdata = (char *)SMB_REALLOC(
3628 		*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3629 	if (*ppdata == NULL) {
3630 		return NT_STATUS_NO_MEMORY;
3631 	}
3632 
3633 	pdata = *ppdata;
3634 	memset((char *)pdata,'\0',max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
3635 	end_data = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
3636 
3637 	*fixed_portion = 0;
3638 
3639 	switch (info_level) {
3640 		case SMB_INFO_ALLOCATION:
3641 		{
3642 			uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3643 			data_len = 18;
3644 			df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3645 						&dfree, &dsize);
3646 			if (df_ret == (uint64_t)-1) {
3647 				return map_nt_error_from_unix(errno);
3648 			}
3649 
3650 			block_size = lp_block_size(snum);
3651 			if (bsize < block_size) {
3652 				uint64_t factor = block_size/bsize;
3653 				bsize = block_size;
3654 				dsize /= factor;
3655 				dfree /= factor;
3656 			}
3657 			if (bsize > block_size) {
3658 				uint64_t factor = bsize/block_size;
3659 				bsize = block_size;
3660 				dsize *= factor;
3661 				dfree *= factor;
3662 			}
3663 			sectors_per_unit = bsize/bytes_per_sector;
3664 
3665 			DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
3666 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
3667 				(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3668 
3669 			/*
3670 			 * For large drives, return max values and not modulo.
3671 			 */
3672 			dsize = MIN(dsize, UINT32_MAX);
3673 			dfree = MIN(dfree, UINT32_MAX);
3674 
3675 			SIVAL(pdata,l1_idFileSystem,st.st_ex_dev);
3676 			SIVAL(pdata,l1_cSectorUnit,sectors_per_unit);
3677 			SIVAL(pdata,l1_cUnit,dsize);
3678 			SIVAL(pdata,l1_cUnitAvail,dfree);
3679 			SSVAL(pdata,l1_cbSector,bytes_per_sector);
3680 			break;
3681 		}
3682 
3683 		case SMB_INFO_VOLUME:
3684 			/* Return volume name */
3685 			/*
3686 			 * Add volume serial number - hash of a combination of
3687 			 * the called hostname and the service name.
3688 			 */
3689 			SIVAL(pdata,0,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^ (str_checksum(get_local_machine_name())<<16) );
3690 			/*
3691 			 * Win2k3 and previous mess this up by sending a name length
3692 			 * one byte short. I believe only older clients (OS/2 Win9x) use
3693 			 * this call so try fixing this by adding a terminating null to
3694 			 * the pushed string. The change here was adding the STR_TERMINATE. JRA.
3695 			 */
3696 			status = srvstr_push(
3697 				pdata, flags2,
3698 				pdata+l2_vol_szVolLabel, vname,
3699 				PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
3700 				STR_NOALIGN|STR_TERMINATE, &len);
3701 			if (!NT_STATUS_IS_OK(status)) {
3702 				return status;
3703 			}
3704 			SCVAL(pdata,l2_vol_cch,len);
3705 			data_len = l2_vol_szVolLabel + len;
3706 			DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %u, name = %s\n",
3707 				 (unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
3708 				 (unsigned)len, vname));
3709 			break;
3710 
3711 		case SMB_QUERY_FS_ATTRIBUTE_INFO:
3712 		case SMB_FS_ATTRIBUTE_INFORMATION:
3713 
3714 			additional_flags = 0;
3715 #if defined(HAVE_SYS_QUOTAS)
3716 			additional_flags |= FILE_VOLUME_QUOTAS;
3717 #endif
3718 
3719 			if(lp_nt_acl_support(SNUM(conn))) {
3720 				additional_flags |= FILE_PERSISTENT_ACLS;
3721 			}
3722 
3723 			/* Capabilities are filled in at connection time through STATVFS call */
3724 			additional_flags |= conn->fs_capabilities;
3725 			additional_flags |= lp_parm_int(conn->params->service,
3726 							"share", "fake_fscaps",
3727 							0);
3728 
3729 			SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
3730 				FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
3731 				additional_flags); /* FS ATTRIBUTES */
3732 
3733 			SIVAL(pdata,4,255); /* Max filename component length */
3734 			/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
3735 				and will think we can't do long filenames */
3736 			status = srvstr_push(pdata, flags2, pdata+12, fstype,
3737 					  PTR_DIFF(end_data, pdata+12),
3738 					  STR_UNICODE, &len);
3739 			if (!NT_STATUS_IS_OK(status)) {
3740 				return status;
3741 			}
3742 			SIVAL(pdata,8,len);
3743 			data_len = 12 + len;
3744 			if (max_data_bytes >= 16 && data_len > max_data_bytes) {
3745 				/* the client only requested a portion of the
3746 				   file system name */
3747 				data_len = max_data_bytes;
3748 				status = STATUS_BUFFER_OVERFLOW;
3749 			}
3750 			*fixed_portion = 16;
3751 			break;
3752 
3753 		case SMB_QUERY_FS_LABEL_INFO:
3754 		case SMB_FS_LABEL_INFORMATION:
3755 			status = srvstr_push(pdata, flags2, pdata+4, vname,
3756 					  PTR_DIFF(end_data, pdata+4), 0, &len);
3757 			if (!NT_STATUS_IS_OK(status)) {
3758 				return status;
3759 			}
3760 			data_len = 4 + len;
3761 			SIVAL(pdata,0,len);
3762 			break;
3763 
3764 		case SMB_QUERY_FS_VOLUME_INFO:
3765 		case SMB_FS_VOLUME_INFORMATION:
3766 
3767 			/*
3768 			 * Add volume serial number - hash of a combination of
3769 			 * the called hostname and the service name.
3770 			 */
3771 			SIVAL(pdata,8,str_checksum(lp_servicename(talloc_tos(), lp_sub, snum)) ^
3772 				(str_checksum(get_local_machine_name())<<16));
3773 
3774 			/* Max label len is 32 characters. */
3775 			status = srvstr_push(pdata, flags2, pdata+18, vname,
3776 					  PTR_DIFF(end_data, pdata+18),
3777 					  STR_UNICODE, &len);
3778 			if (!NT_STATUS_IS_OK(status)) {
3779 				return status;
3780 			}
3781 			SIVAL(pdata,12,len);
3782 			data_len = 18+len;
3783 
3784 			DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
3785 				(int)strlen(vname),vname,
3786 				lp_servicename(talloc_tos(), lp_sub, snum)));
3787 			if (max_data_bytes >= 24 && data_len > max_data_bytes) {
3788 				/* the client only requested a portion of the
3789 				   volume label */
3790 				data_len = max_data_bytes;
3791 				status = STATUS_BUFFER_OVERFLOW;
3792 			}
3793 			*fixed_portion = 24;
3794 			break;
3795 
3796 		case SMB_QUERY_FS_SIZE_INFO:
3797 		case SMB_FS_SIZE_INFORMATION:
3798 		{
3799 			uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3800 			data_len = 24;
3801 			df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3802 						&dfree, &dsize);
3803 			if (df_ret == (uint64_t)-1) {
3804 				return map_nt_error_from_unix(errno);
3805 			}
3806 			block_size = lp_block_size(snum);
3807 			if (bsize < block_size) {
3808 				uint64_t factor = block_size/bsize;
3809 				bsize = block_size;
3810 				dsize /= factor;
3811 				dfree /= factor;
3812 			}
3813 			if (bsize > block_size) {
3814 				uint64_t factor = bsize/block_size;
3815 				bsize = block_size;
3816 				dsize *= factor;
3817 				dfree *= factor;
3818 			}
3819 			sectors_per_unit = bsize/bytes_per_sector;
3820 			DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3821 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3822 				(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3823 			SBIG_UINT(pdata,0,dsize);
3824 			SBIG_UINT(pdata,8,dfree);
3825 			SIVAL(pdata,16,sectors_per_unit);
3826 			SIVAL(pdata,20,bytes_per_sector);
3827 			*fixed_portion = 24;
3828 			break;
3829 		}
3830 
3831 		case SMB_FS_FULL_SIZE_INFORMATION:
3832 		{
3833 			uint64_t dfree,dsize,bsize,block_size,sectors_per_unit;
3834 			data_len = 32;
3835 			df_ret = get_dfree_info(conn, &smb_fname, &bsize,
3836 						&dfree, &dsize);
3837 			if (df_ret == (uint64_t)-1) {
3838 				return map_nt_error_from_unix(errno);
3839 			}
3840 			block_size = lp_block_size(snum);
3841 			if (bsize < block_size) {
3842 				uint64_t factor = block_size/bsize;
3843 				bsize = block_size;
3844 				dsize /= factor;
3845 				dfree /= factor;
3846 			}
3847 			if (bsize > block_size) {
3848 				uint64_t factor = bsize/block_size;
3849 				bsize = block_size;
3850 				dsize *= factor;
3851 				dfree *= factor;
3852 			}
3853 			sectors_per_unit = bsize/bytes_per_sector;
3854 			DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
3855 cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
3856 				(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
3857 			SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
3858 			SBIG_UINT(pdata,8,dfree); /* Caller available allocation units. */
3859 			SBIG_UINT(pdata,16,dfree); /* Actual available allocation units. */
3860 			SIVAL(pdata,24,sectors_per_unit); /* Sectors per allocation unit. */
3861 			SIVAL(pdata,28,bytes_per_sector); /* Bytes per sector. */
3862 			*fixed_portion = 32;
3863 			break;
3864 		}
3865 
3866 		case SMB_QUERY_FS_DEVICE_INFO:
3867 		case SMB_FS_DEVICE_INFORMATION:
3868 		{
3869 			uint32_t characteristics = FILE_DEVICE_IS_MOUNTED;
3870 
3871 			if (!CAN_WRITE(conn)) {
3872 				characteristics |= FILE_READ_ONLY_DEVICE;
3873 			}
3874 			data_len = 8;
3875 			SIVAL(pdata,0,FILE_DEVICE_DISK); /* dev type */
3876 			SIVAL(pdata,4,characteristics);
3877 			*fixed_portion = 8;
3878 			break;
3879 		}
3880 
3881 #ifdef HAVE_SYS_QUOTAS
3882 		case SMB_FS_QUOTA_INFORMATION:
3883 		/*
3884 		 * what we have to send --metze:
3885 		 *
3886 		 * Unknown1: 		24 NULL bytes
3887 		 * Soft Quota Treshold: 8 bytes seems like uint64_t or so
3888 		 * Hard Quota Limit:	8 bytes seems like uint64_t or so
3889 		 * Quota Flags:		2 byte :
3890 		 * Unknown3:		6 NULL bytes
3891 		 *
3892 		 * 48 bytes total
3893 		 *
3894 		 * details for Quota Flags:
3895 		 *
3896 		 * 0x0020 Log Limit: log if the user exceeds his Hard Quota
3897 		 * 0x0010 Log Warn:  log if the user exceeds his Soft Quota
3898 		 * 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
3899 		 * 0x0001 Enable Quotas: enable quota for this fs
3900 		 *
3901 		 */
3902 		{
3903 			/* we need to fake up a fsp here,
3904 			 * because its not send in this call
3905 			 */
3906 			files_struct fsp;
3907 			SMB_NTQUOTA_STRUCT quotas;
3908 
3909 			ZERO_STRUCT(fsp);
3910 			ZERO_STRUCT(quotas);
3911 
3912 			fsp.conn = conn;
3913 			fsp.fnum = FNUM_FIELD_INVALID;
3914 
3915 			/* access check */
3916 			if (get_current_uid(conn) != 0) {
3917 				DEBUG(0,("get_user_quota: access_denied "
3918 					 "service [%s] user [%s]\n",
3919 					 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
3920 					 conn->session_info->unix_info->unix_name));
3921 				return NT_STATUS_ACCESS_DENIED;
3922 			}
3923 
3924 			status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
3925 						 NULL, &quotas);
3926 			if (!NT_STATUS_IS_OK(status)) {
3927 				DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
3928 				return status;
3929 			}
3930 
3931 			data_len = 48;
3932 
3933 			DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
3934 				  lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
3935 
3936 			/* Unknown1 24 NULL bytes*/
3937 			SBIG_UINT(pdata,0,(uint64_t)0);
3938 			SBIG_UINT(pdata,8,(uint64_t)0);
3939 			SBIG_UINT(pdata,16,(uint64_t)0);
3940 
3941 			/* Default Soft Quota 8 bytes */
3942 			SBIG_UINT(pdata,24,quotas.softlim);
3943 
3944 			/* Default Hard Quota 8 bytes */
3945 			SBIG_UINT(pdata,32,quotas.hardlim);
3946 
3947 			/* Quota flag 2 bytes */
3948 			SSVAL(pdata,40,quotas.qflags);
3949 
3950 			/* Unknown3 6 NULL bytes */
3951 			SSVAL(pdata,42,0);
3952 			SIVAL(pdata,44,0);
3953 
3954 			break;
3955 		}
3956 #endif /* HAVE_SYS_QUOTAS */
3957 		case SMB_FS_OBJECTID_INFORMATION:
3958 		{
3959 			unsigned char objid[16];
3960 			struct smb_extended_info extended_info;
3961 			memcpy(pdata,create_volume_objectid(conn, objid),16);
3962 			samba_extended_info_version (&extended_info);
3963 			SIVAL(pdata,16,extended_info.samba_magic);
3964 			SIVAL(pdata,20,extended_info.samba_version);
3965 			SIVAL(pdata,24,extended_info.samba_subversion);
3966 			SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
3967 			memcpy(pdata+36,extended_info.samba_version_string,28);
3968 			data_len = 64;
3969 			break;
3970 		}
3971 
3972 		case SMB_FS_SECTOR_SIZE_INFORMATION:
3973 		{
3974 			data_len = 28;
3975 			/*
3976 			 * These values match a physical Windows Server 2012
3977 			 * share backed by NTFS atop spinning rust.
3978 			 */
3979 			DEBUG(5, ("SMB_FS_SECTOR_SIZE_INFORMATION:"));
3980 			/* logical_bytes_per_sector */
3981 			SIVAL(pdata, 0, bytes_per_sector);
3982 			/* phys_bytes_per_sector_atomic */
3983 			SIVAL(pdata, 4, bytes_per_sector);
3984 			/* phys_bytes_per_sector_perf */
3985 			SIVAL(pdata, 8, bytes_per_sector);
3986 			/* fs_effective_phys_bytes_per_sector_atomic */
3987 			SIVAL(pdata, 12, bytes_per_sector);
3988 			/* flags */
3989 			SIVAL(pdata, 16, SSINFO_FLAGS_ALIGNED_DEVICE
3990 				| SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE);
3991 			/* byte_off_sector_align */
3992 			SIVAL(pdata, 20, 0);
3993 			/* byte_off_partition_align */
3994 			SIVAL(pdata, 24, 0);
3995 			*fixed_portion = 28;
3996 			break;
3997 		}
3998 
3999 
4000 		/*
4001 		 * Query the version and capabilities of the CIFS UNIX extensions
4002 		 * in use.
4003 		 */
4004 
4005 		case SMB_QUERY_CIFS_UNIX_INFO:
4006 		{
4007 			bool large_write = lp_min_receive_file_size() &&
4008 					!srv_is_signing_active(xconn);
4009 			bool large_read = !srv_is_signing_active(xconn);
4010 			int encrypt_caps = 0;
4011 
4012 			if (!lp_unix_extensions()) {
4013 				return NT_STATUS_INVALID_LEVEL;
4014 			}
4015 
4016 			switch (conn->encrypt_level) {
4017 			case SMB_SIGNING_OFF:
4018 				encrypt_caps = 0;
4019 				break;
4020 			case SMB_SIGNING_DESIRED:
4021 			case SMB_SIGNING_IF_REQUIRED:
4022 			case SMB_SIGNING_DEFAULT:
4023 				encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP;
4024 				break;
4025 			case SMB_SIGNING_REQUIRED:
4026 				encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP|
4027 						CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP;
4028 				large_write = false;
4029 				large_read = false;
4030 				break;
4031 			}
4032 
4033 			data_len = 12;
4034 			SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
4035 			SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
4036 
4037 			/* We have POSIX ACLs, pathname, encryption,
4038 			 * large read/write, and locking capability. */
4039 
4040 			SBIG_UINT(pdata,4,((uint64_t)(
4041 					CIFS_UNIX_POSIX_ACLS_CAP|
4042 					CIFS_UNIX_POSIX_PATHNAMES_CAP|
4043 					CIFS_UNIX_FCNTL_LOCKS_CAP|
4044 					CIFS_UNIX_EXTATTR_CAP|
4045 					CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP|
4046 					encrypt_caps|
4047 					(large_read ? CIFS_UNIX_LARGE_READ_CAP : 0) |
4048 					(large_write ?
4049 					CIFS_UNIX_LARGE_WRITE_CAP : 0))));
4050 			break;
4051 		}
4052 
4053 		case SMB_QUERY_POSIX_FS_INFO:
4054 		{
4055 			int rc;
4056 			vfs_statvfs_struct svfs;
4057 
4058 			if (!lp_unix_extensions()) {
4059 				return NT_STATUS_INVALID_LEVEL;
4060 			}
4061 
4062 			rc = SMB_VFS_STATVFS(conn, &smb_fname, &svfs);
4063 
4064 			if (!rc) {
4065 				data_len = 56;
4066 				SIVAL(pdata,0,svfs.OptimalTransferSize);
4067 				SIVAL(pdata,4,svfs.BlockSize);
4068 				SBIG_UINT(pdata,8,svfs.TotalBlocks);
4069 				SBIG_UINT(pdata,16,svfs.BlocksAvail);
4070 				SBIG_UINT(pdata,24,svfs.UserBlocksAvail);
4071 				SBIG_UINT(pdata,32,svfs.TotalFileNodes);
4072 				SBIG_UINT(pdata,40,svfs.FreeFileNodes);
4073 				SBIG_UINT(pdata,48,svfs.FsIdentifier);
4074 				DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
4075 #ifdef EOPNOTSUPP
4076 			} else if (rc == EOPNOTSUPP) {
4077 				return NT_STATUS_INVALID_LEVEL;
4078 #endif /* EOPNOTSUPP */
4079 			} else {
4080 				DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4081 				return NT_STATUS_DOS(ERRSRV, ERRerror);
4082 			}
4083 			break;
4084 		}
4085 
4086 		case SMB_QUERY_POSIX_WHOAMI:
4087 		{
4088 			uint32_t flags = 0;
4089 			uint32_t sid_bytes;
4090 			int i;
4091 
4092 			if (!lp_unix_extensions()) {
4093 				return NT_STATUS_INVALID_LEVEL;
4094 			}
4095 
4096 			if (max_data_bytes < 40) {
4097 				return NT_STATUS_BUFFER_TOO_SMALL;
4098 			}
4099 
4100 			if (security_session_user_level(conn->session_info, NULL) < SECURITY_USER) {
4101 				flags |= SMB_WHOAMI_GUEST;
4102 			}
4103 
4104 			/* NOTE: 8 bytes for UID/GID, irrespective of native
4105 			 * platform size. This matches
4106 			 * SMB_QUERY_FILE_UNIX_BASIC and friends.
4107 			 */
4108 			data_len = 4 /* flags */
4109 			    + 4 /* flag mask */
4110 			    + 8 /* uid */
4111 			    + 8 /* gid */
4112 			    + 4 /* ngroups */
4113 			    + 4 /* num_sids */
4114 			    + 4 /* SID bytes */
4115 			    + 4 /* pad/reserved */
4116 			    + (conn->session_info->unix_token->ngroups * 8)
4117 				/* groups list */
4118 			    + (conn->session_info->security_token->num_sids *
4119 				    SID_MAX_SIZE)
4120 				/* SID list */;
4121 
4122 			SIVAL(pdata, 0, flags);
4123 			SIVAL(pdata, 4, SMB_WHOAMI_MASK);
4124 			SBIG_UINT(pdata, 8,
4125 				  (uint64_t)conn->session_info->unix_token->uid);
4126 			SBIG_UINT(pdata, 16,
4127 				  (uint64_t)conn->session_info->unix_token->gid);
4128 
4129 
4130 			if (data_len >= max_data_bytes) {
4131 				/* Potential overflow, skip the GIDs and SIDs. */
4132 
4133 				SIVAL(pdata, 24, 0); /* num_groups */
4134 				SIVAL(pdata, 28, 0); /* num_sids */
4135 				SIVAL(pdata, 32, 0); /* num_sid_bytes */
4136 				SIVAL(pdata, 36, 0); /* reserved */
4137 
4138 				data_len = 40;
4139 				break;
4140 			}
4141 
4142 			SIVAL(pdata, 24, conn->session_info->unix_token->ngroups);
4143 			SIVAL(pdata, 28, conn->session_info->security_token->num_sids);
4144 
4145 			/* We walk the SID list twice, but this call is fairly
4146 			 * infrequent, and I don't expect that it's performance
4147 			 * sensitive -- jpeach
4148 			 */
4149 			for (i = 0, sid_bytes = 0;
4150 			     i < conn->session_info->security_token->num_sids; ++i) {
4151 				sid_bytes += ndr_size_dom_sid(
4152 					&conn->session_info->security_token->sids[i],
4153 					0);
4154 			}
4155 
4156 			/* SID list byte count */
4157 			SIVAL(pdata, 32, sid_bytes);
4158 
4159 			/* 4 bytes pad/reserved - must be zero */
4160 			SIVAL(pdata, 36, 0);
4161 			data_len = 40;
4162 
4163 			/* GID list */
4164 			for (i = 0; i < conn->session_info->unix_token->ngroups; ++i) {
4165 				SBIG_UINT(pdata, data_len,
4166 					  (uint64_t)conn->session_info->unix_token->groups[i]);
4167 				data_len += 8;
4168 			}
4169 
4170 			/* SID list */
4171 			for (i = 0;
4172 			    i < conn->session_info->security_token->num_sids; ++i) {
4173 				int sid_len = ndr_size_dom_sid(
4174 					&conn->session_info->security_token->sids[i],
4175 					0);
4176 
4177 				sid_linearize((uint8_t *)(pdata + data_len),
4178 					      sid_len,
4179 				    &conn->session_info->security_token->sids[i]);
4180 				data_len += sid_len;
4181 			}
4182 
4183 			break;
4184 		}
4185 
4186 		case SMB_MAC_QUERY_FS_INFO:
4187 			/*
4188 			 * Thursby MAC extension... ONLY on NTFS filesystems
4189 			 * once we do streams then we don't need this
4190 			 */
4191 			if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
4192 				data_len = 88;
4193 				SIVAL(pdata,84,0x100); /* Don't support mac... */
4194 				break;
4195 			}
4196 
4197 			FALL_THROUGH;
4198 		default:
4199 			return NT_STATUS_INVALID_LEVEL;
4200 	}
4201 
4202 	*ret_data_len = data_len;
4203 	return status;
4204 }
4205 
smb_set_fsquota(connection_struct * conn,struct smb_request * req,files_struct * fsp,const DATA_BLOB * qdata)4206 static NTSTATUS smb_set_fsquota(connection_struct *conn,
4207 			struct smb_request *req,
4208 			files_struct *fsp,
4209 			const DATA_BLOB *qdata)
4210 {
4211 	const struct loadparm_substitution *lp_sub =
4212 		loadparm_s3_global_substitution();
4213 	NTSTATUS status;
4214 	SMB_NTQUOTA_STRUCT quotas;
4215 
4216 	ZERO_STRUCT(quotas);
4217 
4218 	/* access check */
4219 	if ((get_current_uid(conn) != 0) || !CAN_WRITE(conn)) {
4220 		DEBUG(3, ("set_fsquota: access_denied service [%s] user [%s]\n",
4221 			  lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
4222 			  conn->session_info->unix_info->unix_name));
4223 		return NT_STATUS_ACCESS_DENIED;
4224 	}
4225 
4226 	if (!check_fsp_ntquota_handle(conn, req,
4227 				      fsp)) {
4228 		DEBUG(1, ("set_fsquota: no valid QUOTA HANDLE\n"));
4229 		return NT_STATUS_INVALID_HANDLE;
4230 	}
4231 
4232 	/* note: normally there're 48 bytes,
4233 	 * but we didn't use the last 6 bytes for now
4234 	 * --metze
4235 	 */
4236 	if (qdata->length < 42) {
4237 		DEBUG(0,("set_fsquota: requires total_data(%u) >= 42 bytes!\n",
4238 			(unsigned int)qdata->length));
4239 		return NT_STATUS_INVALID_PARAMETER;
4240 	}
4241 
4242 	/* unknown_1 24 NULL bytes in pdata*/
4243 
4244 	/* the soft quotas 8 bytes (uint64_t)*/
4245 	quotas.softlim = BVAL(qdata->data,24);
4246 
4247 	/* the hard quotas 8 bytes (uint64_t)*/
4248 	quotas.hardlim = BVAL(qdata->data,32);
4249 
4250 	/* quota_flags 2 bytes **/
4251 	quotas.qflags = SVAL(qdata->data,40);
4252 
4253 	/* unknown_2 6 NULL bytes follow*/
4254 
4255 	/* now set the quotas */
4256 	if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
4257 		DEBUG(1, ("vfs_set_ntquota() failed for service [%s]\n",
4258 			  lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4259 		status =  map_nt_error_from_unix(errno);
4260 	} else {
4261 		status = NT_STATUS_OK;
4262 	}
4263 	return status;
4264 }
4265 
smbd_do_setfsinfo(connection_struct * conn,struct smb_request * req,TALLOC_CTX * mem_ctx,uint16_t info_level,files_struct * fsp,const DATA_BLOB * pdata)4266 NTSTATUS smbd_do_setfsinfo(connection_struct *conn,
4267                                 struct smb_request *req,
4268                                 TALLOC_CTX *mem_ctx,
4269                                 uint16_t info_level,
4270                                 files_struct *fsp,
4271 				const DATA_BLOB *pdata)
4272 {
4273 	switch (info_level) {
4274 		case SMB_FS_QUOTA_INFORMATION:
4275 		{
4276 			return smb_set_fsquota(conn,
4277 						req,
4278 						fsp,
4279 						pdata);
4280 		}
4281 
4282 		default:
4283 			break;
4284 	}
4285 	return NT_STATUS_INVALID_LEVEL;
4286 }
4287 
4288 /****************************************************************************
4289  Reply to a TRANS2_QFSINFO (query filesystem info).
4290 ****************************************************************************/
4291 
call_trans2qfsinfo(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)4292 static void call_trans2qfsinfo(connection_struct *conn,
4293 			       struct smb_request *req,
4294 			       char **pparams, int total_params,
4295 			       char **ppdata, int total_data,
4296 			       unsigned int max_data_bytes)
4297 {
4298 	char *params = *pparams;
4299 	uint16_t info_level;
4300 	int data_len = 0;
4301 	size_t fixed_portion;
4302 	NTSTATUS status;
4303 
4304 	if (total_params < 2) {
4305 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4306 		return;
4307 	}
4308 
4309 	info_level = SVAL(params,0);
4310 
4311 	if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
4312 		if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
4313 			DEBUG(0,("call_trans2qfsinfo: encryption required "
4314 				"and info level 0x%x sent.\n",
4315 				(unsigned int)info_level));
4316 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4317 			return;
4318 		}
4319 	}
4320 
4321 	DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
4322 
4323 	status = smbd_do_qfsinfo(req->xconn, conn, req,
4324 				 info_level,
4325 				 req->flags2,
4326 				 max_data_bytes,
4327 				 &fixed_portion,
4328 				 NULL,
4329 				 ppdata, &data_len);
4330 	if (!NT_STATUS_IS_OK(status)) {
4331 		reply_nterror(req, status);
4332 		return;
4333 	}
4334 
4335 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 0, *ppdata, data_len,
4336 			    max_data_bytes);
4337 
4338 	DEBUG( 4, ( "%s info_level = %d\n",
4339 		    smb_fn_name(req->cmd), info_level) );
4340 
4341 	return;
4342 }
4343 
4344 /****************************************************************************
4345  Reply to a TRANS2_SETFSINFO (set filesystem info).
4346 ****************************************************************************/
4347 
call_trans2setfsinfo(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)4348 static void call_trans2setfsinfo(connection_struct *conn,
4349 				 struct smb_request *req,
4350 				 char **pparams, int total_params,
4351 				 char **ppdata, int total_data,
4352 				 unsigned int max_data_bytes)
4353 {
4354 	const struct loadparm_substitution *lp_sub =
4355 		loadparm_s3_global_substitution();
4356 	struct smbXsrv_connection *xconn = req->xconn;
4357 	char *pdata = *ppdata;
4358 	char *params = *pparams;
4359 	uint16_t info_level;
4360 
4361 	DEBUG(10,("call_trans2setfsinfo: for service [%s]\n",
4362 		  lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4363 
4364 	/*  */
4365 	if (total_params < 4) {
4366 		DEBUG(0,("call_trans2setfsinfo: requires total_params(%d) >= 4 bytes!\n",
4367 			total_params));
4368 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
4369 		return;
4370 	}
4371 
4372 	info_level = SVAL(params,2);
4373 
4374 	if (IS_IPC(conn)) {
4375 		if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION &&
4376 				info_level != SMB_SET_CIFS_UNIX_INFO) {
4377 			DEBUG(0,("call_trans2setfsinfo: not an allowed "
4378 				"info level (0x%x) on IPC$.\n",
4379 				(unsigned int)info_level));
4380 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4381 			return;
4382 		}
4383 	}
4384 
4385 	if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
4386 		if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
4387 			DEBUG(0,("call_trans2setfsinfo: encryption required "
4388 				"and info level 0x%x sent.\n",
4389 				(unsigned int)info_level));
4390 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
4391 			return;
4392 		}
4393 	}
4394 
4395 	switch(info_level) {
4396 		case SMB_SET_CIFS_UNIX_INFO:
4397 			if (!lp_unix_extensions()) {
4398 				DEBUG(2,("call_trans2setfsinfo: "
4399 					"SMB_SET_CIFS_UNIX_INFO is invalid with "
4400 					"unix extensions off\n"));
4401 				reply_nterror(req,
4402 					      NT_STATUS_INVALID_LEVEL);
4403 				return;
4404 			}
4405 
4406 			/* There should be 12 bytes of capabilities set. */
4407 			if (total_data < 12) {
4408 				reply_nterror(
4409 					req,
4410 					NT_STATUS_INVALID_PARAMETER);
4411 				return;
4412 			}
4413 			xconn->smb1.unix_info.client_major = SVAL(pdata,0);
4414 			xconn->smb1.unix_info.client_minor = SVAL(pdata,2);
4415 			xconn->smb1.unix_info.client_cap_low = IVAL(pdata,4);
4416 			xconn->smb1.unix_info.client_cap_high = IVAL(pdata,8);
4417 			/* Just print these values for now. */
4418 			DEBUG(10, ("call_trans2setfsinfo: set unix_info info. "
4419 				   "major = %u, minor = %u cap_low = 0x%x, "
4420 				   "cap_high = 0x%xn",
4421 				   (unsigned int)xconn->
4422 				   smb1.unix_info.client_major,
4423 				   (unsigned int)xconn->
4424 				   smb1.unix_info.client_minor,
4425 				   (unsigned int)xconn->
4426 				   smb1.unix_info.client_cap_low,
4427 				   (unsigned int)xconn->
4428 				   smb1.unix_info.client_cap_high));
4429 
4430 			/* Here is where we must switch to posix pathname processing... */
4431 			if (xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
4432 				lp_set_posix_pathnames();
4433 				mangle_change_to_posix();
4434 			}
4435 
4436 			if ((xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) &&
4437 			    !(xconn->smb1.unix_info.client_cap_low & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP)) {
4438 				/* Client that knows how to do posix locks,
4439 				 * but not posix open/mkdir operations. Set a
4440 				 * default type for read/write checks. */
4441 
4442 				lp_set_posix_default_cifsx_readwrite_locktype(POSIX_LOCK);
4443 
4444 			}
4445 			break;
4446 
4447 		case SMB_REQUEST_TRANSPORT_ENCRYPTION:
4448 			{
4449 				NTSTATUS status;
4450 				size_t param_len = 0;
4451 				size_t data_len = total_data;
4452 
4453 				if (!lp_unix_extensions()) {
4454 					reply_nterror(
4455 						req,
4456 						NT_STATUS_INVALID_LEVEL);
4457 					return;
4458 				}
4459 
4460 				if (lp_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) {
4461 					reply_nterror(
4462 						req,
4463 						NT_STATUS_NOT_SUPPORTED);
4464 					return;
4465 				}
4466 
4467 				if (xconn->smb1.echo_handler.trusted_fde) {
4468 					DEBUG( 2,("call_trans2setfsinfo: "
4469 						"request transport encryption disabled"
4470 						"with 'fork echo handler = yes'\n"));
4471 					reply_nterror(
4472 						req,
4473 						NT_STATUS_NOT_SUPPORTED);
4474 					return;
4475 				}
4476 
4477 				DEBUG( 4,("call_trans2setfsinfo: "
4478 					"request transport encryption.\n"));
4479 
4480 				status = srv_request_encryption_setup(conn,
4481 								(unsigned char **)ppdata,
4482 								&data_len,
4483 								(unsigned char **)pparams,
4484 								&param_len);
4485 
4486 				if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
4487 						!NT_STATUS_IS_OK(status)) {
4488 					reply_nterror(req, status);
4489 					return;
4490 				}
4491 
4492 				send_trans2_replies(conn, req,
4493 						NT_STATUS_OK,
4494 						*pparams,
4495 						param_len,
4496 						*ppdata,
4497 						data_len,
4498 						max_data_bytes);
4499 
4500 				if (NT_STATUS_IS_OK(status)) {
4501 					/* Server-side transport
4502 					 * encryption is now *on*. */
4503 					status = srv_encryption_start(conn);
4504 					if (!NT_STATUS_IS_OK(status)) {
4505 						char *reason = talloc_asprintf(talloc_tos(),
4506 									       "Failure in setting "
4507 									       "up encrypted transport: %s",
4508 									       nt_errstr(status));
4509 						exit_server_cleanly(reason);
4510 					}
4511 				}
4512 				return;
4513 			}
4514 
4515 		case SMB_FS_QUOTA_INFORMATION:
4516 			{
4517 				NTSTATUS status;
4518 				DATA_BLOB qdata = {
4519 						.data = (uint8_t *)pdata,
4520 						.length = total_data
4521 				};
4522 				files_struct *fsp = NULL;
4523 				fsp = file_fsp(req, SVAL(params,0));
4524 
4525 				status = smb_set_fsquota(conn,
4526 							req,
4527 							fsp,
4528 							&qdata);
4529 				if (!NT_STATUS_IS_OK(status)) {
4530 					reply_nterror(req, status);
4531 					return;
4532 				}
4533 				break;
4534 			}
4535 		default:
4536 			DEBUG(3,("call_trans2setfsinfo: unknown level (0x%X) not implemented yet.\n",
4537 				info_level));
4538 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
4539 			return;
4540 			break;
4541 	}
4542 
4543 	/*
4544 	 * sending this reply works fine,
4545 	 * but I'm not sure it's the same
4546 	 * like windows do...
4547 	 * --metze
4548 	 */
4549 	reply_outbuf(req, 10, 0);
4550 }
4551 
4552 #if defined(HAVE_POSIX_ACLS)
4553 /****************************************************************************
4554  Utility function to count the number of entries in a POSIX acl.
4555 ****************************************************************************/
4556 
count_acl_entries(connection_struct * conn,SMB_ACL_T posix_acl)4557 static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
4558 {
4559 	unsigned int ace_count = 0;
4560 	int entry_id = SMB_ACL_FIRST_ENTRY;
4561 	SMB_ACL_ENTRY_T entry;
4562 
4563 	while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
4564 		/* get_next... */
4565 		if (entry_id == SMB_ACL_FIRST_ENTRY) {
4566 			entry_id = SMB_ACL_NEXT_ENTRY;
4567 		}
4568 		ace_count++;
4569 	}
4570 	return ace_count;
4571 }
4572 
4573 /****************************************************************************
4574  Utility function to marshall a POSIX acl into wire format.
4575 ****************************************************************************/
4576 
marshall_posix_acl(connection_struct * conn,char * pdata,SMB_STRUCT_STAT * pst,SMB_ACL_T posix_acl)4577 static bool marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
4578 {
4579 	int entry_id = SMB_ACL_FIRST_ENTRY;
4580 	SMB_ACL_ENTRY_T entry;
4581 
4582 	while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) {
4583 		SMB_ACL_TAG_T tagtype;
4584 		SMB_ACL_PERMSET_T permset;
4585 		unsigned char perms = 0;
4586 		unsigned int own_grp;
4587 
4588 		/* get_next... */
4589 		if (entry_id == SMB_ACL_FIRST_ENTRY) {
4590 			entry_id = SMB_ACL_NEXT_ENTRY;
4591 		}
4592 
4593 		if (sys_acl_get_tag_type(entry, &tagtype) == -1) {
4594 			DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
4595 			return False;
4596 		}
4597 
4598 		if (sys_acl_get_permset(entry, &permset) == -1) {
4599 			DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
4600 			return False;
4601 		}
4602 
4603 		perms |= (sys_acl_get_perm(permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
4604 		perms |= (sys_acl_get_perm(permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
4605 		perms |= (sys_acl_get_perm(permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
4606 
4607 		SCVAL(pdata,1,perms);
4608 
4609 		switch (tagtype) {
4610 			case SMB_ACL_USER_OBJ:
4611 				SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
4612 				own_grp = (unsigned int)pst->st_ex_uid;
4613 				SIVAL(pdata,2,own_grp);
4614 				SIVAL(pdata,6,0);
4615 				break;
4616 			case SMB_ACL_USER:
4617 				{
4618 					uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry);
4619 					if (!puid) {
4620 						DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4621 						return False;
4622 					}
4623 					own_grp = (unsigned int)*puid;
4624 					SCVAL(pdata,0,SMB_POSIX_ACL_USER);
4625 					SIVAL(pdata,2,own_grp);
4626 					SIVAL(pdata,6,0);
4627 					break;
4628 				}
4629 			case SMB_ACL_GROUP_OBJ:
4630 				SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
4631 				own_grp = (unsigned int)pst->st_ex_gid;
4632 				SIVAL(pdata,2,own_grp);
4633 				SIVAL(pdata,6,0);
4634 				break;
4635 			case SMB_ACL_GROUP:
4636 				{
4637 					gid_t *pgid= (gid_t *)sys_acl_get_qualifier(entry);
4638 					if (!pgid) {
4639 						DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
4640 						return False;
4641 					}
4642 					own_grp = (unsigned int)*pgid;
4643 					SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
4644 					SIVAL(pdata,2,own_grp);
4645 					SIVAL(pdata,6,0);
4646 					break;
4647 				}
4648 			case SMB_ACL_MASK:
4649 				SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
4650 				SIVAL(pdata,2,0xFFFFFFFF);
4651 				SIVAL(pdata,6,0xFFFFFFFF);
4652 				break;
4653 			case SMB_ACL_OTHER:
4654 				SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
4655 				SIVAL(pdata,2,0xFFFFFFFF);
4656 				SIVAL(pdata,6,0xFFFFFFFF);
4657 				break;
4658 			default:
4659 				DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
4660 				return False;
4661 		}
4662 		pdata += SMB_POSIX_ACL_ENTRY_SIZE;
4663 	}
4664 
4665 	return True;
4666 }
4667 #endif
4668 
4669 /****************************************************************************
4670  Store the FILE_UNIX_BASIC info.
4671 ****************************************************************************/
4672 
store_file_unix_basic(connection_struct * conn,char * pdata,files_struct * fsp,const SMB_STRUCT_STAT * psbuf)4673 static char *store_file_unix_basic(connection_struct *conn,
4674 				char *pdata,
4675 				files_struct *fsp,
4676 				const SMB_STRUCT_STAT *psbuf)
4677 {
4678 	dev_t devno;
4679 
4680 	DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
4681 	DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
4682 
4683 	SOFF_T(pdata,0,get_file_size_stat(psbuf));             /* File size 64 Bit */
4684 	pdata += 8;
4685 
4686 	SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
4687 	pdata += 8;
4688 
4689 	put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, &psbuf->st_ex_ctime);       /* Change Time 64 Bit */
4690 	put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, &psbuf->st_ex_atime);     /* Last access time 64 Bit */
4691 	put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, &psbuf->st_ex_mtime);    /* Last modification time 64 Bit */
4692 	pdata += 24;
4693 
4694 	SIVAL(pdata,0,psbuf->st_ex_uid);               /* user id for the owner */
4695 	SIVAL(pdata,4,0);
4696 	pdata += 8;
4697 
4698 	SIVAL(pdata,0,psbuf->st_ex_gid);               /* group id of owner */
4699 	SIVAL(pdata,4,0);
4700 	pdata += 8;
4701 
4702 	SIVAL(pdata,0,unix_filetype(psbuf->st_ex_mode));
4703 	pdata += 4;
4704 
4705 	if (S_ISBLK(psbuf->st_ex_mode) || S_ISCHR(psbuf->st_ex_mode)) {
4706 		devno = psbuf->st_ex_rdev;
4707 	} else {
4708 		devno = psbuf->st_ex_dev;
4709 	}
4710 
4711 	SIVAL(pdata,0,unix_dev_major(devno));   /* Major device number if type is device */
4712 	SIVAL(pdata,4,0);
4713 	pdata += 8;
4714 
4715 	SIVAL(pdata,0,unix_dev_minor(devno));   /* Minor device number if type is device */
4716 	SIVAL(pdata,4,0);
4717 	pdata += 8;
4718 
4719 	SINO_T_VAL(pdata, 0, psbuf->st_ex_ino);   /* inode number */
4720 	pdata += 8;
4721 
4722 	SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard UNIX file permissions */
4723 	SIVAL(pdata,4,0);
4724 	pdata += 8;
4725 
4726 	SIVAL(pdata,0,psbuf->st_ex_nlink);             /* number of hard links */
4727 	SIVAL(pdata,4,0);
4728 	pdata += 8;
4729 
4730 	return pdata;
4731 }
4732 
4733 /* Forward and reverse mappings from the UNIX_INFO2 file flags field and
4734  * the chflags(2) (or equivalent) flags.
4735  *
4736  * XXX: this really should be behind the VFS interface. To do this, we would
4737  * need to alter SMB_STRUCT_STAT so that it included a flags and a mask field.
4738  * Each VFS module could then implement its own mapping as appropriate for the
4739  * platform. We would then pass the SMB flags into SMB_VFS_CHFLAGS.
4740  */
4741 static const struct {unsigned stat_fflag; unsigned smb_fflag;}
4742 	info2_flags_map[] =
4743 {
4744 #ifdef UF_NODUMP
4745     { UF_NODUMP, EXT_DO_NOT_BACKUP },
4746 #endif
4747 
4748 #ifdef UF_IMMUTABLE
4749     { UF_IMMUTABLE, EXT_IMMUTABLE },
4750 #endif
4751 
4752 #ifdef UF_APPEND
4753     { UF_APPEND, EXT_OPEN_APPEND_ONLY },
4754 #endif
4755 
4756 #ifdef UF_HIDDEN
4757     { UF_HIDDEN, EXT_HIDDEN },
4758 #endif
4759 
4760     /* Do not remove. We need to guarantee that this array has at least one
4761      * entry to build on HP-UX.
4762      */
4763     { 0, 0 }
4764 
4765 };
4766 
map_info2_flags_from_sbuf(const SMB_STRUCT_STAT * psbuf,uint32_t * smb_fflags,uint32_t * smb_fmask)4767 static void map_info2_flags_from_sbuf(const SMB_STRUCT_STAT *psbuf,
4768 				uint32_t *smb_fflags, uint32_t *smb_fmask)
4769 {
4770 	int i;
4771 
4772 	for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4773 	    *smb_fmask |= info2_flags_map[i].smb_fflag;
4774 	    if (psbuf->st_ex_flags & info2_flags_map[i].stat_fflag) {
4775 		    *smb_fflags |= info2_flags_map[i].smb_fflag;
4776 	    }
4777 	}
4778 }
4779 
map_info2_flags_to_sbuf(const SMB_STRUCT_STAT * psbuf,const uint32_t smb_fflags,const uint32_t smb_fmask,int * stat_fflags)4780 static bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf,
4781 				const uint32_t smb_fflags,
4782 				const uint32_t smb_fmask,
4783 				int *stat_fflags)
4784 {
4785 	uint32_t max_fmask = 0;
4786 	int i;
4787 
4788 	*stat_fflags = psbuf->st_ex_flags;
4789 
4790 	/* For each flags requested in smb_fmask, check the state of the
4791 	 * corresponding flag in smb_fflags and set or clear the matching
4792 	 * stat flag.
4793 	 */
4794 
4795 	for (i = 0; i < ARRAY_SIZE(info2_flags_map); ++i) {
4796 	    max_fmask |= info2_flags_map[i].smb_fflag;
4797 	    if (smb_fmask & info2_flags_map[i].smb_fflag) {
4798 		    if (smb_fflags & info2_flags_map[i].smb_fflag) {
4799 			    *stat_fflags |= info2_flags_map[i].stat_fflag;
4800 		    } else {
4801 			    *stat_fflags &= ~info2_flags_map[i].stat_fflag;
4802 		    }
4803 	    }
4804 	}
4805 
4806 	/* If smb_fmask is asking to set any bits that are not supported by
4807 	 * our flag mappings, we should fail.
4808 	 */
4809 	if ((smb_fmask & max_fmask) != smb_fmask) {
4810 		return False;
4811 	}
4812 
4813 	return True;
4814 }
4815 
4816 
4817 /* Just like SMB_QUERY_FILE_UNIX_BASIC, but with the addition
4818  * of file flags and birth (create) time.
4819  */
store_file_unix_basic_info2(connection_struct * conn,char * pdata,files_struct * fsp,const SMB_STRUCT_STAT * psbuf)4820 static char *store_file_unix_basic_info2(connection_struct *conn,
4821 				char *pdata,
4822 				files_struct *fsp,
4823 				const SMB_STRUCT_STAT *psbuf)
4824 {
4825 	uint32_t file_flags = 0;
4826 	uint32_t flags_mask = 0;
4827 
4828 	pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
4829 
4830 	/* Create (birth) time 64 bit */
4831 	put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, &psbuf->st_ex_btime);
4832 	pdata += 8;
4833 
4834 	map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
4835 	SIVAL(pdata, 0, file_flags); /* flags */
4836 	SIVAL(pdata, 4, flags_mask); /* mask */
4837 	pdata += 8;
4838 
4839 	return pdata;
4840 }
4841 
marshall_stream_info(unsigned int num_streams,const struct stream_struct * streams,char * data,unsigned int max_data_bytes,unsigned int * data_size)4842 static NTSTATUS marshall_stream_info(unsigned int num_streams,
4843 				     const struct stream_struct *streams,
4844 				     char *data,
4845 				     unsigned int max_data_bytes,
4846 				     unsigned int *data_size)
4847 {
4848 	unsigned int i;
4849 	unsigned int ofs = 0;
4850 
4851 	if (max_data_bytes < 32) {
4852 		return NT_STATUS_INFO_LENGTH_MISMATCH;
4853 	}
4854 
4855 	for (i = 0; i < num_streams; i++) {
4856 		unsigned int next_offset;
4857 		size_t namelen;
4858 		smb_ucs2_t *namebuf;
4859 
4860 		if (!push_ucs2_talloc(talloc_tos(), &namebuf,
4861 				      streams[i].name, &namelen) ||
4862 		    namelen <= 2)
4863 		{
4864 			return NT_STATUS_INVALID_PARAMETER;
4865 		}
4866 
4867 		/*
4868 		 * name_buf is now null-terminated, we need to marshall as not
4869 		 * terminated
4870 		 */
4871 
4872 		namelen -= 2;
4873 
4874 		/*
4875 		 * We cannot overflow ...
4876 		 */
4877 		if ((ofs + 24 + namelen) > max_data_bytes) {
4878 			DEBUG(10, ("refusing to overflow reply at stream %u\n",
4879 				i));
4880 			TALLOC_FREE(namebuf);
4881 			return STATUS_BUFFER_OVERFLOW;
4882 		}
4883 
4884 		SIVAL(data, ofs+4, namelen);
4885 		SOFF_T(data, ofs+8, streams[i].size);
4886 		SOFF_T(data, ofs+16, streams[i].alloc_size);
4887 		memcpy(data+ofs+24, namebuf, namelen);
4888 		TALLOC_FREE(namebuf);
4889 
4890 		next_offset = ofs + 24 + namelen;
4891 
4892 		if (i == num_streams-1) {
4893 			SIVAL(data, ofs, 0);
4894 		}
4895 		else {
4896 			unsigned int align = ndr_align_size(next_offset, 8);
4897 
4898 			if ((next_offset + align) > max_data_bytes) {
4899 				DEBUG(10, ("refusing to overflow align "
4900 					"reply at stream %u\n",
4901 					i));
4902 				TALLOC_FREE(namebuf);
4903 				return STATUS_BUFFER_OVERFLOW;
4904 			}
4905 
4906 			memset(data+next_offset, 0, align);
4907 			next_offset += align;
4908 
4909 			SIVAL(data, ofs, next_offset - ofs);
4910 			ofs = next_offset;
4911 		}
4912 
4913 		ofs = next_offset;
4914 	}
4915 
4916 	DEBUG(10, ("max_data: %u, data_size: %u\n", max_data_bytes, ofs));
4917 
4918 	*data_size = ofs;
4919 
4920 	return NT_STATUS_OK;
4921 }
4922 
4923 #if defined(HAVE_POSIX_ACLS)
smb_query_posix_acl(connection_struct * conn,struct smb_request * req,files_struct * fsp,struct smb_filename * smb_fname,char * pdata,unsigned int data_size_in,unsigned int * pdata_size_out)4924 static NTSTATUS smb_query_posix_acl(connection_struct *conn,
4925 				struct smb_request *req,
4926 				files_struct *fsp,
4927 				struct smb_filename *smb_fname,
4928 				char *pdata,
4929 				unsigned int data_size_in,
4930 				unsigned int *pdata_size_out)
4931 {
4932 	SMB_ACL_T file_acl = NULL;
4933 	SMB_ACL_T def_acl = NULL;
4934 	uint16_t num_file_acls = 0;
4935 	uint16_t num_def_acls = 0;
4936 	unsigned int size_needed = 0;
4937 	NTSTATUS status;
4938 	bool ok;
4939 	bool close_fsp = false;
4940 
4941 	/*
4942 	 * Ensure we always operate on a file descriptor, not just
4943 	 * the filename.
4944 	 */
4945 	if (fsp == NULL) {
4946 		uint32_t access_mask = SEC_STD_READ_CONTROL|
4947 					FILE_READ_ATTRIBUTES|
4948 					FILE_WRITE_ATTRIBUTES;
4949 
4950 		status = get_posix_fsp(conn,
4951 					req,
4952 					smb_fname,
4953 					access_mask,
4954 					&fsp);
4955 
4956 		if (!NT_STATUS_IS_OK(status)) {
4957 			goto out;
4958 		}
4959 		close_fsp = true;
4960 	}
4961 
4962 	SMB_ASSERT(fsp != NULL);
4963 
4964 	status = refuse_symlink(conn,
4965 				fsp,
4966 				fsp->fsp_name);
4967 	if (!NT_STATUS_IS_OK(status)) {
4968 		goto out;
4969 	}
4970 
4971 	file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp,
4972 					talloc_tos());
4973 
4974 	if (file_acl == NULL && no_acl_syscall_error(errno)) {
4975 		DBG_INFO("ACLs not implemented on "
4976 			"filesystem containing %s\n",
4977 			fsp_str_dbg(fsp));
4978 		status = NT_STATUS_NOT_IMPLEMENTED;
4979 		goto out;
4980 	}
4981 
4982 	if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4983 		/*
4984 		 * We can only have default POSIX ACLs on
4985 		 * directories.
4986 		 */
4987 		if (!fsp->is_directory) {
4988 			DBG_INFO("Non-directory open %s\n",
4989 				fsp_str_dbg(fsp));
4990 			status = NT_STATUS_INVALID_HANDLE;
4991 			goto out;
4992 		}
4993 		def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn,
4994 					fsp->fsp_name,
4995 					SMB_ACL_TYPE_DEFAULT,
4996 					talloc_tos());
4997 		def_acl = free_empty_sys_acl(conn, def_acl);
4998 	}
4999 
5000 	num_file_acls = count_acl_entries(conn, file_acl);
5001 	num_def_acls = count_acl_entries(conn, def_acl);
5002 
5003 	/* Wrap checks. */
5004 	if (num_file_acls + num_def_acls < num_file_acls) {
5005 		status = NT_STATUS_INVALID_PARAMETER;
5006 		goto out;
5007 	}
5008 
5009 	size_needed = num_file_acls + num_def_acls;
5010 
5011 	/*
5012 	 * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
5013 	 * than UINT_MAX, so check by division.
5014 	 */
5015 	if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
5016 		status = NT_STATUS_INVALID_PARAMETER;
5017 		goto out;
5018 	}
5019 
5020 	size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
5021 	if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
5022 		status = NT_STATUS_INVALID_PARAMETER;
5023 		goto out;
5024 	}
5025 	size_needed += SMB_POSIX_ACL_HEADER_SIZE;
5026 
5027 	if ( data_size_in < size_needed) {
5028 		DBG_INFO("data_size too small (%u) need %u\n",
5029 			data_size_in,
5030 			size_needed);
5031 		status = NT_STATUS_BUFFER_TOO_SMALL;
5032 		goto out;
5033 	}
5034 
5035 	SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
5036 	SSVAL(pdata,2,num_file_acls);
5037 	SSVAL(pdata,4,num_def_acls);
5038 	pdata += SMB_POSIX_ACL_HEADER_SIZE;
5039 
5040 	ok = marshall_posix_acl(conn,
5041 			pdata,
5042 			&fsp->fsp_name->st,
5043 			file_acl);
5044 	if (!ok) {
5045 		status = NT_STATUS_INTERNAL_ERROR;
5046 		goto out;
5047 	}
5048 	pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
5049 
5050 	ok = marshall_posix_acl(conn,
5051 			pdata,
5052 			&fsp->fsp_name->st,
5053 			def_acl);
5054 	if (!ok) {
5055 		status = NT_STATUS_INTERNAL_ERROR;
5056 		goto out;
5057 	}
5058 
5059 	*pdata_size_out = size_needed;
5060 	status = NT_STATUS_OK;
5061 
5062   out:
5063 
5064 	if (close_fsp) {
5065 		/*
5066 		 * Ensure the stat struct in smb_fname is up to
5067 		 * date. Structure copy.
5068 		 */
5069 		smb_fname->st = fsp->fsp_name->st;
5070 		(void)close_file(req, fsp, NORMAL_CLOSE);
5071 		fsp = NULL;
5072 	}
5073 
5074 	TALLOC_FREE(file_acl);
5075 	TALLOC_FREE(def_acl);
5076 	return status;
5077 }
5078 #endif
5079 
5080 /****************************************************************************
5081  Reply to a TRANSACT2_QFILEINFO on a PIPE !
5082 ****************************************************************************/
5083 
call_trans2qpipeinfo(connection_struct * conn,struct smb_request * req,unsigned int tran_call,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)5084 static void call_trans2qpipeinfo(connection_struct *conn,
5085 				 struct smb_request *req,
5086 				 unsigned int tran_call,
5087 				 char **pparams, int total_params,
5088 				 char **ppdata, int total_data,
5089 				 unsigned int max_data_bytes)
5090 {
5091 	char *params = *pparams;
5092 	char *pdata = *ppdata;
5093 	unsigned int data_size = 0;
5094 	unsigned int param_size = 2;
5095 	uint16_t info_level;
5096 	files_struct *fsp;
5097 
5098 	if (!params) {
5099 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5100 		return;
5101 	}
5102 
5103 	if (total_params < 4) {
5104 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5105 		return;
5106 	}
5107 
5108 	fsp = file_fsp(req, SVAL(params,0));
5109 	if (!fsp_is_np(fsp)) {
5110 		reply_nterror(req, NT_STATUS_INVALID_HANDLE);
5111 		return;
5112 	}
5113 
5114 	info_level = SVAL(params,2);
5115 
5116 	*pparams = (char *)SMB_REALLOC(*pparams,2);
5117 	if (*pparams == NULL) {
5118 		reply_nterror(req, NT_STATUS_NO_MEMORY);
5119 		return;
5120 	}
5121 	params = *pparams;
5122 	SSVAL(params,0,0);
5123 	if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5124 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
5125 		return;
5126 	}
5127 	data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5128 	*ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
5129 	if (*ppdata == NULL ) {
5130 		reply_nterror(req, NT_STATUS_NO_MEMORY);
5131 		return;
5132 	}
5133 	pdata = *ppdata;
5134 
5135 	switch (info_level) {
5136 		case SMB_FILE_STANDARD_INFORMATION:
5137 			memset(pdata,0,24);
5138 			SOFF_T(pdata,0,4096LL);
5139 			SIVAL(pdata,16,1);
5140 			SIVAL(pdata,20,1);
5141 			data_size = 24;
5142 			break;
5143 
5144 		default:
5145 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
5146 			return;
5147 	}
5148 
5149 	send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
5150 			    max_data_bytes);
5151 
5152 	return;
5153 }
5154 
smbd_do_qfilepathinfo(connection_struct * conn,TALLOC_CTX * mem_ctx,struct smb_request * req,uint16_t info_level,files_struct * fsp,struct smb_filename * smb_fname,bool delete_pending,struct timespec write_time_ts,struct ea_list * ea_list,int lock_data_count,char * lock_data,uint16_t flags2,unsigned int max_data_bytes,size_t * fixed_portion,char ** ppdata,unsigned int * pdata_size)5155 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
5156 			       TALLOC_CTX *mem_ctx,
5157 			       struct smb_request *req,
5158 			       uint16_t info_level,
5159 			       files_struct *fsp,
5160 			       struct smb_filename *smb_fname,
5161 			       bool delete_pending,
5162 			       struct timespec write_time_ts,
5163 			       struct ea_list *ea_list,
5164 			       int lock_data_count,
5165 			       char *lock_data,
5166 			       uint16_t flags2,
5167 			       unsigned int max_data_bytes,
5168 			       size_t *fixed_portion,
5169 			       char **ppdata,
5170 			       unsigned int *pdata_size)
5171 {
5172 	char *pdata = *ppdata;
5173 	char *dstart, *dend;
5174 	unsigned int data_size;
5175 	struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
5176 	time_t create_time, mtime, atime, c_time;
5177 	SMB_STRUCT_STAT *psbuf = &smb_fname->st;
5178 	char *p;
5179 	char *base_name;
5180 	char *dos_fname;
5181 	int mode;
5182 	int nlink;
5183 	NTSTATUS status;
5184 	uint64_t file_size = 0;
5185 	uint64_t pos = 0;
5186 	uint64_t allocation_size = 0;
5187 	uint64_t file_id = 0;
5188 	uint32_t access_mask = 0;
5189 	size_t len = 0;
5190 
5191 	if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
5192 		return NT_STATUS_INVALID_LEVEL;
5193 	}
5194 
5195 	DEBUG(5,("smbd_do_qfilepathinfo: %s (%s) level=%d max_data=%u\n",
5196 		 smb_fname_str_dbg(smb_fname),
5197 		 fsp_fnum_dbg(fsp),
5198 		 info_level, max_data_bytes));
5199 
5200 	mode = dos_mode(conn, smb_fname);
5201 	nlink = psbuf->st_ex_nlink;
5202 
5203 	if (nlink && (mode&FILE_ATTRIBUTE_DIRECTORY)) {
5204 		nlink = 1;
5205 	}
5206 
5207 	if ((nlink > 0) && delete_pending) {
5208 		nlink -= 1;
5209 	}
5210 
5211 	if (max_data_bytes + DIR_ENTRY_SAFETY_MARGIN < max_data_bytes) {
5212 		return NT_STATUS_INVALID_PARAMETER;
5213 	}
5214 
5215 	data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
5216 	*ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
5217 	if (*ppdata == NULL) {
5218 		return NT_STATUS_NO_MEMORY;
5219 	}
5220 	pdata = *ppdata;
5221 	dstart = pdata;
5222 	dend = dstart + data_size - 1;
5223 
5224 	if (!is_omit_timespec(&write_time_ts) &&
5225 	    !INFO_LEVEL_IS_UNIX(info_level))
5226 	{
5227 		update_stat_ex_mtime(psbuf, write_time_ts);
5228 	}
5229 
5230 	create_time_ts = get_create_timespec(conn, fsp, smb_fname);
5231 	mtime_ts = psbuf->st_ex_mtime;
5232 	atime_ts = psbuf->st_ex_atime;
5233 	ctime_ts = get_change_timespec(conn, fsp, smb_fname);
5234 
5235 	if (lp_dos_filetime_resolution(SNUM(conn))) {
5236 		dos_filetime_timespec(&create_time_ts);
5237 		dos_filetime_timespec(&mtime_ts);
5238 		dos_filetime_timespec(&atime_ts);
5239 		dos_filetime_timespec(&ctime_ts);
5240 	}
5241 
5242 	create_time = convert_timespec_to_time_t(create_time_ts);
5243 	mtime = convert_timespec_to_time_t(mtime_ts);
5244 	atime = convert_timespec_to_time_t(atime_ts);
5245 	c_time = convert_timespec_to_time_t(ctime_ts);
5246 
5247 	p = strrchr_m(smb_fname->base_name,'/');
5248 	if (!p)
5249 		base_name = smb_fname->base_name;
5250 	else
5251 		base_name = p+1;
5252 
5253 	/* NT expects the name to be in an exact form of the *full*
5254 	   filename. See the trans2 torture test */
5255 	if (ISDOT(base_name)) {
5256 		dos_fname = talloc_strdup(mem_ctx, "\\");
5257 		if (!dos_fname) {
5258 			return NT_STATUS_NO_MEMORY;
5259 		}
5260 	} else {
5261 		dos_fname = talloc_asprintf(mem_ctx,
5262 				"\\%s",
5263 				smb_fname->base_name);
5264 		if (!dos_fname) {
5265 			return NT_STATUS_NO_MEMORY;
5266 		}
5267 		if (is_ntfs_stream_smb_fname(smb_fname)) {
5268 			dos_fname = talloc_asprintf(dos_fname, "%s",
5269 						    smb_fname->stream_name);
5270 			if (!dos_fname) {
5271 				return NT_STATUS_NO_MEMORY;
5272 			}
5273 		}
5274 
5275 		string_replace(dos_fname, '/', '\\');
5276 	}
5277 
5278 	allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
5279 
5280 	if (!fsp) {
5281 		/* Do we have this path open ? */
5282 		files_struct *fsp1;
5283 		struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
5284 		fsp1 = file_find_di_first(conn->sconn, fileid);
5285 		if (fsp1 && fsp1->initial_allocation_size) {
5286 			allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
5287 		}
5288 	}
5289 
5290 	if (!(mode & FILE_ATTRIBUTE_DIRECTORY)) {
5291 		file_size = get_file_size_stat(psbuf);
5292 	}
5293 
5294 	if (fsp) {
5295 		pos = fsp->fh->position_information;
5296 	}
5297 
5298 	if (fsp) {
5299 		access_mask = fsp->access_mask;
5300 	} else {
5301 		/* GENERIC_EXECUTE mapping from Windows */
5302 		access_mask = 0x12019F;
5303 	}
5304 
5305 	/* This should be an index number - looks like
5306 	   dev/ino to me :-)
5307 
5308 	   I think this causes us to fail the IFSKIT
5309 	   BasicFileInformationTest. -tpot */
5310 	file_id = SMB_VFS_FS_FILE_ID(conn, psbuf);
5311 
5312 	*fixed_portion = 0;
5313 
5314 	switch (info_level) {
5315 		case SMB_INFO_STANDARD:
5316 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
5317 			data_size = 22;
5318 			srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
5319 			srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
5320 			srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
5321 			SIVAL(pdata,l1_cbFile,(uint32_t)file_size);
5322 			SIVAL(pdata,l1_cbFileAlloc,(uint32_t)allocation_size);
5323 			SSVAL(pdata,l1_attrFile,mode);
5324 			break;
5325 
5326 		case SMB_INFO_QUERY_EA_SIZE:
5327 		{
5328 			unsigned int ea_size =
5329 			    estimate_ea_size(conn, fsp,
5330 					     smb_fname);
5331 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
5332 			data_size = 26;
5333 			srv_put_dos_date2(pdata,0,create_time);
5334 			srv_put_dos_date2(pdata,4,atime);
5335 			srv_put_dos_date2(pdata,8,mtime); /* write time */
5336 			SIVAL(pdata,12,(uint32_t)file_size);
5337 			SIVAL(pdata,16,(uint32_t)allocation_size);
5338 			SSVAL(pdata,20,mode);
5339 			SIVAL(pdata,22,ea_size);
5340 			break;
5341 		}
5342 
5343 		case SMB_INFO_IS_NAME_VALID:
5344 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
5345 			if (fsp) {
5346 				/* os/2 needs this ? really ?*/
5347 				return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
5348 			}
5349 			/* This is only reached for qpathinfo */
5350 			data_size = 0;
5351 			break;
5352 
5353 		case SMB_INFO_QUERY_EAS_FROM_LIST:
5354 		{
5355 			size_t total_ea_len = 0;
5356 			struct ea_list *ea_file_list = NULL;
5357 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
5358 
5359 			status =
5360 			    get_ea_list_from_file(mem_ctx, conn, fsp,
5361 						  smb_fname,
5362 						  &total_ea_len, &ea_file_list);
5363 			if (!NT_STATUS_IS_OK(status)) {
5364 				return status;
5365 			}
5366 
5367 			ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
5368 
5369 			if (!ea_list || (total_ea_len > data_size)) {
5370 				data_size = 4;
5371 				SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5372 				break;
5373 			}
5374 
5375 			data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5376 			break;
5377 		}
5378 
5379 		case SMB_INFO_QUERY_ALL_EAS:
5380 		{
5381 			/* We have data_size bytes to put EA's into. */
5382 			size_t total_ea_len = 0;
5383 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
5384 
5385 			status = get_ea_list_from_file(mem_ctx, conn, fsp,
5386 							smb_fname,
5387 							&total_ea_len, &ea_list);
5388 			if (!NT_STATUS_IS_OK(status)) {
5389 				return status;
5390 			}
5391 
5392 			if (!ea_list || (total_ea_len > data_size)) {
5393 				data_size = 4;
5394 				SIVAL(pdata,0,4);   /* EA List Length must be set to 4 if no EA's. */
5395 				break;
5396 			}
5397 
5398 			data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
5399 			break;
5400 		}
5401 
5402 		case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
5403 		{
5404 			/* This is FileFullEaInformation - 0xF which maps to
5405 			 * 1015 (decimal) in smbd_do_setfilepathinfo. */
5406 
5407 			/* We have data_size bytes to put EA's into. */
5408 			size_t total_ea_len = 0;
5409 			struct ea_list *ea_file_list = NULL;
5410 
5411 			DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
5412 
5413 			/*TODO: add filtering and index handling */
5414 
5415 			status  =
5416 				get_ea_list_from_file(mem_ctx, conn, fsp,
5417 						  smb_fname,
5418 						  &total_ea_len, &ea_file_list);
5419 			if (!NT_STATUS_IS_OK(status)) {
5420 				return status;
5421 			}
5422 			if (!ea_file_list) {
5423 				return NT_STATUS_NO_EAS_ON_FILE;
5424 			}
5425 
5426 			status = fill_ea_chained_buffer(mem_ctx,
5427 							pdata,
5428 							data_size,
5429 							&data_size,
5430 							conn, ea_file_list);
5431 			if (!NT_STATUS_IS_OK(status)) {
5432 				return status;
5433 			}
5434 			break;
5435 		}
5436 
5437 		case SMB_FILE_BASIC_INFORMATION:
5438 		case SMB_QUERY_FILE_BASIC_INFO:
5439 
5440 			if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
5441 				DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
5442 				data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
5443 			} else {
5444 				DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
5445 				data_size = 40;
5446 				SIVAL(pdata,36,0);
5447 			}
5448 			put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5449 			put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5450 			put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5451 			put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5452 			SIVAL(pdata,32,mode);
5453 
5454 			DEBUG(5,("SMB_QFBI - "));
5455 			DEBUG(5,("create: %s ", ctime(&create_time)));
5456 			DEBUG(5,("access: %s ", ctime(&atime)));
5457 			DEBUG(5,("write: %s ", ctime(&mtime)));
5458 			DEBUG(5,("change: %s ", ctime(&c_time)));
5459 			DEBUG(5,("mode: %x\n", mode));
5460 			*fixed_portion = data_size;
5461 			break;
5462 
5463 		case SMB_FILE_STANDARD_INFORMATION:
5464 		case SMB_QUERY_FILE_STANDARD_INFO:
5465 
5466 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
5467 			data_size = 24;
5468 			SOFF_T(pdata,0,allocation_size);
5469 			SOFF_T(pdata,8,file_size);
5470 			SIVAL(pdata,16,nlink);
5471 			SCVAL(pdata,20,delete_pending?1:0);
5472 			SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5473 			SSVAL(pdata,22,0); /* Padding. */
5474 			*fixed_portion = 24;
5475 			break;
5476 
5477 		case SMB_FILE_EA_INFORMATION:
5478 		case SMB_QUERY_FILE_EA_INFO:
5479 		{
5480 			unsigned int ea_size =
5481 			    estimate_ea_size(conn, fsp,	smb_fname);
5482 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
5483 			data_size = 4;
5484 			*fixed_portion = 4;
5485 			SIVAL(pdata,0,ea_size);
5486 			break;
5487 		}
5488 
5489 		/* Get the 8.3 name - used if NT SMB was negotiated. */
5490 		case SMB_QUERY_FILE_ALT_NAME_INFO:
5491 		case SMB_FILE_ALTERNATE_NAME_INFORMATION:
5492 		{
5493 			char mangled_name[13];
5494 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
5495 			if (!name_to_8_3(base_name,mangled_name,
5496 						True,conn->params)) {
5497 				return NT_STATUS_NO_MEMORY;
5498 			}
5499 			status = srvstr_push(dstart, flags2,
5500 					  pdata+4, mangled_name,
5501 					  PTR_DIFF(dend, pdata+4),
5502 					  STR_UNICODE, &len);
5503 			if (!NT_STATUS_IS_OK(status)) {
5504 				return status;
5505 			}
5506 			data_size = 4 + len;
5507 			SIVAL(pdata,0,len);
5508 			*fixed_portion = 8;
5509 			break;
5510 		}
5511 
5512 		case SMB_QUERY_FILE_NAME_INFO:
5513 		{
5514 			/*
5515 			  this must be *exactly* right for ACLs on mapped drives to work
5516 			 */
5517 			status = srvstr_push(dstart, flags2,
5518 					  pdata+4, dos_fname,
5519 					  PTR_DIFF(dend, pdata+4),
5520 					  STR_UNICODE, &len);
5521 			if (!NT_STATUS_IS_OK(status)) {
5522 				return status;
5523 			}
5524 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
5525 			data_size = 4 + len;
5526 			SIVAL(pdata,0,len);
5527 			break;
5528 		}
5529 
5530 		case SMB_FILE_NORMALIZED_NAME_INFORMATION:
5531 		{
5532 			char *nfname = NULL;
5533 
5534 			if (fsp == NULL || !fsp->conn->sconn->using_smb2) {
5535 				return NT_STATUS_INVALID_LEVEL;
5536 			}
5537 
5538 			nfname = talloc_strdup(mem_ctx, smb_fname->base_name);
5539 			if (nfname == NULL) {
5540 				return NT_STATUS_NO_MEMORY;
5541 			}
5542 
5543 			if (ISDOT(nfname)) {
5544 				nfname[0] = '\0';
5545 			}
5546 			string_replace(nfname, '/', '\\');
5547 
5548 			if (smb_fname->stream_name != NULL) {
5549 				const char *s = smb_fname->stream_name;
5550 				const char *e = NULL;
5551 				size_t n;
5552 
5553 				SMB_ASSERT(s[0] != '\0');
5554 
5555 				/*
5556 				 * smb_fname->stream_name is in form
5557 				 * of ':StrEam:$DATA', but we should only
5558 				 * append ':StrEam' here.
5559 				 */
5560 
5561 				e = strchr(&s[1], ':');
5562 				if (e == NULL) {
5563 					n = strlen(s);
5564 				} else {
5565 					n = PTR_DIFF(e, s);
5566 				}
5567 				nfname = talloc_strndup_append(nfname, s, n);
5568 				if (nfname == NULL) {
5569 					return NT_STATUS_NO_MEMORY;
5570 				}
5571 			}
5572 
5573 			status = srvstr_push(dstart, flags2,
5574 					  pdata+4, nfname,
5575 					  PTR_DIFF(dend, pdata+4),
5576 					  STR_UNICODE, &len);
5577 			if (!NT_STATUS_IS_OK(status)) {
5578 				return status;
5579 			}
5580 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n"));
5581 			data_size = 4 + len;
5582 			SIVAL(pdata,0,len);
5583 			*fixed_portion = 8;
5584 			break;
5585 		}
5586 
5587 		case SMB_FILE_ALLOCATION_INFORMATION:
5588 		case SMB_QUERY_FILE_ALLOCATION_INFO:
5589 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
5590 			data_size = 8;
5591 			SOFF_T(pdata,0,allocation_size);
5592 			break;
5593 
5594 		case SMB_FILE_END_OF_FILE_INFORMATION:
5595 		case SMB_QUERY_FILE_END_OF_FILEINFO:
5596 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
5597 			data_size = 8;
5598 			SOFF_T(pdata,0,file_size);
5599 			break;
5600 
5601 		case SMB_QUERY_FILE_ALL_INFO:
5602 		case SMB_FILE_ALL_INFORMATION:
5603 		{
5604 			unsigned int ea_size =
5605 			    estimate_ea_size(conn, fsp, smb_fname);
5606 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
5607 			put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5608 			put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5609 			put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5610 			put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5611 			SIVAL(pdata,32,mode);
5612 			SIVAL(pdata,36,0); /* padding. */
5613 			pdata += 40;
5614 			SOFF_T(pdata,0,allocation_size);
5615 			SOFF_T(pdata,8,file_size);
5616 			SIVAL(pdata,16,nlink);
5617 			SCVAL(pdata,20,delete_pending);
5618 			SCVAL(pdata,21,(mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5619 			SSVAL(pdata,22,0);
5620 			pdata += 24;
5621 			SIVAL(pdata,0,ea_size);
5622 			pdata += 4; /* EA info */
5623 			status = srvstr_push(dstart, flags2,
5624 					  pdata+4, dos_fname,
5625 					  PTR_DIFF(dend, pdata+4),
5626 					  STR_UNICODE, &len);
5627 			if (!NT_STATUS_IS_OK(status)) {
5628 				return status;
5629 			}
5630 			SIVAL(pdata,0,len);
5631 			pdata += 4 + len;
5632 			data_size = PTR_DIFF(pdata,(*ppdata));
5633 			*fixed_portion = 10;
5634 			break;
5635 		}
5636 
5637 		case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
5638 		{
5639 			unsigned int ea_size =
5640 			    estimate_ea_size(conn, fsp, smb_fname);
5641 			DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
5642 			put_long_date_full_timespec(conn->ts_res,pdata+0x00,&create_time_ts);
5643 			put_long_date_full_timespec(conn->ts_res,pdata+0x08,&atime_ts);
5644 			put_long_date_full_timespec(conn->ts_res,pdata+0x10,&mtime_ts); /* write time */
5645 			put_long_date_full_timespec(conn->ts_res,pdata+0x18,&ctime_ts); /* change time */
5646 			SIVAL(pdata,	0x20, mode);
5647 			SIVAL(pdata,	0x24, 0); /* padding. */
5648 			SBVAL(pdata,	0x28, allocation_size);
5649 			SBVAL(pdata,	0x30, file_size);
5650 			SIVAL(pdata,	0x38, nlink);
5651 			SCVAL(pdata,	0x3C, delete_pending);
5652 			SCVAL(pdata,	0x3D, (mode&FILE_ATTRIBUTE_DIRECTORY)?1:0);
5653 			SSVAL(pdata,	0x3E, 0); /* padding */
5654 			SBVAL(pdata,	0x40, file_id);
5655 			SIVAL(pdata,	0x48, ea_size);
5656 			SIVAL(pdata,	0x4C, access_mask);
5657 			SBVAL(pdata,	0x50, pos);
5658 			SIVAL(pdata,	0x58, mode); /*TODO: mode != mode fix this!!! */
5659 			SIVAL(pdata,	0x5C, 0); /* No alignment needed. */
5660 
5661 			pdata += 0x60;
5662 
5663 			status = srvstr_push(dstart, flags2,
5664 					  pdata+4, dos_fname,
5665 					  PTR_DIFF(dend, pdata+4),
5666 					  STR_UNICODE, &len);
5667 			if (!NT_STATUS_IS_OK(status)) {
5668 				return status;
5669 			}
5670 			SIVAL(pdata,0,len);
5671 			pdata += 4 + len;
5672 			data_size = PTR_DIFF(pdata,(*ppdata));
5673 			*fixed_portion = 104;
5674 			break;
5675 		}
5676 		case SMB_FILE_INTERNAL_INFORMATION:
5677 
5678 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
5679 			SBVAL(pdata, 0, file_id);
5680 			data_size = 8;
5681 			*fixed_portion = 8;
5682 			break;
5683 
5684 		case SMB_FILE_ACCESS_INFORMATION:
5685 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
5686 			SIVAL(pdata, 0, access_mask);
5687 			data_size = 4;
5688 			*fixed_portion = 4;
5689 			break;
5690 
5691 		case SMB_FILE_NAME_INFORMATION:
5692 			/* Pathname with leading '\'. */
5693 			{
5694 				size_t byte_len;
5695 				byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
5696 				DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
5697 				SIVAL(pdata,0,byte_len);
5698 				data_size = 4 + byte_len;
5699 				break;
5700 			}
5701 
5702 		case SMB_FILE_DISPOSITION_INFORMATION:
5703 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
5704 			data_size = 1;
5705 			SCVAL(pdata,0,delete_pending);
5706 			*fixed_portion = 1;
5707 			break;
5708 
5709 		case SMB_FILE_POSITION_INFORMATION:
5710 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
5711 			data_size = 8;
5712 			SOFF_T(pdata,0,pos);
5713 			*fixed_portion = 8;
5714 			break;
5715 
5716 		case SMB_FILE_MODE_INFORMATION:
5717 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
5718 			SIVAL(pdata,0,mode);
5719 			data_size = 4;
5720 			*fixed_portion = 4;
5721 			break;
5722 
5723 		case SMB_FILE_ALIGNMENT_INFORMATION:
5724 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
5725 			SIVAL(pdata,0,0); /* No alignment needed. */
5726 			data_size = 4;
5727 			*fixed_portion = 4;
5728 			break;
5729 
5730 		/*
5731 		 * NT4 server just returns "invalid query" to this - if we try
5732 		 * to answer it then NTws gets a BSOD! (tridge).  W2K seems to
5733 		 * want this. JRA.
5734 		 */
5735 		/* The first statement above is false - verified using Thursby
5736 		 * client against NT4 -- gcolley.
5737 		 */
5738 		case SMB_QUERY_FILE_STREAM_INFO:
5739 		case SMB_FILE_STREAM_INFORMATION: {
5740 			unsigned int num_streams = 0;
5741 			struct stream_struct *streams = NULL;
5742 
5743 			DEBUG(10,("smbd_do_qfilepathinfo: "
5744 				  "SMB_FILE_STREAM_INFORMATION\n"));
5745 
5746 			if (is_ntfs_stream_smb_fname(smb_fname)) {
5747 				return NT_STATUS_INVALID_PARAMETER;
5748 			}
5749 
5750 			status = vfs_streaminfo(conn,
5751 						fsp,
5752 						smb_fname,
5753 						talloc_tos(),
5754 						&num_streams,
5755 						&streams);
5756 
5757 			if (!NT_STATUS_IS_OK(status)) {
5758 				DEBUG(10, ("could not get stream info: %s\n",
5759 					   nt_errstr(status)));
5760 				return status;
5761 			}
5762 
5763 			status = marshall_stream_info(num_streams, streams,
5764 						      pdata, max_data_bytes,
5765 						      &data_size);
5766 
5767 			if (!NT_STATUS_IS_OK(status)) {
5768 				DEBUG(10, ("marshall_stream_info failed: %s\n",
5769 					   nt_errstr(status)));
5770 				TALLOC_FREE(streams);
5771 				return status;
5772 			}
5773 
5774 			TALLOC_FREE(streams);
5775 
5776 			*fixed_portion = 32;
5777 
5778 			break;
5779 		}
5780 		case SMB_QUERY_COMPRESSION_INFO:
5781 		case SMB_FILE_COMPRESSION_INFORMATION:
5782 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
5783 			SOFF_T(pdata,0,file_size);
5784 			SIVAL(pdata,8,0); /* ??? */
5785 			SIVAL(pdata,12,0); /* ??? */
5786 			data_size = 16;
5787 			*fixed_portion = 16;
5788 			break;
5789 
5790 		case SMB_FILE_NETWORK_OPEN_INFORMATION:
5791 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
5792 			put_long_date_full_timespec(conn->ts_res,pdata,&create_time_ts);
5793 			put_long_date_full_timespec(conn->ts_res,pdata+8,&atime_ts);
5794 			put_long_date_full_timespec(conn->ts_res,pdata+16,&mtime_ts); /* write time */
5795 			put_long_date_full_timespec(conn->ts_res,pdata+24,&ctime_ts); /* change time */
5796 			SOFF_T(pdata,32,allocation_size);
5797 			SOFF_T(pdata,40,file_size);
5798 			SIVAL(pdata,48,mode);
5799 			SIVAL(pdata,52,0); /* ??? */
5800 			data_size = 56;
5801 			*fixed_portion = 56;
5802 			break;
5803 
5804 		case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
5805 			DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
5806 			SIVAL(pdata,0,mode);
5807 			SIVAL(pdata,4,0);
5808 			data_size = 8;
5809 			*fixed_portion = 8;
5810 			break;
5811 
5812 		/*
5813 		 * CIFS UNIX Extensions.
5814 		 */
5815 
5816 		case SMB_QUERY_FILE_UNIX_BASIC:
5817 
5818 			pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
5819 			data_size = PTR_DIFF(pdata,(*ppdata));
5820 
5821 			DEBUG(4,("smbd_do_qfilepathinfo: "
5822 				 "SMB_QUERY_FILE_UNIX_BASIC\n"));
5823 			dump_data(4, (uint8_t *)(*ppdata), data_size);
5824 
5825 			break;
5826 
5827 		case SMB_QUERY_FILE_UNIX_INFO2:
5828 
5829 			pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
5830 			data_size = PTR_DIFF(pdata,(*ppdata));
5831 
5832 			{
5833 				int i;
5834 				DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
5835 
5836 				for (i=0; i<100; i++)
5837 					DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
5838 				DEBUG(4,("\n"));
5839 			}
5840 
5841 			break;
5842 
5843 		case SMB_QUERY_FILE_UNIX_LINK:
5844 			{
5845 				int link_len = 0;
5846 				char *buffer = talloc_array(mem_ctx, char, PATH_MAX+1);
5847 
5848 				if (!buffer) {
5849 					return NT_STATUS_NO_MEMORY;
5850 				}
5851 
5852 				DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
5853 #ifdef S_ISLNK
5854 				if(!S_ISLNK(psbuf->st_ex_mode)) {
5855 					return NT_STATUS_DOS(ERRSRV, ERRbadlink);
5856 				}
5857 #else
5858 				return NT_STATUS_DOS(ERRDOS, ERRbadlink);
5859 #endif
5860 				link_len = SMB_VFS_READLINKAT(conn,
5861 							conn->cwd_fsp,
5862 							smb_fname,
5863 							buffer,
5864 							PATH_MAX);
5865 
5866 				if (link_len == -1) {
5867 					return map_nt_error_from_unix(errno);
5868 				}
5869 				buffer[link_len] = 0;
5870 				status = srvstr_push(dstart, flags2,
5871 						  pdata, buffer,
5872 						  PTR_DIFF(dend, pdata),
5873 						  STR_TERMINATE, &len);
5874 				if (!NT_STATUS_IS_OK(status)) {
5875 					return status;
5876 				}
5877 				pdata += len;
5878 				data_size = PTR_DIFF(pdata,(*ppdata));
5879 
5880 				break;
5881 			}
5882 
5883 #if defined(HAVE_POSIX_ACLS)
5884 		case SMB_QUERY_POSIX_ACL:
5885 			{
5886 				status = smb_query_posix_acl(conn,
5887 							req,
5888 							fsp,
5889 							smb_fname,
5890 							pdata,
5891 							data_size,
5892 							&data_size);
5893 				if (!NT_STATUS_IS_OK(status)) {
5894 					return status;
5895 				}
5896 				break;
5897 			}
5898 #endif
5899 
5900 
5901 		case SMB_QUERY_POSIX_LOCK:
5902 		{
5903 			uint64_t count;
5904 			uint64_t offset;
5905 			uint64_t smblctx;
5906 			enum brl_type lock_type;
5907 
5908 			/* We need an open file with a real fd for this. */
5909 			if (!fsp || fsp->fh->fd == -1) {
5910 				return NT_STATUS_INVALID_LEVEL;
5911 			}
5912 
5913 			if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
5914 				return NT_STATUS_INVALID_PARAMETER;
5915 			}
5916 
5917 			switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
5918 				case POSIX_LOCK_TYPE_READ:
5919 					lock_type = READ_LOCK;
5920 					break;
5921 				case POSIX_LOCK_TYPE_WRITE:
5922 					lock_type = WRITE_LOCK;
5923 					break;
5924 				case POSIX_LOCK_TYPE_UNLOCK:
5925 				default:
5926 					/* There's no point in asking for an unlock... */
5927 					return NT_STATUS_INVALID_PARAMETER;
5928 			}
5929 
5930 			smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
5931 			offset = BVAL(pdata,POSIX_LOCK_START_OFFSET);
5932 			count = BVAL(pdata,POSIX_LOCK_LEN_OFFSET);
5933 
5934 			status = query_lock(fsp,
5935 					&smblctx,
5936 					&count,
5937 					&offset,
5938 					&lock_type,
5939 					POSIX_LOCK);
5940 
5941 			if (ERROR_WAS_LOCK_DENIED(status)) {
5942 				/* Here we need to report who has it locked... */
5943 				data_size = POSIX_LOCK_DATA_SIZE;
5944 
5945 				SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, lock_type);
5946 				SSVAL(pdata, POSIX_LOCK_FLAGS_OFFSET, 0);
5947 				SIVAL(pdata, POSIX_LOCK_PID_OFFSET, (uint32_t)smblctx);
5948 				SBVAL(pdata, POSIX_LOCK_START_OFFSET, offset);
5949 				SBVAL(pdata, POSIX_LOCK_LEN_OFFSET, count);
5950 
5951 			} else if (NT_STATUS_IS_OK(status)) {
5952 				/* For success we just return a copy of what we sent
5953 				   with the lock type set to POSIX_LOCK_TYPE_UNLOCK. */
5954 				data_size = POSIX_LOCK_DATA_SIZE;
5955 				memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
5956 				SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
5957 			} else {
5958 				return status;
5959 			}
5960 			break;
5961 		}
5962 
5963 		default:
5964 			return NT_STATUS_INVALID_LEVEL;
5965 	}
5966 
5967 	*pdata_size = data_size;
5968 	return NT_STATUS_OK;
5969 }
5970 
5971 /****************************************************************************
5972  Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
5973  file name or file id).
5974 ****************************************************************************/
5975 
call_trans2qfilepathinfo(connection_struct * conn,struct smb_request * req,unsigned int tran_call,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)5976 static void call_trans2qfilepathinfo(connection_struct *conn,
5977 				     struct smb_request *req,
5978 				     unsigned int tran_call,
5979 				     char **pparams, int total_params,
5980 				     char **ppdata, int total_data,
5981 				     unsigned int max_data_bytes)
5982 {
5983 	char *params = *pparams;
5984 	char *pdata = *ppdata;
5985 	uint16_t info_level;
5986 	unsigned int data_size = 0;
5987 	unsigned int param_size = 2;
5988 	struct smb_filename *smb_fname = NULL;
5989 	bool delete_pending = False;
5990 	struct timespec write_time_ts;
5991 	files_struct *fsp = NULL;
5992 	struct file_id fileid;
5993 	struct ea_list *ea_list = NULL;
5994 	int lock_data_count = 0;
5995 	char *lock_data = NULL;
5996 	size_t fixed_portion;
5997 	NTSTATUS status = NT_STATUS_OK;
5998 
5999 	if (!params) {
6000 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6001 		return;
6002 	}
6003 
6004 	ZERO_STRUCT(write_time_ts);
6005 
6006 	if (tran_call == TRANSACT2_QFILEINFO) {
6007 		if (total_params < 4) {
6008 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6009 			return;
6010 		}
6011 
6012 		if (IS_IPC(conn)) {
6013 			call_trans2qpipeinfo(conn, req,	tran_call,
6014 					     pparams, total_params,
6015 					     ppdata, total_data,
6016 					     max_data_bytes);
6017 			return;
6018 		}
6019 
6020 		fsp = file_fsp(req, SVAL(params,0));
6021 		info_level = SVAL(params,2);
6022 
6023 		DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
6024 
6025 		if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
6026 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6027 			return;
6028 		}
6029 
6030 		/* Initial check for valid fsp ptr. */
6031 		if (!check_fsp_open(conn, req, fsp)) {
6032 			return;
6033 		}
6034 
6035 		smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
6036 		if (smb_fname == NULL) {
6037 			reply_nterror(req, NT_STATUS_NO_MEMORY);
6038 			return;
6039 		}
6040 
6041 		if(fsp->fake_file_handle) {
6042 			/*
6043 			 * This is actually for the QUOTA_FAKE_FILE --metze
6044 			 */
6045 
6046 			/* We know this name is ok, it's already passed the checks. */
6047 
6048 		} else if(fsp->fh->fd == -1) {
6049 			/*
6050 			 * This is actually a QFILEINFO on a directory
6051 			 * handle (returned from an NT SMB). NT5.0 seems
6052 			 * to do this call. JRA.
6053 			 */
6054 
6055 			if (INFO_LEVEL_IS_UNIX(info_level)) {
6056 				/* Always do lstat for UNIX calls. */
6057 				if (SMB_VFS_LSTAT(conn, smb_fname)) {
6058 					DEBUG(3,("call_trans2qfilepathinfo: "
6059 						 "SMB_VFS_LSTAT of %s failed "
6060 						 "(%s)\n",
6061 						 smb_fname_str_dbg(smb_fname),
6062 						 strerror(errno)));
6063 					reply_nterror(req,
6064 						map_nt_error_from_unix(errno));
6065 					return;
6066 				}
6067 			} else if (SMB_VFS_STAT(conn, smb_fname)) {
6068 				DEBUG(3,("call_trans2qfilepathinfo: "
6069 					 "SMB_VFS_STAT of %s failed (%s)\n",
6070 					 smb_fname_str_dbg(smb_fname),
6071 					 strerror(errno)));
6072 				reply_nterror(req,
6073 					map_nt_error_from_unix(errno));
6074 				return;
6075 			}
6076 
6077 			if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6078 				fileid = vfs_file_id_from_sbuf(
6079 					conn, &smb_fname->st);
6080 				get_file_infos(fileid, fsp->name_hash,
6081 					       &delete_pending,
6082 					       &write_time_ts);
6083 			}
6084 		} else {
6085 			/*
6086 			 * Original code - this is an open file.
6087 			 */
6088 			if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
6089 				DEBUG(3, ("fstat of %s failed (%s)\n",
6090 					  fsp_fnum_dbg(fsp), strerror(errno)));
6091 				reply_nterror(req,
6092 					map_nt_error_from_unix(errno));
6093 				return;
6094 			}
6095 			if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6096 				fileid = vfs_file_id_from_sbuf(
6097 					conn, &smb_fname->st);
6098 				get_file_infos(fileid, fsp->name_hash,
6099 					       &delete_pending,
6100 					       &write_time_ts);
6101 			}
6102 		}
6103 
6104 	} else {
6105 		uint32_t name_hash;
6106 		char *fname = NULL;
6107 		uint32_t ucf_flags = ucf_flags_from_smb_request(req);
6108 
6109 		/* qpathinfo */
6110 		if (total_params < 7) {
6111 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
6112 			return;
6113 		}
6114 
6115 		info_level = SVAL(params,0);
6116 
6117 		DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
6118 
6119 		if (INFO_LEVEL_IS_UNIX(info_level)) {
6120 			if (!lp_unix_extensions()) {
6121 				reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6122 				return;
6123 			}
6124 			if (info_level == SMB_QUERY_FILE_UNIX_BASIC ||
6125 					info_level == SMB_QUERY_FILE_UNIX_INFO2 ||
6126 					info_level == SMB_QUERY_FILE_UNIX_LINK ||
6127 					req->posix_pathnames) {
6128 				ucf_flags |= UCF_UNIX_NAME_LOOKUP;
6129 			}
6130 		}
6131 
6132 		if (req->posix_pathnames) {
6133 			srvstr_get_path_posix(req,
6134 				params,
6135 				req->flags2,
6136 				&fname,
6137 				&params[6],
6138 				total_params - 6,
6139 				STR_TERMINATE,
6140 				&status);
6141 		} else {
6142 			srvstr_get_path(req,
6143 				params,
6144 				req->flags2,
6145 				&fname,
6146 				&params[6],
6147 				total_params - 6,
6148 				STR_TERMINATE,
6149 				&status);
6150 		}
6151 		if (!NT_STATUS_IS_OK(status)) {
6152 			reply_nterror(req, status);
6153 			return;
6154 		}
6155 
6156 		status = filename_convert(req,
6157 					conn,
6158 					fname,
6159 					ucf_flags,
6160 					NULL,
6161 					NULL,
6162 					&smb_fname);
6163 		if (!NT_STATUS_IS_OK(status)) {
6164 			if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
6165 				reply_botherror(req,
6166 						NT_STATUS_PATH_NOT_COVERED,
6167 						ERRSRV, ERRbadpath);
6168 				return;
6169 			}
6170 			reply_nterror(req, status);
6171 			return;
6172 		}
6173 
6174 		/* If this is a stream, check if there is a delete_pending. */
6175 		if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6176 		    && is_ntfs_stream_smb_fname(smb_fname)) {
6177 			struct smb_filename *smb_fname_base;
6178 
6179 			/* Create an smb_filename with stream_name == NULL. */
6180 			smb_fname_base = synthetic_smb_fname(
6181 						talloc_tos(),
6182 						smb_fname->base_name,
6183 						NULL,
6184 						NULL,
6185 						smb_fname->flags);
6186 			if (smb_fname_base == NULL) {
6187 				reply_nterror(req, NT_STATUS_NO_MEMORY);
6188 				return;
6189 			}
6190 
6191 			if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6192 				/* Always do lstat for UNIX calls. */
6193 				if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
6194 					DEBUG(3,("call_trans2qfilepathinfo: "
6195 						 "SMB_VFS_LSTAT of %s failed "
6196 						 "(%s)\n",
6197 						 smb_fname_str_dbg(smb_fname_base),
6198 						 strerror(errno)));
6199 					TALLOC_FREE(smb_fname_base);
6200 					reply_nterror(req,
6201 						map_nt_error_from_unix(errno));
6202 					return;
6203 				}
6204 			} else {
6205 				if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
6206 					DEBUG(3,("call_trans2qfilepathinfo: "
6207 						 "fileinfo of %s failed "
6208 						 "(%s)\n",
6209 						 smb_fname_str_dbg(smb_fname_base),
6210 						 strerror(errno)));
6211 					TALLOC_FREE(smb_fname_base);
6212 					reply_nterror(req,
6213 						map_nt_error_from_unix(errno));
6214 					return;
6215 				}
6216 			}
6217 
6218 			status = file_name_hash(conn,
6219 					smb_fname_str_dbg(smb_fname_base),
6220 					&name_hash);
6221 			if (!NT_STATUS_IS_OK(status)) {
6222 				TALLOC_FREE(smb_fname_base);
6223 				reply_nterror(req, status);
6224 				return;
6225 			}
6226 
6227 			fileid = vfs_file_id_from_sbuf(conn,
6228 						       &smb_fname_base->st);
6229 			TALLOC_FREE(smb_fname_base);
6230 			get_file_infos(fileid, name_hash, &delete_pending, NULL);
6231 			if (delete_pending) {
6232 				reply_nterror(req, NT_STATUS_DELETE_PENDING);
6233 				return;
6234 			}
6235 		}
6236 
6237 		if (INFO_LEVEL_IS_UNIX(info_level) || req->posix_pathnames) {
6238 			/* Always do lstat for UNIX calls. */
6239 			if (SMB_VFS_LSTAT(conn, smb_fname)) {
6240 				DEBUG(3,("call_trans2qfilepathinfo: "
6241 					 "SMB_VFS_LSTAT of %s failed (%s)\n",
6242 					 smb_fname_str_dbg(smb_fname),
6243 					 strerror(errno)));
6244 				reply_nterror(req,
6245 					map_nt_error_from_unix(errno));
6246 				return;
6247 			}
6248 
6249 		} else {
6250 			if (SMB_VFS_STAT(conn, smb_fname) != 0) {
6251 				DEBUG(3,("call_trans2qfilepathinfo: "
6252 					 "SMB_VFS_STAT of %s failed (%s)\n",
6253 					 smb_fname_str_dbg(smb_fname),
6254 					 strerror(errno)));
6255 				reply_nterror(req,
6256 					map_nt_error_from_unix(errno));
6257 				return;
6258 			}
6259 		}
6260 
6261 		status = file_name_hash(conn,
6262 				smb_fname_str_dbg(smb_fname),
6263 				&name_hash);
6264 		if (!NT_STATUS_IS_OK(status)) {
6265 			reply_nterror(req, status);
6266 			return;
6267 		}
6268 
6269 		if (lp_smbd_getinfo_ask_sharemode(SNUM(conn))) {
6270 			fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
6271 			get_file_infos(fileid, name_hash, &delete_pending,
6272 				       &write_time_ts);
6273 		}
6274 
6275 		if (delete_pending) {
6276 			reply_nterror(req, NT_STATUS_DELETE_PENDING);
6277 			return;
6278 		}
6279 	}
6280 
6281 	DEBUG(3,("call_trans2qfilepathinfo %s (%s) level=%d call=%d "
6282 		 "total_data=%d\n", smb_fname_str_dbg(smb_fname),
6283 		 fsp_fnum_dbg(fsp),
6284 		 info_level,tran_call,total_data));
6285 
6286 	/* Pull out any data sent here before we realloc. */
6287 	switch (info_level) {
6288 		case SMB_INFO_QUERY_EAS_FROM_LIST:
6289 		{
6290 			/* Pull any EA list from the data portion. */
6291 			uint32_t ea_size;
6292 
6293 			if (total_data < 4) {
6294 				reply_nterror(
6295 					req, NT_STATUS_INVALID_PARAMETER);
6296 				return;
6297 			}
6298 			ea_size = IVAL(pdata,0);
6299 
6300 			if (total_data > 0 && ea_size != total_data) {
6301 				DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
6302 total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
6303 				reply_nterror(
6304 					req, NT_STATUS_INVALID_PARAMETER);
6305 				return;
6306 			}
6307 
6308 			if (!lp_ea_support(SNUM(conn))) {
6309 				reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
6310 				return;
6311 			}
6312 
6313 			/* Pull out the list of names. */
6314 			ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
6315 			if (!ea_list) {
6316 				reply_nterror(
6317 					req, NT_STATUS_INVALID_PARAMETER);
6318 				return;
6319 			}
6320 			break;
6321 		}
6322 
6323 		case SMB_QUERY_POSIX_LOCK:
6324 		{
6325 			if (fsp == NULL || fsp->fh->fd == -1) {
6326 				reply_nterror(req, NT_STATUS_INVALID_HANDLE);
6327 				return;
6328 			}
6329 
6330 			if (total_data != POSIX_LOCK_DATA_SIZE) {
6331 				reply_nterror(
6332 					req, NT_STATUS_INVALID_PARAMETER);
6333 				return;
6334 			}
6335 
6336 			/* Copy the lock range data. */
6337 			lock_data = (char *)talloc_memdup(
6338 				req, pdata, total_data);
6339 			if (!lock_data) {
6340 				reply_nterror(req, NT_STATUS_NO_MEMORY);
6341 				return;
6342 			}
6343 			lock_data_count = total_data;
6344 		}
6345 		default:
6346 			break;
6347 	}
6348 
6349 	*pparams = (char *)SMB_REALLOC(*pparams,2);
6350 	if (*pparams == NULL) {
6351 		reply_nterror(req, NT_STATUS_NO_MEMORY);
6352 		return;
6353 	}
6354 	params = *pparams;
6355 	SSVAL(params,0,0);
6356 
6357 	/*
6358 	 * draft-leach-cifs-v1-spec-02.txt
6359 	 * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
6360 	 * says:
6361 	 *
6362 	 *  The requested information is placed in the Data portion of the
6363 	 *  transaction response. For the information levels greater than 0x100,
6364 	 *  the transaction response has 1 parameter word which should be
6365 	 *  ignored by the client.
6366 	 *
6367 	 * However Windows only follows this rule for the IS_NAME_VALID call.
6368 	 */
6369 	switch (info_level) {
6370 	case SMB_INFO_IS_NAME_VALID:
6371 		param_size = 0;
6372 		break;
6373 	}
6374 
6375 	if ((info_level & 0xFF00) == 0xFF00) {
6376 		/*
6377 		 * We use levels that start with 0xFF00
6378 		 * internally to represent SMB2 specific levels
6379 		 */
6380 		reply_nterror(req, NT_STATUS_INVALID_LEVEL);
6381 		return;
6382 	}
6383 
6384 	status = smbd_do_qfilepathinfo(conn, req, req, info_level,
6385 				       fsp, smb_fname,
6386 				       delete_pending, write_time_ts,
6387 				       ea_list,
6388 				       lock_data_count, lock_data,
6389 				       req->flags2, max_data_bytes,
6390 				       &fixed_portion,
6391 				       ppdata, &data_size);
6392 	if (!NT_STATUS_IS_OK(status)) {
6393 		if (open_was_deferred(req->xconn, req->mid)) {
6394 			/* We have re-scheduled this call. */
6395 			return;
6396 		}
6397 		if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6398 			bool ok = defer_smb1_sharing_violation(req);
6399 			if (ok) {
6400 				return;
6401 			}
6402 		}
6403 		reply_nterror(req, status);
6404 		return;
6405 	}
6406 	if (fixed_portion > max_data_bytes) {
6407 		reply_nterror(req, NT_STATUS_INFO_LENGTH_MISMATCH);
6408 		return;
6409 	}
6410 
6411 	send_trans2_replies(conn, req, NT_STATUS_OK, params, param_size, *ppdata, data_size,
6412 			    max_data_bytes);
6413 
6414 	return;
6415 }
6416 
6417 /****************************************************************************
6418  Set a hard link (called by UNIX extensions and by NT rename with HARD link
6419  code.
6420 ****************************************************************************/
6421 
hardlink_internals(TALLOC_CTX * ctx,connection_struct * conn,struct smb_request * req,bool overwrite_if_exists,const struct smb_filename * smb_fname_old,struct smb_filename * smb_fname_new)6422 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
6423 		connection_struct *conn,
6424 		struct smb_request *req,
6425 		bool overwrite_if_exists,
6426 		const struct smb_filename *smb_fname_old,
6427 		struct smb_filename *smb_fname_new)
6428 {
6429 	NTSTATUS status = NT_STATUS_OK;
6430 	int ret;
6431 	bool ok;
6432 
6433 	/* source must already exist. */
6434 	if (!VALID_STAT(smb_fname_old->st)) {
6435 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6436 	}
6437 
6438 	if (VALID_STAT(smb_fname_new->st)) {
6439 		if (overwrite_if_exists) {
6440 			if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
6441 				return NT_STATUS_FILE_IS_A_DIRECTORY;
6442 			}
6443 			status = unlink_internals(conn,
6444 						req,
6445 						FILE_ATTRIBUTE_NORMAL,
6446 						smb_fname_new,
6447 						false);
6448 			if (!NT_STATUS_IS_OK(status)) {
6449 				return status;
6450 			}
6451 		} else {
6452 			/* Disallow if newname already exists. */
6453 			return NT_STATUS_OBJECT_NAME_COLLISION;
6454 		}
6455 	}
6456 
6457 	/* No links from a directory. */
6458 	if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
6459 		return NT_STATUS_FILE_IS_A_DIRECTORY;
6460 	}
6461 
6462 	/* Setting a hardlink to/from a stream isn't currently supported. */
6463 	ok = is_ntfs_stream_smb_fname(smb_fname_old);
6464 	if (ok) {
6465 		DBG_DEBUG("Old name has streams\n");
6466 		return NT_STATUS_INVALID_PARAMETER;
6467 	}
6468 	ok = is_ntfs_stream_smb_fname(smb_fname_new);
6469 	if (ok) {
6470 		DBG_DEBUG("New name has streams\n");
6471 		return NT_STATUS_INVALID_PARAMETER;
6472 	}
6473 
6474 	DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
6475 		  smb_fname_old->base_name, smb_fname_new->base_name));
6476 
6477 	ret = SMB_VFS_LINKAT(conn,
6478 			conn->cwd_fsp,
6479 			smb_fname_old,
6480 			conn->cwd_fsp,
6481 			smb_fname_new,
6482 			0);
6483 
6484 	if (ret != 0) {
6485 		status = map_nt_error_from_unix(errno);
6486 		DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
6487 			 nt_errstr(status), smb_fname_old->base_name,
6488 			 smb_fname_new->base_name));
6489 	}
6490 	return status;
6491 }
6492 
6493 /****************************************************************************
6494  Deal with setting the time from any of the setfilepathinfo functions.
6495  NOTE !!!! The check for FILE_WRITE_ATTRIBUTES access must be done *before*
6496  calling this function.
6497 ****************************************************************************/
6498 
smb_set_file_time(connection_struct * conn,files_struct * fsp,const struct smb_filename * smb_fname,struct smb_file_time * ft,bool setting_write_time)6499 NTSTATUS smb_set_file_time(connection_struct *conn,
6500 			   files_struct *fsp,
6501 			   const struct smb_filename *smb_fname,
6502 			   struct smb_file_time *ft,
6503 			   bool setting_write_time)
6504 {
6505 	struct smb_filename smb_fname_base;
6506 	struct timeval_buf tbuf[4];
6507 	uint32_t action =
6508 		FILE_NOTIFY_CHANGE_LAST_ACCESS
6509 		|FILE_NOTIFY_CHANGE_LAST_WRITE
6510 		|FILE_NOTIFY_CHANGE_CREATION;
6511 
6512 	if (!VALID_STAT(smb_fname->st)) {
6513 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6514 	}
6515 
6516 	/* get some defaults (no modifications) if any info is zero or -1. */
6517 	if (is_omit_timespec(&ft->create_time)) {
6518 		action &= ~FILE_NOTIFY_CHANGE_CREATION;
6519 	}
6520 
6521 	if (is_omit_timespec(&ft->atime)) {
6522 		action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
6523 	}
6524 
6525 	if (is_omit_timespec(&ft->mtime)) {
6526 		action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6527 	}
6528 
6529 	if (!setting_write_time) {
6530 		/* ft->mtime comes from change time, not write time. */
6531 		action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
6532 	}
6533 
6534 	/* Ensure the resolution is the correct for
6535 	 * what we can store on this filesystem. */
6536 
6537 	round_timespec(conn->ts_res, &ft->create_time);
6538 	round_timespec(conn->ts_res, &ft->ctime);
6539 	round_timespec(conn->ts_res, &ft->atime);
6540 	round_timespec(conn->ts_res, &ft->mtime);
6541 
6542 	DBG_DEBUG("smb_set_filetime: actime: %s\n ",
6543 		  timespec_string_buf(&ft->atime, true, &tbuf[0]));
6544 	DBG_DEBUG("smb_set_filetime: modtime: %s\n ",
6545 		  timespec_string_buf(&ft->mtime, true, &tbuf[1]));
6546 	DBG_DEBUG("smb_set_filetime: ctime: %s\n ",
6547 		  timespec_string_buf(&ft->ctime, true, &tbuf[2]));
6548 	DBG_DEBUG("smb_set_file_time: createtime: %s\n ",
6549 		  timespec_string_buf(&ft->create_time, true, &tbuf[3]));
6550 
6551 	if (setting_write_time) {
6552 		/*
6553 		 * This was a Windows setfileinfo on an open file.
6554 		 * NT does this a lot. We also need to
6555 		 * set the time here, as it can be read by
6556 		 * FindFirst/FindNext and with the patch for bug #2045
6557 		 * in smbd/fileio.c it ensures that this timestamp is
6558 		 * kept sticky even after a write. We save the request
6559 		 * away and will set it on file close and after a write. JRA.
6560 		 */
6561 
6562 		DBG_DEBUG("setting pending modtime to %s\n",
6563 			  timespec_string_buf(&ft->mtime, true, &tbuf[0]));
6564 
6565 		if (fsp != NULL) {
6566 			if (fsp->base_fsp) {
6567 				set_sticky_write_time_fsp(fsp->base_fsp,
6568 							  ft->mtime);
6569 			} else {
6570 				set_sticky_write_time_fsp(fsp, ft->mtime);
6571 			}
6572 		} else {
6573 			set_sticky_write_time_path(
6574 				vfs_file_id_from_sbuf(conn, &smb_fname->st),
6575 				ft->mtime);
6576 		}
6577 	}
6578 
6579 	DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
6580 
6581 	/* Always call ntimes on the base, even if a stream was passed in. */
6582 	smb_fname_base = *smb_fname;
6583 	smb_fname_base.stream_name = NULL;
6584 
6585 	if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
6586 		return map_nt_error_from_unix(errno);
6587 	}
6588 
6589 	notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
6590 		     smb_fname->base_name);
6591 	return NT_STATUS_OK;
6592 }
6593 
6594 /****************************************************************************
6595  Deal with setting the dosmode from any of the setfilepathinfo functions.
6596  NB. The check for FILE_WRITE_ATTRIBUTES access on this path must have been
6597  done before calling this function.
6598 ****************************************************************************/
6599 
smb_set_file_dosmode(connection_struct * conn,const struct smb_filename * smb_fname,uint32_t dosmode)6600 static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
6601 				     const struct smb_filename *smb_fname,
6602 				     uint32_t dosmode)
6603 {
6604 	struct smb_filename *smb_fname_base;
6605 	NTSTATUS status;
6606 
6607 	if (!VALID_STAT(smb_fname->st)) {
6608 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6609 	}
6610 
6611 	/* Always operate on the base_name, even if a stream was passed in. */
6612 	smb_fname_base = synthetic_smb_fname(talloc_tos(),
6613 					smb_fname->base_name,
6614 					NULL,
6615 					&smb_fname->st,
6616 					smb_fname->flags);
6617 	if (smb_fname_base == NULL) {
6618 		return NT_STATUS_NO_MEMORY;
6619 	}
6620 
6621 	if (dosmode) {
6622 		if (S_ISDIR(smb_fname_base->st.st_ex_mode)) {
6623 			dosmode |= FILE_ATTRIBUTE_DIRECTORY;
6624 		} else {
6625 			dosmode &= ~FILE_ATTRIBUTE_DIRECTORY;
6626 		}
6627 	}
6628 
6629 	DEBUG(6,("smb_set_file_dosmode: dosmode: 0x%x\n", (unsigned int)dosmode));
6630 
6631 	/* check the mode isn't different, before changing it */
6632 	if ((dosmode != 0) && (dosmode != dos_mode(conn, smb_fname_base))) {
6633 		DEBUG(10,("smb_set_file_dosmode: file %s : setting dos mode "
6634 			  "0x%x\n", smb_fname_str_dbg(smb_fname_base),
6635 			  (unsigned int)dosmode));
6636 
6637 		if(file_set_dosmode(conn, smb_fname_base, dosmode, NULL,
6638 				    false)) {
6639 			DEBUG(2,("smb_set_file_dosmode: file_set_dosmode of "
6640 				 "%s failed (%s)\n",
6641 				 smb_fname_str_dbg(smb_fname_base),
6642 				 strerror(errno)));
6643 			status = map_nt_error_from_unix(errno);
6644 			goto out;
6645 		}
6646 	}
6647 	status = NT_STATUS_OK;
6648  out:
6649 	TALLOC_FREE(smb_fname_base);
6650 	return status;
6651 }
6652 
6653 /****************************************************************************
6654  Deal with setting the size from any of the setfilepathinfo functions.
6655 ****************************************************************************/
6656 
smb_set_file_size(connection_struct * conn,struct smb_request * req,files_struct * fsp,const struct smb_filename * smb_fname,const SMB_STRUCT_STAT * psbuf,off_t size,bool fail_after_createfile)6657 static NTSTATUS smb_set_file_size(connection_struct *conn,
6658 				  struct smb_request *req,
6659 				  files_struct *fsp,
6660 				  const struct smb_filename *smb_fname,
6661 				  const SMB_STRUCT_STAT *psbuf,
6662 				  off_t size,
6663 				  bool fail_after_createfile)
6664 {
6665 	NTSTATUS status = NT_STATUS_OK;
6666 	struct smb_filename *smb_fname_tmp = NULL;
6667 	files_struct *new_fsp = NULL;
6668 
6669 	if (!VALID_STAT(*psbuf)) {
6670 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
6671 	}
6672 
6673 	DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
6674 		 (uint64_t)size,
6675 		 get_file_size_stat(psbuf));
6676 
6677 	if (size == get_file_size_stat(psbuf)) {
6678 		if (fsp == NULL) {
6679 			return NT_STATUS_OK;
6680 		}
6681 		if (!fsp->modified) {
6682 			return NT_STATUS_OK;
6683 		}
6684 		trigger_write_time_update_immediate(fsp);
6685 		return NT_STATUS_OK;
6686 	}
6687 
6688 	DEBUG(10,("smb_set_file_size: file %s : setting new size to %.0f\n",
6689 		  smb_fname_str_dbg(smb_fname), (double)size));
6690 
6691 	if (fsp && fsp->fh->fd != -1) {
6692 		/* Handle based call. */
6693 		if (!(fsp->access_mask & FILE_WRITE_DATA)) {
6694 			return NT_STATUS_ACCESS_DENIED;
6695 		}
6696 
6697 		if (vfs_set_filelen(fsp, size) == -1) {
6698 			return map_nt_error_from_unix(errno);
6699 		}
6700 		trigger_write_time_update_immediate(fsp);
6701 		return NT_STATUS_OK;
6702 	}
6703 
6704 	smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
6705 	if (smb_fname_tmp == NULL) {
6706 		return NT_STATUS_NO_MEMORY;
6707 	}
6708 
6709 	smb_fname_tmp->st = *psbuf;
6710 
6711         status = SMB_VFS_CREATE_FILE(
6712 		conn,					/* conn */
6713 		req,					/* req */
6714 		0,					/* root_dir_fid */
6715 		smb_fname_tmp,				/* fname */
6716 		FILE_WRITE_DATA,			/* access_mask */
6717 		(FILE_SHARE_READ | FILE_SHARE_WRITE |	/* share_access */
6718 		    FILE_SHARE_DELETE),
6719 		FILE_OPEN,				/* create_disposition*/
6720 		0,					/* create_options */
6721 		FILE_ATTRIBUTE_NORMAL,			/* file_attributes */
6722 		0,					/* oplock_request */
6723 		NULL,					/* lease */
6724 		0,					/* allocation_size */
6725 		0,					/* private_flags */
6726 		NULL,					/* sd */
6727 		NULL,					/* ea_list */
6728 		&new_fsp,				/* result */
6729 		NULL,					/* pinfo */
6730 		NULL, NULL);				/* create context */
6731 
6732 	TALLOC_FREE(smb_fname_tmp);
6733 
6734 	if (!NT_STATUS_IS_OK(status)) {
6735 		/* NB. We check for open_was_deferred in the caller. */
6736 		return status;
6737 	}
6738 
6739 	/* See RAW-SFILEINFO-END-OF-FILE */
6740 	if (fail_after_createfile) {
6741 		close_file(req, new_fsp,NORMAL_CLOSE);
6742 		return NT_STATUS_INVALID_LEVEL;
6743 	}
6744 
6745 	if (vfs_set_filelen(new_fsp, size) == -1) {
6746 		status = map_nt_error_from_unix(errno);
6747 		close_file(req, new_fsp,NORMAL_CLOSE);
6748 		return status;
6749 	}
6750 
6751 	trigger_write_time_update_immediate(new_fsp);
6752 	close_file(req, new_fsp,NORMAL_CLOSE);
6753 	return NT_STATUS_OK;
6754 }
6755 
6756 /****************************************************************************
6757  Deal with SMB_INFO_SET_EA.
6758 ****************************************************************************/
6759 
smb_info_set_ea(connection_struct * conn,const char * pdata,int total_data,files_struct * fsp,const struct smb_filename * smb_fname)6760 static NTSTATUS smb_info_set_ea(connection_struct *conn,
6761 				const char *pdata,
6762 				int total_data,
6763 				files_struct *fsp,
6764 				const struct smb_filename *smb_fname)
6765 {
6766 	struct ea_list *ea_list = NULL;
6767 	TALLOC_CTX *ctx = NULL;
6768 	NTSTATUS status = NT_STATUS_OK;
6769 
6770 	if (total_data < 10) {
6771 
6772 		/* OS/2 workplace shell seems to send SET_EA requests of "null"
6773 		   length. They seem to have no effect. Bug #3212. JRA */
6774 
6775 		if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
6776 			/* We're done. We only get EA info in this call. */
6777 			return NT_STATUS_OK;
6778 		}
6779 
6780 		return NT_STATUS_INVALID_PARAMETER;
6781 	}
6782 
6783 	if (IVAL(pdata,0) > total_data) {
6784 		DEBUG(10,("smb_info_set_ea: bad total data size (%u) > %u\n",
6785 			IVAL(pdata,0), (unsigned int)total_data));
6786 		return NT_STATUS_INVALID_PARAMETER;
6787 	}
6788 
6789 	ctx = talloc_tos();
6790 	ea_list = read_ea_list(ctx, pdata + 4, total_data - 4);
6791 	if (!ea_list) {
6792 		return NT_STATUS_INVALID_PARAMETER;
6793 	}
6794 
6795 	status = set_ea(conn, fsp, smb_fname, ea_list);
6796 
6797 	return status;
6798 }
6799 
6800 /****************************************************************************
6801  Deal with SMB_FILE_FULL_EA_INFORMATION set.
6802 ****************************************************************************/
6803 
smb_set_file_full_ea_info(connection_struct * conn,const char * pdata,int total_data,files_struct * fsp)6804 static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
6805 				const char *pdata,
6806 				int total_data,
6807 				files_struct *fsp)
6808 {
6809 	struct ea_list *ea_list = NULL;
6810 	NTSTATUS status;
6811 
6812 	if (!fsp) {
6813 		return NT_STATUS_INVALID_HANDLE;
6814 	}
6815 
6816 	if (!lp_ea_support(SNUM(conn))) {
6817 		DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
6818 			"EA's not supported.\n",
6819 			(unsigned int)total_data));
6820 		return NT_STATUS_EAS_NOT_SUPPORTED;
6821 	}
6822 
6823 	if (total_data < 10) {
6824 		DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
6825 			"too small.\n",
6826 			(unsigned int)total_data));
6827 		return NT_STATUS_INVALID_PARAMETER;
6828 	}
6829 
6830 	ea_list = read_nttrans_ea_list(talloc_tos(),
6831 				pdata,
6832 				total_data);
6833 
6834 	if (!ea_list) {
6835 		return NT_STATUS_INVALID_PARAMETER;
6836 	}
6837 
6838 	status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
6839 
6840 	DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
6841 		smb_fname_str_dbg(fsp->fsp_name),
6842 		nt_errstr(status) ));
6843 
6844 	return status;
6845 }
6846 
6847 
6848 /****************************************************************************
6849  Deal with SMB_SET_FILE_DISPOSITION_INFO.
6850 ****************************************************************************/
6851 
smb_set_file_disposition_info(connection_struct * conn,const char * pdata,int total_data,files_struct * fsp,struct smb_filename * smb_fname)6852 static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
6853 				const char *pdata,
6854 				int total_data,
6855 				files_struct *fsp,
6856 				struct smb_filename *smb_fname)
6857 {
6858 	NTSTATUS status = NT_STATUS_OK;
6859 	bool delete_on_close;
6860 	uint32_t dosmode = 0;
6861 
6862 	if (total_data < 1) {
6863 		return NT_STATUS_INVALID_PARAMETER;
6864 	}
6865 
6866 	if (fsp == NULL) {
6867 		return NT_STATUS_INVALID_HANDLE;
6868 	}
6869 
6870 	delete_on_close = (CVAL(pdata,0) ? True : False);
6871 	dosmode = dos_mode(conn, smb_fname);
6872 
6873 	DEBUG(10,("smb_set_file_disposition_info: file %s, dosmode = %u, "
6874 		"delete_on_close = %u\n",
6875 		smb_fname_str_dbg(smb_fname),
6876 		(unsigned int)dosmode,
6877 		(unsigned int)delete_on_close ));
6878 
6879 	if (delete_on_close) {
6880 		status = can_set_delete_on_close(fsp, dosmode);
6881 		if (!NT_STATUS_IS_OK(status)) {
6882 			return status;
6883 		}
6884 	}
6885 
6886 	/* The set is across all open files on this dev/inode pair. */
6887 	if (!set_delete_on_close(fsp, delete_on_close,
6888 				 conn->session_info->security_token,
6889 				 conn->session_info->unix_token)) {
6890 		return NT_STATUS_ACCESS_DENIED;
6891 	}
6892 	return NT_STATUS_OK;
6893 }
6894 
6895 /****************************************************************************
6896  Deal with SMB_FILE_POSITION_INFORMATION.
6897 ****************************************************************************/
6898 
smb_file_position_information(connection_struct * conn,const char * pdata,int total_data,files_struct * fsp)6899 static NTSTATUS smb_file_position_information(connection_struct *conn,
6900 				const char *pdata,
6901 				int total_data,
6902 				files_struct *fsp)
6903 {
6904 	uint64_t position_information;
6905 
6906 	if (total_data < 8) {
6907 		return NT_STATUS_INVALID_PARAMETER;
6908 	}
6909 
6910 	if (fsp == NULL) {
6911 		/* Ignore on pathname based set. */
6912 		return NT_STATUS_OK;
6913 	}
6914 
6915 	position_information = (uint64_t)IVAL(pdata,0);
6916 	position_information |= (((uint64_t)IVAL(pdata,4)) << 32);
6917 
6918 	DEBUG(10,("smb_file_position_information: Set file position "
6919 		  "information for file %s to %.0f\n", fsp_str_dbg(fsp),
6920 		  (double)position_information));
6921 	fsp->fh->position_information = position_information;
6922 	return NT_STATUS_OK;
6923 }
6924 
6925 /****************************************************************************
6926  Deal with SMB_FILE_MODE_INFORMATION.
6927 ****************************************************************************/
6928 
smb_file_mode_information(connection_struct * conn,const char * pdata,int total_data)6929 static NTSTATUS smb_file_mode_information(connection_struct *conn,
6930 				const char *pdata,
6931 				int total_data)
6932 {
6933 	uint32_t mode;
6934 
6935 	if (total_data < 4) {
6936 		return NT_STATUS_INVALID_PARAMETER;
6937 	}
6938 	mode = IVAL(pdata,0);
6939 	if (mode != 0 && mode != 2 && mode != 4 && mode != 6) {
6940 		return NT_STATUS_INVALID_PARAMETER;
6941 	}
6942 	return NT_STATUS_OK;
6943 }
6944 
6945 /****************************************************************************
6946  Deal with SMB_SET_FILE_UNIX_LINK (create a UNIX symlink).
6947 ****************************************************************************/
6948 
smb_set_file_unix_link(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,const struct smb_filename * new_smb_fname)6949 static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
6950 				       struct smb_request *req,
6951 				       const char *pdata,
6952 				       int total_data,
6953 				       const struct smb_filename *new_smb_fname)
6954 {
6955 	char *link_target = NULL;
6956 	TALLOC_CTX *ctx = talloc_tos();
6957 	int ret;
6958 
6959 	/* Set a symbolic link. */
6960 	/* Don't allow this if follow links is false. */
6961 
6962 	if (total_data == 0) {
6963 		return NT_STATUS_INVALID_PARAMETER;
6964 	}
6965 
6966 	if (!lp_follow_symlinks(SNUM(conn))) {
6967 		return NT_STATUS_ACCESS_DENIED;
6968 	}
6969 
6970 	srvstr_pull_talloc(ctx, pdata, req->flags2, &link_target, pdata,
6971 		    total_data, STR_TERMINATE);
6972 
6973 	if (!link_target) {
6974 		return NT_STATUS_INVALID_PARAMETER;
6975 	}
6976 
6977 	DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
6978 			new_smb_fname->base_name, link_target ));
6979 
6980 	ret = SMB_VFS_SYMLINKAT(conn,
6981 			link_target,
6982 			conn->cwd_fsp,
6983 			new_smb_fname);
6984 	if (ret != 0) {
6985 		return map_nt_error_from_unix(errno);
6986 	}
6987 
6988 	return NT_STATUS_OK;
6989 }
6990 
6991 /****************************************************************************
6992  Deal with SMB_SET_FILE_UNIX_HLINK (create a UNIX hard link).
6993 ****************************************************************************/
6994 
smb_set_file_unix_hlink(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,struct smb_filename * smb_fname_new)6995 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
6996 					struct smb_request *req,
6997 					const char *pdata, int total_data,
6998 					struct smb_filename *smb_fname_new)
6999 {
7000 	char *oldname = NULL;
7001 	struct smb_filename *smb_fname_old = NULL;
7002 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
7003 	TALLOC_CTX *ctx = talloc_tos();
7004 	NTSTATUS status = NT_STATUS_OK;
7005 
7006 	/* Set a hard link. */
7007 	if (total_data == 0) {
7008 		return NT_STATUS_INVALID_PARAMETER;
7009 	}
7010 
7011 	if (req->posix_pathnames) {
7012 		srvstr_get_path_posix(ctx,
7013 			pdata,
7014 			req->flags2,
7015 			&oldname,
7016 			pdata,
7017 			total_data,
7018 			STR_TERMINATE,
7019 			&status);
7020 	} else {
7021 		srvstr_get_path(ctx,
7022 			pdata,
7023 			req->flags2,
7024 			&oldname,
7025 			pdata,
7026 			total_data,
7027 			STR_TERMINATE,
7028 			&status);
7029 	}
7030 	if (!NT_STATUS_IS_OK(status)) {
7031 		return status;
7032 	}
7033 
7034 	DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
7035 		smb_fname_str_dbg(smb_fname_new), oldname));
7036 
7037 	status = filename_convert(ctx,
7038 				conn,
7039 				oldname,
7040 				ucf_flags,
7041 				NULL,
7042 				NULL,
7043 				&smb_fname_old);
7044 	if (!NT_STATUS_IS_OK(status)) {
7045 		return status;
7046 	}
7047 
7048 	return hardlink_internals(ctx, conn, req, false,
7049 			smb_fname_old, smb_fname_new);
7050 }
7051 
7052 /****************************************************************************
7053  Deal with SMB2_FILE_RENAME_INFORMATION_INTERNAL
7054 ****************************************************************************/
7055 
smb2_file_rename_information(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,struct smb_filename * smb_fname_src)7056 static NTSTATUS smb2_file_rename_information(connection_struct *conn,
7057 					    struct smb_request *req,
7058 					    const char *pdata,
7059 					    int total_data,
7060 					    files_struct *fsp,
7061 					    struct smb_filename *smb_fname_src)
7062 {
7063 	bool overwrite;
7064 	uint32_t len;
7065 	char *newname = NULL;
7066 	struct smb_filename *smb_fname_dst = NULL;
7067 	uint32_t ucf_flags = UCF_SAVE_LCOMP |
7068 		ucf_flags_from_smb_request(req);
7069 	NTSTATUS status = NT_STATUS_OK;
7070 	TALLOC_CTX *ctx = talloc_tos();
7071 
7072 	if (!fsp) {
7073 		return NT_STATUS_INVALID_HANDLE;
7074 	}
7075 
7076 	if (total_data < 20) {
7077 		return NT_STATUS_INVALID_PARAMETER;
7078 	}
7079 
7080 	overwrite = (CVAL(pdata,0) ? True : False);
7081 	len = IVAL(pdata,16);
7082 
7083 	if (len > (total_data - 20) || (len == 0)) {
7084 		return NT_STATUS_INVALID_PARAMETER;
7085 	}
7086 
7087 	if (req->posix_pathnames) {
7088 		srvstr_get_path_posix(ctx,
7089 				pdata,
7090 				req->flags2,
7091 				&newname,
7092 				&pdata[20],
7093 				len,
7094 				STR_TERMINATE,
7095 				&status);
7096 	} else {
7097 		srvstr_get_path(ctx,
7098 				pdata,
7099 				req->flags2,
7100 				&newname,
7101 				&pdata[20],
7102 				len,
7103 				STR_TERMINATE,
7104 				&status);
7105 	}
7106 	if (!NT_STATUS_IS_OK(status)) {
7107 		return status;
7108 	}
7109 
7110 	DEBUG(10,("smb2_file_rename_information: got name |%s|\n",
7111 				newname));
7112 
7113 	status = filename_convert(ctx,
7114 				conn,
7115 				newname,
7116 				ucf_flags,
7117 				NULL,
7118 				NULL,
7119 				&smb_fname_dst);
7120 	if (!NT_STATUS_IS_OK(status)) {
7121 		return status;
7122 	}
7123 
7124 	if (fsp->base_fsp) {
7125 		/* newname must be a stream name. */
7126 		if (newname[0] != ':') {
7127 			return NT_STATUS_NOT_SUPPORTED;
7128 		}
7129 
7130 		/* Create an smb_fname to call rename_internals_fsp() with. */
7131 		smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7132 					fsp->base_fsp->fsp_name->base_name,
7133 					newname,
7134 					NULL,
7135 					fsp->base_fsp->fsp_name->flags);
7136 		if (smb_fname_dst == NULL) {
7137 			status = NT_STATUS_NO_MEMORY;
7138 			goto out;
7139 		}
7140 
7141 		/*
7142 		 * Set the original last component, since
7143 		 * rename_internals_fsp() requires it.
7144 		 */
7145 		smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
7146 							      newname);
7147 		if (smb_fname_dst->original_lcomp == NULL) {
7148 			status = NT_STATUS_NO_MEMORY;
7149 			goto out;
7150 		}
7151 
7152 	}
7153 
7154 	DEBUG(10,("smb2_file_rename_information: "
7155 		  "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7156 		  fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7157 		  smb_fname_str_dbg(smb_fname_dst)));
7158 	status = rename_internals_fsp(conn, fsp, smb_fname_dst,
7159 				(FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM),
7160 				overwrite);
7161 
7162  out:
7163 	TALLOC_FREE(smb_fname_dst);
7164 	return status;
7165 }
7166 
smb_file_link_information(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,struct smb_filename * smb_fname_src)7167 static NTSTATUS smb_file_link_information(connection_struct *conn,
7168 					    struct smb_request *req,
7169 					    const char *pdata,
7170 					    int total_data,
7171 					    files_struct *fsp,
7172 					    struct smb_filename *smb_fname_src)
7173 {
7174 	bool overwrite;
7175 	uint32_t len;
7176 	char *newname = NULL;
7177 	struct smb_filename *smb_fname_dst = NULL;
7178 	NTSTATUS status = NT_STATUS_OK;
7179 	uint32_t ucf_flags = UCF_SAVE_LCOMP |
7180 		ucf_flags_from_smb_request(req);
7181 	TALLOC_CTX *ctx = talloc_tos();
7182 
7183 	if (!fsp) {
7184 		return NT_STATUS_INVALID_HANDLE;
7185 	}
7186 
7187 	if (total_data < 20) {
7188 		return NT_STATUS_INVALID_PARAMETER;
7189 	}
7190 
7191 	overwrite = (CVAL(pdata,0) ? true : false);
7192 	len = IVAL(pdata,16);
7193 
7194 	if (len > (total_data - 20) || (len == 0)) {
7195 		return NT_STATUS_INVALID_PARAMETER;
7196 	}
7197 
7198 	if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
7199 		srvstr_get_path_posix(ctx,
7200 				pdata,
7201 				req->flags2,
7202 				&newname,
7203 				&pdata[20],
7204 				len,
7205 				STR_TERMINATE,
7206 				&status);
7207 		ucf_flags |= UCF_POSIX_PATHNAMES;
7208 	} else {
7209 		srvstr_get_path(ctx,
7210 				pdata,
7211 				req->flags2,
7212 				&newname,
7213 				&pdata[20],
7214 				len,
7215 				STR_TERMINATE,
7216 				&status);
7217 	}
7218 	if (!NT_STATUS_IS_OK(status)) {
7219 		return status;
7220 	}
7221 
7222 	DEBUG(10,("smb_file_link_information: got name |%s|\n",
7223 				newname));
7224 
7225 	status = filename_convert(ctx,
7226 				conn,
7227 				newname,
7228 				ucf_flags,
7229 				NULL,
7230 				NULL,
7231 				&smb_fname_dst);
7232 	if (!NT_STATUS_IS_OK(status)) {
7233 		return status;
7234 	}
7235 
7236 	if (fsp->base_fsp) {
7237 		/* No stream names. */
7238 		return NT_STATUS_NOT_SUPPORTED;
7239 	}
7240 
7241 	DEBUG(10,("smb_file_link_information: "
7242 		  "SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
7243 		  fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7244 		  smb_fname_str_dbg(smb_fname_dst)));
7245 	status = hardlink_internals(ctx,
7246 				conn,
7247 				req,
7248 				overwrite,
7249 				fsp->fsp_name,
7250 				smb_fname_dst);
7251 
7252 	TALLOC_FREE(smb_fname_dst);
7253 	return status;
7254 }
7255 
7256 /****************************************************************************
7257  Deal with SMB_FILE_RENAME_INFORMATION.
7258 ****************************************************************************/
7259 
smb_file_rename_information(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,struct smb_filename * smb_fname_src)7260 static NTSTATUS smb_file_rename_information(connection_struct *conn,
7261 					    struct smb_request *req,
7262 					    const char *pdata,
7263 					    int total_data,
7264 					    files_struct *fsp,
7265 					    struct smb_filename *smb_fname_src)
7266 {
7267 	bool overwrite;
7268 	uint32_t root_fid;
7269 	uint32_t len;
7270 	char *newname = NULL;
7271 	struct smb_filename *smb_fname_dst = NULL;
7272 	bool dest_has_wcard = False;
7273 	NTSTATUS status = NT_STATUS_OK;
7274 	char *p;
7275 	TALLOC_CTX *ctx = talloc_tos();
7276 
7277 	if (total_data < 13) {
7278 		return NT_STATUS_INVALID_PARAMETER;
7279 	}
7280 
7281 	overwrite = (CVAL(pdata,0) ? True : False);
7282 	root_fid = IVAL(pdata,4);
7283 	len = IVAL(pdata,8);
7284 
7285 	if (len > (total_data - 12) || (len == 0) || (root_fid != 0)) {
7286 		return NT_STATUS_INVALID_PARAMETER;
7287 	}
7288 
7289 	if (req->posix_pathnames) {
7290 		srvstr_get_path_wcard_posix(ctx,
7291 				pdata,
7292 				req->flags2,
7293 				&newname,
7294 				&pdata[12],
7295 				len,
7296 				0,
7297 				&status,
7298 				&dest_has_wcard);
7299 	} else {
7300 		srvstr_get_path_wcard(ctx,
7301 				pdata,
7302 				req->flags2,
7303 				&newname,
7304 				&pdata[12],
7305 				len,
7306 				0,
7307 				&status,
7308 				&dest_has_wcard);
7309 	}
7310 	if (!NT_STATUS_IS_OK(status)) {
7311 		return status;
7312 	}
7313 
7314 	DEBUG(10,("smb_file_rename_information: got name |%s|\n",
7315 				newname));
7316 
7317 	if (req->flags2 & FLAGS2_DFS_PATHNAMES) {
7318 		status = resolve_dfspath_wcard(ctx, conn,
7319 				       newname,
7320 				       UCF_COND_ALLOW_WCARD_LCOMP,
7321 				       !conn->sconn->using_smb2,
7322 				       &newname,
7323 				       &dest_has_wcard);
7324 		if (!NT_STATUS_IS_OK(status)) {
7325 			return status;
7326 		}
7327 	}
7328 
7329 	/* Check the new name has no '/' characters. */
7330 	if (strchr_m(newname, '/')) {
7331 		return NT_STATUS_NOT_SUPPORTED;
7332 	}
7333 
7334 	if (fsp && fsp->base_fsp) {
7335 		/* newname must be a stream name. */
7336 		if (newname[0] != ':') {
7337 			return NT_STATUS_NOT_SUPPORTED;
7338 		}
7339 
7340 		/* Create an smb_fname to call rename_internals_fsp() with. */
7341 		smb_fname_dst = synthetic_smb_fname(talloc_tos(),
7342 					fsp->base_fsp->fsp_name->base_name,
7343 					newname,
7344 					NULL,
7345 					fsp->base_fsp->fsp_name->flags);
7346 		if (smb_fname_dst == NULL) {
7347 			status = NT_STATUS_NO_MEMORY;
7348 			goto out;
7349 		}
7350 
7351 		/*
7352 		 * Set the original last component, since
7353 		 * rename_internals_fsp() requires it.
7354 		 */
7355 		smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
7356 							      newname);
7357 		if (smb_fname_dst->original_lcomp == NULL) {
7358 			status = NT_STATUS_NO_MEMORY;
7359 			goto out;
7360 		}
7361 
7362 	} else {
7363 		/*
7364 		 * Build up an smb_fname_dst based on the filename passed in.
7365 		 * We basically just strip off the last component, and put on
7366 		 * the newname instead.
7367 		 */
7368 		char *base_name = NULL;
7369 		uint32_t ucf_flags = UCF_SAVE_LCOMP |
7370 			ucf_flags_from_smb_request(req);
7371 
7372 		if (dest_has_wcard) {
7373 			ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
7374 		}
7375 
7376 		/* newname must *not* be a stream name. */
7377 		if (newname[0] == ':') {
7378 			return NT_STATUS_NOT_SUPPORTED;
7379 		}
7380 
7381 		/*
7382 		 * Strip off the last component (filename) of the path passed
7383 		 * in.
7384 		 */
7385 		base_name = talloc_strdup(ctx, smb_fname_src->base_name);
7386 		if (!base_name) {
7387 			return NT_STATUS_NO_MEMORY;
7388 		}
7389 		p = strrchr_m(base_name, '/');
7390 		if (p) {
7391 			p[1] = '\0';
7392 		} else {
7393 			base_name = talloc_strdup(ctx, "");
7394 			if (!base_name) {
7395 				return NT_STATUS_NO_MEMORY;
7396 			}
7397 		}
7398 		/* Append the new name. */
7399 		base_name = talloc_asprintf_append(base_name,
7400 				"%s",
7401 				newname);
7402 		if (!base_name) {
7403 			return NT_STATUS_NO_MEMORY;
7404 		}
7405 
7406 		status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
7407 					ucf_flags);
7408 
7409 		/* If an error we expect this to be
7410 		 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
7411 
7412 		if (!NT_STATUS_IS_OK(status)) {
7413 			if(!NT_STATUS_EQUAL(NT_STATUS_OBJECT_PATH_NOT_FOUND,
7414 					    status)) {
7415 				goto out;
7416 			}
7417 			/* Create an smb_fname to call rename_internals_fsp() */
7418 			smb_fname_dst = synthetic_smb_fname(ctx,
7419 						base_name,
7420 						NULL,
7421 						NULL,
7422 						smb_fname_src->flags);
7423 			if (smb_fname_dst == NULL) {
7424 				status = NT_STATUS_NO_MEMORY;
7425 				goto out;
7426 			}
7427 		}
7428 	}
7429 
7430 	if (fsp) {
7431 		DEBUG(10,("smb_file_rename_information: "
7432 			  "SMB_FILE_RENAME_INFORMATION (%s) %s -> %s\n",
7433 			  fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
7434 			  smb_fname_str_dbg(smb_fname_dst)));
7435 		status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
7436 					      overwrite);
7437 	} else {
7438 		DEBUG(10,("smb_file_rename_information: "
7439 			  "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
7440 			  smb_fname_str_dbg(smb_fname_src),
7441 			  smb_fname_str_dbg(smb_fname_dst)));
7442 		status = rename_internals(ctx, conn, req, smb_fname_src,
7443 					  smb_fname_dst, 0, overwrite, false,
7444 					  dest_has_wcard,
7445 					  FILE_WRITE_ATTRIBUTES);
7446 	}
7447  out:
7448 	TALLOC_FREE(smb_fname_dst);
7449 	return status;
7450 }
7451 
7452 /****************************************************************************
7453  Deal with SMB_SET_POSIX_ACL.
7454 ****************************************************************************/
7455 
7456 #if defined(HAVE_POSIX_ACLS)
smb_set_posix_acl(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data_in,files_struct * fsp,const struct smb_filename * smb_fname)7457 static NTSTATUS smb_set_posix_acl(connection_struct *conn,
7458 				struct smb_request *req,
7459 				const char *pdata,
7460 				int total_data_in,
7461 				files_struct *fsp,
7462 				const struct smb_filename *smb_fname)
7463 {
7464 	uint16_t posix_acl_version;
7465 	uint16_t num_file_acls;
7466 	uint16_t num_def_acls;
7467 	bool valid_file_acls = true;
7468 	bool valid_def_acls = true;
7469 	NTSTATUS status;
7470 	unsigned int size_needed;
7471 	unsigned int total_data;
7472 	bool close_fsp = false;
7473 
7474 	if (total_data_in < 0) {
7475 		status = NT_STATUS_INVALID_PARAMETER;
7476 		goto out;
7477 	}
7478 
7479 	total_data = total_data_in;
7480 
7481 	if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
7482 		status = NT_STATUS_INVALID_PARAMETER;
7483 		goto out;
7484 	}
7485 	posix_acl_version = SVAL(pdata,0);
7486 	num_file_acls = SVAL(pdata,2);
7487 	num_def_acls = SVAL(pdata,4);
7488 
7489 	if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7490 		valid_file_acls = false;
7491 		num_file_acls = 0;
7492 	}
7493 
7494 	if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
7495 		valid_def_acls = false;
7496 		num_def_acls = 0;
7497 	}
7498 
7499 	if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
7500 		status = NT_STATUS_INVALID_PARAMETER;
7501 		goto out;
7502 	}
7503 
7504 	/* Wrap checks. */
7505 	if (num_file_acls + num_def_acls < num_file_acls) {
7506 		status = NT_STATUS_INVALID_PARAMETER;
7507 		goto out;
7508 	}
7509 
7510 	size_needed = num_file_acls + num_def_acls;
7511 
7512 	/*
7513 	 * (size_needed * SMB_POSIX_ACL_ENTRY_SIZE) must be less
7514 	 * than UINT_MAX, so check by division.
7515 	 */
7516 	if (size_needed > (UINT_MAX/SMB_POSIX_ACL_ENTRY_SIZE)) {
7517 		status = NT_STATUS_INVALID_PARAMETER;
7518 		goto out;
7519 	}
7520 
7521 	size_needed = size_needed*SMB_POSIX_ACL_ENTRY_SIZE;
7522 	if (size_needed + SMB_POSIX_ACL_HEADER_SIZE < size_needed) {
7523 		status = NT_STATUS_INVALID_PARAMETER;
7524 		goto out;
7525 	}
7526 	size_needed += SMB_POSIX_ACL_HEADER_SIZE;
7527 
7528 	if (total_data < size_needed) {
7529 		status = NT_STATUS_INVALID_PARAMETER;
7530 		goto out;
7531 	}
7532 
7533 	/*
7534 	 * Ensure we always operate on a file descriptor, not just
7535 	 * the filename.
7536 	 */
7537 	if (fsp == NULL) {
7538 		uint32_t access_mask = SEC_STD_WRITE_OWNER|
7539 					SEC_STD_WRITE_DAC|
7540 					SEC_STD_READ_CONTROL|
7541 					FILE_READ_ATTRIBUTES|
7542 					FILE_WRITE_ATTRIBUTES;
7543 
7544 		status = get_posix_fsp(conn,
7545 					req,
7546 					smb_fname,
7547 					access_mask,
7548 					&fsp);
7549 
7550 		if (!NT_STATUS_IS_OK(status)) {
7551 			goto out;
7552 		}
7553 		close_fsp = true;
7554 	}
7555 
7556 	/* Here we know fsp != NULL */
7557 	SMB_ASSERT(fsp != NULL);
7558 
7559 	status = refuse_symlink(conn, fsp, fsp->fsp_name);
7560 	if (!NT_STATUS_IS_OK(status)) {
7561 		goto out;
7562 	}
7563 
7564 	/* If we have a default acl, this *must* be a directory. */
7565 	if (valid_def_acls && !fsp->is_directory) {
7566 		DBG_INFO("Can't set default acls on "
7567 			 "non-directory %s\n",
7568 			 fsp_str_dbg(fsp));
7569 		return NT_STATUS_INVALID_HANDLE;
7570 	}
7571 
7572 	DBG_DEBUG("file %s num_file_acls = %"PRIu16", "
7573 		  "num_def_acls = %"PRIu16"\n",
7574 		  fsp_str_dbg(fsp),
7575 		  num_file_acls,
7576 		  num_def_acls);
7577 
7578 	/* Move pdata to the start of the file ACL entries. */
7579 	pdata += SMB_POSIX_ACL_HEADER_SIZE;
7580 
7581 	if (valid_file_acls) {
7582 		status = set_unix_posix_acl(conn,
7583 					fsp,
7584 					num_file_acls,
7585 					pdata);
7586 		if (!NT_STATUS_IS_OK(status)) {
7587 			goto out;
7588 		}
7589 	}
7590 
7591 	/* Move pdata to the start of the default ACL entries. */
7592 	pdata += (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE);
7593 
7594 	if (valid_def_acls) {
7595 		status = set_unix_posix_default_acl(conn,
7596 					fsp,
7597 					num_def_acls,
7598 					pdata);
7599 		if (!NT_STATUS_IS_OK(status)) {
7600 			goto out;
7601 		}
7602 	}
7603 
7604 	status = NT_STATUS_OK;
7605 
7606   out:
7607 
7608 	if (close_fsp) {
7609 		(void)close_file(req, fsp, NORMAL_CLOSE);
7610 		fsp = NULL;
7611 	}
7612 	return status;
7613 }
7614 #endif
7615 
7616 /****************************************************************************
7617  Deal with SMB_SET_POSIX_LOCK.
7618 ****************************************************************************/
7619 
7620 static void smb_set_posix_lock_done(struct tevent_req *subreq);
7621 
smb_set_posix_lock(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp)7622 static NTSTATUS smb_set_posix_lock(connection_struct *conn,
7623 				struct smb_request *req,
7624 				const char *pdata,
7625 				int total_data,
7626 				files_struct *fsp)
7627 {
7628 	struct tevent_req *subreq = NULL;
7629 	struct smbd_lock_element *lck = NULL;
7630 	uint64_t count;
7631 	uint64_t offset;
7632 	uint64_t smblctx;
7633 	bool blocking_lock = False;
7634 	enum brl_type lock_type;
7635 
7636 	NTSTATUS status = NT_STATUS_OK;
7637 
7638 	if (fsp == NULL || fsp->fh->fd == -1) {
7639 		return NT_STATUS_INVALID_HANDLE;
7640 	}
7641 
7642 	if (total_data != POSIX_LOCK_DATA_SIZE) {
7643 		return NT_STATUS_INVALID_PARAMETER;
7644 	}
7645 
7646 	switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
7647 		case POSIX_LOCK_TYPE_READ:
7648 			lock_type = READ_LOCK;
7649 			break;
7650 		case POSIX_LOCK_TYPE_WRITE:
7651 			/* Return the right POSIX-mappable error code for files opened read-only. */
7652 			if (!fsp->can_write) {
7653 				return NT_STATUS_INVALID_HANDLE;
7654 			}
7655 			lock_type = WRITE_LOCK;
7656 			break;
7657 		case POSIX_LOCK_TYPE_UNLOCK:
7658 			lock_type = UNLOCK_LOCK;
7659 			break;
7660 		default:
7661 			return NT_STATUS_INVALID_PARAMETER;
7662 	}
7663 
7664 	switch (SVAL(pdata, POSIX_LOCK_FLAGS_OFFSET)) {
7665 	case POSIX_LOCK_FLAG_NOWAIT:
7666 		blocking_lock = false;
7667 		break;
7668 	case POSIX_LOCK_FLAG_WAIT:
7669 		blocking_lock = true;
7670 		break;
7671 	default:
7672 		return NT_STATUS_INVALID_PARAMETER;
7673 	}
7674 
7675 	if (!lp_blocking_locks(SNUM(conn))) {
7676 		blocking_lock = False;
7677 	}
7678 
7679 	smblctx = (uint64_t)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
7680 	offset = (((uint64_t) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
7681 			((uint64_t) IVAL(pdata,POSIX_LOCK_START_OFFSET));
7682 	count = (((uint64_t) IVAL(pdata,(POSIX_LOCK_LEN_OFFSET+4))) << 32) |
7683 			((uint64_t) IVAL(pdata,POSIX_LOCK_LEN_OFFSET));
7684 
7685 	DBG_DEBUG("file %s, lock_type = %u, smblctx = %"PRIu64", "
7686 		  "count = %"PRIu64", offset = %"PRIu64"\n",
7687 		  fsp_str_dbg(fsp),
7688 		  (unsigned int)lock_type,
7689 		  smblctx,
7690 		  count,
7691 		  offset);
7692 
7693 	if (lock_type == UNLOCK_LOCK) {
7694 		struct smbd_lock_element l = {
7695 			.req_guid = smbd_request_guid(req, 0),
7696 			.smblctx = smblctx,
7697 			.brltype = UNLOCK_LOCK,
7698 			.offset = offset,
7699 			.count = count,
7700 		};
7701 		status = smbd_do_unlocking(req, fsp, 1, &l, POSIX_LOCK);
7702 		return status;
7703 	}
7704 
7705 	lck = talloc(req, struct smbd_lock_element);
7706 	if (lck == NULL) {
7707 		return NT_STATUS_NO_MEMORY;
7708 	}
7709 
7710 	*lck = (struct smbd_lock_element) {
7711 		.req_guid = smbd_request_guid(req, 0),
7712 		.smblctx = smblctx,
7713 		.brltype = lock_type,
7714 		.count = count,
7715 		.offset = offset,
7716 	};
7717 
7718 	subreq = smbd_smb1_do_locks_send(
7719 		fsp,
7720 		req->sconn->ev_ctx,
7721 		&req,
7722 		fsp,
7723 		blocking_lock ? UINT32_MAX : 0,
7724 		true,		/* large_offset */
7725 		POSIX_LOCK,
7726 		1,
7727 		lck);
7728 	if (subreq == NULL) {
7729 		TALLOC_FREE(lck);
7730 		return NT_STATUS_NO_MEMORY;
7731 	}
7732 	tevent_req_set_callback(subreq, smb_set_posix_lock_done, req);
7733 	return NT_STATUS_EVENT_PENDING;
7734 }
7735 
smb_set_posix_lock_done(struct tevent_req * subreq)7736 static void smb_set_posix_lock_done(struct tevent_req *subreq)
7737 {
7738 	struct smb_request *req = NULL;
7739 	NTSTATUS status;
7740 	bool ok;
7741 
7742 	ok = smbd_smb1_do_locks_extract_smbreq(subreq, talloc_tos(), &req);
7743 	SMB_ASSERT(ok);
7744 
7745 	status = smbd_smb1_do_locks_recv(subreq);
7746 	TALLOC_FREE(subreq);
7747 
7748 	if (NT_STATUS_IS_OK(status)) {
7749 		char params[2] = {0};
7750 		/* Fake up max_data_bytes here - we know it fits. */
7751 		send_trans2_replies(
7752 			req->conn,
7753 			req,
7754 			NT_STATUS_OK,
7755 			params,
7756 			2,
7757 			NULL,
7758 			0,
7759 			0xffff);
7760 	} else {
7761 		reply_nterror(req, status);
7762 		ok = srv_send_smb(
7763 			req->xconn,
7764 			(char *)req->outbuf,
7765 			true,
7766 			req->seqnum+1,
7767 			IS_CONN_ENCRYPTED(req->conn),
7768 			NULL);
7769 		if (!ok) {
7770 			exit_server_cleanly("smb_set_posix_lock_done: "
7771 					    "srv_send_smb failed.");
7772 		}
7773 	}
7774 
7775 	TALLOC_FREE(req);
7776 	return;
7777 }
7778 
7779 /****************************************************************************
7780  Deal with SMB_SET_FILE_BASIC_INFO.
7781 ****************************************************************************/
7782 
smb_set_file_basic_info(connection_struct * conn,const char * pdata,int total_data,files_struct * fsp,const struct smb_filename * smb_fname)7783 static NTSTATUS smb_set_file_basic_info(connection_struct *conn,
7784 					const char *pdata,
7785 					int total_data,
7786 					files_struct *fsp,
7787 					const struct smb_filename *smb_fname)
7788 {
7789 	/* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
7790 	struct smb_file_time ft;
7791 	uint32_t dosmode = 0;
7792 	NTSTATUS status = NT_STATUS_OK;
7793 
7794 	init_smb_file_time(&ft);
7795 
7796 	if (total_data < 36) {
7797 		return NT_STATUS_INVALID_PARAMETER;
7798 	}
7799 
7800 	status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
7801 	if (!NT_STATUS_IS_OK(status)) {
7802 		return status;
7803 	}
7804 
7805 	/* Set the attributes */
7806 	dosmode = IVAL(pdata,32);
7807 	status = smb_set_file_dosmode(conn, smb_fname, dosmode);
7808 	if (!NT_STATUS_IS_OK(status)) {
7809 		return status;
7810 	}
7811 
7812 	/* create time */
7813 	ft.create_time = pull_long_date_full_timespec(pdata);
7814 
7815 	/* access time */
7816 	ft.atime = pull_long_date_full_timespec(pdata+8);
7817 
7818 	/* write time. */
7819 	ft.mtime = pull_long_date_full_timespec(pdata+16);
7820 
7821 	/* change time. */
7822 	ft.ctime = pull_long_date_full_timespec(pdata+24);
7823 
7824 	DEBUG(10, ("smb_set_file_basic_info: file %s\n",
7825 		   smb_fname_str_dbg(smb_fname)));
7826 
7827 	status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
7828 	if (!NT_STATUS_IS_OK(status)) {
7829 		return status;
7830 	}
7831 
7832 	if (fsp != NULL && fsp->modified) {
7833 		trigger_write_time_update_immediate(fsp);
7834 	}
7835 	return NT_STATUS_OK;
7836 }
7837 
7838 /****************************************************************************
7839  Deal with SMB_INFO_STANDARD.
7840 ****************************************************************************/
7841 
smb_set_info_standard(connection_struct * conn,const char * pdata,int total_data,files_struct * fsp,const struct smb_filename * smb_fname)7842 static NTSTATUS smb_set_info_standard(connection_struct *conn,
7843 					const char *pdata,
7844 					int total_data,
7845 					files_struct *fsp,
7846 					const struct smb_filename *smb_fname)
7847 {
7848 	NTSTATUS status;
7849 	struct smb_file_time ft;
7850 
7851 	init_smb_file_time(&ft);
7852 
7853 	if (total_data < 12) {
7854 		return NT_STATUS_INVALID_PARAMETER;
7855 	}
7856 
7857 	/* create time */
7858 	ft.create_time = time_t_to_full_timespec(srv_make_unix_date2(pdata));
7859 	/* access time */
7860 	ft.atime = time_t_to_full_timespec(srv_make_unix_date2(pdata+4));
7861 	/* write time */
7862 	ft.mtime = time_t_to_full_timespec(srv_make_unix_date2(pdata+8));
7863 
7864 	DEBUG(10,("smb_set_info_standard: file %s\n",
7865 		smb_fname_str_dbg(smb_fname)));
7866 
7867 	status = check_access(conn, fsp, smb_fname, FILE_WRITE_ATTRIBUTES);
7868 	if (!NT_STATUS_IS_OK(status)) {
7869 		return status;
7870 	}
7871 
7872 	status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
7873 	if (!NT_STATUS_IS_OK(status)) {
7874 		return status;
7875 	}
7876 
7877 	if (fsp != NULL && fsp->modified) {
7878 		trigger_write_time_update_immediate(fsp);
7879 	}
7880 	return NT_STATUS_OK;
7881 }
7882 
7883 /****************************************************************************
7884  Deal with SMB_SET_FILE_ALLOCATION_INFO.
7885 ****************************************************************************/
7886 
smb_set_file_allocation_info(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,struct smb_filename * smb_fname)7887 static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
7888 					     struct smb_request *req,
7889 					const char *pdata,
7890 					int total_data,
7891 					files_struct *fsp,
7892 					struct smb_filename *smb_fname)
7893 {
7894 	uint64_t allocation_size = 0;
7895 	NTSTATUS status = NT_STATUS_OK;
7896 	files_struct *new_fsp = NULL;
7897 
7898 	if (!VALID_STAT(smb_fname->st)) {
7899 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
7900 	}
7901 
7902 	if (total_data < 8) {
7903 		return NT_STATUS_INVALID_PARAMETER;
7904 	}
7905 
7906 	allocation_size = (uint64_t)IVAL(pdata,0);
7907 	allocation_size |= (((uint64_t)IVAL(pdata,4)) << 32);
7908 	DEBUG(10,("smb_set_file_allocation_info: Set file allocation info for "
7909 		  "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
7910 		  (double)allocation_size));
7911 
7912 	if (allocation_size) {
7913 		allocation_size = smb_roundup(conn, allocation_size);
7914 	}
7915 
7916 	DEBUG(10,("smb_set_file_allocation_info: file %s : setting new "
7917 		  "allocation size to %.0f\n", smb_fname_str_dbg(smb_fname),
7918 		  (double)allocation_size));
7919 
7920 	if (fsp && fsp->fh->fd != -1) {
7921 		/* Open file handle. */
7922 		if (!(fsp->access_mask & FILE_WRITE_DATA)) {
7923 			return NT_STATUS_ACCESS_DENIED;
7924 		}
7925 
7926 		/* Only change if needed. */
7927 		if (allocation_size != get_file_size_stat(&smb_fname->st)) {
7928 			if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
7929 				return map_nt_error_from_unix(errno);
7930 			}
7931 		}
7932 		/* But always update the time. */
7933 		/*
7934 		 * This is equivalent to a write. Ensure it's seen immediately
7935 		 * if there are no pending writes.
7936 		 */
7937 		trigger_write_time_update_immediate(fsp);
7938 		return NT_STATUS_OK;
7939 	}
7940 
7941 	/* Pathname or stat or directory file. */
7942 	status = SMB_VFS_CREATE_FILE(
7943 		conn,					/* conn */
7944 		req,					/* req */
7945 		0,					/* root_dir_fid */
7946 		smb_fname,				/* fname */
7947 		FILE_WRITE_DATA,			/* access_mask */
7948 		(FILE_SHARE_READ | FILE_SHARE_WRITE |	/* share_access */
7949 		    FILE_SHARE_DELETE),
7950 		FILE_OPEN,				/* create_disposition*/
7951 		0,					/* create_options */
7952 		FILE_ATTRIBUTE_NORMAL,			/* file_attributes */
7953 		0,					/* oplock_request */
7954 		NULL,					/* lease */
7955 		0,					/* allocation_size */
7956 		0,					/* private_flags */
7957 		NULL,					/* sd */
7958 		NULL,					/* ea_list */
7959 		&new_fsp,				/* result */
7960 		NULL,					/* pinfo */
7961 		NULL, NULL);				/* create context */
7962 
7963 	if (!NT_STATUS_IS_OK(status)) {
7964 		/* NB. We check for open_was_deferred in the caller. */
7965 		return status;
7966 	}
7967 
7968 	/* Only change if needed. */
7969 	if (allocation_size != get_file_size_stat(&smb_fname->st)) {
7970 		if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
7971 			status = map_nt_error_from_unix(errno);
7972 			close_file(req, new_fsp, NORMAL_CLOSE);
7973 			return status;
7974 		}
7975 	}
7976 
7977 	/* Changing the allocation size should set the last mod time. */
7978 	/*
7979 	 * This is equivalent to a write. Ensure it's seen immediately
7980 	 * if there are no pending writes.
7981 	 */
7982 	trigger_write_time_update_immediate(new_fsp);
7983 	close_file(req, new_fsp, NORMAL_CLOSE);
7984 	return NT_STATUS_OK;
7985 }
7986 
7987 /****************************************************************************
7988  Deal with SMB_SET_FILE_END_OF_FILE_INFO.
7989 ****************************************************************************/
7990 
smb_set_file_end_of_file_info(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,const struct smb_filename * smb_fname,bool fail_after_createfile)7991 static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
7992 					      struct smb_request *req,
7993 					const char *pdata,
7994 					int total_data,
7995 					files_struct *fsp,
7996 					const struct smb_filename *smb_fname,
7997 					bool fail_after_createfile)
7998 {
7999 	off_t size;
8000 
8001 	if (total_data < 8) {
8002 		return NT_STATUS_INVALID_PARAMETER;
8003 	}
8004 
8005 	size = IVAL(pdata,0);
8006 	size |= (((off_t)IVAL(pdata,4)) << 32);
8007 	DEBUG(10,("smb_set_file_end_of_file_info: Set end of file info for "
8008 		  "file %s to %.0f\n", smb_fname_str_dbg(smb_fname),
8009 		  (double)size));
8010 
8011 	return smb_set_file_size(conn, req,
8012 				fsp,
8013 				smb_fname,
8014 				&smb_fname->st,
8015 				size,
8016 				fail_after_createfile);
8017 }
8018 
8019 /****************************************************************************
8020  Allow a UNIX info mknod.
8021 ****************************************************************************/
8022 
smb_unix_mknod(connection_struct * conn,const char * pdata,int total_data,const struct smb_filename * smb_fname)8023 static NTSTATUS smb_unix_mknod(connection_struct *conn,
8024 					const char *pdata,
8025 					int total_data,
8026 					const struct smb_filename *smb_fname)
8027 {
8028 	uint32_t file_type = IVAL(pdata,56);
8029 #if defined(HAVE_MAKEDEV)
8030 	uint32_t dev_major = IVAL(pdata,60);
8031 	uint32_t dev_minor = IVAL(pdata,68);
8032 #endif
8033 	SMB_DEV_T dev = (SMB_DEV_T)0;
8034 	uint32_t raw_unixmode = IVAL(pdata,84);
8035 	NTSTATUS status;
8036 	mode_t unixmode;
8037 	int ret;
8038 
8039 	if (total_data < 100) {
8040 		return NT_STATUS_INVALID_PARAMETER;
8041 	}
8042 
8043 	status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8044 				      PERM_NEW_FILE, &unixmode);
8045 	if (!NT_STATUS_IS_OK(status)) {
8046 		return status;
8047 	}
8048 
8049 #if defined(HAVE_MAKEDEV)
8050 	dev = makedev(dev_major, dev_minor);
8051 #endif
8052 
8053 	switch (file_type) {
8054 		/* We can't create other objects here. */
8055 		case UNIX_TYPE_FILE:
8056 		case UNIX_TYPE_DIR:
8057 		case UNIX_TYPE_SYMLINK:
8058 			return NT_STATUS_ACCESS_DENIED;
8059 #if defined(S_IFIFO)
8060 		case UNIX_TYPE_FIFO:
8061 			unixmode |= S_IFIFO;
8062 			break;
8063 #endif
8064 #if defined(S_IFSOCK)
8065 		case UNIX_TYPE_SOCKET:
8066 			unixmode |= S_IFSOCK;
8067 			break;
8068 #endif
8069 #if defined(S_IFCHR)
8070 		case UNIX_TYPE_CHARDEV:
8071 			/* This is only allowed for root. */
8072 			if (get_current_uid(conn) != sec_initial_uid()) {
8073 				return NT_STATUS_ACCESS_DENIED;
8074 			}
8075 			unixmode |= S_IFCHR;
8076 			break;
8077 #endif
8078 #if defined(S_IFBLK)
8079 		case UNIX_TYPE_BLKDEV:
8080 			if (get_current_uid(conn) != sec_initial_uid()) {
8081 				return NT_STATUS_ACCESS_DENIED;
8082 			}
8083 			unixmode |= S_IFBLK;
8084 			break;
8085 #endif
8086 		default:
8087 			return NT_STATUS_INVALID_PARAMETER;
8088 	}
8089 
8090 	DEBUG(10,("smb_unix_mknod: SMB_SET_FILE_UNIX_BASIC doing mknod dev "
8091 		  "%.0f mode 0%o for file %s\n", (double)dev,
8092 		  (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
8093 
8094 	/* Ok - do the mknod. */
8095 	ret = SMB_VFS_MKNODAT(conn,
8096 			conn->cwd_fsp,
8097 			smb_fname,
8098 			unixmode,
8099 			dev);
8100 
8101 	if (ret != 0) {
8102 		return map_nt_error_from_unix(errno);
8103 	}
8104 
8105 	/* If any of the other "set" calls fail we
8106  	 * don't want to end up with a half-constructed mknod.
8107  	 */
8108 
8109 	if (lp_inherit_permissions(SNUM(conn))) {
8110 		char *parent;
8111 		if (!parent_dirname(talloc_tos(), smb_fname->base_name,
8112 				    &parent, NULL)) {
8113 			return NT_STATUS_NO_MEMORY;
8114 		}
8115 		inherit_access_posix_acl(conn, parent, smb_fname,
8116 					 unixmode);
8117 		TALLOC_FREE(parent);
8118 	}
8119 
8120 	return NT_STATUS_OK;
8121 }
8122 
8123 /****************************************************************************
8124  Deal with SMB_SET_FILE_UNIX_BASIC.
8125 ****************************************************************************/
8126 
smb_set_file_unix_basic(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,const struct smb_filename * smb_fname)8127 static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
8128 					struct smb_request *req,
8129 					const char *pdata,
8130 					int total_data,
8131 					files_struct *fsp,
8132 					const struct smb_filename *smb_fname)
8133 {
8134 	struct smb_file_time ft;
8135 	uint32_t raw_unixmode;
8136 	mode_t unixmode;
8137 	off_t size = 0;
8138 	uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
8139 	gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
8140 	NTSTATUS status = NT_STATUS_OK;
8141 	enum perm_type ptype;
8142 	files_struct *all_fsps = NULL;
8143 	bool modify_mtime = true;
8144 	struct file_id id;
8145 	SMB_STRUCT_STAT sbuf;
8146 
8147 	init_smb_file_time(&ft);
8148 
8149 	if (total_data < 100) {
8150 		return NT_STATUS_INVALID_PARAMETER;
8151 	}
8152 
8153 	if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
8154 	   IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
8155 		size=IVAL(pdata,0); /* first 8 Bytes are size */
8156 		size |= (((off_t)IVAL(pdata,4)) << 32);
8157 	}
8158 
8159 	ft.atime = pull_long_date_full_timespec(pdata+24); /* access_time */
8160 	ft.mtime = pull_long_date_full_timespec(pdata+32); /* modification_time */
8161 	set_owner = (uid_t)IVAL(pdata,40);
8162 	set_grp = (gid_t)IVAL(pdata,48);
8163 	raw_unixmode = IVAL(pdata,84);
8164 
8165 	if (VALID_STAT(smb_fname->st)) {
8166 		if (S_ISDIR(smb_fname->st.st_ex_mode)) {
8167 			ptype = PERM_EXISTING_DIR;
8168 		} else {
8169 			ptype = PERM_EXISTING_FILE;
8170 		}
8171 	} else {
8172 		ptype = PERM_NEW_FILE;
8173 	}
8174 
8175 	status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8176 				      ptype, &unixmode);
8177 	if (!NT_STATUS_IS_OK(status)) {
8178 		return status;
8179 	}
8180 
8181 	DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = "
8182 		  "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
8183 		  smb_fname_str_dbg(smb_fname), (double)size,
8184 		  (unsigned int)set_owner, (unsigned int)set_grp,
8185 		  (int)raw_unixmode));
8186 
8187 	sbuf = smb_fname->st;
8188 
8189 	if (!VALID_STAT(sbuf)) {
8190 		/*
8191 		 * The only valid use of this is to create character and block
8192 		 * devices, and named pipes. This is deprecated (IMHO) and
8193 		 * a new info level should be used for mknod. JRA.
8194 		 */
8195 
8196 		return smb_unix_mknod(conn,
8197 					pdata,
8198 					total_data,
8199 					smb_fname);
8200 	}
8201 
8202 #if 1
8203 	/* Horrible backwards compatibility hack as an old server bug
8204 	 * allowed a CIFS client bug to remain unnoticed :-(. JRA.
8205 	 * */
8206 
8207 	if (!size) {
8208 		size = get_file_size_stat(&sbuf);
8209 	}
8210 #endif
8211 
8212 	/*
8213 	 * Deal with the UNIX specific mode set.
8214 	 */
8215 
8216 	if (raw_unixmode != SMB_MODE_NO_CHANGE) {
8217 		int ret;
8218 
8219 		DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8220 			  "setting mode 0%o for file %s\n",
8221 			  (unsigned int)unixmode,
8222 			  smb_fname_str_dbg(smb_fname)));
8223 		if (fsp && fsp->fh->fd != -1) {
8224 			ret = SMB_VFS_FCHMOD(fsp, unixmode);
8225 		} else {
8226 			ret = SMB_VFS_CHMOD(conn, smb_fname, unixmode);
8227 		}
8228 		if (ret != 0) {
8229 			return map_nt_error_from_unix(errno);
8230 		}
8231 	}
8232 
8233 	/*
8234 	 * Deal with the UNIX specific uid set.
8235 	 */
8236 
8237 	if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) &&
8238 	    (sbuf.st_ex_uid != set_owner)) {
8239 		int ret;
8240 
8241 		DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8242 			  "changing owner %u for path %s\n",
8243 			  (unsigned int)set_owner,
8244 			  smb_fname_str_dbg(smb_fname)));
8245 
8246 		if (fsp && fsp->fh->fd != -1) {
8247 			ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
8248 		} else {
8249 			/*
8250 			 * UNIX extensions calls must always operate
8251 			 * on symlinks.
8252 			 */
8253 			ret = SMB_VFS_LCHOWN(conn, smb_fname,
8254 					     set_owner, (gid_t)-1);
8255 		}
8256 
8257 		if (ret != 0) {
8258 			status = map_nt_error_from_unix(errno);
8259 			return status;
8260 		}
8261 	}
8262 
8263 	/*
8264 	 * Deal with the UNIX specific gid set.
8265 	 */
8266 
8267 	if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
8268 	    (sbuf.st_ex_gid != set_grp)) {
8269 		int ret;
8270 
8271 		DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
8272 			  "changing group %u for file %s\n",
8273 			  (unsigned int)set_grp,
8274 			  smb_fname_str_dbg(smb_fname)));
8275 		if (fsp && fsp->fh->fd != -1) {
8276 			ret = SMB_VFS_FCHOWN(fsp, (uid_t)-1, set_grp);
8277 		} else {
8278 			/*
8279 			 * UNIX extensions calls must always operate
8280 			 * on symlinks.
8281 			 */
8282 			ret = SMB_VFS_LCHOWN(conn, smb_fname, (uid_t)-1,
8283 				  set_grp);
8284 		}
8285 		if (ret != 0) {
8286 			status = map_nt_error_from_unix(errno);
8287 			return status;
8288 		}
8289 	}
8290 
8291 	/* Deal with any size changes. */
8292 
8293 	if (S_ISREG(sbuf.st_ex_mode)) {
8294 		status = smb_set_file_size(conn, req,
8295 					   fsp,
8296 					   smb_fname,
8297 					   &sbuf,
8298 					   size,
8299 					   false);
8300 		if (!NT_STATUS_IS_OK(status)) {
8301 			return status;
8302 		}
8303 	}
8304 
8305 	/* Deal with any time changes. */
8306 	if (is_omit_timespec(&ft.mtime) && is_omit_timespec(&ft.atime)) {
8307 		/* No change, don't cancel anything. */
8308 		return status;
8309 	}
8310 
8311 	id = vfs_file_id_from_sbuf(conn, &sbuf);
8312 	for(all_fsps = file_find_di_first(conn->sconn, id); all_fsps;
8313 			all_fsps = file_find_di_next(all_fsps)) {
8314 		/*
8315 		 * We're setting the time explicitly for UNIX.
8316 		 * Cancel any pending changes over all handles.
8317 		 */
8318 		all_fsps->update_write_time_on_close = false;
8319 		TALLOC_FREE(all_fsps->update_write_time_event);
8320 	}
8321 
8322 	/*
8323 	 * Override the "setting_write_time"
8324 	 * parameter here as it almost does what
8325 	 * we need. Just remember if we modified
8326 	 * mtime and send the notify ourselves.
8327 	 */
8328 	if (is_omit_timespec(&ft.mtime)) {
8329 		modify_mtime = false;
8330 	}
8331 
8332 	status = smb_set_file_time(conn,
8333 				fsp,
8334 				smb_fname,
8335 				&ft,
8336 				false);
8337 	if (modify_mtime) {
8338 		notify_fname(conn, NOTIFY_ACTION_MODIFIED,
8339 			FILE_NOTIFY_CHANGE_LAST_WRITE, smb_fname->base_name);
8340 	}
8341 	return status;
8342 }
8343 
8344 /****************************************************************************
8345  Deal with SMB_SET_FILE_UNIX_INFO2.
8346 ****************************************************************************/
8347 
smb_set_file_unix_info2(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,files_struct * fsp,const struct smb_filename * smb_fname)8348 static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
8349 					struct smb_request *req,
8350 					const char *pdata,
8351 					int total_data,
8352 					files_struct *fsp,
8353 					const struct smb_filename *smb_fname)
8354 {
8355 	NTSTATUS status;
8356 	uint32_t smb_fflags;
8357 	uint32_t smb_fmask;
8358 
8359 	if (total_data < 116) {
8360 		return NT_STATUS_INVALID_PARAMETER;
8361 	}
8362 
8363 	/* Start by setting all the fields that are common between UNIX_BASIC
8364 	 * and UNIX_INFO2.
8365 	 */
8366 	status = smb_set_file_unix_basic(conn, req, pdata, total_data,
8367 					 fsp, smb_fname);
8368 	if (!NT_STATUS_IS_OK(status)) {
8369 		return status;
8370 	}
8371 
8372 	smb_fflags = IVAL(pdata, 108);
8373 	smb_fmask = IVAL(pdata, 112);
8374 
8375 	/* NB: We should only attempt to alter the file flags if the client
8376 	 * sends a non-zero mask.
8377 	 */
8378 	if (smb_fmask != 0) {
8379 		int stat_fflags = 0;
8380 
8381 		if (!map_info2_flags_to_sbuf(&smb_fname->st, smb_fflags,
8382 					     smb_fmask, &stat_fflags)) {
8383 			/* Client asked to alter a flag we don't understand. */
8384 			return NT_STATUS_INVALID_PARAMETER;
8385 		}
8386 
8387 		if (fsp && fsp->fh->fd != -1) {
8388 			/* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
8389 			return NT_STATUS_NOT_SUPPORTED;
8390 		} else {
8391 			if (SMB_VFS_CHFLAGS(conn, smb_fname,
8392 					    stat_fflags) != 0) {
8393 				return map_nt_error_from_unix(errno);
8394 			}
8395 		}
8396 	}
8397 
8398 	/* XXX: need to add support for changing the create_time here. You
8399 	 * can do this for paths on Darwin with setattrlist(2). The right way
8400 	 * to hook this up is probably by extending the VFS utimes interface.
8401 	 */
8402 
8403 	return NT_STATUS_OK;
8404 }
8405 
8406 /****************************************************************************
8407  Create a directory with POSIX semantics.
8408 ****************************************************************************/
8409 
smb_posix_mkdir(connection_struct * conn,struct smb_request * req,char ** ppdata,int total_data,struct smb_filename * smb_fname,int * pdata_return_size)8410 static NTSTATUS smb_posix_mkdir(connection_struct *conn,
8411 				struct smb_request *req,
8412 				char **ppdata,
8413 				int total_data,
8414 				struct smb_filename *smb_fname,
8415 				int *pdata_return_size)
8416 {
8417 	NTSTATUS status = NT_STATUS_OK;
8418 	uint32_t raw_unixmode = 0;
8419 	uint32_t mod_unixmode = 0;
8420 	mode_t unixmode = (mode_t)0;
8421 	files_struct *fsp = NULL;
8422 	uint16_t info_level_return = 0;
8423 	int info;
8424 	char *pdata = *ppdata;
8425 
8426 	if (total_data < 18) {
8427 		return NT_STATUS_INVALID_PARAMETER;
8428 	}
8429 
8430 	raw_unixmode = IVAL(pdata,8);
8431 	/* Next 4 bytes are not yet defined. */
8432 
8433 	status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8434 				      PERM_NEW_DIR, &unixmode);
8435 	if (!NT_STATUS_IS_OK(status)) {
8436 		return status;
8437 	}
8438 
8439 	mod_unixmode = (uint32_t)unixmode | FILE_FLAG_POSIX_SEMANTICS;
8440 
8441 	DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
8442 		  smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
8443 
8444         status = SMB_VFS_CREATE_FILE(
8445 		conn,					/* conn */
8446 		req,					/* req */
8447 		0,					/* root_dir_fid */
8448 		smb_fname,				/* fname */
8449 		FILE_READ_ATTRIBUTES,			/* access_mask */
8450 		FILE_SHARE_NONE,			/* share_access */
8451 		FILE_CREATE,				/* create_disposition*/
8452 		FILE_DIRECTORY_FILE,			/* create_options */
8453 		mod_unixmode,				/* file_attributes */
8454 		0,					/* oplock_request */
8455 		NULL,					/* lease */
8456 		0,					/* allocation_size */
8457 		0,					/* private_flags */
8458 		NULL,					/* sd */
8459 		NULL,					/* ea_list */
8460 		&fsp,					/* result */
8461 		&info,					/* pinfo */
8462 		NULL, NULL);				/* create context */
8463 
8464         if (NT_STATUS_IS_OK(status)) {
8465                 close_file(req, fsp, NORMAL_CLOSE);
8466         }
8467 
8468 	info_level_return = SVAL(pdata,16);
8469 
8470 	if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8471 		*pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8472 	} else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8473 		*pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8474 	} else {
8475 		*pdata_return_size = 12;
8476 	}
8477 
8478 	/* Realloc the data size */
8479 	*ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8480 	if (*ppdata == NULL) {
8481 		*pdata_return_size = 0;
8482 		return NT_STATUS_NO_MEMORY;
8483 	}
8484 	pdata = *ppdata;
8485 
8486 	SSVAL(pdata,0,NO_OPLOCK_RETURN);
8487 	SSVAL(pdata,2,0); /* No fnum. */
8488 	SIVAL(pdata,4,info); /* Was directory created. */
8489 
8490 	switch (info_level_return) {
8491 		case SMB_QUERY_FILE_UNIX_BASIC:
8492 			SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8493 			SSVAL(pdata,10,0); /* Padding. */
8494 			store_file_unix_basic(conn, pdata + 12, fsp,
8495 					      &smb_fname->st);
8496 			break;
8497 		case SMB_QUERY_FILE_UNIX_INFO2:
8498 			SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8499 			SSVAL(pdata,10,0); /* Padding. */
8500 			store_file_unix_basic_info2(conn, pdata + 12, fsp,
8501 						    &smb_fname->st);
8502 			break;
8503 		default:
8504 			SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8505 			SSVAL(pdata,10,0); /* Padding. */
8506 			break;
8507 	}
8508 
8509 	return status;
8510 }
8511 
8512 /****************************************************************************
8513  Open/Create a file with POSIX semantics.
8514 ****************************************************************************/
8515 
8516 #define SMB_O_RDONLY_MAPPING (FILE_READ_DATA|FILE_READ_ATTRIBUTES|FILE_READ_EA)
8517 #define SMB_O_WRONLY_MAPPING (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA)
8518 
smb_posix_open(connection_struct * conn,struct smb_request * req,char ** ppdata,int total_data,struct smb_filename * smb_fname,int * pdata_return_size)8519 static NTSTATUS smb_posix_open(connection_struct *conn,
8520 			       struct smb_request *req,
8521 				char **ppdata,
8522 				int total_data,
8523 				struct smb_filename *smb_fname,
8524 				int *pdata_return_size)
8525 {
8526 	bool extended_oplock_granted = False;
8527 	char *pdata = *ppdata;
8528 	uint32_t flags = 0;
8529 	uint32_t wire_open_mode = 0;
8530 	uint32_t raw_unixmode = 0;
8531 	uint32_t mod_unixmode = 0;
8532 	uint32_t create_disp = 0;
8533 	uint32_t access_mask = 0;
8534 	uint32_t create_options = FILE_NON_DIRECTORY_FILE;
8535 	NTSTATUS status = NT_STATUS_OK;
8536 	mode_t unixmode = (mode_t)0;
8537 	files_struct *fsp = NULL;
8538 	int oplock_request = 0;
8539 	int info = 0;
8540 	uint16_t info_level_return = 0;
8541 
8542 	if (total_data < 18) {
8543 		return NT_STATUS_INVALID_PARAMETER;
8544 	}
8545 
8546 	flags = IVAL(pdata,0);
8547 	oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
8548 	if (oplock_request) {
8549 		oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
8550 	}
8551 
8552 	wire_open_mode = IVAL(pdata,4);
8553 
8554 	if (wire_open_mode == (SMB_O_CREAT|SMB_O_DIRECTORY)) {
8555 		return smb_posix_mkdir(conn, req,
8556 					ppdata,
8557 					total_data,
8558 					smb_fname,
8559 					pdata_return_size);
8560 	}
8561 
8562 	switch (wire_open_mode & SMB_ACCMODE) {
8563 		case SMB_O_RDONLY:
8564 			access_mask = SMB_O_RDONLY_MAPPING;
8565 			break;
8566 		case SMB_O_WRONLY:
8567 			access_mask = SMB_O_WRONLY_MAPPING;
8568 			break;
8569 		case SMB_O_RDWR:
8570 			access_mask = (SMB_O_RDONLY_MAPPING|
8571 					SMB_O_WRONLY_MAPPING);
8572 			break;
8573 		default:
8574 			DEBUG(5,("smb_posix_open: invalid open mode 0x%x\n",
8575 				(unsigned int)wire_open_mode ));
8576 			return NT_STATUS_INVALID_PARAMETER;
8577 	}
8578 
8579 	wire_open_mode &= ~SMB_ACCMODE;
8580 
8581 	/* First take care of O_CREAT|O_EXCL interactions. */
8582 	switch (wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL)) {
8583 		case (SMB_O_CREAT | SMB_O_EXCL):
8584 			/* File exists fail. File not exist create. */
8585 			create_disp = FILE_CREATE;
8586 			break;
8587 		case SMB_O_CREAT:
8588 			/* File exists open. File not exist create. */
8589 			create_disp = FILE_OPEN_IF;
8590 			break;
8591 		case SMB_O_EXCL:
8592 			/* O_EXCL on its own without O_CREAT is undefined.
8593 			   We deliberately ignore it as some versions of
8594 			   Linux CIFSFS can send a bare O_EXCL on the
8595 			   wire which other filesystems in the kernel
8596 			   ignore. See bug 9519 for details. */
8597 
8598 			/* Fallthrough. */
8599 
8600 		case 0:
8601 			/* File exists open. File not exist fail. */
8602 			create_disp = FILE_OPEN;
8603 			break;
8604 		default:
8605 			DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n",
8606 				(unsigned int)wire_open_mode ));
8607 			return NT_STATUS_INVALID_PARAMETER;
8608 	}
8609 
8610 	/* Next factor in the effects of O_TRUNC. */
8611 	wire_open_mode &= ~(SMB_O_CREAT | SMB_O_EXCL);
8612 
8613 	if (wire_open_mode & SMB_O_TRUNC) {
8614 		switch (create_disp) {
8615 			case FILE_CREATE:
8616 				/* (SMB_O_CREAT | SMB_O_EXCL | O_TRUNC) */
8617 				/* Leave create_disp alone as
8618 				   (O_CREAT|O_EXCL|O_TRUNC) == (O_CREAT|O_EXCL)
8619 				*/
8620 				/* File exists fail. File not exist create. */
8621 				break;
8622 			case FILE_OPEN_IF:
8623 				/* SMB_O_CREAT | SMB_O_TRUNC */
8624 				/* File exists overwrite. File not exist create. */
8625 				create_disp = FILE_OVERWRITE_IF;
8626 				break;
8627 			case FILE_OPEN:
8628 				/* SMB_O_TRUNC */
8629 				/* File exists overwrite. File not exist fail. */
8630 				create_disp = FILE_OVERWRITE;
8631 				break;
8632 			default:
8633 				/* Cannot get here. */
8634 				smb_panic("smb_posix_open: logic error");
8635 				return NT_STATUS_INVALID_PARAMETER;
8636 		}
8637 	}
8638 
8639 	raw_unixmode = IVAL(pdata,8);
8640 	/* Next 4 bytes are not yet defined. */
8641 
8642 	status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
8643 				      (VALID_STAT(smb_fname->st) ?
8644 					  PERM_EXISTING_FILE : PERM_NEW_FILE),
8645 				      &unixmode);
8646 
8647 	if (!NT_STATUS_IS_OK(status)) {
8648 		return status;
8649 	}
8650 
8651 	mod_unixmode = (uint32_t)unixmode | FILE_FLAG_POSIX_SEMANTICS;
8652 
8653 	if (wire_open_mode & SMB_O_SYNC) {
8654 		create_options |= FILE_WRITE_THROUGH;
8655 	}
8656 	if (wire_open_mode & SMB_O_APPEND) {
8657 		access_mask |= FILE_APPEND_DATA;
8658 	}
8659 	if (wire_open_mode & SMB_O_DIRECT) {
8660 		mod_unixmode |= FILE_FLAG_NO_BUFFERING;
8661 	}
8662 
8663 	if ((wire_open_mode & SMB_O_DIRECTORY) ||
8664 			VALID_STAT_OF_DIR(smb_fname->st)) {
8665 		if (access_mask != SMB_O_RDONLY_MAPPING) {
8666 			return NT_STATUS_FILE_IS_A_DIRECTORY;
8667 		}
8668 		create_options &= ~FILE_NON_DIRECTORY_FILE;
8669 		create_options |= FILE_DIRECTORY_FILE;
8670 	}
8671 
8672 	DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
8673 		smb_fname_str_dbg(smb_fname),
8674 		(unsigned int)wire_open_mode,
8675 		(unsigned int)unixmode ));
8676 
8677         status = SMB_VFS_CREATE_FILE(
8678 		conn,					/* conn */
8679 		req,					/* req */
8680 		0,					/* root_dir_fid */
8681 		smb_fname,				/* fname */
8682 		access_mask,				/* access_mask */
8683 		(FILE_SHARE_READ | FILE_SHARE_WRITE |	/* share_access */
8684 		    FILE_SHARE_DELETE),
8685 		create_disp,				/* create_disposition*/
8686 		create_options,				/* create_options */
8687 		mod_unixmode,				/* file_attributes */
8688 		oplock_request,				/* oplock_request */
8689 		NULL,					/* lease */
8690 		0,					/* allocation_size */
8691 		0,					/* private_flags */
8692 		NULL,					/* sd */
8693 		NULL,					/* ea_list */
8694 		&fsp,					/* result */
8695 		&info,					/* pinfo */
8696 		NULL, NULL);				/* create context */
8697 
8698 	if (!NT_STATUS_IS_OK(status)) {
8699 		return status;
8700 	}
8701 
8702 	if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
8703 		extended_oplock_granted = True;
8704 	}
8705 
8706 	if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
8707 		extended_oplock_granted = True;
8708 	}
8709 
8710 	info_level_return = SVAL(pdata,16);
8711 
8712 	/* Allocate the correct return size. */
8713 
8714 	if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
8715 		*pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
8716 	} else if (info_level_return ==  SMB_QUERY_FILE_UNIX_INFO2) {
8717 		*pdata_return_size = 12 + SMB_FILE_UNIX_INFO2_SIZE;
8718 	} else {
8719 		*pdata_return_size = 12;
8720 	}
8721 
8722 	/* Realloc the data size */
8723 	*ppdata = (char *)SMB_REALLOC(*ppdata,*pdata_return_size);
8724 	if (*ppdata == NULL) {
8725 		close_file(req, fsp, ERROR_CLOSE);
8726 		*pdata_return_size = 0;
8727 		return NT_STATUS_NO_MEMORY;
8728 	}
8729 	pdata = *ppdata;
8730 
8731 	if (extended_oplock_granted) {
8732 		if (flags & REQUEST_BATCH_OPLOCK) {
8733 			SSVAL(pdata,0, BATCH_OPLOCK_RETURN);
8734 		} else {
8735 			SSVAL(pdata,0, EXCLUSIVE_OPLOCK_RETURN);
8736 		}
8737 	} else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
8738 		SSVAL(pdata,0, LEVEL_II_OPLOCK_RETURN);
8739 	} else {
8740 		SSVAL(pdata,0,NO_OPLOCK_RETURN);
8741 	}
8742 
8743 	SSVAL(pdata,2,fsp->fnum);
8744 	SIVAL(pdata,4,info); /* Was file created etc. */
8745 
8746 	switch (info_level_return) {
8747 		case SMB_QUERY_FILE_UNIX_BASIC:
8748 			SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
8749 			SSVAL(pdata,10,0); /* padding. */
8750 			store_file_unix_basic(conn, pdata + 12, fsp,
8751 					      &smb_fname->st);
8752 			break;
8753 		case SMB_QUERY_FILE_UNIX_INFO2:
8754 			SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
8755 			SSVAL(pdata,10,0); /* padding. */
8756 			store_file_unix_basic_info2(conn, pdata + 12, fsp,
8757 						    &smb_fname->st);
8758 			break;
8759 		default:
8760 			SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
8761 			SSVAL(pdata,10,0); /* padding. */
8762 			break;
8763 	}
8764 	return NT_STATUS_OK;
8765 }
8766 
8767 /****************************************************************************
8768  Delete a file with POSIX semantics.
8769 ****************************************************************************/
8770 
smb_posix_unlink(connection_struct * conn,struct smb_request * req,const char * pdata,int total_data,struct smb_filename * smb_fname)8771 static NTSTATUS smb_posix_unlink(connection_struct *conn,
8772 				 struct smb_request *req,
8773 				const char *pdata,
8774 				int total_data,
8775 				struct smb_filename *smb_fname)
8776 {
8777 	NTSTATUS status = NT_STATUS_OK;
8778 	files_struct *fsp = NULL;
8779 	uint16_t flags = 0;
8780 	char del = 1;
8781 	int info = 0;
8782 	int create_options = 0;
8783 	struct share_mode_lock *lck = NULL;
8784 	bool other_nonposix_opens;
8785 
8786 	if (total_data < 2) {
8787 		return NT_STATUS_INVALID_PARAMETER;
8788 	}
8789 
8790 	flags = SVAL(pdata,0);
8791 
8792 	if (!VALID_STAT(smb_fname->st)) {
8793 		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
8794 	}
8795 
8796 	if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
8797 			!VALID_STAT_OF_DIR(smb_fname->st)) {
8798 		return NT_STATUS_NOT_A_DIRECTORY;
8799 	}
8800 
8801 	DEBUG(10,("smb_posix_unlink: %s %s\n",
8802 		(flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
8803 		smb_fname_str_dbg(smb_fname)));
8804 
8805 	if (VALID_STAT_OF_DIR(smb_fname->st)) {
8806 		create_options |= FILE_DIRECTORY_FILE;
8807 	}
8808 
8809         status = SMB_VFS_CREATE_FILE(
8810 		conn,					/* conn */
8811 		req,					/* req */
8812 		0,					/* root_dir_fid */
8813 		smb_fname,				/* fname */
8814 		DELETE_ACCESS,				/* access_mask */
8815 		(FILE_SHARE_READ | FILE_SHARE_WRITE |	/* share_access */
8816 		    FILE_SHARE_DELETE),
8817 		FILE_OPEN,				/* create_disposition*/
8818 		create_options,				/* create_options */
8819 		FILE_FLAG_POSIX_SEMANTICS|0777,		/* file_attributes */
8820 		0,					/* oplock_request */
8821 		NULL,					/* lease */
8822 		0,					/* allocation_size */
8823 		0,					/* private_flags */
8824 		NULL,					/* sd */
8825 		NULL,					/* ea_list */
8826 		&fsp,					/* result */
8827 		&info,					/* pinfo */
8828 		NULL, NULL);				/* create context */
8829 
8830 	if (!NT_STATUS_IS_OK(status)) {
8831 		return status;
8832 	}
8833 
8834 	/*
8835 	 * Don't lie to client. If we can't really delete due to
8836 	 * non-POSIX opens return SHARING_VIOLATION.
8837 	 */
8838 
8839 	lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
8840 	if (lck == NULL) {
8841 		DEBUG(0, ("smb_posix_unlink: Could not get share mode "
8842 			  "lock for file %s\n", fsp_str_dbg(fsp)));
8843 		close_file(req, fsp, NORMAL_CLOSE);
8844 		return NT_STATUS_INVALID_PARAMETER;
8845 	}
8846 
8847 	other_nonposix_opens = has_other_nonposix_opens(lck, fsp);
8848 	if (other_nonposix_opens) {
8849 		/* Fail with sharing violation. */
8850 		TALLOC_FREE(lck);
8851 		close_file(req, fsp, NORMAL_CLOSE);
8852 		return NT_STATUS_SHARING_VIOLATION;
8853 	}
8854 
8855 	/*
8856 	 * Set the delete on close.
8857 	 */
8858 	status = smb_set_file_disposition_info(conn,
8859 						&del,
8860 						1,
8861 						fsp,
8862 						smb_fname);
8863 
8864 	TALLOC_FREE(lck);
8865 
8866 	if (!NT_STATUS_IS_OK(status)) {
8867 		close_file(req, fsp, NORMAL_CLOSE);
8868 		return status;
8869 	}
8870 	return close_file(req, fsp, NORMAL_CLOSE);
8871 }
8872 
smbd_do_setfilepathinfo(connection_struct * conn,struct smb_request * req,TALLOC_CTX * mem_ctx,uint16_t info_level,files_struct * fsp,struct smb_filename * smb_fname,char ** ppdata,int total_data,int * ret_data_size)8873 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
8874 				struct smb_request *req,
8875 				TALLOC_CTX *mem_ctx,
8876 				uint16_t info_level,
8877 				files_struct *fsp,
8878 				struct smb_filename *smb_fname,
8879 				char **ppdata, int total_data,
8880 				int *ret_data_size)
8881 {
8882 	char *pdata = *ppdata;
8883 	NTSTATUS status = NT_STATUS_OK;
8884 	int data_return_size = 0;
8885 
8886 	*ret_data_size = 0;
8887 
8888 	if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
8889 		return NT_STATUS_INVALID_LEVEL;
8890 	}
8891 
8892 	if (!CAN_WRITE(conn)) {
8893 		/* Allow POSIX opens. The open path will deny
8894 		 * any non-readonly opens. */
8895 		if (info_level != SMB_POSIX_PATH_OPEN) {
8896 			return NT_STATUS_DOS(ERRSRV, ERRaccess);
8897 		}
8898 	}
8899 
8900 	DEBUG(3,("smbd_do_setfilepathinfo: %s (%s) info_level=%d "
8901 		 "totdata=%d\n", smb_fname_str_dbg(smb_fname),
8902 		 fsp_fnum_dbg(fsp),
8903 		 info_level, total_data));
8904 
8905 	switch (info_level) {
8906 
8907 		case SMB_INFO_STANDARD:
8908 		{
8909 			status = smb_set_info_standard(conn,
8910 					pdata,
8911 					total_data,
8912 					fsp,
8913 					smb_fname);
8914 			break;
8915 		}
8916 
8917 		case SMB_INFO_SET_EA:
8918 		{
8919 			status = smb_info_set_ea(conn,
8920 						pdata,
8921 						total_data,
8922 						fsp,
8923 						smb_fname);
8924 			break;
8925 		}
8926 
8927 		case SMB_SET_FILE_BASIC_INFO:
8928 		case SMB_FILE_BASIC_INFORMATION:
8929 		{
8930 			status = smb_set_file_basic_info(conn,
8931 							pdata,
8932 							total_data,
8933 							fsp,
8934 							smb_fname);
8935 			break;
8936 		}
8937 
8938 		case SMB_FILE_ALLOCATION_INFORMATION:
8939 		case SMB_SET_FILE_ALLOCATION_INFO:
8940 		{
8941 			status = smb_set_file_allocation_info(conn, req,
8942 								pdata,
8943 								total_data,
8944 								fsp,
8945 								smb_fname);
8946 			break;
8947 		}
8948 
8949 		case SMB_FILE_END_OF_FILE_INFORMATION:
8950 		case SMB_SET_FILE_END_OF_FILE_INFO:
8951 		{
8952 			/*
8953 			 * XP/Win7 both fail after the createfile with
8954 			 * SMB_SET_FILE_END_OF_FILE_INFO but not
8955 			 * SMB_FILE_END_OF_FILE_INFORMATION (pass-through).
8956 			 * The level is known here, so pass it down
8957 			 * appropriately.
8958 			 */
8959 			bool should_fail =
8960 			    (info_level == SMB_SET_FILE_END_OF_FILE_INFO);
8961 
8962 			status = smb_set_file_end_of_file_info(conn, req,
8963 								pdata,
8964 								total_data,
8965 								fsp,
8966 								smb_fname,
8967 								should_fail);
8968 			break;
8969 		}
8970 
8971 		case SMB_FILE_DISPOSITION_INFORMATION:
8972 		case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
8973 		{
8974 #if 0
8975 			/* JRA - We used to just ignore this on a path ?
8976 			 * Shouldn't this be invalid level on a pathname
8977 			 * based call ?
8978 			 */
8979 			if (tran_call != TRANSACT2_SETFILEINFO) {
8980 				return ERROR_NT(NT_STATUS_INVALID_LEVEL);
8981 			}
8982 #endif
8983 			status = smb_set_file_disposition_info(conn,
8984 						pdata,
8985 						total_data,
8986 						fsp,
8987 						smb_fname);
8988 			break;
8989 		}
8990 
8991 		case SMB_FILE_POSITION_INFORMATION:
8992 		{
8993 			status = smb_file_position_information(conn,
8994 						pdata,
8995 						total_data,
8996 						fsp);
8997 			break;
8998 		}
8999 
9000 		case SMB_FILE_FULL_EA_INFORMATION:
9001 		{
9002 			status = smb_set_file_full_ea_info(conn,
9003 						pdata,
9004 						total_data,
9005 						fsp);
9006 			break;
9007 		}
9008 
9009 		/* From tridge Samba4 :
9010 		 * MODE_INFORMATION in setfileinfo (I have no
9011 		 * idea what "mode information" on a file is - it takes a value of 0,
9012 		 * 2, 4 or 6. What could it be?).
9013 		 */
9014 
9015 		case SMB_FILE_MODE_INFORMATION:
9016 		{
9017 			status = smb_file_mode_information(conn,
9018 						pdata,
9019 						total_data);
9020 			break;
9021 		}
9022 
9023 		/* [MS-SMB2] 3.3.5.21.1 states we MUST fail with STATUS_NOT_SUPPORTED. */
9024 		case SMB_FILE_VALID_DATA_LENGTH_INFORMATION:
9025 		case SMB_FILE_SHORT_NAME_INFORMATION:
9026 			return NT_STATUS_NOT_SUPPORTED;
9027 
9028 		/*
9029 		 * CIFS UNIX extensions.
9030 		 */
9031 
9032 		case SMB_SET_FILE_UNIX_BASIC:
9033 		{
9034 			status = smb_set_file_unix_basic(conn, req,
9035 							pdata,
9036 							total_data,
9037 							fsp,
9038 							smb_fname);
9039 			break;
9040 		}
9041 
9042 		case SMB_SET_FILE_UNIX_INFO2:
9043 		{
9044 			status = smb_set_file_unix_info2(conn, req,
9045 							pdata,
9046 							total_data,
9047 							fsp,
9048 							smb_fname);
9049 			break;
9050 		}
9051 
9052 		case SMB_SET_FILE_UNIX_LINK:
9053 		{
9054 			if (fsp) {
9055 				/* We must have a pathname for this. */
9056 				return NT_STATUS_INVALID_LEVEL;
9057 			}
9058 			status = smb_set_file_unix_link(conn, req, pdata,
9059 							total_data, smb_fname);
9060 			break;
9061 		}
9062 
9063 		case SMB_SET_FILE_UNIX_HLINK:
9064 		{
9065 			if (fsp) {
9066 				/* We must have a pathname for this. */
9067 				return NT_STATUS_INVALID_LEVEL;
9068 			}
9069 			status = smb_set_file_unix_hlink(conn, req,
9070 							 pdata,	total_data,
9071 							 smb_fname);
9072 			break;
9073 		}
9074 
9075 		case SMB_FILE_RENAME_INFORMATION:
9076 		{
9077 			status = smb_file_rename_information(conn, req,
9078 							     pdata, total_data,
9079 							     fsp, smb_fname);
9080 			break;
9081 		}
9082 
9083 		case SMB2_FILE_RENAME_INFORMATION_INTERNAL:
9084 		{
9085 			/* SMB2 rename information. */
9086 			status = smb2_file_rename_information(conn, req,
9087 							     pdata, total_data,
9088 							     fsp, smb_fname);
9089 			break;
9090 		}
9091 
9092 		case SMB_FILE_LINK_INFORMATION:
9093 		{
9094 			status = smb_file_link_information(conn, req,
9095 							pdata, total_data,
9096 							fsp, smb_fname);
9097 			break;
9098 		}
9099 
9100 #if defined(HAVE_POSIX_ACLS)
9101 		case SMB_SET_POSIX_ACL:
9102 		{
9103 			status = smb_set_posix_acl(conn,
9104 						req,
9105 						pdata,
9106 						total_data,
9107 						fsp,
9108 						smb_fname);
9109 			break;
9110 		}
9111 #endif
9112 
9113 		case SMB_SET_POSIX_LOCK:
9114 		{
9115 			if (!fsp) {
9116 				return NT_STATUS_INVALID_LEVEL;
9117 			}
9118 			status = smb_set_posix_lock(conn, req,
9119 						    pdata, total_data, fsp);
9120 			break;
9121 		}
9122 
9123 		case SMB_POSIX_PATH_OPEN:
9124 		{
9125 			if (fsp) {
9126 				/* We must have a pathname for this. */
9127 				return NT_STATUS_INVALID_LEVEL;
9128 			}
9129 
9130 			status = smb_posix_open(conn, req,
9131 						ppdata,
9132 						total_data,
9133 						smb_fname,
9134 						&data_return_size);
9135 			break;
9136 		}
9137 
9138 		case SMB_POSIX_PATH_UNLINK:
9139 		{
9140 			if (fsp) {
9141 				/* We must have a pathname for this. */
9142 				return NT_STATUS_INVALID_LEVEL;
9143 			}
9144 
9145 			status = smb_posix_unlink(conn, req,
9146 						pdata,
9147 						total_data,
9148 						smb_fname);
9149 			break;
9150 		}
9151 
9152 		default:
9153 			return NT_STATUS_INVALID_LEVEL;
9154 	}
9155 
9156 	if (!NT_STATUS_IS_OK(status)) {
9157 		return status;
9158 	}
9159 
9160 	*ret_data_size = data_return_size;
9161 	return NT_STATUS_OK;
9162 }
9163 
9164 /****************************************************************************
9165  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
9166 ****************************************************************************/
9167 
call_trans2setfilepathinfo(connection_struct * conn,struct smb_request * req,unsigned int tran_call,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)9168 static void call_trans2setfilepathinfo(connection_struct *conn,
9169 				       struct smb_request *req,
9170 				       unsigned int tran_call,
9171 				       char **pparams, int total_params,
9172 				       char **ppdata, int total_data,
9173 				       unsigned int max_data_bytes)
9174 {
9175 	char *params = *pparams;
9176 	char *pdata = *ppdata;
9177 	uint16_t info_level;
9178 	struct smb_filename *smb_fname = NULL;
9179 	files_struct *fsp = NULL;
9180 	NTSTATUS status = NT_STATUS_OK;
9181 	int data_return_size = 0;
9182 
9183 	if (!params) {
9184 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9185 		return;
9186 	}
9187 
9188 	if (tran_call == TRANSACT2_SETFILEINFO) {
9189 		if (total_params < 4) {
9190 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9191 			return;
9192 		}
9193 
9194 		fsp = file_fsp(req, SVAL(params,0));
9195 		/* Basic check for non-null fsp. */
9196 	        if (!check_fsp_open(conn, req, fsp)) {
9197 			return;
9198 		}
9199 		info_level = SVAL(params,2);
9200 
9201 		smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name);
9202 		if (smb_fname == NULL) {
9203 			reply_nterror(req, NT_STATUS_NO_MEMORY);
9204 			return;
9205 		}
9206 
9207 		if(fsp->fh->fd == -1) {
9208 			/*
9209 			 * This is actually a SETFILEINFO on a directory
9210 			 * handle (returned from an NT SMB). NT5.0 seems
9211 			 * to do this call. JRA.
9212 			 */
9213 			if (INFO_LEVEL_IS_UNIX(info_level)) {
9214 				/* Always do lstat for UNIX calls. */
9215 				if (SMB_VFS_LSTAT(conn, smb_fname)) {
9216 					DEBUG(3,("call_trans2setfilepathinfo: "
9217 						 "SMB_VFS_LSTAT of %s failed "
9218 						 "(%s)\n",
9219 						 smb_fname_str_dbg(smb_fname),
9220 						 strerror(errno)));
9221 					reply_nterror(req, map_nt_error_from_unix(errno));
9222 					return;
9223 				}
9224 			} else {
9225 				if (SMB_VFS_STAT(conn, smb_fname) != 0) {
9226 					DEBUG(3,("call_trans2setfilepathinfo: "
9227 						 "fileinfo of %s failed (%s)\n",
9228 						 smb_fname_str_dbg(smb_fname),
9229 						 strerror(errno)));
9230 					reply_nterror(req, map_nt_error_from_unix(errno));
9231 					return;
9232 				}
9233 			}
9234 		} else if (fsp->print_file) {
9235 			/*
9236 			 * Doing a DELETE_ON_CLOSE should cancel a print job.
9237 			 */
9238 			if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
9239 				fsp->fh->private_options |= NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE;
9240 
9241 				DEBUG(3,("call_trans2setfilepathinfo: "
9242 					 "Cancelling print job (%s)\n",
9243 					 fsp_str_dbg(fsp)));
9244 
9245 				SSVAL(params,0,0);
9246 				send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
9247 						    *ppdata, 0,
9248 						    max_data_bytes);
9249 				return;
9250 			} else {
9251 				reply_nterror(req,
9252 					NT_STATUS_OBJECT_PATH_NOT_FOUND);
9253 				return;
9254 			}
9255 		} else {
9256 			/*
9257 			 * Original code - this is an open file.
9258 			 */
9259 			if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
9260 				DEBUG(3,("call_trans2setfilepathinfo: fstat "
9261 					 "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
9262 					 strerror(errno)));
9263 				reply_nterror(req, map_nt_error_from_unix(errno));
9264 				return;
9265 			}
9266 		}
9267 	} else {
9268 		char *fname = NULL;
9269 		uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9270 
9271 		/* set path info */
9272 		if (total_params < 7) {
9273 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9274 			return;
9275 		}
9276 
9277 		info_level = SVAL(params,0);
9278 		if (req->posix_pathnames) {
9279 			srvstr_get_path_posix(req,
9280 				params,
9281 				req->flags2,
9282 				&fname,
9283 				&params[6],
9284 				total_params - 6,
9285 				STR_TERMINATE,
9286 				&status);
9287 		} else {
9288 			srvstr_get_path(req,
9289 				params,
9290 				req->flags2,
9291 				&fname,
9292 				&params[6],
9293 				total_params - 6,
9294 				STR_TERMINATE,
9295 				&status);
9296 		}
9297 		if (!NT_STATUS_IS_OK(status)) {
9298 			reply_nterror(req, status);
9299 			return;
9300 		}
9301 
9302 		if (info_level == SMB_SET_FILE_UNIX_BASIC ||
9303 				info_level == SMB_SET_FILE_UNIX_INFO2 ||
9304 				info_level == SMB_FILE_RENAME_INFORMATION ||
9305 				info_level == SMB_POSIX_PATH_OPEN ||
9306 				info_level == SMB_POSIX_PATH_UNLINK) {
9307 			ucf_flags |= UCF_UNIX_NAME_LOOKUP;
9308 		}
9309 
9310 		status = filename_convert(req, conn,
9311 					 fname,
9312 					 ucf_flags,
9313 					 NULL,
9314 					 NULL,
9315 					 &smb_fname);
9316 		if (!NT_STATUS_IS_OK(status)) {
9317 			if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9318 				reply_botherror(req,
9319 						NT_STATUS_PATH_NOT_COVERED,
9320 						ERRSRV, ERRbadpath);
9321 				return;
9322 			}
9323 			reply_nterror(req, status);
9324 			return;
9325 		}
9326 
9327 		if (INFO_LEVEL_IS_UNIX(info_level)) {
9328 			/*
9329 			 * For CIFS UNIX extensions the target name may not exist.
9330 			 */
9331 
9332 			/* Always do lstat for UNIX calls. */
9333 			SMB_VFS_LSTAT(conn, smb_fname);
9334 
9335 		} else if (!VALID_STAT(smb_fname->st) &&
9336 			   SMB_VFS_STAT(conn, smb_fname)) {
9337 			DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
9338 				 "%s failed (%s)\n",
9339 				 smb_fname_str_dbg(smb_fname),
9340 				 strerror(errno)));
9341 			reply_nterror(req, map_nt_error_from_unix(errno));
9342 			return;
9343 		}
9344 	}
9345 
9346 	DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
9347 		 "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
9348 		 fsp_fnum_dbg(fsp),
9349 		 info_level,total_data));
9350 
9351 	/* Realloc the parameter size */
9352 	*pparams = (char *)SMB_REALLOC(*pparams,2);
9353 	if (*pparams == NULL) {
9354 		reply_nterror(req, NT_STATUS_NO_MEMORY);
9355 		return;
9356 	}
9357 	params = *pparams;
9358 
9359 	SSVAL(params,0,0);
9360 
9361 	status = smbd_do_setfilepathinfo(conn, req, req,
9362 					 info_level,
9363 					 fsp,
9364 					 smb_fname,
9365 					 ppdata, total_data,
9366 					 &data_return_size);
9367 	if (!NT_STATUS_IS_OK(status)) {
9368 		if (open_was_deferred(req->xconn, req->mid)) {
9369 			/* We have re-scheduled this call. */
9370 			return;
9371 		}
9372 		if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
9373 			bool ok = defer_smb1_sharing_violation(req);
9374 			if (ok) {
9375 				return;
9376 			}
9377 		}
9378 		if (NT_STATUS_EQUAL(status, NT_STATUS_EVENT_PENDING)) {
9379 			/* We have re-scheduled this call. */
9380 			return;
9381 		}
9382 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9383 			reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
9384 					ERRSRV, ERRbadpath);
9385 			return;
9386 		}
9387 		if (info_level == SMB_POSIX_PATH_OPEN) {
9388 			reply_openerror(req, status);
9389 			return;
9390 		}
9391 
9392 		/*
9393 		 * Invalid EA name needs to return 2 param bytes,
9394 		 * not a zero-length error packet.
9395 		 */
9396 		if (NT_STATUS_EQUAL(status, STATUS_INVALID_EA_NAME)) {
9397 			send_trans2_replies(conn, req, status, params, 2, NULL, 0,
9398 					max_data_bytes);
9399 		} else {
9400 			reply_nterror(req, status);
9401 		}
9402 		return;
9403 	}
9404 
9405 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, data_return_size,
9406 			    max_data_bytes);
9407 
9408 	return;
9409 }
9410 
9411 /****************************************************************************
9412  Reply to a TRANS2_MKDIR (make directory with extended attributes).
9413 ****************************************************************************/
9414 
call_trans2mkdir(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)9415 static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
9416 			     char **pparams, int total_params,
9417 			     char **ppdata, int total_data,
9418 			     unsigned int max_data_bytes)
9419 {
9420 	struct smb_filename *smb_dname = NULL;
9421 	char *params = *pparams;
9422 	char *pdata = *ppdata;
9423 	char *directory = NULL;
9424 	NTSTATUS status = NT_STATUS_OK;
9425 	struct ea_list *ea_list = NULL;
9426 	uint32_t ucf_flags = ucf_flags_from_smb_request(req);
9427 	TALLOC_CTX *ctx = talloc_tos();
9428 
9429 	if (!CAN_WRITE(conn)) {
9430 		reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9431 		return;
9432 	}
9433 
9434 	if (total_params < 5) {
9435 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9436 		return;
9437 	}
9438 
9439 	if (req->posix_pathnames) {
9440 		srvstr_get_path_posix(ctx,
9441 			params,
9442 			req->flags2,
9443 			&directory,
9444 			&params[4],
9445 			total_params - 4,
9446 			STR_TERMINATE,
9447 			&status);
9448 	} else {
9449 		srvstr_get_path(ctx,
9450 			params,
9451 			req->flags2,
9452 			&directory,
9453 			&params[4],
9454 			total_params - 4,
9455 			STR_TERMINATE,
9456 			&status);
9457 	}
9458 	if (!NT_STATUS_IS_OK(status)) {
9459 		reply_nterror(req, status);
9460 		return;
9461 	}
9462 
9463 	DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
9464 
9465 	status = filename_convert(ctx,
9466 				conn,
9467 				directory,
9468 				ucf_flags,
9469 				NULL,
9470 				NULL,
9471 				&smb_dname);
9472 
9473 	if (!NT_STATUS_IS_OK(status)) {
9474 		if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
9475 			reply_botherror(req,
9476 				NT_STATUS_PATH_NOT_COVERED,
9477 				ERRSRV, ERRbadpath);
9478 			return;
9479 		}
9480 		reply_nterror(req, status);
9481 		return;
9482         }
9483 
9484 	/*
9485 	 * OS/2 workplace shell seems to send SET_EA requests of "null"
9486 	 * length (4 bytes containing IVAL 4).
9487 	 * They seem to have no effect. Bug #3212. JRA.
9488 	 */
9489 
9490 	if (total_data && (total_data != 4)) {
9491 		/* Any data in this call is an EA list. */
9492 		if (total_data < 10) {
9493 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9494 			goto out;
9495 		}
9496 
9497 		if (IVAL(pdata,0) > total_data) {
9498 			DEBUG(10,("call_trans2mkdir: bad total data size (%u) > %u\n",
9499 				IVAL(pdata,0), (unsigned int)total_data));
9500 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9501 			goto out;
9502 		}
9503 
9504 		ea_list = read_ea_list(talloc_tos(), pdata + 4,
9505 				       total_data - 4);
9506 		if (!ea_list) {
9507 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9508 			goto out;
9509 		}
9510 
9511 		if (!lp_ea_support(SNUM(conn))) {
9512 			reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
9513 			goto out;
9514 		}
9515 	}
9516 	/* If total_data == 4 Windows doesn't care what values
9517 	 * are placed in that field, it just ignores them.
9518 	 * The System i QNTC IBM SMB client puts bad values here,
9519 	 * so ignore them. */
9520 
9521 	status = create_directory(conn, req, smb_dname);
9522 
9523 	if (!NT_STATUS_IS_OK(status)) {
9524 		reply_nterror(req, status);
9525 		goto out;
9526 	}
9527 
9528 	/* Try and set any given EA. */
9529 	if (ea_list) {
9530 		status = set_ea(conn, NULL, smb_dname, ea_list);
9531 		if (!NT_STATUS_IS_OK(status)) {
9532 			reply_nterror(req, status);
9533 			goto out;
9534 		}
9535 	}
9536 
9537 	/* Realloc the parameter and data sizes */
9538 	*pparams = (char *)SMB_REALLOC(*pparams,2);
9539 	if(*pparams == NULL) {
9540 		reply_nterror(req, NT_STATUS_NO_MEMORY);
9541 		goto out;
9542 	}
9543 	params = *pparams;
9544 
9545 	SSVAL(params,0,0);
9546 
9547 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 2, *ppdata, 0, max_data_bytes);
9548 
9549  out:
9550 	TALLOC_FREE(smb_dname);
9551 	return;
9552 }
9553 
9554 /****************************************************************************
9555  Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
9556  We don't actually do this - we just send a null response.
9557 ****************************************************************************/
9558 
call_trans2findnotifyfirst(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)9559 static void call_trans2findnotifyfirst(connection_struct *conn,
9560 				       struct smb_request *req,
9561 				       char **pparams, int total_params,
9562 				       char **ppdata, int total_data,
9563 				       unsigned int max_data_bytes)
9564 {
9565 	char *params = *pparams;
9566 	uint16_t info_level;
9567 
9568 	if (total_params < 6) {
9569 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9570 		return;
9571 	}
9572 
9573 	info_level = SVAL(params,4);
9574 	DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
9575 
9576 	switch (info_level) {
9577 		case 1:
9578 		case 2:
9579 			break;
9580 		default:
9581 			reply_nterror(req, NT_STATUS_INVALID_LEVEL);
9582 			return;
9583 	}
9584 
9585 	/* Realloc the parameter and data sizes */
9586 	*pparams = (char *)SMB_REALLOC(*pparams,6);
9587 	if (*pparams == NULL) {
9588 		reply_nterror(req, NT_STATUS_NO_MEMORY);
9589 		return;
9590 	}
9591 	params = *pparams;
9592 
9593 	SSVAL(params,0,fnf_handle);
9594 	SSVAL(params,2,0); /* No changes */
9595 	SSVAL(params,4,0); /* No EA errors */
9596 
9597 	fnf_handle++;
9598 
9599 	if(fnf_handle == 0)
9600 		fnf_handle = 257;
9601 
9602 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 6, *ppdata, 0, max_data_bytes);
9603 
9604 	return;
9605 }
9606 
9607 /****************************************************************************
9608  Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
9609  changes). Currently this does nothing.
9610 ****************************************************************************/
9611 
call_trans2findnotifynext(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)9612 static void call_trans2findnotifynext(connection_struct *conn,
9613 				      struct smb_request *req,
9614 				      char **pparams, int total_params,
9615 				      char **ppdata, int total_data,
9616 				      unsigned int max_data_bytes)
9617 {
9618 	char *params = *pparams;
9619 
9620 	DEBUG(3,("call_trans2findnotifynext\n"));
9621 
9622 	/* Realloc the parameter and data sizes */
9623 	*pparams = (char *)SMB_REALLOC(*pparams,4);
9624 	if (*pparams == NULL) {
9625 		reply_nterror(req, NT_STATUS_NO_MEMORY);
9626 		return;
9627 	}
9628 	params = *pparams;
9629 
9630 	SSVAL(params,0,0); /* No changes */
9631 	SSVAL(params,2,0); /* No EA errors */
9632 
9633 	send_trans2_replies(conn, req, NT_STATUS_OK, params, 4, *ppdata, 0, max_data_bytes);
9634 
9635 	return;
9636 }
9637 
9638 /****************************************************************************
9639  Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
9640 ****************************************************************************/
9641 
call_trans2getdfsreferral(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)9642 static void call_trans2getdfsreferral(connection_struct *conn,
9643 				      struct smb_request *req,
9644 				      char **pparams, int total_params,
9645 				      char **ppdata, int total_data,
9646 				      unsigned int max_data_bytes)
9647 {
9648 	char *params = *pparams;
9649   	char *pathname = NULL;
9650 	int reply_size = 0;
9651 	int max_referral_level;
9652 	NTSTATUS status = NT_STATUS_OK;
9653 	TALLOC_CTX *ctx = talloc_tos();
9654 
9655 	DEBUG(10,("call_trans2getdfsreferral\n"));
9656 
9657 	if (total_params < 3) {
9658 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9659 		return;
9660 	}
9661 
9662 	max_referral_level = SVAL(params,0);
9663 
9664 	if(!lp_host_msdfs()) {
9665 		reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9666 		return;
9667 	}
9668 
9669 	srvstr_pull_talloc(ctx, params, req->flags2, &pathname, &params[2],
9670 		    total_params - 2, STR_TERMINATE);
9671 	if (!pathname) {
9672 		reply_nterror(req, NT_STATUS_NOT_FOUND);
9673 		return;
9674 	}
9675 	if((reply_size = setup_dfs_referral(conn, pathname, max_referral_level,
9676 					    ppdata,&status)) < 0) {
9677 		reply_nterror(req, status);
9678 		return;
9679 	}
9680 
9681 	SSVAL((discard_const_p(uint8_t, req->inbuf)), smb_flg2,
9682 	      SVAL(req->inbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
9683 	send_trans2_replies(conn, req, NT_STATUS_OK, 0,0,*ppdata,reply_size, max_data_bytes);
9684 
9685 	return;
9686 }
9687 
9688 #define LMCAT_SPL       0x53
9689 #define LMFUNC_GETJOBID 0x60
9690 
9691 /****************************************************************************
9692  Reply to a TRANS2_IOCTL - used for OS/2 printing.
9693 ****************************************************************************/
9694 
call_trans2ioctl(connection_struct * conn,struct smb_request * req,char ** pparams,int total_params,char ** ppdata,int total_data,unsigned int max_data_bytes)9695 static void call_trans2ioctl(connection_struct *conn,
9696 			     struct smb_request *req,
9697 			     char **pparams, int total_params,
9698 			     char **ppdata, int total_data,
9699 			     unsigned int max_data_bytes)
9700 {
9701 	const struct loadparm_substitution *lp_sub =
9702 		loadparm_s3_global_substitution();
9703 	char *pdata = *ppdata;
9704 	files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
9705 	NTSTATUS status;
9706 	size_t len = 0;
9707 
9708 	/* check for an invalid fid before proceeding */
9709 
9710 	if (!fsp) {
9711 		reply_nterror(req, NT_STATUS_INVALID_HANDLE);
9712 		return;
9713 	}
9714 
9715 	if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
9716 	    && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
9717 		*ppdata = (char *)SMB_REALLOC(*ppdata, 32);
9718 		if (*ppdata == NULL) {
9719 			reply_nterror(req, NT_STATUS_NO_MEMORY);
9720 			return;
9721 		}
9722 		pdata = *ppdata;
9723 
9724 		/* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
9725 			CAN ACCEPT THIS IN UNICODE. JRA. */
9726 
9727 		/* Job number */
9728 		SSVAL(pdata, 0, print_spool_rap_jobid(fsp->print_file));
9729 
9730 		status = srvstr_push(pdata, req->flags2, pdata + 2,
9731 			    lp_netbios_name(), 15,
9732 			    STR_ASCII|STR_TERMINATE, &len); /* Our NetBIOS name */
9733 		if (!NT_STATUS_IS_OK(status)) {
9734 			reply_nterror(req, status);
9735 			return;
9736 		}
9737 		status = srvstr_push(pdata, req->flags2, pdata+18,
9738 			    lp_servicename(talloc_tos(), lp_sub, SNUM(conn)), 13,
9739 			    STR_ASCII|STR_TERMINATE, &len); /* Service name */
9740 		if (!NT_STATUS_IS_OK(status)) {
9741 			reply_nterror(req, status);
9742 			return;
9743 		}
9744 		send_trans2_replies(conn, req, NT_STATUS_OK, *pparams, 0, *ppdata, 32,
9745 				    max_data_bytes);
9746 		return;
9747 	}
9748 
9749 	DEBUG(2,("Unknown TRANS2_IOCTL\n"));
9750 	reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9751 }
9752 
9753 /****************************************************************************
9754  Reply to a SMBfindclose (stop trans2 directory search).
9755 ****************************************************************************/
9756 
reply_findclose(struct smb_request * req)9757 void reply_findclose(struct smb_request *req)
9758 {
9759 	int dptr_num;
9760 	struct smbd_server_connection *sconn = req->sconn;
9761 	files_struct *fsp = NULL;
9762 
9763 	START_PROFILE(SMBfindclose);
9764 
9765 	if (req->wct < 1) {
9766 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9767 		END_PROFILE(SMBfindclose);
9768 		return;
9769 	}
9770 
9771 	dptr_num = SVALS(req->vwv+0, 0);
9772 
9773 	DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
9774 
9775 	/*
9776 	 * OS/2 seems to use -1 to indicate "close all directories"
9777 	 * This has to mean on this specific connection struct.
9778 	 */
9779 	if (dptr_num == -1) {
9780 		dptr_closecnum(req->conn);
9781 	} else {
9782 		fsp = dptr_fetch_lanman2_fsp(sconn, dptr_num);
9783 		dptr_num = -1;
9784 		if (fsp != NULL) {
9785 			close_file(NULL, fsp, NORMAL_CLOSE);
9786 			fsp = NULL;
9787 		}
9788 	}
9789 
9790 	reply_outbuf(req, 0, 0);
9791 
9792 	DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
9793 
9794 	END_PROFILE(SMBfindclose);
9795 	return;
9796 }
9797 
9798 /****************************************************************************
9799  Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
9800 ****************************************************************************/
9801 
reply_findnclose(struct smb_request * req)9802 void reply_findnclose(struct smb_request *req)
9803 {
9804 	int dptr_num;
9805 
9806 	START_PROFILE(SMBfindnclose);
9807 
9808 	if (req->wct < 1) {
9809 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
9810 		END_PROFILE(SMBfindnclose);
9811 		return;
9812 	}
9813 
9814 	dptr_num = SVAL(req->vwv+0, 0);
9815 
9816 	DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
9817 
9818 	/* We never give out valid handles for a
9819 	   findnotifyfirst - so any dptr_num is ok here.
9820 	   Just ignore it. */
9821 
9822 	reply_outbuf(req, 0, 0);
9823 
9824 	DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
9825 
9826 	END_PROFILE(SMBfindnclose);
9827 	return;
9828 }
9829 
handle_trans2(connection_struct * conn,struct smb_request * req,struct trans_state * state)9830 static void handle_trans2(connection_struct *conn, struct smb_request *req,
9831 			  struct trans_state *state)
9832 {
9833 	if (get_Protocol() >= PROTOCOL_NT1) {
9834 		req->flags2 |= 0x40; /* IS_LONG_NAME */
9835 		SSVAL((discard_const_p(uint8_t, req->inbuf)),smb_flg2,req->flags2);
9836 	}
9837 
9838 	if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
9839 		if (state->call != TRANSACT2_QFSINFO &&
9840 		    state->call != TRANSACT2_SETFSINFO) {
9841 			DEBUG(0,("handle_trans2: encryption required "
9842 				"with call 0x%x\n",
9843 				(unsigned int)state->call));
9844 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
9845 			return;
9846 		}
9847 	}
9848 
9849 	SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
9850 
9851 	/* Now we must call the relevant TRANS2 function */
9852 	switch(state->call)  {
9853 	case TRANSACT2_OPEN:
9854 	{
9855 		START_PROFILE(Trans2_open);
9856 		call_trans2open(conn, req,
9857 				&state->param, state->total_param,
9858 				&state->data, state->total_data,
9859 				state->max_data_return);
9860 		END_PROFILE(Trans2_open);
9861 		break;
9862 	}
9863 
9864 	case TRANSACT2_FINDFIRST:
9865 	{
9866 		START_PROFILE(Trans2_findfirst);
9867 		call_trans2findfirst(conn, req,
9868 				     &state->param, state->total_param,
9869 				     &state->data, state->total_data,
9870 				     state->max_data_return);
9871 		END_PROFILE(Trans2_findfirst);
9872 		break;
9873 	}
9874 
9875 	case TRANSACT2_FINDNEXT:
9876 	{
9877 		START_PROFILE(Trans2_findnext);
9878 		call_trans2findnext(conn, req,
9879 				    &state->param, state->total_param,
9880 				    &state->data, state->total_data,
9881 				    state->max_data_return);
9882 		END_PROFILE(Trans2_findnext);
9883 		break;
9884 	}
9885 
9886 	case TRANSACT2_QFSINFO:
9887 	{
9888 		START_PROFILE(Trans2_qfsinfo);
9889 		call_trans2qfsinfo(conn, req,
9890 				   &state->param, state->total_param,
9891 				   &state->data, state->total_data,
9892 				   state->max_data_return);
9893 		END_PROFILE(Trans2_qfsinfo);
9894 	    break;
9895 	}
9896 
9897 	case TRANSACT2_SETFSINFO:
9898 	{
9899 		START_PROFILE(Trans2_setfsinfo);
9900 		call_trans2setfsinfo(conn, req,
9901 				     &state->param, state->total_param,
9902 				     &state->data, state->total_data,
9903 				     state->max_data_return);
9904 		END_PROFILE(Trans2_setfsinfo);
9905 		break;
9906 	}
9907 
9908 	case TRANSACT2_QPATHINFO:
9909 	case TRANSACT2_QFILEINFO:
9910 	{
9911 		START_PROFILE(Trans2_qpathinfo);
9912 		call_trans2qfilepathinfo(conn, req, state->call,
9913 					 &state->param, state->total_param,
9914 					 &state->data, state->total_data,
9915 					 state->max_data_return);
9916 		END_PROFILE(Trans2_qpathinfo);
9917 		break;
9918 	}
9919 
9920 	case TRANSACT2_SETPATHINFO:
9921 	case TRANSACT2_SETFILEINFO:
9922 	{
9923 		START_PROFILE(Trans2_setpathinfo);
9924 		call_trans2setfilepathinfo(conn, req, state->call,
9925 					   &state->param, state->total_param,
9926 					   &state->data, state->total_data,
9927 					   state->max_data_return);
9928 		END_PROFILE(Trans2_setpathinfo);
9929 		break;
9930 	}
9931 
9932 	case TRANSACT2_FINDNOTIFYFIRST:
9933 	{
9934 		START_PROFILE(Trans2_findnotifyfirst);
9935 		call_trans2findnotifyfirst(conn, req,
9936 					   &state->param, state->total_param,
9937 					   &state->data, state->total_data,
9938 					   state->max_data_return);
9939 		END_PROFILE(Trans2_findnotifyfirst);
9940 		break;
9941 	}
9942 
9943 	case TRANSACT2_FINDNOTIFYNEXT:
9944 	{
9945 		START_PROFILE(Trans2_findnotifynext);
9946 		call_trans2findnotifynext(conn, req,
9947 					  &state->param, state->total_param,
9948 					  &state->data, state->total_data,
9949 					  state->max_data_return);
9950 		END_PROFILE(Trans2_findnotifynext);
9951 		break;
9952 	}
9953 
9954 	case TRANSACT2_MKDIR:
9955 	{
9956 		START_PROFILE(Trans2_mkdir);
9957 		call_trans2mkdir(conn, req,
9958 				 &state->param, state->total_param,
9959 				 &state->data, state->total_data,
9960 				 state->max_data_return);
9961 		END_PROFILE(Trans2_mkdir);
9962 		break;
9963 	}
9964 
9965 	case TRANSACT2_GET_DFS_REFERRAL:
9966 	{
9967 		START_PROFILE(Trans2_get_dfs_referral);
9968 		call_trans2getdfsreferral(conn, req,
9969 					  &state->param, state->total_param,
9970 					  &state->data, state->total_data,
9971 					  state->max_data_return);
9972 		END_PROFILE(Trans2_get_dfs_referral);
9973 		break;
9974 	}
9975 
9976 	case TRANSACT2_IOCTL:
9977 	{
9978 		START_PROFILE(Trans2_ioctl);
9979 		call_trans2ioctl(conn, req,
9980 				 &state->param, state->total_param,
9981 				 &state->data, state->total_data,
9982 				 state->max_data_return);
9983 		END_PROFILE(Trans2_ioctl);
9984 		break;
9985 	}
9986 
9987 	default:
9988 		/* Error in request */
9989 		DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
9990 		reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
9991 	}
9992 }
9993 
9994 /****************************************************************************
9995  Reply to a SMBtrans2.
9996  ****************************************************************************/
9997 
reply_trans2(struct smb_request * req)9998 void reply_trans2(struct smb_request *req)
9999 {
10000 	connection_struct *conn = req->conn;
10001 	unsigned int dsoff;
10002 	unsigned int dscnt;
10003 	unsigned int psoff;
10004 	unsigned int pscnt;
10005 	unsigned int tran_call;
10006 	struct trans_state *state;
10007 	NTSTATUS result;
10008 
10009 	START_PROFILE(SMBtrans2);
10010 
10011 	if (req->wct < 14) {
10012 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10013 		END_PROFILE(SMBtrans2);
10014 		return;
10015 	}
10016 
10017 	dsoff = SVAL(req->vwv+12, 0);
10018 	dscnt = SVAL(req->vwv+11, 0);
10019 	psoff = SVAL(req->vwv+10, 0);
10020 	pscnt = SVAL(req->vwv+9, 0);
10021 	tran_call = SVAL(req->vwv+14, 0);
10022 
10023 	result = allow_new_trans(conn->pending_trans, req->mid);
10024 	if (!NT_STATUS_IS_OK(result)) {
10025 		DEBUG(2, ("Got invalid trans2 request: %s\n",
10026 			  nt_errstr(result)));
10027 		reply_nterror(req, result);
10028 		END_PROFILE(SMBtrans2);
10029 		return;
10030 	}
10031 
10032 	if (IS_IPC(conn)) {
10033 		switch (tran_call) {
10034 		/* List the allowed trans2 calls on IPC$ */
10035 		case TRANSACT2_OPEN:
10036 		case TRANSACT2_GET_DFS_REFERRAL:
10037 		case TRANSACT2_QFILEINFO:
10038 		case TRANSACT2_QFSINFO:
10039 		case TRANSACT2_SETFSINFO:
10040 			break;
10041 		default:
10042 			reply_nterror(req, NT_STATUS_ACCESS_DENIED);
10043 			END_PROFILE(SMBtrans2);
10044 			return;
10045 		}
10046 	}
10047 
10048 	if ((state = talloc(conn, struct trans_state)) == NULL) {
10049 		DEBUG(0, ("talloc failed\n"));
10050 		reply_nterror(req, NT_STATUS_NO_MEMORY);
10051 		END_PROFILE(SMBtrans2);
10052 		return;
10053 	}
10054 
10055 	state->cmd = SMBtrans2;
10056 
10057 	state->mid = req->mid;
10058 	state->vuid = req->vuid;
10059 	state->setup_count = SVAL(req->vwv+13, 0);
10060 	state->setup = NULL;
10061 	state->total_param = SVAL(req->vwv+0, 0);
10062 	state->param = NULL;
10063 	state->total_data =  SVAL(req->vwv+1, 0);
10064 	state->data = NULL;
10065 	state->max_param_return = SVAL(req->vwv+2, 0);
10066 	state->max_data_return  = SVAL(req->vwv+3, 0);
10067 	state->max_setup_return = SVAL(req->vwv+4, 0);
10068 	state->close_on_completion = BITSETW(req->vwv+5, 0);
10069 	state->one_way = BITSETW(req->vwv+5, 1);
10070 
10071 	state->call = tran_call;
10072 
10073 	/* All trans2 messages we handle have smb_sucnt == 1 - ensure this
10074 	   is so as a sanity check */
10075 	if (state->setup_count != 1) {
10076 		/*
10077 		 * Need to have rc=0 for ioctl to get job id for OS/2.
10078 		 *  Network printing will fail if function is not successful.
10079 		 *  Similar function in reply.c will be used if protocol
10080 		 *  is LANMAN1.0 instead of LM1.2X002.
10081 		 *  Until DosPrintSetJobInfo with PRJINFO3 is supported,
10082 		 *  outbuf doesn't have to be set(only job id is used).
10083 		 */
10084 		if ( (state->setup_count == 4)
10085 		     && (tran_call == TRANSACT2_IOCTL)
10086 		     && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
10087 		     &&	(SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
10088 			DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
10089 		} else {
10090 			DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
10091 			DEBUG(2,("Transaction is %d\n",tran_call));
10092 			TALLOC_FREE(state);
10093 			reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10094 			END_PROFILE(SMBtrans2);
10095 			return;
10096 		}
10097 	}
10098 
10099 	if ((dscnt > state->total_data) || (pscnt > state->total_param))
10100 		goto bad_param;
10101 
10102 	if (state->total_data) {
10103 
10104 		if (trans_oob(state->total_data, 0, dscnt)
10105 		    || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
10106 			goto bad_param;
10107 		}
10108 
10109 		/* Can't use talloc here, the core routines do realloc on the
10110 		 * params and data. */
10111 		state->data = (char *)SMB_MALLOC(state->total_data);
10112 		if (state->data == NULL) {
10113 			DEBUG(0,("reply_trans2: data malloc fail for %u "
10114 				 "bytes !\n", (unsigned int)state->total_data));
10115 			TALLOC_FREE(state);
10116 			reply_nterror(req, NT_STATUS_NO_MEMORY);
10117 			END_PROFILE(SMBtrans2);
10118 			return;
10119 		}
10120 
10121 		memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
10122 	}
10123 
10124 	if (state->total_param) {
10125 
10126 		if (trans_oob(state->total_param, 0, pscnt)
10127 		    || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
10128 			goto bad_param;
10129 		}
10130 
10131 		/* Can't use talloc here, the core routines do realloc on the
10132 		 * params and data. */
10133 		state->param = (char *)SMB_MALLOC(state->total_param);
10134 		if (state->param == NULL) {
10135 			DEBUG(0,("reply_trans: param malloc fail for %u "
10136 				 "bytes !\n", (unsigned int)state->total_param));
10137 			SAFE_FREE(state->data);
10138 			TALLOC_FREE(state);
10139 			reply_nterror(req, NT_STATUS_NO_MEMORY);
10140 			END_PROFILE(SMBtrans2);
10141 			return;
10142 		}
10143 
10144 		memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
10145 	}
10146 
10147 	state->received_data  = dscnt;
10148 	state->received_param = pscnt;
10149 
10150 	if ((state->received_param == state->total_param) &&
10151 	    (state->received_data == state->total_data)) {
10152 
10153 		handle_trans2(conn, req, state);
10154 
10155 		SAFE_FREE(state->data);
10156 		SAFE_FREE(state->param);
10157 		TALLOC_FREE(state);
10158 		END_PROFILE(SMBtrans2);
10159 		return;
10160 	}
10161 
10162 	DLIST_ADD(conn->pending_trans, state);
10163 
10164 	/* We need to send an interim response then receive the rest
10165 	   of the parameter/data bytes */
10166 	reply_outbuf(req, 0, 0);
10167 	show_msg((char *)req->outbuf);
10168 	END_PROFILE(SMBtrans2);
10169 	return;
10170 
10171   bad_param:
10172 
10173 	DEBUG(0,("reply_trans2: invalid trans parameters\n"));
10174 	SAFE_FREE(state->data);
10175 	SAFE_FREE(state->param);
10176 	TALLOC_FREE(state);
10177 	END_PROFILE(SMBtrans2);
10178 	reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10179 }
10180 
10181 
10182 /****************************************************************************
10183  Reply to a SMBtranss2
10184  ****************************************************************************/
10185 
reply_transs2(struct smb_request * req)10186 void reply_transs2(struct smb_request *req)
10187 {
10188 	connection_struct *conn = req->conn;
10189 	unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
10190 	struct trans_state *state;
10191 
10192 	START_PROFILE(SMBtranss2);
10193 
10194 	show_msg((const char *)req->inbuf);
10195 
10196 	/* Windows clients expect all replies to
10197 	   a transact secondary (SMBtranss2 0x33)
10198 	   to have a command code of transact
10199 	   (SMBtrans2 0x32). See bug #8989
10200 	   and also [MS-CIFS] section 2.2.4.47.2
10201 	   for details.
10202 	*/
10203 	req->cmd = SMBtrans2;
10204 
10205 	if (req->wct < 8) {
10206 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10207 		END_PROFILE(SMBtranss2);
10208 		return;
10209 	}
10210 
10211 	for (state = conn->pending_trans; state != NULL;
10212 	     state = state->next) {
10213 		if (state->mid == req->mid) {
10214 			break;
10215 		}
10216 	}
10217 
10218 	if ((state == NULL) || (state->cmd != SMBtrans2)) {
10219 		reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10220 		END_PROFILE(SMBtranss2);
10221 		return;
10222 	}
10223 
10224 	/* Revise state->total_param and state->total_data in case they have
10225 	   changed downwards */
10226 
10227 	if (SVAL(req->vwv+0, 0) < state->total_param)
10228 		state->total_param = SVAL(req->vwv+0, 0);
10229 	if (SVAL(req->vwv+1, 0) < state->total_data)
10230 		state->total_data = SVAL(req->vwv+1, 0);
10231 
10232 	pcnt = SVAL(req->vwv+2, 0);
10233 	poff = SVAL(req->vwv+3, 0);
10234 	pdisp = SVAL(req->vwv+4, 0);
10235 
10236 	dcnt = SVAL(req->vwv+5, 0);
10237 	doff = SVAL(req->vwv+6, 0);
10238 	ddisp = SVAL(req->vwv+7, 0);
10239 
10240 	state->received_param += pcnt;
10241 	state->received_data += dcnt;
10242 
10243 	if ((state->received_data > state->total_data) ||
10244 	    (state->received_param > state->total_param))
10245 		goto bad_param;
10246 
10247 	if (pcnt) {
10248 		if (trans_oob(state->total_param, pdisp, pcnt)
10249 		    || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
10250 			goto bad_param;
10251 		}
10252 		memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
10253 	}
10254 
10255 	if (dcnt) {
10256 		if (trans_oob(state->total_data, ddisp, dcnt)
10257 		    || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
10258 			goto bad_param;
10259 		}
10260 		memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
10261 	}
10262 
10263 	if ((state->received_param < state->total_param) ||
10264 	    (state->received_data < state->total_data)) {
10265 		END_PROFILE(SMBtranss2);
10266 		return;
10267 	}
10268 
10269 	handle_trans2(conn, req, state);
10270 
10271 	DLIST_REMOVE(conn->pending_trans, state);
10272 	SAFE_FREE(state->data);
10273 	SAFE_FREE(state->param);
10274 	TALLOC_FREE(state);
10275 
10276 	END_PROFILE(SMBtranss2);
10277 	return;
10278 
10279   bad_param:
10280 
10281 	DEBUG(0,("reply_transs2: invalid trans parameters\n"));
10282 	DLIST_REMOVE(conn->pending_trans, state);
10283 	SAFE_FREE(state->data);
10284 	SAFE_FREE(state->param);
10285 	TALLOC_FREE(state);
10286 	reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
10287 	END_PROFILE(SMBtranss2);
10288 	return;
10289 }
10290