Merge ~joalif/ubuntu/+source/cifs-utils:lp1886551-bionic into ubuntu/+source/cifs-utils:ubuntu/devel

Proposed by Ioanna Alifieraki
Status: Superseded
Proposed branch: ~joalif/ubuntu/+source/cifs-utils:lp1886551-bionic
Merge into: ubuntu/+source/cifs-utils:ubuntu/devel
Diff against target: 4247 lines (+4109/-0) (has conflicts)
21 files modified
debian/changelog (+33/-0)
debian/patches/0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch (+465/-0)
debian/patches/0002-smbinfo.rst-document-kernel-version.patch (+28/-0)
debian/patches/0003-smbinfo-Add-more-File-Information-classes.patch (+602/-0)
debian/patches/0004-smbinfo-update-help-text.patch (+36/-0)
debian/patches/0005-smbinfo-Update-the-usage-text-with-the-new-infolevel.patch (+45/-0)
debian/patches/0006-smbinfo-add-FileFsFullSizeInformation.patch (+103/-0)
debian/patches/0007-smbinfo-decode-the-ACEs.patch (+347/-0)
debian/patches/0008-smbinfo-fix-code-style.patch (+1473/-0)
debian/patches/0009-smbinfo-add-fsctl-getobjid-support.patch (+131/-0)
debian/patches/0010-smbinfo-missing-help-for-fsctl-getobjid.patch (+34/-0)
debian/patches/0011-smbinfo-Add-ability-to-query-snapshots-previous-vers.patch (+173/-0)
debian/patches/0012-smbinfo-make-argument-order-consistent.patch (+62/-0)
debian/patches/0013-smbinfo-use-constant-for-input-buffer-length.patch (+35/-0)
debian/patches/0014-smbinfo-Improve-help-usage-and-add-h-option.patch (+108/-0)
debian/patches/0015-smbinfo-add-GETCOMPRESSION-support.patch (+102/-0)
debian/patches/0016-smbinfo-print-the-security-information-needed-to-dec.patch (+108/-0)
debian/patches/0017-smbinfo-Add-SETCOMPRESSION-support.patch (+119/-0)
debian/patches/0018-smbinfo.rst-document-new-keys-command.patch (+30/-0)
debian/patches/series (+22/-0)
debian/patches/setcifsacl-fix-adding-ACE-when-owner-sid-in-unexpect.patch (+53/-0)
Conflict in debian/changelog
Conflict in debian/patches/series
Reviewer Review Type Date Requested Status
Andreas Hasenack Pending
Review via email: mp+390521@code.launchpad.net

This proposal has been superseded by a proposal from 2020-09-10.

To post a comment you must log in.
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

The target of this merge needs to be ubuntu/bionic-devel, not ubuntu/devel, as the latter one represents groovy at the moment

Unmerged commits

b070456... by Ioanna Alifieraki

update debian/changelog

7f4bffe... by Ioanna Alifieraki

LP #1886551 patch #18

a1d84a2... by Ioanna Alifieraki

LP #1886551 patch #17

b576b0b... by Ioanna Alifieraki

LP #1886551 patch #16

0f28916... by Ioanna Alifieraki

LP #1886551 patch #15

8a6bf1c... by Ioanna Alifieraki

LP #1886551 patch #14

9358f8e... by Ioanna Alifieraki

LP #1886551 patch #13

d26d8db... by Ioanna Alifieraki

LP #1886551 patch #12

406bc80... by Ioanna Alifieraki

LP #1886551 patch #11

a66a231... by Ioanna Alifieraki

LP #1886551 patch #10

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index eaa06da..24347d8 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,4 @@
6+<<<<<<< debian/changelog
7 cifs-utils (2:6.10-0ubuntu1) groovy; urgency=medium
8
9 [ Sergio Durigan Junior ]
10@@ -37,6 +38,38 @@ cifs-utils (2:6.8-2) unstable; urgency=medium
11 * Update Standards-Version to 4.1.4, no change
12
13 -- Mathieu Parent <sathieu@debian.org> Sun, 17 Jun 2018 21:58:28 +0200
14+=======
15+cifs-utils (2:6.8-1ubuntu2) bionic; urgency=medium
16+
17+ * d/p/0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch
18+ * d/p/0002-smbinfo.rst-document-kernel-version.patch
19+ * d/p/0003-smbinfo-Add-more-File-Information-classes.patch
20+ * d/p/0004-smbinfo-update-help-text.patch
21+ * d/p/0005-smbinfo-Update-the-usage-text-with-the-new-infolevel.patch
22+ * d/p/0006-smbinfo-add-FileFsFullSizeInformation.patch
23+ * d/p/0007-smbinfo-decode-the-ACEs.patch
24+ * d/p/0008-smbinfo-fix-code-style.patch
25+ * d/p/0009-smbinfo-add-fsctl-getobjid-support.patch
26+ * d/p/0010-smbinfo-missing-help-for-fsctl-getobjid.patch
27+ * d/p/0011-smbinfo-Add-ability-to-query-snapshots-previous-vers.patch
28+ * d/p/0012-smbinfo-make-argument-order-consistent.patch
29+ * d/p/0013-smbinfo-use-constant-for-input-buffer-length.patch
30+ * d/p/0014-smbinfo-Improve-help-usage-and-add-h-option.patch
31+ * d/p/0015-smbinfo-add-GETCOMPRESSION-support.patch
32+ * d/p/0016-smbinfo-print-the-security-information-needed-to-dec.patch
33+ * d/p/0017-smbinfo-Add-SETCOMPRESSION-support.patch
34+ * d/p/0018-smbinfo.rst-document-new-keys-command.patch :
35+ Add smbinfo utility and 'keys' command (LP: #1886551)
36+
37+ -- Ioanna Alifieraki <ioanna-maria.alifieraki@canonical.com> Thu, 10 Sep 2020 02:31:09 +0100
38+
39+cifs-utils (2:6.8-1ubuntu1) bionic; urgency=medium
40+
41+ * d/p/setcifsacl-fix-adding-ACE-when-owner-sid-in-unexpect.patch:
42+ Fix adding ACE when owner sid in unexpected location (LP: #1886548)
43+
44+ -- Eric Desrochers <eric.desrochers@canonical.com> Wed, 08 Jul 2020 17:44:31 +0000
45+>>>>>>> debian/changelog
46
47 cifs-utils (2:6.8-1) unstable; urgency=medium
48
49diff --git a/debian/patches/0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch b/debian/patches/0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch
50new file mode 100644
51index 0000000..988b651
52--- /dev/null
53+++ b/debian/patches/0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch
54@@ -0,0 +1,465 @@
55+From 3eb33a11665aebc503024b1b8ed655a32eb55035 Mon Sep 17 00:00:00 2001
56+From: Ronnie Sahlberg <lsahlber@redhat.com>
57+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=3eb33a11665aebc503024b1b8ed655a32eb55035
58+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
59+Date: Wed, 3 Oct 2018 10:42:03 +1000
60+Subject: [PATCH] smbinfo: add a utility to display smb specific information
61+ about objects
62+
63+For example
64+ smbinfo secdesc <file> will print the security descriptor
65+ smbinfo quota <file> will print the quotas for the volume
66+
67+Signed-off-by: Aurelien Aptel <aaptel@suse.com>
68+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
69+---
70+ Makefile.am | 6 +
71+ configure.ac | 6 +
72+ smbinfo.c | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++
73+ smbinfo.rst | 81 ++++++++++++++
74+ 4 files changed, 398 insertions(+)
75+ create mode 100644 smbinfo.c
76+ create mode 100644 smbinfo.rst
77+
78+diff --git a/Makefile.am b/Makefile.am
79+index f37c9ae..8291b99 100644
80+--- a/Makefile.am
81++++ b/Makefile.am
82+@@ -79,6 +79,12 @@ setcifsacl.rst: setcifsacl.rst.in
83+ $(SED) 's,[@]pluginpath@,$(pluginpath),' $(srcdir)/$@.in > $@-t && mv $@-t $@
84+ endif
85+
86++if CONFIG_SMBINFO
87++bin_PROGRAMS += smbinfo
88++smbinfo_SOURCES = smbinfo.c
89++rst_man_pages += smbinfo.1
90++endif
91++
92+ if CONFIG_PLUGIN
93+ plugindir = $(pkglibdir)
94+ plugin_PROGRAMS = idmapwb.so
95+diff --git a/configure.ac b/configure.ac
96+index 8e3d6ce..aaef452 100644
97+--- a/configure.ac
98++++ b/configure.ac
99+@@ -40,6 +40,11 @@ AC_ARG_ENABLE(cifsacl,
100+ enable_cifsacl=$enableval,
101+ enable_cifsacl="maybe")
102+
103++AC_ARG_ENABLE(smbinfo,
104++ [AS_HELP_STRING([--enable-smbinfo],[Create smbinfo binary @<:@default=yes@@])],
105++ enable_smbinfo=$enableval,
106++ enable_smbinfo="maybe")
107++
108+ AC_ARG_ENABLE(pam,
109+ [AS_HELP_STRING([--enable-pam],[Create cifscreds PAM module @<:@default=yes@:>@])],
110+ enable_pam=$enableval,
111+@@ -275,6 +280,7 @@ AM_CONDITIONAL(CONFIG_CIFSUPCALL, [test "$enable_cifsupcall" != "no"])
112+ AM_CONDITIONAL(CONFIG_CIFSCREDS, [test "$enable_cifscreds" != "no"])
113+ AM_CONDITIONAL(CONFIG_CIFSIDMAP, [test "$enable_cifsidmap" != "no"])
114+ AM_CONDITIONAL(CONFIG_CIFSACL, [test "$enable_cifsacl" != "no"])
115++AM_CONDITIONAL(CONFIG_SMBINFO, [test "$enable_smbinfo" != "no"])
116+ AM_CONDITIONAL(CONFIG_PAM, [test "$enable_pam" != "no"])
117+ AM_CONDITIONAL(CONFIG_PLUGIN, [test "$enable_cifsidmap" != "no" -o "$enable_cifsacl" != "no"])
118+
119+diff --git a/smbinfo.c b/smbinfo.c
120+new file mode 100644
121+index 0000000..b1c129b
122+--- /dev/null
123++++ b/smbinfo.c
124+@@ -0,0 +1,305 @@
125++/*
126++ * smbinfo
127++ *
128++ * Copyright (C) Ronnie Sahlberg (lsahlberg@redhat.com) 2018
129++ * Copyright (C) Aurelien Aptel (aaptel@suse.com) 2018
130++ *
131++ * Display SMB-specific file information using cifs IOCTL
132++ *
133++ * This program is free software; you can redistribute it and/or modify
134++ * it under the terms of the GNU General Public License as published by
135++ * the Free Software Foundation; either version 2 of the License, or
136++ * (at your option) any later version.
137++ * This program is distributed in the hope that it will be useful,
138++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
139++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
140++ * GNU General Public License for more details.
141++ * You should have received a copy of the GNU General Public License
142++ * along with this program; if not, write to the Free Software
143++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
144++ */
145++
146++#ifdef HAVE_CONFIG_H
147++#include "config.h"
148++#endif /* HAVE_CONFIG_H */
149++
150++#include <endian.h>
151++#include <errno.h>
152++#include <getopt.h>
153++#include <sys/ioctl.h>
154++#include <sys/types.h>
155++#include <sys/stat.h>
156++#include <fcntl.h>
157++#include <string.h>
158++#include <stdint.h>
159++#include <stdio.h>
160++#include <stdlib.h>
161++#include <time.h>
162++#include <unistd.h>
163++#include <inttypes.h>
164++
165++#define CIFS_IOCTL_MAGIC 0xCF
166++struct smb_query_info {
167++ uint32_t info_type;
168++ uint32_t file_info_class;
169++ uint32_t additional_information;
170++ uint32_t flags;
171++ uint32_t input_buffer_length;
172++ uint32_t output_buffer_length;
173++ /* char buffer[]; */
174++} __packed;
175++
176++#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
177++#define INPUT_BUFFER_LENGTH 16384
178++
179++static void
180++usage(char *name)
181++{
182++ fprintf(stderr, "Usage: %s <command> <file>\n"
183++ "Commands are\n"
184++ " secdesc:\n"
185++ " Prints the security descriptor for a cifs file.\n"
186++ " quota:\n"
187++ " Prints the quota for a cifs file.\n",
188++ name);
189++ exit(1);
190++}
191++
192++static void
193++print_sid(unsigned char *sd)
194++{
195++ int i;
196++ uint32_t subauth;
197++ uint64_t idauth;
198++
199++ if (sd[0] != 1) {
200++ fprintf(stderr, "Unknown SID revision\n");
201++ return;
202++ }
203++
204++ idauth = 0;
205++ for (i = 0; i < 6; i++)
206++ idauth = (idauth << 8) | sd[2 + i];
207++
208++ printf("S-1-%" PRIu64, idauth);
209++ for (i = 0; i < sd[1]; i++) {
210++ memcpy(&subauth, &sd[8 + 4 * i], 4);
211++ subauth = le32toh(subauth);
212++ printf("-%d", subauth);
213++ }
214++}
215++
216++static void
217++print_acl(unsigned char *sd)
218++{
219++ int i, j, off;
220++ uint16_t count, size;
221++
222++ if (sd[0] != 2) {
223++ fprintf(stderr, "Unknown ACL revision\n");
224++ return;
225++ }
226++
227++ memcpy(&count, &sd[4], 2);
228++ count = le16toh(count);
229++ off = 8;
230++ for (i = 0; i < count; i++) {
231++ printf("Type:%02x Flags:%02x ", sd[off], sd[off + 1]);
232++ memcpy(&size, &sd[off + 2], 2);
233++ size = le16toh(size);
234++
235++ for (j = 0; j < size; j++)
236++ printf("%02x", sd[off + 4 + j]);
237++
238++ off += size;
239++ printf("\n");
240++ }
241++}
242++
243++static void
244++print_sd(uint8_t *sd)
245++{
246++ int offset_owner, offset_group, offset_dacl;
247++
248++ printf("Revision:%d\n", sd[0]);
249++ if (sd[0] != 1) {
250++ fprintf(stderr, "Unknown SD revision\n");
251++ exit(1);
252++ }
253++
254++ printf("Control: %02x%02x\n", sd[2], sd[3]);
255++
256++ memcpy(&offset_owner, &sd[4], 4);
257++ offset_owner = le32toh(offset_owner);
258++ memcpy(&offset_group, &sd[8], 4);
259++ offset_group = le32toh(offset_group);
260++ memcpy(&offset_dacl, &sd[16], 4);
261++ offset_dacl = le32toh(offset_dacl);
262++
263++ if (offset_owner) {
264++ printf("Owner: ");
265++ print_sid(&sd[offset_owner]);
266++ printf("\n");
267++ }
268++ if (offset_group) {
269++ printf("Group: ");
270++ print_sid(&sd[offset_group]);
271++ printf("\n");
272++ }
273++ if (offset_dacl) {
274++ printf("DACL:\n");
275++ print_acl(&sd[offset_dacl]);
276++ }
277++}
278++
279++void secdesc(int f) {
280++ struct smb_query_info *qi;
281++
282++ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
283++ qi->info_type = 0x03;
284++ qi->file_info_class = 0;
285++ qi->additional_information = 0x00000007; /* Owner, Group, Dacl */
286++ qi->input_buffer_length = INPUT_BUFFER_LENGTH;
287++
288++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
289++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
290++ exit(1);
291++ }
292++
293++ print_sd((uint8_t *)(&qi[1]));
294++}
295++
296++void
297++win_to_timeval(uint64_t smb2_time, struct timeval *tv)
298++{
299++ tv->tv_usec = (smb2_time / 10) % 1000000;
300++ tv->tv_sec = (smb2_time - 116444736000000000) / 10000000;
301++}
302++
303++static void
304++print_quota(unsigned char *sd)
305++{
306++ uint32_t u32, neo;
307++ uint64_t u64;
308++ struct timeval tv;
309++ struct tm;
310++ int i, off = 0;
311++
312++ one_more:
313++ memcpy(&u32, &sd[off], 4);
314++ neo = le32toh(u32);
315++
316++ memcpy(&u32, &sd[off + 4], 4);
317++ u32 = le32toh(u32);
318++ printf("SID Length %d\n", u32);
319++
320++ memcpy(&u64, &sd[off + 8], 8);
321++ win_to_timeval(le64toh(u64), &tv);
322++ printf("Change Time %s", ctime(&tv.tv_sec));
323++
324++ memcpy(&u64, &sd[off + 16], 8);
325++ u64 = le32toh(u64);
326++ printf("Quota Used %" PRIu64 "\n", u64);
327++
328++ memcpy(&u64, &sd[off + 24], 8);
329++ u64 = le64toh(u64);
330++ if (u64 == 0xffffffffffffffff) {
331++ printf("Quota Threshold NO THRESHOLD\n");
332++ } else {
333++ printf("Quota Threshold %" PRIu64 "\n", u64);
334++ }
335++
336++ memcpy(&u64, &sd[off + 32], 8);
337++ u64 = le64toh(u64);
338++ if (u64 == 0xffffffffffffffff) {
339++ printf("Quota Limit NO LIMIT\n");
340++ } else {
341++ printf("Quota Limit %" PRIu64 "\n", u64);
342++ }
343++
344++ printf("SID: S-1");
345++ u64 = 0;
346++ for (i = 0; i < 6; i++)
347++ u64 = (u64 << 8) | sd[off + 42 + i];
348++ printf("-%" PRIu64, u64);
349++
350++ for (i = 0; i < sd[off + 41]; i++) {
351++ memcpy(&u32, &sd[off + 48 + 4 * i], 4);
352++ u32 = le32toh(u32);
353++ printf("-%u", u32);
354++ }
355++ printf("\n\n");
356++ off += neo;
357++
358++ if (neo != 0) {
359++ goto one_more;
360++ }
361++}
362++
363++void quota(int f) {
364++ struct smb_query_info *qi;
365++ char *buf;
366++ int i;
367++
368++ qi = malloc(sizeof(struct smb_query_info) + 16384);
369++ memset(qi, 0, sizeof(struct smb_query_info) + 16384);
370++ qi->info_type = 0x04;
371++ qi->file_info_class = 0;
372++ qi->additional_information = 0; /* Owner, Group, Dacl */
373++ qi->input_buffer_length = 16384;
374++
375++ buf = (char *)&qi[1];
376++ buf[0] = 0; /* return single */
377++ buf[1] = 1; /* restart scan */
378++
379++ /* sid list length */
380++ i = 0;
381++ memcpy(&buf[4], &i, 4);
382++
383++ qi->output_buffer_length = 16;
384++
385++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
386++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
387++ exit(1);
388++ }
389++
390++ print_quota((unsigned char *)(&qi[1]));
391++}
392++
393++int main(int argc, char *argv[])
394++{
395++ int c;
396++ int f;
397++
398++ while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) {
399++ switch (c) {
400++ case 'v':
401++ printf("smbinfo version %s\n", VERSION);
402++ return 0;
403++ default:
404++ usage(argv[0]);
405++ }
406++ }
407++
408++ if (optind >= argc - 1)
409++ usage(argv[0]);
410++
411++ if ((f = open(argv[optind + 1], O_RDONLY)) < 0) {
412++ fprintf(stderr, "Failed to open %s\n", argv[optind + 1]);
413++ exit(1);
414++ }
415++
416++
417++ if (!strcmp(argv[1], "secdesc")) {
418++ secdesc(f);
419++ } else if (!strcmp(argv[1], "quota")) {
420++ quota(f);
421++ } else {
422++ fprintf(stderr, "Unknown command %s\n", argv[optind]);
423++ exit(1);
424++ }
425++
426++
427++ close(f);
428++ return 0;
429++}
430+diff --git a/smbinfo.rst b/smbinfo.rst
431+new file mode 100644
432+index 0000000..e37c709
433+--- /dev/null
434++++ b/smbinfo.rst
435+@@ -0,0 +1,81 @@
436++============
437++smbinfo
438++============
439++
440++-----------------------------------------------------------------------------------------------------
441++Userspace helper to display SMB-specific file information for the Linux SMB client file system (CIFS)
442++-----------------------------------------------------------------------------------------------------
443++:Manual section: 1
444++
445++********
446++SYNOPSIS
447++********
448++
449++ smbinfo [-v] {command} {file system object}
450++
451++***********
452++DESCRIPTION
453++***********
454++
455++This tool is part of the cifs-utils suite.
456++
457++`smbinfo` is a userspace helper program for the Linux SMB
458++client file system (CIFS). It is intended to display SMB-specific file
459++informations such as Security Descriptors and Quota.
460++
461++This tool works by making an CIFS_QUERY_INFO IOCTL call to the Linux
462++SMB client which in turn issues a SMB Query Info request and returns
463++the result. This differs from `getcifsacl` which uses extended file
464++attributes.
465++
466++*******
467++OPTIONS
468++*******
469++
470++-v
471++ Print version number and exit.
472++
473++*******
474++COMMAND
475++*******
476++
477++`secdesc`: Print the security descriptor in the form
478++- Revision
479++- Control
480++- Owner SID
481++- Group SID
482++- ACL
483++- File types
484++- File flags
485++
486++`quota`: Print the quota for the volume in the form
487++- SID Length
488++- Change Time
489++- Quota Used
490++- Quota Threshold
491++- Quota Limit
492++- SID
493++
494++*****
495++NOTES
496++*****
497++
498++Kernel support for smbinfo utilities requires the CIFS_QUERY_INFO
499++IOCTL which was initially introduced in the XXX kernel and is only
500++implemented for mount points using SMB2 or above (see mount.cifs(8)
501++`vers` option).
502++
503++********
504++SEE ALSO
505++********
506++
507++mount.cifs(8), getcifsacl(1)
508++
509++******
510++AUTHOR
511++******
512++
513++Ronnie Sahlberg wrote the smbinfo program.
514++
515++The Linux CIFS Mailing list is the preferred place to ask questions
516++regarding these programs.
517+--
518+2.17.1
519+
520diff --git a/debian/patches/0002-smbinfo.rst-document-kernel-version.patch b/debian/patches/0002-smbinfo.rst-document-kernel-version.patch
521new file mode 100644
522index 0000000..8ffa7fe
523--- /dev/null
524+++ b/debian/patches/0002-smbinfo.rst-document-kernel-version.patch
525@@ -0,0 +1,28 @@
526+From f0c95ea8d2835b16ac17895fa7bcbbfdc95ed708 Mon Sep 17 00:00:00 2001
527+From: Aurelien Aptel <aaptel@suse.com>
528+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=f0c95ea8d2835b16ac17895fa7bcbbfdc95ed708
529+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
530+Date: Thu, 24 Jan 2019 18:13:56 +0100
531+Subject: [PATCH] smbinfo.rst: document kernel version
532+
533+Signed-off-by: Aurelien Aptel <aaptel@suse.com>
534+---
535+ smbinfo.rst | 2 +-
536+ 1 file changed, 1 insertion(+), 1 deletion(-)
537+
538+diff --git a/smbinfo.rst b/smbinfo.rst
539+index e37c709..a10edb1 100644
540+--- a/smbinfo.rst
541++++ b/smbinfo.rst
542+@@ -61,7 +61,7 @@ NOTES
543+ *****
544+
545+ Kernel support for smbinfo utilities requires the CIFS_QUERY_INFO
546+-IOCTL which was initially introduced in the XXX kernel and is only
547++IOCTL which was initially introduced in the 4.20 kernel and is only
548+ implemented for mount points using SMB2 or above (see mount.cifs(8)
549+ `vers` option).
550+
551+--
552+2.17.1
553+
554diff --git a/debian/patches/0003-smbinfo-Add-more-File-Information-classes.patch b/debian/patches/0003-smbinfo-Add-more-File-Information-classes.patch
555new file mode 100644
556index 0000000..f0d1009
557--- /dev/null
558+++ b/debian/patches/0003-smbinfo-Add-more-File-Information-classes.patch
559@@ -0,0 +1,602 @@
560+From 0ca46dbb7d50d8872b60e71baa337d96884cd881 Mon Sep 17 00:00:00 2001
561+From: Ronnie Sahlberg <lsahlber@redhat.com>
562+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=0ca46dbb7d50d8872b60e71baa337d96884cd881
563+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
564+Date: Tue, 29 Jan 2019 16:53:57 +1000
565+Subject: [PATCH] smbinfo: Add more File*Information classes
566+
567+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
568+---
569+ smbinfo.c | 483 ++++++++++++++++++++++++++++++++++++++++++++++++++--
570+ smbinfo.rst | 34 +++-
571+ 2 files changed, 497 insertions(+), 20 deletions(-)
572+
573+diff --git a/smbinfo.c b/smbinfo.c
574+index b1c129b..7184a68 100644
575+--- a/smbinfo.c
576++++ b/smbinfo.c
577+@@ -65,6 +65,447 @@ usage(char *name)
578+ exit(1);
579+ }
580+
581++static void
582++win_to_timeval(uint64_t smb2_time, struct timeval *tv)
583++{
584++ tv->tv_usec = (smb2_time / 10) % 1000000;
585++ tv->tv_sec = (smb2_time - 116444736000000000) / 10000000;
586++}
587++
588++struct bit_string {
589++ unsigned int bit;
590++ char *string;
591++};
592++
593++struct bit_string directory_access_mask[] = {
594++ { 0x00000001, "LIST_DIRECTORY" },
595++ { 0x00000002, "ADD_FILE" },
596++ { 0x00000004, "ADD_SUBDIRECTORY" },
597++ { 0x00000008, "READ_EA" },
598++ { 0x00000010, "WRITE_EA" },
599++ { 0x00000020, "TRAVERSE" },
600++ { 0x00000040, "DELETE_CHILD" },
601++ { 0x00000080, "READ_ATTRIBUTES" },
602++ { 0x00000100, "WRITE_ATTRIBUTES" },
603++ { 0x00010000, "DELETE" },
604++ { 0x00020000, "READ_CONTROL" },
605++ { 0x00040000, "WRITE_DAC" },
606++ { 0x00080000, "WRITE_OWNER" },
607++ { 0x00100000, "SYNCHRONIZER" },
608++ { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
609++ { 0x02000000, "MAXIMUM_ALLOWED" },
610++ { 0x10000000, "GENERIC_ALL" },
611++ { 0x20000000, "GENERIC_EXECUTE" },
612++ { 0x40000000, "GENERIC_WRITE" },
613++ { 0x80000000, "GENERIC_READ" },
614++ { 0, NULL }
615++};
616++
617++struct bit_string file_access_mask[] = {
618++ { 0x00000001, "READ_DATA" },
619++ { 0x00000002, "WRITE_DATA" },
620++ { 0x00000004, "APPEND_DATA" },
621++ { 0x00000008, "READ_EA" },
622++ { 0x00000010, "WRITE_EA" },
623++ { 0x00000020, "EXECUTE" },
624++ { 0x00000040, "DELETE_CHILD" },
625++ { 0x00000080, "READ_ATTRIBUTES" },
626++ { 0x00000100, "WRITE_ATTRIBUTES" },
627++ { 0x00010000, "DELETE" },
628++ { 0x00020000, "READ_CONTROL" },
629++ { 0x00040000, "WRITE_DAC" },
630++ { 0x00080000, "WRITE_OWNER" },
631++ { 0x00100000, "SYNCHRONIZER" },
632++ { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
633++ { 0x02000000, "MAXIMUM_ALLOWED" },
634++ { 0x10000000, "GENERIC_ALL" },
635++ { 0x20000000, "GENERIC_EXECUTE" },
636++ { 0x40000000, "GENERIC_WRITE" },
637++ { 0x80000000, "GENERIC_READ" },
638++ { 0, NULL }
639++};
640++
641++static void
642++print_bits(uint32_t mask, struct bit_string *bs)
643++{
644++ while (bs->string) {
645++ if (mask & bs->bit)
646++ printf("%s ", bs->string);
647++ bs++;
648++ }
649++}
650++
651++static void
652++print_fileaccessinfo(uint8_t *sd, int type)
653++{
654++ uint32_t access_flags;
655++
656++ memcpy(&access_flags, &sd[0], 4);
657++ access_flags = le32toh(access_flags);
658++
659++ if (type == S_IFDIR) {
660++ printf("Directory access flags 0x%08x: ", access_flags);
661++ print_bits(access_flags, directory_access_mask);
662++ } else {
663++ printf("File/Printer access flags 0x%08x: ", access_flags);
664++ print_bits(access_flags, file_access_mask);
665++ }
666++ printf("\n");
667++}
668++
669++static void
670++fileaccessinfo(int f)
671++{
672++ struct smb_query_info *qi;
673++ struct stat st;
674++
675++ fstat(f, &st);
676++
677++ qi = malloc(sizeof(struct smb_query_info) + 4);
678++ memset(qi, 0, sizeof(qi) + 4);
679++ qi->info_type = 0x01;
680++ qi->file_info_class = 8;
681++ qi->additional_information = 0;
682++ qi->input_buffer_length = 4;
683++
684++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
685++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
686++ exit(1);
687++ }
688++
689++ print_fileaccessinfo((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
690++ free(qi);
691++}
692++
693++static void
694++print_filealigninfo(uint8_t *sd)
695++{
696++ uint32_t mask;
697++
698++ memcpy(&mask, &sd[0], 4);
699++ mask = le32toh(mask);
700++
701++ printf("File alignment: ");
702++ if (mask == 0)
703++ printf("BYTE_ALIGNMENT");
704++ else if (mask == 1)
705++ printf("WORD_ALIGNMENT");
706++ else if (mask == 3)
707++ printf("LONG_ALIGNMENT");
708++ else if (mask == 7)
709++ printf("QUAD_ALIGNMENT");
710++ else if (mask == 15)
711++ printf("OCTA_ALIGNMENT");
712++ else if (mask == 31)
713++ printf("32_bit_ALIGNMENT");
714++ else if (mask == 63)
715++ printf("64_bit_ALIGNMENT");
716++ else if (mask == 127)
717++ printf("128_bit_ALIGNMENT");
718++ else if (mask == 255)
719++ printf("254_bit_ALIGNMENT");
720++ else if (mask == 511)
721++ printf("512_bit_ALIGNMENT");
722++
723++ printf("\n");
724++}
725++
726++static void
727++filealigninfo(int f)
728++{
729++ struct smb_query_info *qi;
730++
731++ qi = malloc(sizeof(struct smb_query_info) + 4);
732++ memset(qi, 0, sizeof(qi) + 4);
733++ qi->info_type = 0x01;
734++ qi->file_info_class = 17;
735++ qi->additional_information = 0;
736++ qi->input_buffer_length = 4;
737++
738++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
739++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
740++ exit(1);
741++ }
742++
743++ print_filealigninfo((uint8_t *)(&qi[1]));
744++ free(qi);
745++}
746++
747++struct bit_string file_attributes_mask[] = {
748++ { 0x00000001, "READ_ONLY" },
749++ { 0x00000002, "HIDDEN" },
750++ { 0x00000004, "SYSTEM" },
751++ { 0x00000010, "DIRECTORY" },
752++ { 0x00000020, "ARCHIVE" },
753++ { 0x00000080, "NORMAL" },
754++ { 0x00000100, "TEMPORARY" },
755++ { 0x00000200, "SPARSE_FILE" },
756++ { 0x00000400, "REPARSE_POINT" },
757++ { 0x00000800, "COMPRESSED" },
758++ { 0x00001000, "OFFLINE" },
759++ { 0x00002000, "NOT_CONTENT_INDEXED" },
760++ { 0x00004000, "ENCRYPTED" },
761++ { 0x00008000, "INTEGRITY_STREAM" },
762++ { 0x00020000, "NO_SCRUB_DATA" },
763++ { 0, NULL }
764++};
765++
766++static void
767++print_filebasicinfo(uint8_t *sd)
768++{
769++ struct timeval tv;
770++ uint64_t u64;
771++ uint32_t u32;
772++
773++ memcpy(&u64, &sd[0], 8);
774++ win_to_timeval(le64toh(u64), &tv);
775++ printf("Creation Time %s", ctime(&tv.tv_sec));
776++
777++ memcpy(&u64, &sd[8], 8);
778++ win_to_timeval(le64toh(u64), &tv);
779++ printf("Last Access Time %s", ctime(&tv.tv_sec));
780++
781++ memcpy(&u64, &sd[16], 8);
782++ win_to_timeval(le64toh(u64), &tv);
783++ printf("Last Write Time %s", ctime(&tv.tv_sec));
784++
785++ memcpy(&u64, &sd[24], 8);
786++ win_to_timeval(le64toh(u64), &tv);
787++ printf("Last Change Time %s", ctime(&tv.tv_sec));
788++
789++ memcpy(&u32, &sd[32], 4);
790++ u32 = le32toh(u32);
791++ printf("File Attributes 0x%08x: ", u32);
792++ print_bits(u32, file_attributes_mask);
793++ printf("\n");
794++}
795++
796++static void
797++filebasicinfo(int f)
798++{
799++ struct smb_query_info *qi;
800++
801++ qi = malloc(sizeof(struct smb_query_info) + 40);
802++ memset(qi, 0, sizeof(qi) + 40);
803++ qi->info_type = 0x01;
804++ qi->file_info_class = 4;
805++ qi->additional_information = 0;
806++ qi->input_buffer_length = 40;
807++
808++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
809++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
810++ exit(1);
811++ }
812++
813++ print_filebasicinfo((uint8_t *)(&qi[1]));
814++ free(qi);
815++}
816++
817++static void
818++print_filestandardinfo(uint8_t *sd)
819++{
820++ uint64_t u64;
821++ uint32_t u32;
822++
823++ memcpy(&u64, &sd[0], 8);
824++ printf("Allocation Size %" PRIu64 "\n", le64toh(u64));
825++
826++ memcpy(&u64, &sd[8], 8);
827++ printf("End Of File %" PRIu64 "\n", le64toh(u64));
828++
829++ memcpy(&u32, &sd[16], 4);
830++ printf("Number Of Links %" PRIu32 "\n", le32toh(u32));
831++
832++ printf("Delete Pending %d\n", sd[20]);
833++ printf("Delete Directory %d\n", sd[21]);
834++}
835++
836++static void
837++filestandardinfo(int f)
838++{
839++ struct smb_query_info *qi;
840++
841++ qi = malloc(sizeof(struct smb_query_info) + 24);
842++ memset(qi, 0, sizeof(qi) + 24);
843++ qi->info_type = 0x01;
844++ qi->file_info_class = 5;
845++ qi->additional_information = 0;
846++ qi->input_buffer_length = 24;
847++
848++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
849++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
850++ exit(1);
851++ }
852++
853++ print_filestandardinfo((uint8_t *)(&qi[1]));
854++ free(qi);
855++}
856++
857++static void
858++print_fileinternalinfo(uint8_t *sd)
859++{
860++ uint64_t u64;
861++
862++ memcpy(&u64, &sd[0], 8);
863++ printf("Index Number %" PRIu64 "\n", le64toh(u64));
864++}
865++
866++static void
867++fileinternalinfo(int f)
868++{
869++ struct smb_query_info *qi;
870++
871++ qi = malloc(sizeof(struct smb_query_info) + 8);
872++ memset(qi, 0, sizeof(qi) + 8);
873++ qi->info_type = 0x01;
874++ qi->file_info_class = 6;
875++ qi->additional_information = 0;
876++ qi->input_buffer_length = 8;
877++
878++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
879++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
880++ exit(1);
881++ }
882++
883++ print_fileinternalinfo((uint8_t *)(&qi[1]));
884++ free(qi);
885++}
886++
887++struct bit_string file_mode_mask[] = {
888++ { 0x00000002, "WRITE_THROUGH" },
889++ { 0x00000004, "SEQUENTIAL_ONLY" },
890++ { 0x00000008, "NO_INTERMEDIATE_BUFFERING" },
891++ { 0x00000010, "SYNCHRONOUS_IO_ALERT" },
892++ { 0x00000020, "SYNCHRONOUS_IO_NONALERT" },
893++ { 0x00001000, "DELETE_ON_CLOSE" },
894++ { 0, NULL }
895++};
896++
897++static void
898++print_filemodeinfo(uint8_t *sd)
899++{
900++ uint32_t u32;
901++
902++ memcpy(&u32, &sd[32], 4);
903++ u32 = le32toh(u32);
904++ printf("Mode 0x%08x: ", u32);
905++ print_bits(u32, file_mode_mask);
906++ printf("\n");
907++}
908++
909++static void
910++filemodeinfo(int f)
911++{
912++ struct smb_query_info *qi;
913++
914++ qi = malloc(sizeof(struct smb_query_info) + 4);
915++ memset(qi, 0, sizeof(qi) + 4);
916++ qi->info_type = 0x01;
917++ qi->file_info_class = 16;
918++ qi->additional_information = 0;
919++ qi->input_buffer_length = 4;
920++
921++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
922++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
923++ exit(1);
924++ }
925++
926++ print_filemodeinfo((uint8_t *)(&qi[1]));
927++ free(qi);
928++}
929++
930++static void
931++print_filepositioninfo(uint8_t *sd)
932++{
933++ uint64_t u64;
934++
935++ memcpy(&u64, &sd[0], 8);
936++ printf("Current Byte Offset %" PRIu64 "\n", le64toh(u64));
937++}
938++
939++static void
940++filepositioninfo(int f)
941++{
942++ struct smb_query_info *qi;
943++
944++ qi = malloc(sizeof(struct smb_query_info) + 8);
945++ memset(qi, 0, sizeof(qi) + 8);
946++ qi->info_type = 0x01;
947++ qi->file_info_class = 14;
948++ qi->additional_information = 0;
949++ qi->input_buffer_length = 8;
950++
951++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
952++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
953++ exit(1);
954++ }
955++
956++ print_filepositioninfo((uint8_t *)(&qi[1]));
957++ free(qi);
958++}
959++
960++static void
961++print_fileeainfo(uint8_t *sd)
962++{
963++ uint32_t u32;
964++
965++ memcpy(&u32, &sd[0], 4);
966++ printf("Ea Size %" PRIu32 "\n", le32toh(u32));
967++}
968++
969++static void
970++fileeainfo(int f)
971++{
972++ struct smb_query_info *qi;
973++
974++ qi = malloc(sizeof(struct smb_query_info) + 4);
975++ memset(qi, 0, sizeof(qi) + 4);
976++ qi->info_type = 0x01;
977++ qi->file_info_class = 7;
978++ qi->additional_information = 0;
979++ qi->input_buffer_length = 4;
980++
981++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
982++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
983++ exit(1);
984++ }
985++
986++ print_fileeainfo((uint8_t *)(&qi[1]));
987++ free(qi);
988++}
989++
990++static void
991++fileallinfo(int f)
992++{
993++ struct smb_query_info *qi;
994++ struct stat st;
995++
996++ fstat(f, &st);
997++
998++ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
999++ memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
1000++ qi->info_type = 0x01;
1001++ qi->file_info_class = 18;
1002++ qi->additional_information = 0;
1003++ qi->input_buffer_length = INPUT_BUFFER_LENGTH;
1004++
1005++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
1006++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
1007++ exit(1);
1008++ }
1009++
1010++ print_filebasicinfo((uint8_t *)(&qi[1]));
1011++ print_filestandardinfo((uint8_t *)(&qi[1]) + 40);
1012++ print_fileinternalinfo((uint8_t *)(&qi[1]) + 64);
1013++ print_fileeainfo((uint8_t *)(&qi[1]) + 72);
1014++ print_fileaccessinfo((uint8_t *)(&qi[1]) + 76, st.st_mode & S_IFMT);
1015++ print_filepositioninfo((uint8_t *)(&qi[1]) + 80);
1016++ print_filemodeinfo((uint8_t *)(&qi[1]) + 88);
1017++ print_filealigninfo((uint8_t *)(&qi[1]) + 92);
1018++ // SMB2 servers like Win16 does not seem to return name info
1019++ free(qi);
1020++}
1021++
1022+ static void
1023+ print_sid(unsigned char *sd)
1024+ {
1025+@@ -152,10 +593,13 @@ print_sd(uint8_t *sd)
1026+ }
1027+ }
1028+
1029+-void secdesc(int f) {
1030++static void
1031++secdesc(int f)
1032++{
1033+ struct smb_query_info *qi;
1034+
1035+ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
1036++ memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
1037+ qi->info_type = 0x03;
1038+ qi->file_info_class = 0;
1039+ qi->additional_information = 0x00000007; /* Owner, Group, Dacl */
1040+@@ -167,13 +611,7 @@ void secdesc(int f) {
1041+ }
1042+
1043+ print_sd((uint8_t *)(&qi[1]));
1044+-}
1045+-
1046+-void
1047+-win_to_timeval(uint64_t smb2_time, struct timeval *tv)
1048+-{
1049+- tv->tv_usec = (smb2_time / 10) % 1000000;
1050+- tv->tv_sec = (smb2_time - 116444736000000000) / 10000000;
1051++ free(qi);
1052+ }
1053+
1054+ static void
1055+@@ -236,7 +674,9 @@ print_quota(unsigned char *sd)
1056+ }
1057+ }
1058+
1059+-void quota(int f) {
1060++static void
1061++quota(int f)
1062++{
1063+ struct smb_query_info *qi;
1064+ char *buf;
1065+ int i;
1066+@@ -264,6 +704,7 @@ void quota(int f) {
1067+ }
1068+
1069+ print_quota((unsigned char *)(&qi[1]));
1070++ free(qi);
1071+ }
1072+
1073+ int main(int argc, char *argv[])
1074+@@ -290,11 +731,29 @@ int main(int argc, char *argv[])
1075+ }
1076+
1077+
1078+- if (!strcmp(argv[1], "secdesc")) {
1079++ if (!strcmp(argv[1], "fileaccessinfo"))
1080++ fileaccessinfo(f);
1081++ else if (!strcmp(argv[1], "filealigninfo"))
1082++ filealigninfo(f);
1083++ else if (!strcmp(argv[1], "fileallinfo"))
1084++ fileallinfo(f);
1085++ else if (!strcmp(argv[1], "filebasicinfo"))
1086++ filebasicinfo(f);
1087++ else if (!strcmp(argv[1], "fileeainfo"))
1088++ fileeainfo(f);
1089++ else if (!strcmp(argv[1], "fileinternalinfo"))
1090++ fileinternalinfo(f);
1091++ else if (!strcmp(argv[1], "filemodeinfo"))
1092++ filemodeinfo(f);
1093++ else if (!strcmp(argv[1], "filepositioninfo"))
1094++ filepositioninfo(f);
1095++ else if (!strcmp(argv[1], "filestandardinfo"))
1096++ filestandardinfo(f);
1097++ else if (!strcmp(argv[1], "secdesc"))
1098+ secdesc(f);
1099+- } else if (!strcmp(argv[1], "quota")) {
1100++ else if (!strcmp(argv[1], "quota"))
1101+ quota(f);
1102+- } else {
1103++ else {
1104+ fprintf(stderr, "Unknown command %s\n", argv[optind]);
1105+ exit(1);
1106+ }
1107+diff --git a/smbinfo.rst b/smbinfo.rst
1108+index a10edb1..85de4cb 100644
1109+--- a/smbinfo.rst
1110++++ b/smbinfo.rst
1111+@@ -39,14 +39,23 @@ OPTIONS
1112+ COMMAND
1113+ *******
1114+
1115+-`secdesc`: Print the security descriptor in the form
1116+-- Revision
1117+-- Control
1118+-- Owner SID
1119+-- Group SID
1120+-- ACL
1121+-- File types
1122+-- File flags
1123++`fileaccessinfo`: Prints the FileAccessInformation class
1124++
1125++`filealigninfo`: Prints the FileAlignmentInformation class
1126++
1127++`fileallinfo`: Prints the FileAllInformation class
1128++
1129++`filebasicinfo`: Prints the FileBasicInformation class
1130++
1131++`fileeainfo`: Prints the FileEaInformation class
1132++
1133++`fileinternalinfo`: Prints the FileInternalInformation class
1134++
1135++`filemodeinfo`: Prints the FileModeInformation class
1136++
1137++`filepositioninfo`: Prints the FilePositionInformation class
1138++
1139++`filestandardinfo`: Prints the FileStandardInformation class
1140+
1141+ `quota`: Print the quota for the volume in the form
1142+ - SID Length
1143+@@ -56,6 +65,15 @@ COMMAND
1144+ - Quota Limit
1145+ - SID
1146+
1147++`secdesc`: Print the security descriptor in the form
1148++- Revision
1149++- Control
1150++- Owner SID
1151++- Group SID
1152++- ACL
1153++- File types
1154++- File flags
1155++
1156+ *****
1157+ NOTES
1158+ *****
1159+--
1160+2.17.1
1161+
1162diff --git a/debian/patches/0004-smbinfo-update-help-text.patch b/debian/patches/0004-smbinfo-update-help-text.patch
1163new file mode 100644
1164index 0000000..0032c72
1165--- /dev/null
1166+++ b/debian/patches/0004-smbinfo-update-help-text.patch
1167@@ -0,0 +1,36 @@
1168+From db9d117fd6e2660768a35e72a374540ffc68d36d Mon Sep 17 00:00:00 2001
1169+From: Steve French <stfrench@microsoft.com>
1170+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=db9d117fd6e2660768a35e72a374540ffc68d36d
1171+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
1172+Date: Tue, 29 Jan 2019 07:03:01 -0600
1173+Subject: [PATCH] smbinfo: update help text
1174+
1175+Add description for fileallinfo query option.
1176+
1177+Note that there are eight other recently added query options, but they
1178+are mostly a subset a "fileallinfo" so could be of little value
1179+(and may even be very confusing if we documented all nine in the
1180+help text in smbinfo, instead of just this one). The man page
1181+has a full description of them.
1182+
1183+Signed-off-by: Steve French <stfrench@microsoft.com>
1184+---
1185+ smbinfo.c | 2 ++
1186+ 1 file changed, 2 insertions(+)
1187+
1188+diff --git a/smbinfo.c b/smbinfo.c
1189+index 7184a68..76e722e 100644
1190+--- a/smbinfo.c
1191++++ b/smbinfo.c
1192+@@ -57,6 +57,8 @@ usage(char *name)
1193+ {
1194+ fprintf(stderr, "Usage: %s <command> <file>\n"
1195+ "Commands are\n"
1196++ " fileallinfo:\n"
1197++ " Prints common metadata associated with a file.\n"
1198+ " secdesc:\n"
1199+ " Prints the security descriptor for a cifs file.\n"
1200+ " quota:\n"
1201+--
1202+2.17.1
1203+
1204diff --git a/debian/patches/0005-smbinfo-Update-the-usage-text-with-the-new-infolevel.patch b/debian/patches/0005-smbinfo-Update-the-usage-text-with-the-new-infolevel.patch
1205new file mode 100644
1206index 0000000..f8e2c76
1207--- /dev/null
1208+++ b/debian/patches/0005-smbinfo-Update-the-usage-text-with-the-new-infolevel.patch
1209@@ -0,0 +1,45 @@
1210+From 858ac4df38169d0b7835113c54a0f85d309303ce Mon Sep 17 00:00:00 2001
1211+From: Ronnie Sahlberg <lsahlber@redhat.com>
1212+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=858ac4df38169d0b7835113c54a0f85d309303ce
1213+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
1214+Date: Wed, 13 Feb 2019 15:47:36 +1000
1215+Subject: [PATCH] smbinfo: Update the usage text with the new infolevels
1216+
1217+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
1218+---
1219+ smbinfo.c | 18 +++++++++++++++++-
1220+ 1 file changed, 17 insertions(+), 1 deletion(-)
1221+
1222+diff --git a/smbinfo.c b/smbinfo.c
1223+index 76e722e..5815f06 100644
1224+--- a/smbinfo.c
1225++++ b/smbinfo.c
1226+@@ -57,8 +57,24 @@ usage(char *name)
1227+ {
1228+ fprintf(stderr, "Usage: %s <command> <file>\n"
1229+ "Commands are\n"
1230++ " fileaccessinfo:\n"
1231++ " Prints FileAccessInfo for a cifs file.\n"
1232++ " filealigninfo:\n"
1233++ " Prints FileAlignInfo for a cifs file.\n"
1234+ " fileallinfo:\n"
1235+- " Prints common metadata associated with a file.\n"
1236++ " Prints FileAllInfo for a cifs file.\n"
1237++ " filebasicinfo:\n"
1238++ " Prints FileBasicInfo for a cifs file.\n"
1239++ " fileeainfo:\n"
1240++ " Prints FileEAInfo for a cifs file.\n"
1241++ " fileinternalinfo:\n"
1242++ " Prints FileInternalInfo for a cifs file.\n"
1243++ " filemodeinfo:\n"
1244++ " Prints FileModeInfo for a cifs file.\n"
1245++ " filepositioninfo:\n"
1246++ " Prints FilePositionInfo for a cifs file.\n"
1247++ " filestandardinfo:\n"
1248++ " Prints FileStandardInfo for a cifs file.\n"
1249+ " secdesc:\n"
1250+ " Prints the security descriptor for a cifs file.\n"
1251+ " quota:\n"
1252+--
1253+2.17.1
1254+
1255diff --git a/debian/patches/0006-smbinfo-add-FileFsFullSizeInformation.patch b/debian/patches/0006-smbinfo-add-FileFsFullSizeInformation.patch
1256new file mode 100644
1257index 0000000..2554f12
1258--- /dev/null
1259+++ b/debian/patches/0006-smbinfo-add-FileFsFullSizeInformation.patch
1260@@ -0,0 +1,103 @@
1261+From 70902177e944c79aeb5c88e2092ef329724138fc Mon Sep 17 00:00:00 2001
1262+From: Ronnie Sahlberg <lsahlber@redhat.com>
1263+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=70902177e944c79aeb5c88e2092ef329724138fc
1264+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
1265+Date: Wed, 13 Feb 2019 15:47:37 +1000
1266+Subject: [PATCH] smbinfo: add FileFsFullSizeInformation
1267+
1268+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
1269+---
1270+ smbinfo.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1271+ smbinfo.rst | 2 ++
1272+ 2 files changed, 51 insertions(+)
1273+
1274+diff --git a/smbinfo.c b/smbinfo.c
1275+index 5815f06..02910c6 100644
1276+--- a/smbinfo.c
1277++++ b/smbinfo.c
1278+@@ -67,6 +67,8 @@ usage(char *name)
1279+ " Prints FileBasicInfo for a cifs file.\n"
1280+ " fileeainfo:\n"
1281+ " Prints FileEAInfo for a cifs file.\n"
1282++ " filefsfullsizeinfo:\n"
1283++ " Prints FileFsFullSizeInfo for a cifs share.\n"
1284+ " fileinternalinfo:\n"
1285+ " Prints FileInternalInfo for a cifs file.\n"
1286+ " filemodeinfo:\n"
1287+@@ -492,6 +494,51 @@ fileeainfo(int f)
1288+ free(qi);
1289+ }
1290+
1291++static void
1292++print_filefullsizeinfo(uint8_t *sd)
1293++{
1294++ uint32_t u32;
1295++ uint64_t u64;
1296++
1297++ memcpy(&u64, &sd[0], 8);
1298++ printf("Total Allocation Units: %" PRIu64 "\n", le64toh(u64));
1299++
1300++ memcpy(&u64, &sd[8], 8);
1301++ printf("Caller Available Allocation Units: %" PRIu64 "\n",
1302++ le64toh(u64));
1303++
1304++ memcpy(&u64, &sd[16], 8);
1305++ printf("Actual Available Allocation Units: %" PRIu64 "\n",
1306++ le64toh(u64));
1307++
1308++ memcpy(&u32, &sd[24], 4);
1309++ printf("Sectors Per Allocation Unit: %" PRIu32 "\n", le32toh(u32));
1310++
1311++ memcpy(&u32, &sd[28], 4);
1312++ printf("Bytes Per Sector: %" PRIu32 "\n", le32toh(u32));
1313++}
1314++
1315++static void
1316++filefsfullsizeinfo(int f)
1317++{
1318++ struct smb_query_info *qi;
1319++
1320++ qi = malloc(sizeof(struct smb_query_info) + 32);
1321++ memset(qi, 0, sizeof(qi) + 32);
1322++ qi->info_type = 0x02;
1323++ qi->file_info_class = 7;
1324++ qi->additional_information = 0;
1325++ qi->input_buffer_length = 32;
1326++
1327++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
1328++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
1329++ exit(1);
1330++ }
1331++
1332++ print_filefullsizeinfo((uint8_t *)(&qi[1]));
1333++ free(qi);
1334++}
1335++
1336+ static void
1337+ fileallinfo(int f)
1338+ {
1339+@@ -759,6 +806,8 @@ int main(int argc, char *argv[])
1340+ filebasicinfo(f);
1341+ else if (!strcmp(argv[1], "fileeainfo"))
1342+ fileeainfo(f);
1343++ else if (!strcmp(argv[1], "filefsfullsizeinfo"))
1344++ filefsfullsizeinfo(f);
1345+ else if (!strcmp(argv[1], "fileinternalinfo"))
1346+ fileinternalinfo(f);
1347+ else if (!strcmp(argv[1], "filemodeinfo"))
1348+diff --git a/smbinfo.rst b/smbinfo.rst
1349+index 85de4cb..5222a71 100644
1350+--- a/smbinfo.rst
1351++++ b/smbinfo.rst
1352+@@ -49,6 +49,8 @@ COMMAND
1353+
1354+ `fileeainfo`: Prints the FileEaInformation class
1355+
1356++`filefsfullsizeinfo`: Prints the FileFsFullSizeInformation class
1357++
1358+ `fileinternalinfo`: Prints the FileInternalInformation class
1359+
1360+ `filemodeinfo`: Prints the FileModeInformation class
1361+--
1362+2.17.1
1363+
1364diff --git a/debian/patches/0007-smbinfo-decode-the-ACEs.patch b/debian/patches/0007-smbinfo-decode-the-ACEs.patch
1365new file mode 100644
1366index 0000000..0fc50a6
1367--- /dev/null
1368+++ b/debian/patches/0007-smbinfo-decode-the-ACEs.patch
1369@@ -0,0 +1,347 @@
1370+From 1191a6cafde1f6e39546cab26a5b90c3cca523fd Mon Sep 17 00:00:00 2001
1371+From: Ronnie Sahlberg <lsahlber@redhat.com>
1372+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=1191a6cafde1f6e39546cab26a5b90c3cca523fd
1373+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
1374+Date: Fri, 1 Mar 2019 12:05:58 +1000
1375+Subject: [PATCH] smbinfo: decode the ACEs
1376+
1377+Decode the most common ACE types and provide a [-V]erbose option
1378+to show the individual mask bits by name.
1379+
1380+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
1381+---
1382+ smbinfo.c | 197 +++++++++++++++++++++++++++++++++++++++++++---------
1383+ smbinfo.rst | 5 +-
1384+ 2 files changed, 168 insertions(+), 34 deletions(-)
1385+
1386+diff --git a/smbinfo.c b/smbinfo.c
1387+index 02910c6..6290a4c 100644
1388+--- a/smbinfo.c
1389++++ b/smbinfo.c
1390+@@ -52,10 +52,13 @@ struct smb_query_info {
1391+ #define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
1392+ #define INPUT_BUFFER_LENGTH 16384
1393+
1394++int verbose;
1395++
1396+ static void
1397+ usage(char *name)
1398+ {
1399+- fprintf(stderr, "Usage: %s <command> <file>\n"
1400++ fprintf(stderr, "Usage: %s [-V] <command> <file>\n"
1401++ "-V for verbose output\n"
1402+ "Commands are\n"
1403+ " fileaccessinfo:\n"
1404+ " Prints FileAccessInfo for a cifs file.\n"
1405+@@ -148,11 +151,22 @@ struct bit_string file_access_mask[] = {
1406+ static void
1407+ print_bits(uint32_t mask, struct bit_string *bs)
1408+ {
1409++ int first = 1;
1410++
1411++ if (!verbose) {
1412++ return;
1413++ }
1414++
1415+ while (bs->string) {
1416+- if (mask & bs->bit)
1417+- printf("%s ", bs->string);
1418++ if (mask & bs->bit) {
1419++ printf("%s%s", first?"":",", bs->string);
1420++ first = 0;
1421++ }
1422+ bs++;
1423+ }
1424++ if (!first) {
1425++ printf(" ");
1426++ }
1427+ }
1428+
1429+ static void
1430+@@ -591,17 +605,106 @@ print_sid(unsigned char *sd)
1431+ for (i = 0; i < sd[1]; i++) {
1432+ memcpy(&subauth, &sd[8 + 4 * i], 4);
1433+ subauth = le32toh(subauth);
1434+- printf("-%d", subauth);
1435++ printf("-%u", subauth);
1436+ }
1437+ }
1438+
1439+ static void
1440+-print_acl(unsigned char *sd)
1441++print_ace_type(uint8_t t)
1442++{
1443++ switch(t) {
1444++ case 0x00: printf("ALLOWED"); break;
1445++ case 0x01: printf("DENIED"); break;
1446++ case 0x02: printf("AUDIT"); break;
1447++ case 0x03: printf("ALARM"); break;
1448++ case 0x04: printf("ALLOWED_COMPOUND"); break;
1449++ case 0x05: printf("ALLOWED_OBJECT"); break;
1450++ case 0x06: printf("DENIED_OBJECT"); break;
1451++ case 0x07: printf("AUDIT_OBJECT"); break;
1452++ case 0x08: printf("ALARM_OBJECT"); break;
1453++ case 0x09: printf("ALLOWED_CALLBACK"); break;
1454++ case 0x0a: printf("DENIED_CALLBACK"); break;
1455++ case 0x0b: printf("ALLOWED_CALLBACK_OBJECT"); break;
1456++ case 0x0c: printf("DENIED_CALLBACK_OBJECT"); break;
1457++ case 0x0d: printf("AUDIT_CALLBACK"); break;
1458++ case 0x0e: printf("ALARM_CALLBACK"); break;
1459++ case 0x0f: printf("AUDIT_CALLBACK_OBJECT"); break;
1460++ case 0x10: printf("ALARM_CALLBACK_OBJECT"); break;
1461++ case 0x11: printf("MANDATORY_LABEL"); break;
1462++ case 0x12: printf("RESOURCE_ATTRIBUTE"); break;
1463++ case 0x13: printf("SCOPED_POLICY_ID"); break;
1464++ default: printf("<UNKNOWN>");
1465++ }
1466++ printf(" ");
1467++}
1468++
1469++struct bit_string ace_flags_mask[] = {
1470++ { 0x80, "FAILED_ACCESS" },
1471++ { 0x40, "SUCCESSFUL_ACCESS" },
1472++ { 0x10, "INHERITED" },
1473++ { 0x08, "INHERIT_ONLY" },
1474++ { 0x04, "NO_PROPAGATE_INHERIT" },
1475++ { 0x02, "CONTAINER_INHERIT" },
1476++ { 0x01, "OBJECT_INHERIT" },
1477++ { 0, NULL }
1478++};
1479++
1480++static void
1481++print_mask_sid_ace(unsigned char *sd, int type)
1482++{
1483++ uint32_t u32;
1484++
1485++ memcpy(&u32, &sd[0], 4);
1486++ printf("Mask:0x%08x ", le32toh(u32));
1487++ if (type == S_IFDIR) {
1488++ print_bits(le32toh(u32), directory_access_mask);
1489++ } else {
1490++ print_bits(le32toh(u32), file_access_mask);
1491++ }
1492++ printf("SID:");
1493++ print_sid(&sd[4]);
1494++ printf("\n");
1495++}
1496++
1497++static int
1498++print_ace(unsigned char *sd, int type)
1499++{
1500++ uint16_t size;
1501++ int i;
1502++
1503++ printf("Type:0x%02x ", sd[0]);
1504++ if (verbose) {
1505++ print_ace_type(sd[0]);
1506++ }
1507++
1508++ printf("Flags:0x%02x ", sd[1]);
1509++ print_bits(sd[1], ace_flags_mask);
1510++
1511++ memcpy(&size, &sd[2], 2);
1512++ size = le16toh(size);
1513++
1514++ switch (sd[0]) {
1515++ case 0x00:
1516++ case 0x01:
1517++ case 0x02:
1518++ print_mask_sid_ace(&sd[4], type);
1519++ break;
1520++ default:
1521++ for (i = 0; i < size; i++)
1522++ printf("%02x", sd[4 + i]);
1523++ }
1524++
1525++ printf("\n");
1526++ return size;
1527++}
1528++
1529++static void
1530++print_acl(unsigned char *sd, int type)
1531+ {
1532+- int i, j, off;
1533+- uint16_t count, size;
1534++ int i, off;
1535++ uint16_t count;
1536+
1537+- if (sd[0] != 2) {
1538++ if ((sd[0] != 2) && (sd[0] != 4)) {
1539+ fprintf(stderr, "Unknown ACL revision\n");
1540+ return;
1541+ }
1542+@@ -610,22 +713,43 @@ print_acl(unsigned char *sd)
1543+ count = le16toh(count);
1544+ off = 8;
1545+ for (i = 0; i < count; i++) {
1546+- printf("Type:%02x Flags:%02x ", sd[off], sd[off + 1]);
1547+- memcpy(&size, &sd[off + 2], 2);
1548+- size = le16toh(size);
1549++ off += print_ace(&sd[off], type);
1550++ }
1551++}
1552+
1553+- for (j = 0; j < size; j++)
1554+- printf("%02x", sd[off + 4 + j]);
1555++struct bit_string control_bits_mask[] = {
1556++ { 0x8000, "SR" },
1557++ { 0x4000, "RM" },
1558++ { 0x2000, "PS" },
1559++ { 0x1000, "PD" },
1560++ { 0x0800, "SI" },
1561++ { 0x0400, "DI" },
1562++ { 0x0200, "SC" },
1563++ { 0x0100, "DC" },
1564++ { 0x0080, "DT" },
1565++ { 0x0040, "SS" },
1566++ { 0x0020, "SD" },
1567++ { 0x0010, "SP" },
1568++ { 0x0008, "DD" },
1569++ { 0x0004, "DP" },
1570++ { 0x0002, "GD" },
1571++ { 0x0001, "OD" },
1572++ { 0, NULL }
1573++};
1574+
1575+- off += size;
1576+- printf("\n");
1577+- }
1578++static void
1579++print_control(uint16_t c)
1580++{
1581++ printf("Control: 0x%04x ", c);
1582++ print_bits(c, control_bits_mask);
1583++ printf("\n");
1584+ }
1585+
1586+ static void
1587+-print_sd(uint8_t *sd)
1588++print_sd(uint8_t *sd, int type)
1589+ {
1590+ int offset_owner, offset_group, offset_dacl;
1591++ uint16_t u16;
1592+
1593+ printf("Revision:%d\n", sd[0]);
1594+ if (sd[0] != 1) {
1595+@@ -633,7 +757,8 @@ print_sd(uint8_t *sd)
1596+ exit(1);
1597+ }
1598+
1599+- printf("Control: %02x%02x\n", sd[2], sd[3]);
1600++ memcpy(&u16, &sd[2], 2);
1601++ print_control(le16toh(u16));
1602+
1603+ memcpy(&offset_owner, &sd[4], 4);
1604+ offset_owner = le32toh(offset_owner);
1605+@@ -654,7 +779,7 @@ print_sd(uint8_t *sd)
1606+ }
1607+ if (offset_dacl) {
1608+ printf("DACL:\n");
1609+- print_acl(&sd[offset_dacl]);
1610++ print_acl(&sd[offset_dacl], type);
1611+ }
1612+ }
1613+
1614+@@ -662,6 +787,9 @@ static void
1615+ secdesc(int f)
1616+ {
1617+ struct smb_query_info *qi;
1618++ struct stat st;
1619++
1620++ fstat(f, &st);
1621+
1622+ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
1623+ memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
1624+@@ -675,7 +803,7 @@ secdesc(int f)
1625+ exit(1);
1626+ }
1627+
1628+- print_sd((uint8_t *)(&qi[1]));
1629++ print_sd((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
1630+ free(qi);
1631+ }
1632+
1633+@@ -777,11 +905,14 @@ int main(int argc, char *argv[])
1634+ int c;
1635+ int f;
1636+
1637+- while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) {
1638++ while ((c = getopt_long(argc, argv, "vV", NULL, NULL)) != -1) {
1639+ switch (c) {
1640+ case 'v':
1641+ printf("smbinfo version %s\n", VERSION);
1642+ return 0;
1643++ case 'V':
1644++ verbose = 1;
1645++ break;
1646+ default:
1647+ usage(argv[0]);
1648+ }
1649+@@ -796,29 +927,29 @@ int main(int argc, char *argv[])
1650+ }
1651+
1652+
1653+- if (!strcmp(argv[1], "fileaccessinfo"))
1654++ if (!strcmp(argv[optind], "fileaccessinfo"))
1655+ fileaccessinfo(f);
1656+- else if (!strcmp(argv[1], "filealigninfo"))
1657++ else if (!strcmp(argv[optind], "filealigninfo"))
1658+ filealigninfo(f);
1659+- else if (!strcmp(argv[1], "fileallinfo"))
1660++ else if (!strcmp(argv[optind], "fileallinfo"))
1661+ fileallinfo(f);
1662+- else if (!strcmp(argv[1], "filebasicinfo"))
1663++ else if (!strcmp(argv[optind], "filebasicinfo"))
1664+ filebasicinfo(f);
1665+- else if (!strcmp(argv[1], "fileeainfo"))
1666++ else if (!strcmp(argv[optind], "fileeainfo"))
1667+ fileeainfo(f);
1668+- else if (!strcmp(argv[1], "filefsfullsizeinfo"))
1669++ else if (!strcmp(argv[optind], "filefsfullsizeinfo"))
1670+ filefsfullsizeinfo(f);
1671+- else if (!strcmp(argv[1], "fileinternalinfo"))
1672++ else if (!strcmp(argv[optind], "fileinternalinfo"))
1673+ fileinternalinfo(f);
1674+- else if (!strcmp(argv[1], "filemodeinfo"))
1675++ else if (!strcmp(argv[optind], "filemodeinfo"))
1676+ filemodeinfo(f);
1677+- else if (!strcmp(argv[1], "filepositioninfo"))
1678++ else if (!strcmp(argv[optind], "filepositioninfo"))
1679+ filepositioninfo(f);
1680+- else if (!strcmp(argv[1], "filestandardinfo"))
1681++ else if (!strcmp(argv[optind], "filestandardinfo"))
1682+ filestandardinfo(f);
1683+- else if (!strcmp(argv[1], "secdesc"))
1684++ else if (!strcmp(argv[optind], "secdesc"))
1685+ secdesc(f);
1686+- else if (!strcmp(argv[1], "quota"))
1687++ else if (!strcmp(argv[optind], "quota"))
1688+ quota(f);
1689+ else {
1690+ fprintf(stderr, "Unknown command %s\n", argv[optind]);
1691+diff --git a/smbinfo.rst b/smbinfo.rst
1692+index 5222a71..9bfd313 100644
1693+--- a/smbinfo.rst
1694++++ b/smbinfo.rst
1695+@@ -11,7 +11,7 @@ Userspace helper to display SMB-specific file information for the Linux SMB clie
1696+ SYNOPSIS
1697+ ********
1698+
1699+- smbinfo [-v] {command} {file system object}
1700++ smbinfo [-v] [-V] {command} {file system object}
1701+
1702+ ***********
1703+ DESCRIPTION
1704+@@ -35,6 +35,9 @@ OPTIONS
1705+ -v
1706+ Print version number and exit.
1707+
1708++-V
1709++ Verbose output.
1710++
1711+ *******
1712+ COMMAND
1713+ *******
1714+--
1715+2.17.1
1716+
1717diff --git a/debian/patches/0008-smbinfo-fix-code-style.patch b/debian/patches/0008-smbinfo-fix-code-style.patch
1718new file mode 100644
1719index 0000000..eb7078a
1720--- /dev/null
1721+++ b/debian/patches/0008-smbinfo-fix-code-style.patch
1722@@ -0,0 +1,1473 @@
1723+From f9f5d421d62decc5f0d025b77415708b1c45d234 Mon Sep 17 00:00:00 2001
1724+From: Pavel Shilovsky <pshilov@microsoft.com>
1725+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=f9f5d421d62decc5f0d025b77415708b1c45d234
1726+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
1727+Date: Fri, 8 Mar 2019 16:28:45 -0800
1728+Subject: [PATCH] smbinfo: fix code style
1729+
1730+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
1731+---
1732+ smbinfo.c | 1175 ++++++++++++++++++++++++++---------------------------
1733+ 1 file changed, 583 insertions(+), 592 deletions(-)
1734+
1735+diff --git a/smbinfo.c b/smbinfo.c
1736+index 6290a4c..d7e7bf3 100644
1737+--- a/smbinfo.c
1738++++ b/smbinfo.c
1739+@@ -40,13 +40,13 @@
1740+
1741+ #define CIFS_IOCTL_MAGIC 0xCF
1742+ struct smb_query_info {
1743+- uint32_t info_type;
1744+- uint32_t file_info_class;
1745+- uint32_t additional_information;
1746+- uint32_t flags;
1747+- uint32_t input_buffer_length;
1748+- uint32_t output_buffer_length;
1749+- /* char buffer[]; */
1750++ uint32_t info_type;
1751++ uint32_t file_info_class;
1752++ uint32_t additional_information;
1753++ uint32_t flags;
1754++ uint32_t input_buffer_length;
1755++ uint32_t output_buffer_length;
1756++ /* char buffer[]; */
1757+ } __packed;
1758+
1759+ #define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
1760+@@ -57,562 +57,560 @@ int verbose;
1761+ static void
1762+ usage(char *name)
1763+ {
1764+- fprintf(stderr, "Usage: %s [-V] <command> <file>\n"
1765+- "-V for verbose output\n"
1766+- "Commands are\n"
1767+- " fileaccessinfo:\n"
1768+- " Prints FileAccessInfo for a cifs file.\n"
1769+- " filealigninfo:\n"
1770+- " Prints FileAlignInfo for a cifs file.\n"
1771+- " fileallinfo:\n"
1772+- " Prints FileAllInfo for a cifs file.\n"
1773+- " filebasicinfo:\n"
1774+- " Prints FileBasicInfo for a cifs file.\n"
1775+- " fileeainfo:\n"
1776+- " Prints FileEAInfo for a cifs file.\n"
1777+- " filefsfullsizeinfo:\n"
1778+- " Prints FileFsFullSizeInfo for a cifs share.\n"
1779+- " fileinternalinfo:\n"
1780+- " Prints FileInternalInfo for a cifs file.\n"
1781+- " filemodeinfo:\n"
1782+- " Prints FileModeInfo for a cifs file.\n"
1783+- " filepositioninfo:\n"
1784+- " Prints FilePositionInfo for a cifs file.\n"
1785+- " filestandardinfo:\n"
1786+- " Prints FileStandardInfo for a cifs file.\n"
1787+- " secdesc:\n"
1788+- " Prints the security descriptor for a cifs file.\n"
1789+- " quota:\n"
1790+- " Prints the quota for a cifs file.\n",
1791+- name);
1792+- exit(1);
1793++ fprintf(stderr, "Usage: %s [-V] <command> <file>\n"
1794++ "-V for verbose output\n"
1795++ "Commands are\n"
1796++ " fileaccessinfo:\n"
1797++ " Prints FileAccessInfo for a cifs file.\n"
1798++ " filealigninfo:\n"
1799++ " Prints FileAlignInfo for a cifs file.\n"
1800++ " fileallinfo:\n"
1801++ " Prints FileAllInfo for a cifs file.\n"
1802++ " filebasicinfo:\n"
1803++ " Prints FileBasicInfo for a cifs file.\n"
1804++ " fileeainfo:\n"
1805++ " Prints FileEAInfo for a cifs file.\n"
1806++ " filefsfullsizeinfo:\n"
1807++ " Prints FileFsFullSizeInfo for a cifs share.\n"
1808++ " fileinternalinfo:\n"
1809++ " Prints FileInternalInfo for a cifs file.\n"
1810++ " filemodeinfo:\n"
1811++ " Prints FileModeInfo for a cifs file.\n"
1812++ " filepositioninfo:\n"
1813++ " Prints FilePositionInfo for a cifs file.\n"
1814++ " filestandardinfo:\n"
1815++ " Prints FileStandardInfo for a cifs file.\n"
1816++ " secdesc:\n"
1817++ " Prints the security descriptor for a cifs file.\n"
1818++ " quota:\n"
1819++ " Prints the quota for a cifs file.\n",
1820++ name);
1821++ exit(1);
1822+ }
1823+
1824+ static void
1825+ win_to_timeval(uint64_t smb2_time, struct timeval *tv)
1826+ {
1827+- tv->tv_usec = (smb2_time / 10) % 1000000;
1828+- tv->tv_sec = (smb2_time - 116444736000000000) / 10000000;
1829++ tv->tv_usec = (smb2_time / 10) % 1000000;
1830++ tv->tv_sec = (smb2_time - 116444736000000000) / 10000000;
1831+ }
1832+
1833+ struct bit_string {
1834+- unsigned int bit;
1835+- char *string;
1836++ unsigned int bit;
1837++ char *string;
1838+ };
1839+
1840+ struct bit_string directory_access_mask[] = {
1841+- { 0x00000001, "LIST_DIRECTORY" },
1842+- { 0x00000002, "ADD_FILE" },
1843+- { 0x00000004, "ADD_SUBDIRECTORY" },
1844+- { 0x00000008, "READ_EA" },
1845+- { 0x00000010, "WRITE_EA" },
1846+- { 0x00000020, "TRAVERSE" },
1847+- { 0x00000040, "DELETE_CHILD" },
1848+- { 0x00000080, "READ_ATTRIBUTES" },
1849+- { 0x00000100, "WRITE_ATTRIBUTES" },
1850+- { 0x00010000, "DELETE" },
1851+- { 0x00020000, "READ_CONTROL" },
1852+- { 0x00040000, "WRITE_DAC" },
1853+- { 0x00080000, "WRITE_OWNER" },
1854+- { 0x00100000, "SYNCHRONIZER" },
1855+- { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
1856+- { 0x02000000, "MAXIMUM_ALLOWED" },
1857+- { 0x10000000, "GENERIC_ALL" },
1858+- { 0x20000000, "GENERIC_EXECUTE" },
1859+- { 0x40000000, "GENERIC_WRITE" },
1860+- { 0x80000000, "GENERIC_READ" },
1861+- { 0, NULL }
1862++ { 0x00000001, "LIST_DIRECTORY" },
1863++ { 0x00000002, "ADD_FILE" },
1864++ { 0x00000004, "ADD_SUBDIRECTORY" },
1865++ { 0x00000008, "READ_EA" },
1866++ { 0x00000010, "WRITE_EA" },
1867++ { 0x00000020, "TRAVERSE" },
1868++ { 0x00000040, "DELETE_CHILD" },
1869++ { 0x00000080, "READ_ATTRIBUTES" },
1870++ { 0x00000100, "WRITE_ATTRIBUTES" },
1871++ { 0x00010000, "DELETE" },
1872++ { 0x00020000, "READ_CONTROL" },
1873++ { 0x00040000, "WRITE_DAC" },
1874++ { 0x00080000, "WRITE_OWNER" },
1875++ { 0x00100000, "SYNCHRONIZER" },
1876++ { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
1877++ { 0x02000000, "MAXIMUM_ALLOWED" },
1878++ { 0x10000000, "GENERIC_ALL" },
1879++ { 0x20000000, "GENERIC_EXECUTE" },
1880++ { 0x40000000, "GENERIC_WRITE" },
1881++ { 0x80000000, "GENERIC_READ" },
1882++ { 0, NULL }
1883+ };
1884+
1885+ struct bit_string file_access_mask[] = {
1886+- { 0x00000001, "READ_DATA" },
1887+- { 0x00000002, "WRITE_DATA" },
1888+- { 0x00000004, "APPEND_DATA" },
1889+- { 0x00000008, "READ_EA" },
1890+- { 0x00000010, "WRITE_EA" },
1891+- { 0x00000020, "EXECUTE" },
1892+- { 0x00000040, "DELETE_CHILD" },
1893+- { 0x00000080, "READ_ATTRIBUTES" },
1894+- { 0x00000100, "WRITE_ATTRIBUTES" },
1895+- { 0x00010000, "DELETE" },
1896+- { 0x00020000, "READ_CONTROL" },
1897+- { 0x00040000, "WRITE_DAC" },
1898+- { 0x00080000, "WRITE_OWNER" },
1899+- { 0x00100000, "SYNCHRONIZER" },
1900+- { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
1901+- { 0x02000000, "MAXIMUM_ALLOWED" },
1902+- { 0x10000000, "GENERIC_ALL" },
1903+- { 0x20000000, "GENERIC_EXECUTE" },
1904+- { 0x40000000, "GENERIC_WRITE" },
1905+- { 0x80000000, "GENERIC_READ" },
1906+- { 0, NULL }
1907++ { 0x00000001, "READ_DATA" },
1908++ { 0x00000002, "WRITE_DATA" },
1909++ { 0x00000004, "APPEND_DATA" },
1910++ { 0x00000008, "READ_EA" },
1911++ { 0x00000010, "WRITE_EA" },
1912++ { 0x00000020, "EXECUTE" },
1913++ { 0x00000040, "DELETE_CHILD" },
1914++ { 0x00000080, "READ_ATTRIBUTES" },
1915++ { 0x00000100, "WRITE_ATTRIBUTES" },
1916++ { 0x00010000, "DELETE" },
1917++ { 0x00020000, "READ_CONTROL" },
1918++ { 0x00040000, "WRITE_DAC" },
1919++ { 0x00080000, "WRITE_OWNER" },
1920++ { 0x00100000, "SYNCHRONIZER" },
1921++ { 0x01000000, "ACCESS_SYSTEM_SECURITY" },
1922++ { 0x02000000, "MAXIMUM_ALLOWED" },
1923++ { 0x10000000, "GENERIC_ALL" },
1924++ { 0x20000000, "GENERIC_EXECUTE" },
1925++ { 0x40000000, "GENERIC_WRITE" },
1926++ { 0x80000000, "GENERIC_READ" },
1927++ { 0, NULL }
1928+ };
1929+
1930+ static void
1931+ print_bits(uint32_t mask, struct bit_string *bs)
1932+ {
1933+- int first = 1;
1934++ int first = 1;
1935+
1936+- if (!verbose) {
1937+- return;
1938+- }
1939++ if (!verbose)
1940++ return;
1941+
1942+- while (bs->string) {
1943+- if (mask & bs->bit) {
1944+- printf("%s%s", first?"":",", bs->string);
1945+- first = 0;
1946+- }
1947+- bs++;
1948+- }
1949+- if (!first) {
1950+- printf(" ");
1951+- }
1952++ while (bs->string) {
1953++ if (mask & bs->bit) {
1954++ printf("%s%s", first?"":",", bs->string);
1955++ first = 0;
1956++ }
1957++ bs++;
1958++ }
1959++ if (!first)
1960++ printf(" ");
1961+ }
1962+
1963+ static void
1964+ print_fileaccessinfo(uint8_t *sd, int type)
1965+ {
1966+- uint32_t access_flags;
1967++ uint32_t access_flags;
1968+
1969+- memcpy(&access_flags, &sd[0], 4);
1970+- access_flags = le32toh(access_flags);
1971++ memcpy(&access_flags, &sd[0], 4);
1972++ access_flags = le32toh(access_flags);
1973+
1974+- if (type == S_IFDIR) {
1975+- printf("Directory access flags 0x%08x: ", access_flags);
1976+- print_bits(access_flags, directory_access_mask);
1977+- } else {
1978+- printf("File/Printer access flags 0x%08x: ", access_flags);
1979+- print_bits(access_flags, file_access_mask);
1980+- }
1981+- printf("\n");
1982++ if (type == S_IFDIR) {
1983++ printf("Directory access flags 0x%08x: ", access_flags);
1984++ print_bits(access_flags, directory_access_mask);
1985++ } else {
1986++ printf("File/Printer access flags 0x%08x: ", access_flags);
1987++ print_bits(access_flags, file_access_mask);
1988++ }
1989++ printf("\n");
1990+ }
1991+
1992+ static void
1993+ fileaccessinfo(int f)
1994+ {
1995+- struct smb_query_info *qi;
1996+- struct stat st;
1997++ struct smb_query_info *qi;
1998++ struct stat st;
1999+
2000+- fstat(f, &st);
2001++ fstat(f, &st);
2002+
2003+- qi = malloc(sizeof(struct smb_query_info) + 4);
2004+- memset(qi, 0, sizeof(qi) + 4);
2005+- qi->info_type = 0x01;
2006+- qi->file_info_class = 8;
2007+- qi->additional_information = 0;
2008+- qi->input_buffer_length = 4;
2009++ qi = malloc(sizeof(struct smb_query_info) + 4);
2010++ memset(qi, 0, sizeof(qi) + 4);
2011++ qi->info_type = 0x01;
2012++ qi->file_info_class = 8;
2013++ qi->additional_information = 0;
2014++ qi->input_buffer_length = 4;
2015+
2016+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2017+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2018+- exit(1);
2019+- }
2020++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2021++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2022++ exit(1);
2023++ }
2024+
2025+- print_fileaccessinfo((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
2026+- free(qi);
2027++ print_fileaccessinfo((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
2028++ free(qi);
2029+ }
2030+
2031+ static void
2032+ print_filealigninfo(uint8_t *sd)
2033+ {
2034+- uint32_t mask;
2035+-
2036+- memcpy(&mask, &sd[0], 4);
2037+- mask = le32toh(mask);
2038+-
2039+- printf("File alignment: ");
2040+- if (mask == 0)
2041+- printf("BYTE_ALIGNMENT");
2042+- else if (mask == 1)
2043+- printf("WORD_ALIGNMENT");
2044+- else if (mask == 3)
2045+- printf("LONG_ALIGNMENT");
2046+- else if (mask == 7)
2047+- printf("QUAD_ALIGNMENT");
2048+- else if (mask == 15)
2049+- printf("OCTA_ALIGNMENT");
2050+- else if (mask == 31)
2051+- printf("32_bit_ALIGNMENT");
2052+- else if (mask == 63)
2053+- printf("64_bit_ALIGNMENT");
2054+- else if (mask == 127)
2055+- printf("128_bit_ALIGNMENT");
2056+- else if (mask == 255)
2057+- printf("254_bit_ALIGNMENT");
2058+- else if (mask == 511)
2059+- printf("512_bit_ALIGNMENT");
2060+-
2061+- printf("\n");
2062++ uint32_t mask;
2063++
2064++ memcpy(&mask, &sd[0], 4);
2065++ mask = le32toh(mask);
2066++
2067++ printf("File alignment: ");
2068++ if (mask == 0)
2069++ printf("BYTE_ALIGNMENT");
2070++ else if (mask == 1)
2071++ printf("WORD_ALIGNMENT");
2072++ else if (mask == 3)
2073++ printf("LONG_ALIGNMENT");
2074++ else if (mask == 7)
2075++ printf("QUAD_ALIGNMENT");
2076++ else if (mask == 15)
2077++ printf("OCTA_ALIGNMENT");
2078++ else if (mask == 31)
2079++ printf("32_bit_ALIGNMENT");
2080++ else if (mask == 63)
2081++ printf("64_bit_ALIGNMENT");
2082++ else if (mask == 127)
2083++ printf("128_bit_ALIGNMENT");
2084++ else if (mask == 255)
2085++ printf("254_bit_ALIGNMENT");
2086++ else if (mask == 511)
2087++ printf("512_bit_ALIGNMENT");
2088++
2089++ printf("\n");
2090+ }
2091+
2092+ static void
2093+ filealigninfo(int f)
2094+ {
2095+- struct smb_query_info *qi;
2096++ struct smb_query_info *qi;
2097+
2098+- qi = malloc(sizeof(struct smb_query_info) + 4);
2099+- memset(qi, 0, sizeof(qi) + 4);
2100+- qi->info_type = 0x01;
2101+- qi->file_info_class = 17;
2102+- qi->additional_information = 0;
2103+- qi->input_buffer_length = 4;
2104++ qi = malloc(sizeof(struct smb_query_info) + 4);
2105++ memset(qi, 0, sizeof(qi) + 4);
2106++ qi->info_type = 0x01;
2107++ qi->file_info_class = 17;
2108++ qi->additional_information = 0;
2109++ qi->input_buffer_length = 4;
2110+
2111+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2112+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2113+- exit(1);
2114+- }
2115++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2116++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2117++ exit(1);
2118++ }
2119+
2120+- print_filealigninfo((uint8_t *)(&qi[1]));
2121+- free(qi);
2122++ print_filealigninfo((uint8_t *)(&qi[1]));
2123++ free(qi);
2124+ }
2125+
2126+ struct bit_string file_attributes_mask[] = {
2127+- { 0x00000001, "READ_ONLY" },
2128+- { 0x00000002, "HIDDEN" },
2129+- { 0x00000004, "SYSTEM" },
2130+- { 0x00000010, "DIRECTORY" },
2131+- { 0x00000020, "ARCHIVE" },
2132+- { 0x00000080, "NORMAL" },
2133+- { 0x00000100, "TEMPORARY" },
2134+- { 0x00000200, "SPARSE_FILE" },
2135+- { 0x00000400, "REPARSE_POINT" },
2136+- { 0x00000800, "COMPRESSED" },
2137+- { 0x00001000, "OFFLINE" },
2138+- { 0x00002000, "NOT_CONTENT_INDEXED" },
2139+- { 0x00004000, "ENCRYPTED" },
2140+- { 0x00008000, "INTEGRITY_STREAM" },
2141+- { 0x00020000, "NO_SCRUB_DATA" },
2142+- { 0, NULL }
2143++ { 0x00000001, "READ_ONLY" },
2144++ { 0x00000002, "HIDDEN" },
2145++ { 0x00000004, "SYSTEM" },
2146++ { 0x00000010, "DIRECTORY" },
2147++ { 0x00000020, "ARCHIVE" },
2148++ { 0x00000080, "NORMAL" },
2149++ { 0x00000100, "TEMPORARY" },
2150++ { 0x00000200, "SPARSE_FILE" },
2151++ { 0x00000400, "REPARSE_POINT" },
2152++ { 0x00000800, "COMPRESSED" },
2153++ { 0x00001000, "OFFLINE" },
2154++ { 0x00002000, "NOT_CONTENT_INDEXED" },
2155++ { 0x00004000, "ENCRYPTED" },
2156++ { 0x00008000, "INTEGRITY_STREAM" },
2157++ { 0x00020000, "NO_SCRUB_DATA" },
2158++ { 0, NULL }
2159+ };
2160+
2161+ static void
2162+ print_filebasicinfo(uint8_t *sd)
2163+ {
2164+- struct timeval tv;
2165+- uint64_t u64;
2166+- uint32_t u32;
2167++ struct timeval tv;
2168++ uint64_t u64;
2169++ uint32_t u32;
2170+
2171+- memcpy(&u64, &sd[0], 8);
2172+- win_to_timeval(le64toh(u64), &tv);
2173+- printf("Creation Time %s", ctime(&tv.tv_sec));
2174++ memcpy(&u64, &sd[0], 8);
2175++ win_to_timeval(le64toh(u64), &tv);
2176++ printf("Creation Time %s", ctime(&tv.tv_sec));
2177+
2178+- memcpy(&u64, &sd[8], 8);
2179+- win_to_timeval(le64toh(u64), &tv);
2180+- printf("Last Access Time %s", ctime(&tv.tv_sec));
2181++ memcpy(&u64, &sd[8], 8);
2182++ win_to_timeval(le64toh(u64), &tv);
2183++ printf("Last Access Time %s", ctime(&tv.tv_sec));
2184+
2185+- memcpy(&u64, &sd[16], 8);
2186+- win_to_timeval(le64toh(u64), &tv);
2187+- printf("Last Write Time %s", ctime(&tv.tv_sec));
2188++ memcpy(&u64, &sd[16], 8);
2189++ win_to_timeval(le64toh(u64), &tv);
2190++ printf("Last Write Time %s", ctime(&tv.tv_sec));
2191+
2192+- memcpy(&u64, &sd[24], 8);
2193+- win_to_timeval(le64toh(u64), &tv);
2194+- printf("Last Change Time %s", ctime(&tv.tv_sec));
2195++ memcpy(&u64, &sd[24], 8);
2196++ win_to_timeval(le64toh(u64), &tv);
2197++ printf("Last Change Time %s", ctime(&tv.tv_sec));
2198+
2199+- memcpy(&u32, &sd[32], 4);
2200+- u32 = le32toh(u32);
2201+- printf("File Attributes 0x%08x: ", u32);
2202+- print_bits(u32, file_attributes_mask);
2203+- printf("\n");
2204++ memcpy(&u32, &sd[32], 4);
2205++ u32 = le32toh(u32);
2206++ printf("File Attributes 0x%08x: ", u32);
2207++ print_bits(u32, file_attributes_mask);
2208++ printf("\n");
2209+ }
2210+
2211+ static void
2212+ filebasicinfo(int f)
2213+ {
2214+- struct smb_query_info *qi;
2215++ struct smb_query_info *qi;
2216+
2217+- qi = malloc(sizeof(struct smb_query_info) + 40);
2218+- memset(qi, 0, sizeof(qi) + 40);
2219+- qi->info_type = 0x01;
2220+- qi->file_info_class = 4;
2221+- qi->additional_information = 0;
2222+- qi->input_buffer_length = 40;
2223++ qi = malloc(sizeof(struct smb_query_info) + 40);
2224++ memset(qi, 0, sizeof(qi) + 40);
2225++ qi->info_type = 0x01;
2226++ qi->file_info_class = 4;
2227++ qi->additional_information = 0;
2228++ qi->input_buffer_length = 40;
2229+
2230+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2231+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2232+- exit(1);
2233+- }
2234++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2235++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2236++ exit(1);
2237++ }
2238+
2239+- print_filebasicinfo((uint8_t *)(&qi[1]));
2240+- free(qi);
2241++ print_filebasicinfo((uint8_t *)(&qi[1]));
2242++ free(qi);
2243+ }
2244+
2245+ static void
2246+ print_filestandardinfo(uint8_t *sd)
2247+ {
2248+- uint64_t u64;
2249+- uint32_t u32;
2250++ uint64_t u64;
2251++ uint32_t u32;
2252+
2253+- memcpy(&u64, &sd[0], 8);
2254+- printf("Allocation Size %" PRIu64 "\n", le64toh(u64));
2255++ memcpy(&u64, &sd[0], 8);
2256++ printf("Allocation Size %" PRIu64 "\n", le64toh(u64));
2257+
2258+- memcpy(&u64, &sd[8], 8);
2259+- printf("End Of File %" PRIu64 "\n", le64toh(u64));
2260++ memcpy(&u64, &sd[8], 8);
2261++ printf("End Of File %" PRIu64 "\n", le64toh(u64));
2262+
2263+- memcpy(&u32, &sd[16], 4);
2264+- printf("Number Of Links %" PRIu32 "\n", le32toh(u32));
2265++ memcpy(&u32, &sd[16], 4);
2266++ printf("Number Of Links %" PRIu32 "\n", le32toh(u32));
2267+
2268+- printf("Delete Pending %d\n", sd[20]);
2269+- printf("Delete Directory %d\n", sd[21]);
2270++ printf("Delete Pending %d\n", sd[20]);
2271++ printf("Delete Directory %d\n", sd[21]);
2272+ }
2273+
2274+ static void
2275+ filestandardinfo(int f)
2276+ {
2277+- struct smb_query_info *qi;
2278++ struct smb_query_info *qi;
2279+
2280+- qi = malloc(sizeof(struct smb_query_info) + 24);
2281+- memset(qi, 0, sizeof(qi) + 24);
2282+- qi->info_type = 0x01;
2283+- qi->file_info_class = 5;
2284+- qi->additional_information = 0;
2285+- qi->input_buffer_length = 24;
2286++ qi = malloc(sizeof(struct smb_query_info) + 24);
2287++ memset(qi, 0, sizeof(qi) + 24);
2288++ qi->info_type = 0x01;
2289++ qi->file_info_class = 5;
2290++ qi->additional_information = 0;
2291++ qi->input_buffer_length = 24;
2292+
2293+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2294+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2295+- exit(1);
2296+- }
2297++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2298++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2299++ exit(1);
2300++ }
2301+
2302+- print_filestandardinfo((uint8_t *)(&qi[1]));
2303+- free(qi);
2304++ print_filestandardinfo((uint8_t *)(&qi[1]));
2305++ free(qi);
2306+ }
2307+
2308+ static void
2309+ print_fileinternalinfo(uint8_t *sd)
2310+ {
2311+- uint64_t u64;
2312++ uint64_t u64;
2313+
2314+- memcpy(&u64, &sd[0], 8);
2315+- printf("Index Number %" PRIu64 "\n", le64toh(u64));
2316++ memcpy(&u64, &sd[0], 8);
2317++ printf("Index Number %" PRIu64 "\n", le64toh(u64));
2318+ }
2319+
2320+ static void
2321+ fileinternalinfo(int f)
2322+ {
2323+- struct smb_query_info *qi;
2324++ struct smb_query_info *qi;
2325+
2326+- qi = malloc(sizeof(struct smb_query_info) + 8);
2327+- memset(qi, 0, sizeof(qi) + 8);
2328+- qi->info_type = 0x01;
2329+- qi->file_info_class = 6;
2330+- qi->additional_information = 0;
2331+- qi->input_buffer_length = 8;
2332++ qi = malloc(sizeof(struct smb_query_info) + 8);
2333++ memset(qi, 0, sizeof(qi) + 8);
2334++ qi->info_type = 0x01;
2335++ qi->file_info_class = 6;
2336++ qi->additional_information = 0;
2337++ qi->input_buffer_length = 8;
2338+
2339+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2340+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2341+- exit(1);
2342+- }
2343++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2344++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2345++ exit(1);
2346++ }
2347+
2348+- print_fileinternalinfo((uint8_t *)(&qi[1]));
2349+- free(qi);
2350++ print_fileinternalinfo((uint8_t *)(&qi[1]));
2351++ free(qi);
2352+ }
2353+
2354+ struct bit_string file_mode_mask[] = {
2355+- { 0x00000002, "WRITE_THROUGH" },
2356+- { 0x00000004, "SEQUENTIAL_ONLY" },
2357+- { 0x00000008, "NO_INTERMEDIATE_BUFFERING" },
2358+- { 0x00000010, "SYNCHRONOUS_IO_ALERT" },
2359+- { 0x00000020, "SYNCHRONOUS_IO_NONALERT" },
2360+- { 0x00001000, "DELETE_ON_CLOSE" },
2361+- { 0, NULL }
2362++ { 0x00000002, "WRITE_THROUGH" },
2363++ { 0x00000004, "SEQUENTIAL_ONLY" },
2364++ { 0x00000008, "NO_INTERMEDIATE_BUFFERING" },
2365++ { 0x00000010, "SYNCHRONOUS_IO_ALERT" },
2366++ { 0x00000020, "SYNCHRONOUS_IO_NONALERT" },
2367++ { 0x00001000, "DELETE_ON_CLOSE" },
2368++ { 0, NULL }
2369+ };
2370+
2371+ static void
2372+ print_filemodeinfo(uint8_t *sd)
2373+ {
2374+- uint32_t u32;
2375++ uint32_t u32;
2376+
2377+- memcpy(&u32, &sd[32], 4);
2378+- u32 = le32toh(u32);
2379+- printf("Mode 0x%08x: ", u32);
2380+- print_bits(u32, file_mode_mask);
2381+- printf("\n");
2382++ memcpy(&u32, &sd[32], 4);
2383++ u32 = le32toh(u32);
2384++ printf("Mode 0x%08x: ", u32);
2385++ print_bits(u32, file_mode_mask);
2386++ printf("\n");
2387+ }
2388+
2389+ static void
2390+ filemodeinfo(int f)
2391+ {
2392+- struct smb_query_info *qi;
2393++ struct smb_query_info *qi;
2394+
2395+- qi = malloc(sizeof(struct smb_query_info) + 4);
2396+- memset(qi, 0, sizeof(qi) + 4);
2397+- qi->info_type = 0x01;
2398+- qi->file_info_class = 16;
2399+- qi->additional_information = 0;
2400+- qi->input_buffer_length = 4;
2401++ qi = malloc(sizeof(struct smb_query_info) + 4);
2402++ memset(qi, 0, sizeof(qi) + 4);
2403++ qi->info_type = 0x01;
2404++ qi->file_info_class = 16;
2405++ qi->additional_information = 0;
2406++ qi->input_buffer_length = 4;
2407+
2408+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2409+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2410+- exit(1);
2411+- }
2412++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2413++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2414++ exit(1);
2415++ }
2416+
2417+- print_filemodeinfo((uint8_t *)(&qi[1]));
2418+- free(qi);
2419++ print_filemodeinfo((uint8_t *)(&qi[1]));
2420++ free(qi);
2421+ }
2422+
2423+ static void
2424+ print_filepositioninfo(uint8_t *sd)
2425+ {
2426+- uint64_t u64;
2427++ uint64_t u64;
2428+
2429+- memcpy(&u64, &sd[0], 8);
2430+- printf("Current Byte Offset %" PRIu64 "\n", le64toh(u64));
2431++ memcpy(&u64, &sd[0], 8);
2432++ printf("Current Byte Offset %" PRIu64 "\n", le64toh(u64));
2433+ }
2434+
2435+ static void
2436+ filepositioninfo(int f)
2437+ {
2438+- struct smb_query_info *qi;
2439++ struct smb_query_info *qi;
2440+
2441+- qi = malloc(sizeof(struct smb_query_info) + 8);
2442+- memset(qi, 0, sizeof(qi) + 8);
2443+- qi->info_type = 0x01;
2444+- qi->file_info_class = 14;
2445+- qi->additional_information = 0;
2446+- qi->input_buffer_length = 8;
2447++ qi = malloc(sizeof(struct smb_query_info) + 8);
2448++ memset(qi, 0, sizeof(qi) + 8);
2449++ qi->info_type = 0x01;
2450++ qi->file_info_class = 14;
2451++ qi->additional_information = 0;
2452++ qi->input_buffer_length = 8;
2453+
2454+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2455+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2456+- exit(1);
2457+- }
2458++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2459++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2460++ exit(1);
2461++ }
2462+
2463+- print_filepositioninfo((uint8_t *)(&qi[1]));
2464+- free(qi);
2465++ print_filepositioninfo((uint8_t *)(&qi[1]));
2466++ free(qi);
2467+ }
2468+
2469+ static void
2470+ print_fileeainfo(uint8_t *sd)
2471+ {
2472+- uint32_t u32;
2473++ uint32_t u32;
2474+
2475+- memcpy(&u32, &sd[0], 4);
2476+- printf("Ea Size %" PRIu32 "\n", le32toh(u32));
2477++ memcpy(&u32, &sd[0], 4);
2478++ printf("Ea Size %" PRIu32 "\n", le32toh(u32));
2479+ }
2480+
2481+ static void
2482+ fileeainfo(int f)
2483+ {
2484+- struct smb_query_info *qi;
2485++ struct smb_query_info *qi;
2486+
2487+- qi = malloc(sizeof(struct smb_query_info) + 4);
2488+- memset(qi, 0, sizeof(qi) + 4);
2489+- qi->info_type = 0x01;
2490+- qi->file_info_class = 7;
2491+- qi->additional_information = 0;
2492+- qi->input_buffer_length = 4;
2493++ qi = malloc(sizeof(struct smb_query_info) + 4);
2494++ memset(qi, 0, sizeof(qi) + 4);
2495++ qi->info_type = 0x01;
2496++ qi->file_info_class = 7;
2497++ qi->additional_information = 0;
2498++ qi->input_buffer_length = 4;
2499+
2500+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2501+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2502+- exit(1);
2503+- }
2504++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2505++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2506++ exit(1);
2507++ }
2508+
2509+- print_fileeainfo((uint8_t *)(&qi[1]));
2510+- free(qi);
2511++ print_fileeainfo((uint8_t *)(&qi[1]));
2512++ free(qi);
2513+ }
2514+
2515+ static void
2516+ print_filefullsizeinfo(uint8_t *sd)
2517+ {
2518+- uint32_t u32;
2519+- uint64_t u64;
2520++ uint32_t u32;
2521++ uint64_t u64;
2522+
2523+- memcpy(&u64, &sd[0], 8);
2524+- printf("Total Allocation Units: %" PRIu64 "\n", le64toh(u64));
2525++ memcpy(&u64, &sd[0], 8);
2526++ printf("Total Allocation Units: %" PRIu64 "\n", le64toh(u64));
2527+
2528+- memcpy(&u64, &sd[8], 8);
2529+- printf("Caller Available Allocation Units: %" PRIu64 "\n",
2530++ memcpy(&u64, &sd[8], 8);
2531++ printf("Caller Available Allocation Units: %" PRIu64 "\n",
2532+ le64toh(u64));
2533+
2534+- memcpy(&u64, &sd[16], 8);
2535+- printf("Actual Available Allocation Units: %" PRIu64 "\n",
2536++ memcpy(&u64, &sd[16], 8);
2537++ printf("Actual Available Allocation Units: %" PRIu64 "\n",
2538+ le64toh(u64));
2539+
2540+- memcpy(&u32, &sd[24], 4);
2541+- printf("Sectors Per Allocation Unit: %" PRIu32 "\n", le32toh(u32));
2542++ memcpy(&u32, &sd[24], 4);
2543++ printf("Sectors Per Allocation Unit: %" PRIu32 "\n", le32toh(u32));
2544+
2545+- memcpy(&u32, &sd[28], 4);
2546+- printf("Bytes Per Sector: %" PRIu32 "\n", le32toh(u32));
2547++ memcpy(&u32, &sd[28], 4);
2548++ printf("Bytes Per Sector: %" PRIu32 "\n", le32toh(u32));
2549+ }
2550+
2551+ static void
2552+ filefsfullsizeinfo(int f)
2553+ {
2554+- struct smb_query_info *qi;
2555++ struct smb_query_info *qi;
2556+
2557+- qi = malloc(sizeof(struct smb_query_info) + 32);
2558++ qi = malloc(sizeof(struct smb_query_info) + 32);
2559+ memset(qi, 0, sizeof(qi) + 32);
2560+- qi->info_type = 0x02;
2561+- qi->file_info_class = 7;
2562+- qi->additional_information = 0;
2563+- qi->input_buffer_length = 32;
2564+-
2565+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2566+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2567+- exit(1);
2568+- }
2569++ qi->info_type = 0x02;
2570++ qi->file_info_class = 7;
2571++ qi->additional_information = 0;
2572++ qi->input_buffer_length = 32;
2573++
2574++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2575++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2576++ exit(1);
2577++ }
2578+
2579+- print_filefullsizeinfo((uint8_t *)(&qi[1]));
2580++ print_filefullsizeinfo((uint8_t *)(&qi[1]));
2581+ free(qi);
2582+ }
2583+
2584+ static void
2585+ fileallinfo(int f)
2586+ {
2587+- struct smb_query_info *qi;
2588+- struct stat st;
2589++ struct smb_query_info *qi;
2590++ struct stat st;
2591+
2592+- fstat(f, &st);
2593++ fstat(f, &st);
2594+
2595+- qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
2596+- memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
2597+- qi->info_type = 0x01;
2598+- qi->file_info_class = 18;
2599+- qi->additional_information = 0;
2600+- qi->input_buffer_length = INPUT_BUFFER_LENGTH;
2601++ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
2602++ memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
2603++ qi->info_type = 0x01;
2604++ qi->file_info_class = 18;
2605++ qi->additional_information = 0;
2606++ qi->input_buffer_length = INPUT_BUFFER_LENGTH;
2607+
2608+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2609+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2610+- exit(1);
2611+- }
2612++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2613++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2614++ exit(1);
2615++ }
2616+
2617+- print_filebasicinfo((uint8_t *)(&qi[1]));
2618+- print_filestandardinfo((uint8_t *)(&qi[1]) + 40);
2619+- print_fileinternalinfo((uint8_t *)(&qi[1]) + 64);
2620+- print_fileeainfo((uint8_t *)(&qi[1]) + 72);
2621+- print_fileaccessinfo((uint8_t *)(&qi[1]) + 76, st.st_mode & S_IFMT);
2622+- print_filepositioninfo((uint8_t *)(&qi[1]) + 80);
2623+- print_filemodeinfo((uint8_t *)(&qi[1]) + 88);
2624+- print_filealigninfo((uint8_t *)(&qi[1]) + 92);
2625+- // SMB2 servers like Win16 does not seem to return name info
2626+- free(qi);
2627++ print_filebasicinfo((uint8_t *)(&qi[1]));
2628++ print_filestandardinfo((uint8_t *)(&qi[1]) + 40);
2629++ print_fileinternalinfo((uint8_t *)(&qi[1]) + 64);
2630++ print_fileeainfo((uint8_t *)(&qi[1]) + 72);
2631++ print_fileaccessinfo((uint8_t *)(&qi[1]) + 76, st.st_mode & S_IFMT);
2632++ print_filepositioninfo((uint8_t *)(&qi[1]) + 80);
2633++ print_filemodeinfo((uint8_t *)(&qi[1]) + 88);
2634++ print_filealigninfo((uint8_t *)(&qi[1]) + 92);
2635++ // SMB2 servers like Win16 does not seem to return name info
2636++ free(qi);
2637+ }
2638+
2639+ static void
2640+ print_sid(unsigned char *sd)
2641+ {
2642+- int i;
2643+- uint32_t subauth;
2644+- uint64_t idauth;
2645++ int i;
2646++ uint32_t subauth;
2647++ uint64_t idauth;
2648+
2649+- if (sd[0] != 1) {
2650+- fprintf(stderr, "Unknown SID revision\n");
2651+- return;
2652+- }
2653++ if (sd[0] != 1) {
2654++ fprintf(stderr, "Unknown SID revision\n");
2655++ return;
2656++ }
2657+
2658+- idauth = 0;
2659+- for (i = 0; i < 6; i++)
2660+- idauth = (idauth << 8) | sd[2 + i];
2661++ idauth = 0;
2662++ for (i = 0; i < 6; i++)
2663++ idauth = (idauth << 8) | sd[2 + i];
2664+
2665+- printf("S-1-%" PRIu64, idauth);
2666+- for (i = 0; i < sd[1]; i++) {
2667+- memcpy(&subauth, &sd[8 + 4 * i], 4);
2668+- subauth = le32toh(subauth);
2669+- printf("-%u", subauth);
2670+- }
2671++ printf("S-1-%" PRIu64, idauth);
2672++ for (i = 0; i < sd[1]; i++) {
2673++ memcpy(&subauth, &sd[8 + 4 * i], 4);
2674++ subauth = le32toh(subauth);
2675++ printf("-%u", subauth);
2676++ }
2677+ }
2678+
2679+ static void
2680+ print_ace_type(uint8_t t)
2681+ {
2682+- switch(t) {
2683++ switch(t) {
2684+ case 0x00: printf("ALLOWED"); break;
2685+ case 0x01: printf("DENIED"); break;
2686+ case 0x02: printf("AUDIT"); break;
2687+@@ -639,28 +637,27 @@ print_ace_type(uint8_t t)
2688+ }
2689+
2690+ struct bit_string ace_flags_mask[] = {
2691+- { 0x80, "FAILED_ACCESS" },
2692+- { 0x40, "SUCCESSFUL_ACCESS" },
2693+- { 0x10, "INHERITED" },
2694+- { 0x08, "INHERIT_ONLY" },
2695+- { 0x04, "NO_PROPAGATE_INHERIT" },
2696+- { 0x02, "CONTAINER_INHERIT" },
2697+- { 0x01, "OBJECT_INHERIT" },
2698+- { 0, NULL }
2699++ { 0x80, "FAILED_ACCESS" },
2700++ { 0x40, "SUCCESSFUL_ACCESS" },
2701++ { 0x10, "INHERITED" },
2702++ { 0x08, "INHERIT_ONLY" },
2703++ { 0x04, "NO_PROPAGATE_INHERIT" },
2704++ { 0x02, "CONTAINER_INHERIT" },
2705++ { 0x01, "OBJECT_INHERIT" },
2706++ { 0, NULL }
2707+ };
2708+
2709+ static void
2710+ print_mask_sid_ace(unsigned char *sd, int type)
2711+ {
2712+- uint32_t u32;
2713++ uint32_t u32;
2714+
2715+- memcpy(&u32, &sd[0], 4);
2716++ memcpy(&u32, &sd[0], 4);
2717+ printf("Mask:0x%08x ", le32toh(u32));
2718+- if (type == S_IFDIR) {
2719++ if (type == S_IFDIR)
2720+ print_bits(le32toh(u32), directory_access_mask);
2721+- } else {
2722++ else
2723+ print_bits(le32toh(u32), file_access_mask);
2724+- }
2725+ printf("SID:");
2726+ print_sid(&sd[4]);
2727+ printf("\n");
2728+@@ -669,7 +666,7 @@ print_mask_sid_ace(unsigned char *sd, int type)
2729+ static int
2730+ print_ace(unsigned char *sd, int type)
2731+ {
2732+- uint16_t size;
2733++ uint16_t size;
2734+ int i;
2735+
2736+ printf("Type:0x%02x ", sd[0]);
2737+@@ -701,40 +698,39 @@ print_ace(unsigned char *sd, int type)
2738+ static void
2739+ print_acl(unsigned char *sd, int type)
2740+ {
2741+- int i, off;
2742+- uint16_t count;
2743++ int i, off;
2744++ uint16_t count;
2745+
2746+- if ((sd[0] != 2) && (sd[0] != 4)) {
2747+- fprintf(stderr, "Unknown ACL revision\n");
2748+- return;
2749+- }
2750++ if ((sd[0] != 2) && (sd[0] != 4)) {
2751++ fprintf(stderr, "Unknown ACL revision\n");
2752++ return;
2753++ }
2754+
2755+- memcpy(&count, &sd[4], 2);
2756+- count = le16toh(count);
2757+- off = 8;
2758+- for (i = 0; i < count; i++) {
2759++ memcpy(&count, &sd[4], 2);
2760++ count = le16toh(count);
2761++ off = 8;
2762++ for (i = 0; i < count; i++)
2763+ off += print_ace(&sd[off], type);
2764+- }
2765+ }
2766+
2767+ struct bit_string control_bits_mask[] = {
2768+- { 0x8000, "SR" },
2769+- { 0x4000, "RM" },
2770+- { 0x2000, "PS" },
2771+- { 0x1000, "PD" },
2772+- { 0x0800, "SI" },
2773+- { 0x0400, "DI" },
2774+- { 0x0200, "SC" },
2775+- { 0x0100, "DC" },
2776+- { 0x0080, "DT" },
2777+- { 0x0040, "SS" },
2778+- { 0x0020, "SD" },
2779+- { 0x0010, "SP" },
2780+- { 0x0008, "DD" },
2781+- { 0x0004, "DP" },
2782+- { 0x0002, "GD" },
2783+- { 0x0001, "OD" },
2784+- { 0, NULL }
2785++ { 0x8000, "SR" },
2786++ { 0x4000, "RM" },
2787++ { 0x2000, "PS" },
2788++ { 0x1000, "PD" },
2789++ { 0x0800, "SI" },
2790++ { 0x0400, "DI" },
2791++ { 0x0200, "SC" },
2792++ { 0x0100, "DC" },
2793++ { 0x0080, "DT" },
2794++ { 0x0040, "SS" },
2795++ { 0x0020, "SD" },
2796++ { 0x0010, "SP" },
2797++ { 0x0008, "DD" },
2798++ { 0x0004, "DP" },
2799++ { 0x0002, "GD" },
2800++ { 0x0001, "OD" },
2801++ { 0, NULL }
2802+ };
2803+
2804+ static void
2805+@@ -748,215 +744,210 @@ print_control(uint16_t c)
2806+ static void
2807+ print_sd(uint8_t *sd, int type)
2808+ {
2809+- int offset_owner, offset_group, offset_dacl;
2810++ int offset_owner, offset_group, offset_dacl;
2811+ uint16_t u16;
2812+
2813+- printf("Revision:%d\n", sd[0]);
2814+- if (sd[0] != 1) {
2815+- fprintf(stderr, "Unknown SD revision\n");
2816+- exit(1);
2817+- }
2818+-
2819+- memcpy(&u16, &sd[2], 2);
2820+- print_control(le16toh(u16));
2821+-
2822+- memcpy(&offset_owner, &sd[4], 4);
2823+- offset_owner = le32toh(offset_owner);
2824+- memcpy(&offset_group, &sd[8], 4);
2825+- offset_group = le32toh(offset_group);
2826+- memcpy(&offset_dacl, &sd[16], 4);
2827+- offset_dacl = le32toh(offset_dacl);
2828+-
2829+- if (offset_owner) {
2830+- printf("Owner: ");
2831+- print_sid(&sd[offset_owner]);
2832+- printf("\n");
2833+- }
2834+- if (offset_group) {
2835+- printf("Group: ");
2836+- print_sid(&sd[offset_group]);
2837+- printf("\n");
2838+- }
2839+- if (offset_dacl) {
2840+- printf("DACL:\n");
2841+- print_acl(&sd[offset_dacl], type);
2842+- }
2843++ printf("Revision:%d\n", sd[0]);
2844++ if (sd[0] != 1) {
2845++ fprintf(stderr, "Unknown SD revision\n");
2846++ exit(1);
2847++ }
2848++
2849++ memcpy(&u16, &sd[2], 2);
2850++ print_control(le16toh(u16));
2851++
2852++ memcpy(&offset_owner, &sd[4], 4);
2853++ offset_owner = le32toh(offset_owner);
2854++ memcpy(&offset_group, &sd[8], 4);
2855++ offset_group = le32toh(offset_group);
2856++ memcpy(&offset_dacl, &sd[16], 4);
2857++ offset_dacl = le32toh(offset_dacl);
2858++
2859++ if (offset_owner) {
2860++ printf("Owner: ");
2861++ print_sid(&sd[offset_owner]);
2862++ printf("\n");
2863++ }
2864++ if (offset_group) {
2865++ printf("Group: ");
2866++ print_sid(&sd[offset_group]);
2867++ printf("\n");
2868++ }
2869++ if (offset_dacl) {
2870++ printf("DACL:\n");
2871++ print_acl(&sd[offset_dacl], type);
2872++ }
2873+ }
2874+
2875+ static void
2876+ secdesc(int f)
2877+ {
2878+- struct smb_query_info *qi;
2879+- struct stat st;
2880++ struct smb_query_info *qi;
2881++ struct stat st;
2882+
2883+- fstat(f, &st);
2884++ fstat(f, &st);
2885+
2886+- qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
2887+- memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
2888+- qi->info_type = 0x03;
2889+- qi->file_info_class = 0;
2890+- qi->additional_information = 0x00000007; /* Owner, Group, Dacl */
2891+- qi->input_buffer_length = INPUT_BUFFER_LENGTH;
2892++ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
2893++ memset(qi, 0, sizeof(qi) + INPUT_BUFFER_LENGTH);
2894++ qi->info_type = 0x03;
2895++ qi->file_info_class = 0;
2896++ qi->additional_information = 0x00000007; /* Owner, Group, Dacl */
2897++ qi->input_buffer_length = INPUT_BUFFER_LENGTH;
2898+
2899+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2900+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2901+- exit(1);
2902+- }
2903++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
2904++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
2905++ exit(1);
2906++ }
2907+
2908+- print_sd((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
2909+- free(qi);
2910++ print_sd((uint8_t *)(&qi[1]), st.st_mode & S_IFMT);
2911++ free(qi);
2912+ }
2913+
2914+ static void
2915+ print_quota(unsigned char *sd)
2916+ {
2917+- uint32_t u32, neo;
2918+- uint64_t u64;
2919+- struct timeval tv;
2920+- struct tm;
2921+- int i, off = 0;
2922+-
2923+- one_more:
2924+- memcpy(&u32, &sd[off], 4);
2925+- neo = le32toh(u32);
2926+-
2927+- memcpy(&u32, &sd[off + 4], 4);
2928+- u32 = le32toh(u32);
2929+- printf("SID Length %d\n", u32);
2930+-
2931+- memcpy(&u64, &sd[off + 8], 8);
2932+- win_to_timeval(le64toh(u64), &tv);
2933+- printf("Change Time %s", ctime(&tv.tv_sec));
2934+-
2935+- memcpy(&u64, &sd[off + 16], 8);
2936+- u64 = le32toh(u64);
2937+- printf("Quota Used %" PRIu64 "\n", u64);
2938+-
2939+- memcpy(&u64, &sd[off + 24], 8);
2940+- u64 = le64toh(u64);
2941+- if (u64 == 0xffffffffffffffff) {
2942+- printf("Quota Threshold NO THRESHOLD\n");
2943+- } else {
2944+- printf("Quota Threshold %" PRIu64 "\n", u64);
2945+- }
2946+-
2947+- memcpy(&u64, &sd[off + 32], 8);
2948+- u64 = le64toh(u64);
2949+- if (u64 == 0xffffffffffffffff) {
2950+- printf("Quota Limit NO LIMIT\n");
2951+- } else {
2952+- printf("Quota Limit %" PRIu64 "\n", u64);
2953+- }
2954+-
2955+- printf("SID: S-1");
2956+- u64 = 0;
2957+- for (i = 0; i < 6; i++)
2958+- u64 = (u64 << 8) | sd[off + 42 + i];
2959+- printf("-%" PRIu64, u64);
2960+-
2961+- for (i = 0; i < sd[off + 41]; i++) {
2962+- memcpy(&u32, &sd[off + 48 + 4 * i], 4);
2963+- u32 = le32toh(u32);
2964+- printf("-%u", u32);
2965+- }
2966+- printf("\n\n");
2967+- off += neo;
2968+-
2969+- if (neo != 0) {
2970+- goto one_more;
2971+- }
2972++ uint32_t u32, neo;
2973++ uint64_t u64;
2974++ struct timeval tv;
2975++ struct tm;
2976++ int i, off = 0;
2977++
2978++one_more:
2979++ memcpy(&u32, &sd[off], 4);
2980++ neo = le32toh(u32);
2981++
2982++ memcpy(&u32, &sd[off + 4], 4);
2983++ u32 = le32toh(u32);
2984++ printf("SID Length %d\n", u32);
2985++
2986++ memcpy(&u64, &sd[off + 8], 8);
2987++ win_to_timeval(le64toh(u64), &tv);
2988++ printf("Change Time %s", ctime(&tv.tv_sec));
2989++
2990++ memcpy(&u64, &sd[off + 16], 8);
2991++ u64 = le32toh(u64);
2992++ printf("Quota Used %" PRIu64 "\n", u64);
2993++
2994++ memcpy(&u64, &sd[off + 24], 8);
2995++ u64 = le64toh(u64);
2996++ if (u64 == 0xffffffffffffffff)
2997++ printf("Quota Threshold NO THRESHOLD\n");
2998++ else
2999++ printf("Quota Threshold %" PRIu64 "\n", u64);
3000++
3001++ memcpy(&u64, &sd[off + 32], 8);
3002++ u64 = le64toh(u64);
3003++ if (u64 == 0xffffffffffffffff)
3004++ printf("Quota Limit NO LIMIT\n");
3005++ else
3006++ printf("Quota Limit %" PRIu64 "\n", u64);
3007++
3008++ printf("SID: S-1");
3009++ u64 = 0;
3010++ for (i = 0; i < 6; i++)
3011++ u64 = (u64 << 8) | sd[off + 42 + i];
3012++ printf("-%" PRIu64, u64);
3013++
3014++ for (i = 0; i < sd[off + 41]; i++) {
3015++ memcpy(&u32, &sd[off + 48 + 4 * i], 4);
3016++ u32 = le32toh(u32);
3017++ printf("-%u", u32);
3018++ }
3019++ printf("\n\n");
3020++ off += neo;
3021++
3022++ if (neo != 0)
3023++ goto one_more;
3024+ }
3025+
3026+ static void
3027+ quota(int f)
3028+ {
3029+- struct smb_query_info *qi;
3030+- char *buf;
3031+- int i;
3032++ struct smb_query_info *qi;
3033++ char *buf;
3034++ int i;
3035+
3036+- qi = malloc(sizeof(struct smb_query_info) + 16384);
3037+- memset(qi, 0, sizeof(struct smb_query_info) + 16384);
3038+- qi->info_type = 0x04;
3039+- qi->file_info_class = 0;
3040+- qi->additional_information = 0; /* Owner, Group, Dacl */
3041+- qi->input_buffer_length = 16384;
3042++ qi = malloc(sizeof(struct smb_query_info) + 16384);
3043++ memset(qi, 0, sizeof(struct smb_query_info) + 16384);
3044++ qi->info_type = 0x04;
3045++ qi->file_info_class = 0;
3046++ qi->additional_information = 0; /* Owner, Group, Dacl */
3047++ qi->input_buffer_length = 16384;
3048+
3049+- buf = (char *)&qi[1];
3050+- buf[0] = 0; /* return single */
3051+- buf[1] = 1; /* restart scan */
3052++ buf = (char *)&qi[1];
3053++ buf[0] = 0; /* return single */
3054++ buf[1] = 1; /* restart scan */
3055+
3056+- /* sid list length */
3057+- i = 0;
3058+- memcpy(&buf[4], &i, 4);
3059++ /* sid list length */
3060++ i = 0;
3061++ memcpy(&buf[4], &i, 4);
3062+
3063+- qi->output_buffer_length = 16;
3064++ qi->output_buffer_length = 16;
3065+
3066+- if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
3067+- fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
3068+- exit(1);
3069+- }
3070++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
3071++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
3072++ exit(1);
3073++ }
3074+
3075+- print_quota((unsigned char *)(&qi[1]));
3076+- free(qi);
3077++ print_quota((unsigned char *)(&qi[1]));
3078++ free(qi);
3079+ }
3080+
3081+ int main(int argc, char *argv[])
3082+ {
3083+- int c;
3084+- int f;
3085++ int c;
3086++ int f;
3087+
3088+- while ((c = getopt_long(argc, argv, "vV", NULL, NULL)) != -1) {
3089+- switch (c) {
3090+- case 'v':
3091+- printf("smbinfo version %s\n", VERSION);
3092+- return 0;
3093+- case 'V':
3094++ while ((c = getopt_long(argc, argv, "vV", NULL, NULL)) != -1) {
3095++ switch (c) {
3096++ case 'v':
3097++ printf("smbinfo version %s\n", VERSION);
3098++ return 0;
3099++ case 'V':
3100+ verbose = 1;
3101+ break;
3102+- default:
3103+- usage(argv[0]);
3104+- }
3105+- }
3106+-
3107+- if (optind >= argc - 1)
3108+- usage(argv[0]);
3109+-
3110+- if ((f = open(argv[optind + 1], O_RDONLY)) < 0) {
3111+- fprintf(stderr, "Failed to open %s\n", argv[optind + 1]);
3112+- exit(1);
3113+- }
3114+-
3115+-
3116+- if (!strcmp(argv[optind], "fileaccessinfo"))
3117+- fileaccessinfo(f);
3118+- else if (!strcmp(argv[optind], "filealigninfo"))
3119+- filealigninfo(f);
3120+- else if (!strcmp(argv[optind], "fileallinfo"))
3121+- fileallinfo(f);
3122+- else if (!strcmp(argv[optind], "filebasicinfo"))
3123+- filebasicinfo(f);
3124+- else if (!strcmp(argv[optind], "fileeainfo"))
3125+- fileeainfo(f);
3126+- else if (!strcmp(argv[optind], "filefsfullsizeinfo"))
3127+- filefsfullsizeinfo(f);
3128+- else if (!strcmp(argv[optind], "fileinternalinfo"))
3129+- fileinternalinfo(f);
3130+- else if (!strcmp(argv[optind], "filemodeinfo"))
3131+- filemodeinfo(f);
3132+- else if (!strcmp(argv[optind], "filepositioninfo"))
3133+- filepositioninfo(f);
3134+- else if (!strcmp(argv[optind], "filestandardinfo"))
3135+- filestandardinfo(f);
3136+- else if (!strcmp(argv[optind], "secdesc"))
3137+- secdesc(f);
3138+- else if (!strcmp(argv[optind], "quota"))
3139+- quota(f);
3140+- else {
3141+- fprintf(stderr, "Unknown command %s\n", argv[optind]);
3142+- exit(1);
3143+- }
3144+-
3145+-
3146+- close(f);
3147+- return 0;
3148++ default:
3149++ usage(argv[0]);
3150++ }
3151++ }
3152++
3153++ if (optind >= argc - 1)
3154++ usage(argv[0]);
3155++
3156++ if ((f = open(argv[optind + 1], O_RDONLY)) < 0) {
3157++ fprintf(stderr, "Failed to open %s\n", argv[optind + 1]);
3158++ exit(1);
3159++ }
3160++
3161++ if (!strcmp(argv[optind], "fileaccessinfo"))
3162++ fileaccessinfo(f);
3163++ else if (!strcmp(argv[optind], "filealigninfo"))
3164++ filealigninfo(f);
3165++ else if (!strcmp(argv[optind], "fileallinfo"))
3166++ fileallinfo(f);
3167++ else if (!strcmp(argv[optind], "filebasicinfo"))
3168++ filebasicinfo(f);
3169++ else if (!strcmp(argv[optind], "fileeainfo"))
3170++ fileeainfo(f);
3171++ else if (!strcmp(argv[optind], "filefsfullsizeinfo"))
3172++ filefsfullsizeinfo(f);
3173++ else if (!strcmp(argv[optind], "fileinternalinfo"))
3174++ fileinternalinfo(f);
3175++ else if (!strcmp(argv[optind], "filemodeinfo"))
3176++ filemodeinfo(f);
3177++ else if (!strcmp(argv[optind], "filepositioninfo"))
3178++ filepositioninfo(f);
3179++ else if (!strcmp(argv[optind], "filestandardinfo"))
3180++ filestandardinfo(f);
3181++ else if (!strcmp(argv[optind], "secdesc"))
3182++ secdesc(f);
3183++ else if (!strcmp(argv[optind], "quota"))
3184++ quota(f);
3185++ else {
3186++ fprintf(stderr, "Unknown command %s\n", argv[optind]);
3187++ exit(1);
3188++ }
3189++
3190++ close(f);
3191++ return 0;
3192+ }
3193+--
3194+2.17.1
3195+
3196diff --git a/debian/patches/0009-smbinfo-add-fsctl-getobjid-support.patch b/debian/patches/0009-smbinfo-add-fsctl-getobjid-support.patch
3197new file mode 100644
3198index 0000000..c015058
3199--- /dev/null
3200+++ b/debian/patches/0009-smbinfo-add-fsctl-getobjid-support.patch
3201@@ -0,0 +1,131 @@
3202+From fb33ba335325020d4f42985491f2f98eddffc165 Mon Sep 17 00:00:00 2001
3203+From: Ronnie Sahlberg <lsahlber@redhat.com>
3204+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=fb33ba335325020d4f42985491f2f98eddffc165
3205+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3206+Date: Fri, 15 Mar 2019 16:22:15 +1000
3207+Subject: [PATCH] smbinfo: add fsctl-getobjid support
3208+
3209+This will print the ObjectID buffer for the object.
3210+This is an example on how to fetch FSCTL data for an object using
3211+the passthrough API.
3212+
3213+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
3214+---
3215+ smbinfo.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3216+ smbinfo.rst | 2 ++
3217+ 2 files changed, 75 insertions(+)
3218+
3219+diff --git a/smbinfo.c b/smbinfo.c
3220+index d7e7bf3..268114b 100644
3221+--- a/smbinfo.c
3222++++ b/smbinfo.c
3223+@@ -39,6 +39,11 @@
3224+ #include <inttypes.h>
3225+
3226+ #define CIFS_IOCTL_MAGIC 0xCF
3227++
3228++/* query_info flags */
3229++#define PASSTHRU_QUERY_INFO 0x00000000
3230++#define PASSTHRU_FSCTL 0x00000001
3231++
3232+ struct smb_query_info {
3233+ uint32_t info_type;
3234+ uint32_t file_info_class;
3235+@@ -167,6 +172,72 @@ print_bits(uint32_t mask, struct bit_string *bs)
3236+ printf(" ");
3237+ }
3238+
3239++static void
3240++print_guid(uint8_t *sd)
3241++{
3242++ uint32_t u32;
3243++ uint16_t u16;
3244++ int i;
3245++
3246++ memcpy(&u32, &sd[0], 4);
3247++ printf("%08x-", le32toh(u32));
3248++
3249++ memcpy(&u16, &sd[4], 2);
3250++ printf("%04x-", le16toh(u16));
3251++
3252++ memcpy(&u16, &sd[6], 2);
3253++ printf("%04x-", le16toh(u16));
3254++
3255++ printf("%02x%02x-", sd[8], sd[9]);
3256++ for (i = 0; i < 6; i++)
3257++ printf("%02x", sd[10 + i]);
3258++}
3259++
3260++static void
3261++print_objidbuf(uint8_t *sd)
3262++{
3263++ printf("Object-ID: ");
3264++ print_guid(&sd[0]);
3265++ printf("\n");
3266++
3267++ printf("Birth-Volume-ID: ");
3268++ print_guid(&sd[16]);
3269++ printf("\n");
3270++
3271++ printf("Birth-Object-ID: ");
3272++ print_guid(&sd[32]);
3273++ printf("\n");
3274++
3275++ printf("Domain-ID: ");
3276++ print_guid(&sd[48]);
3277++ printf("\n");
3278++}
3279++
3280++static void
3281++fsctlgetobjid(int f)
3282++{
3283++ struct smb_query_info *qi;
3284++ struct stat st;
3285++
3286++ fstat(f, &st);
3287++
3288++ qi = malloc(sizeof(struct smb_query_info) + 64);
3289++ memset(qi, 0, sizeof(qi) + 64);
3290++ qi->info_type = 0x9009c;
3291++ qi->file_info_class = 0;
3292++ qi->additional_information = 0;
3293++ qi->input_buffer_length = 64;
3294++ qi->flags = PASSTHRU_FSCTL;
3295++
3296++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
3297++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
3298++ exit(1);
3299++ }
3300++ print_objidbuf((uint8_t *)(&qi[1]));
3301++
3302++ free(qi);
3303++}
3304++
3305+ static void
3306+ print_fileaccessinfo(uint8_t *sd, int type)
3307+ {
3308+@@ -943,6 +1014,8 @@ int main(int argc, char *argv[])
3309+ secdesc(f);
3310+ else if (!strcmp(argv[optind], "quota"))
3311+ quota(f);
3312++ else if (!strcmp(argv[1], "fsctl-getobjid"))
3313++ fsctlgetobjid(f);
3314+ else {
3315+ fprintf(stderr, "Unknown command %s\n", argv[optind]);
3316+ exit(1);
3317+diff --git a/smbinfo.rst b/smbinfo.rst
3318+index 9bfd313..fd7f0ff 100644
3319+--- a/smbinfo.rst
3320++++ b/smbinfo.rst
3321+@@ -62,6 +62,8 @@ COMMAND
3322+
3323+ `filestandardinfo`: Prints the FileStandardInformation class
3324+
3325++`fsctl-getobjid`: Prints the ObjectID
3326++
3327+ `quota`: Print the quota for the volume in the form
3328+ - SID Length
3329+ - Change Time
3330+--
3331+2.17.1
3332+
3333diff --git a/debian/patches/0010-smbinfo-missing-help-for-fsctl-getobjid.patch b/debian/patches/0010-smbinfo-missing-help-for-fsctl-getobjid.patch
3334new file mode 100644
3335index 0000000..3d09e4c
3336--- /dev/null
3337+++ b/debian/patches/0010-smbinfo-missing-help-for-fsctl-getobjid.patch
3338@@ -0,0 +1,34 @@
3339+From 49eb190518c5000d48c929b21304edd2e8522ea6 Mon Sep 17 00:00:00 2001
3340+From: Steve French <stfrench@microsoft.com>
3341+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=49eb190518c5000d48c929b21304edd2e8522ea6
3342+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3343+Date: Sat, 16 Mar 2019 15:42:40 -0500
3344+Subject: [PATCH] smbinfo: missing help for fsctl-getobjid
3345+
3346+Add usage description for new option fsctl-getobjid
3347+
3348+See section 2.1.3.1 of MS-FSCC
3349+
3350+Signed-off-by: Steve French <stfrench@microsoft.com>
3351+---
3352+ smbinfo.c | 4 +++-
3353+ 1 file changed, 3 insertions(+), 1 deletion(-)
3354+
3355+diff --git a/smbinfo.c b/smbinfo.c
3356+index 268114b..33fca95 100644
3357+--- a/smbinfo.c
3358++++ b/smbinfo.c
3359+@@ -88,7 +88,9 @@ usage(char *name)
3360+ " secdesc:\n"
3361+ " Prints the security descriptor for a cifs file.\n"
3362+ " quota:\n"
3363+- " Prints the quota for a cifs file.\n",
3364++ " Prints the quota for a cifs file.\n"
3365++ " fsctl-getobjid:\n"
3366++ " Prints the objectid of the file and GUID of the underlying volume.\n",
3367+ name);
3368+ exit(1);
3369+ }
3370+--
3371+2.17.1
3372+
3373diff --git a/debian/patches/0011-smbinfo-Add-ability-to-query-snapshots-previous-vers.patch b/debian/patches/0011-smbinfo-Add-ability-to-query-snapshots-previous-vers.patch
3374new file mode 100644
3375index 0000000..81be456
3376--- /dev/null
3377+++ b/debian/patches/0011-smbinfo-Add-ability-to-query-snapshots-previous-vers.patch
3378@@ -0,0 +1,173 @@
3379+From 74ae05342aeb0abe94f1ab9adfdecbbb6ce16dcb Mon Sep 17 00:00:00 2001
3380+From: Steve French <stfrench@microsoft.com>
3381+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=74ae05342aeb0abe94f1ab9adfdecbbb6ce16dcb
3382+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3383+Date: Fri, 29 Mar 2019 03:05:55 -0500
3384+Subject: [PATCH] smbinfo: Add ability to query snapshots (previous versions)
3385+
3386+ "smbinfo list-snapshots"
3387+
3388+Signed-off-by: Steve French <stfrench@microsoft.com>
3389+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
3390+Reviewed-by: Paulo Alcantara <palcantara@suse.de>
3391+---
3392+ smbinfo.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++-
3393+ smbinfo.rst | 2 +
3394+ 2 files changed, 109 insertions(+), 1 deletion(-)
3395+
3396+diff --git a/smbinfo.c b/smbinfo.c
3397+index 33fca95..adfd85e 100644
3398+--- a/smbinfo.c
3399++++ b/smbinfo.c
3400+@@ -89,6 +89,8 @@ usage(char *name)
3401+ " Prints the security descriptor for a cifs file.\n"
3402+ " quota:\n"
3403+ " Prints the quota for a cifs file.\n"
3404++ " list-snapshots:\n"
3405++ " List the previous versions of the volume that backs this file.\n"
3406+ " fsctl-getobjid:\n"
3407+ " Prints the objectid of the file and GUID of the underlying volume.\n",
3408+ name);
3409+@@ -882,7 +884,6 @@ print_quota(unsigned char *sd)
3410+ uint32_t u32, neo;
3411+ uint64_t u64;
3412+ struct timeval tv;
3413+- struct tm;
3414+ int i, off = 0;
3415+
3416+ one_more:
3417+@@ -966,6 +967,109 @@ quota(int f)
3418+ free(qi);
3419+ }
3420+
3421++
3422++struct smb_snapshot_array {
3423++ int32_t number_of_snapshots;
3424++ int32_t number_of_snapshots_returned;
3425++ int32_t snapshot_array_size;
3426++ char snapshot_data[0];
3427++};
3428++
3429++
3430++#define GMT_NAME_LEN 24 /* length of a @GMT- name */
3431++#define GMT_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
3432++
3433++#define NTFS_TIME_OFFSET ((unsigned long long)(369*365 + 89) * 24 * 3600 * 10000000)
3434++
3435++static void print_snapshots(struct smb_snapshot_array *psnap)
3436++{
3437++ int current_snapshot_entry = 0;
3438++ char gmt_token[GMT_NAME_LEN + 1] = {0};
3439++ int i;
3440++ int j = 0;
3441++ struct tm tm;
3442++ unsigned long long dce_time;
3443++
3444++ printf("Number of snapshots: %d Number of snapshots returned: %d\n",
3445++ psnap->number_of_snapshots,
3446++ psnap->number_of_snapshots_returned);
3447++ printf("Snapshot list in GMT (Coordinated UTC Time) and SMB format (100 nanosecond units needed for snapshot mounts):");
3448++ for (i = 0; i < psnap->snapshot_array_size; i++) {
3449++ if (psnap->snapshot_data[i] == '@') {
3450++ j = 0;
3451++ current_snapshot_entry++;
3452++ printf("\n%d) GMT:", current_snapshot_entry);
3453++ }
3454++ if (psnap->snapshot_data[i] != 0) {
3455++ gmt_token[j] = psnap->snapshot_data[i];
3456++ j++;
3457++ }
3458++ if (j == GMT_NAME_LEN) {
3459++ printf("%s", gmt_token);
3460++ j = 0;
3461++ strptime(gmt_token, GMT_FORMAT, &tm);
3462++ dce_time = timegm(&tm) * 10000000 + NTFS_TIME_OFFSET;
3463++ printf("\n SMB3:%llu", dce_time);
3464++ }
3465++ }
3466++ printf("\n");
3467++}
3468++
3469++#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
3470++
3471++#define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */
3472++
3473++static void
3474++list_snapshots(int f)
3475++{
3476++
3477++ struct smb_snapshot_array snap_inf;
3478++ struct smb_snapshot_array *buf;
3479++
3480++ /*
3481++ * When first field in structure we pass in here is zero, cifs.ko can
3482++ * recognize that this is the first query and that it must set the SMB3
3483++ * FSCTL response buffer size (in the request) to exactly 16 bytes
3484++ * (which is required by some servers to process the initial query)
3485++ */
3486++ snap_inf.number_of_snapshots = 0;
3487++ snap_inf.number_of_snapshots_returned = 0;
3488++ snap_inf.snapshot_array_size = sizeof(struct smb_snapshot_array);
3489++
3490++ /* Query the number of snapshots so we know how much to allocate */
3491++ if (ioctl(f, CIFS_ENUMERATE_SNAPSHOTS, &snap_inf) < 0) {
3492++ fprintf(stderr, "Querying snapshots failed with %s\n", strerror(errno));
3493++ exit(1);
3494++ }
3495++
3496++ if (snap_inf.number_of_snapshots == 0)
3497++ return;
3498++
3499++ /* Now that we know the size, query the list from the server */
3500++
3501++ buf = malloc(snap_inf.snapshot_array_size + MIN_SNAPSHOT_ARRAY_SIZE);
3502++
3503++ if (buf == NULL) {
3504++ printf("Failed, out of memory.\n");
3505++ exit(1);
3506++ }
3507++ /*
3508++ * first parm is non-zero which allows cifs.ko to recognize that this is
3509++ * the second query (it has to set response buf size larger)
3510++ */
3511++ buf->number_of_snapshots = snap_inf.number_of_snapshots;
3512++
3513++ buf->snapshot_array_size = snap_inf.snapshot_array_size;
3514++
3515++ if (ioctl(f, CIFS_ENUMERATE_SNAPSHOTS, buf) < 0) {
3516++ fprintf(stderr, "Querying snapshots failed with %s\n", strerror(errno));
3517++ exit(1);
3518++ }
3519++
3520++ print_snapshots(buf);
3521++ free(buf);
3522++}
3523++
3524+ int main(int argc, char *argv[])
3525+ {
3526+ int c;
3527+@@ -1016,6 +1120,8 @@ int main(int argc, char *argv[])
3528+ secdesc(f);
3529+ else if (!strcmp(argv[optind], "quota"))
3530+ quota(f);
3531++ else if (!strcmp(argv[optind], "list-snapshots"))
3532++ list_snapshots(f);
3533+ else if (!strcmp(argv[1], "fsctl-getobjid"))
3534+ fsctlgetobjid(f);
3535+ else {
3536+diff --git a/smbinfo.rst b/smbinfo.rst
3537+index fd7f0ff..0c96050 100644
3538+--- a/smbinfo.rst
3539++++ b/smbinfo.rst
3540+@@ -64,6 +64,8 @@ COMMAND
3541+
3542+ `fsctl-getobjid`: Prints the ObjectID
3543+
3544++`list-snapshots`: Lists the previous versions of the volume that backs this file
3545++
3546+ `quota`: Print the quota for the volume in the form
3547+ - SID Length
3548+ - Change Time
3549+--
3550+2.17.1
3551+
3552diff --git a/debian/patches/0012-smbinfo-make-argument-order-consistent.patch b/debian/patches/0012-smbinfo-make-argument-order-consistent.patch
3553new file mode 100644
3554index 0000000..9b0b841
3555--- /dev/null
3556+++ b/debian/patches/0012-smbinfo-make-argument-order-consistent.patch
3557@@ -0,0 +1,62 @@
3558+From 98907475550ecd459cb6eae9787c53b7e032448d Mon Sep 17 00:00:00 2001
3559+From: Pavel Shilovsky <pshilov@microsoft.com>
3560+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=98907475550ecd459cb6eae9787c53b7e032448d
3561+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3562+Date: Tue, 2 Apr 2019 11:40:40 -0700
3563+Subject: [PATCH] smbinfo: make argument order consistent
3564+
3565+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
3566+Reviewed-by: Paulo Alcantara <palcantara@suse.de>
3567+---
3568+ smbinfo.c | 24 ++++++++++++------------
3569+ 1 file changed, 12 insertions(+), 12 deletions(-)
3570+
3571+diff --git a/smbinfo.c b/smbinfo.c
3572+index adfd85e..f9de7fd 100644
3573+--- a/smbinfo.c
3574++++ b/smbinfo.c
3575+@@ -85,14 +85,14 @@ usage(char *name)
3576+ " Prints FilePositionInfo for a cifs file.\n"
3577+ " filestandardinfo:\n"
3578+ " Prints FileStandardInfo for a cifs file.\n"
3579+- " secdesc:\n"
3580+- " Prints the security descriptor for a cifs file.\n"
3581+- " quota:\n"
3582+- " Prints the quota for a cifs file.\n"
3583++ " fsctl-getobjid:\n"
3584++ " Prints the objectid of the file and GUID of the underlying volume.\n"
3585+ " list-snapshots:\n"
3586+ " List the previous versions of the volume that backs this file.\n"
3587+- " fsctl-getobjid:\n"
3588+- " Prints the objectid of the file and GUID of the underlying volume.\n",
3589++ " quota:\n"
3590++ " Prints the quota for a cifs file.\n"
3591++ " secdesc:\n"
3592++ " Prints the security descriptor for a cifs file.\n",
3593+ name);
3594+ exit(1);
3595+ }
3596+@@ -1116,14 +1116,14 @@ int main(int argc, char *argv[])
3597+ filepositioninfo(f);
3598+ else if (!strcmp(argv[optind], "filestandardinfo"))
3599+ filestandardinfo(f);
3600+- else if (!strcmp(argv[optind], "secdesc"))
3601+- secdesc(f);
3602+- else if (!strcmp(argv[optind], "quota"))
3603+- quota(f);
3604++ else if (!strcmp(argv[optind], "fsctl-getobjid"))
3605++ fsctlgetobjid(f);
3606+ else if (!strcmp(argv[optind], "list-snapshots"))
3607+ list_snapshots(f);
3608+- else if (!strcmp(argv[1], "fsctl-getobjid"))
3609+- fsctlgetobjid(f);
3610++ else if (!strcmp(argv[optind], "quota"))
3611++ quota(f);
3612++ else if (!strcmp(argv[optind], "secdesc"))
3613++ secdesc(f);
3614+ else {
3615+ fprintf(stderr, "Unknown command %s\n", argv[optind]);
3616+ exit(1);
3617+--
3618+2.17.1
3619+
3620diff --git a/debian/patches/0013-smbinfo-use-constant-for-input-buffer-length.patch b/debian/patches/0013-smbinfo-use-constant-for-input-buffer-length.patch
3621new file mode 100644
3622index 0000000..f42901d
3623--- /dev/null
3624+++ b/debian/patches/0013-smbinfo-use-constant-for-input-buffer-length.patch
3625@@ -0,0 +1,35 @@
3626+From aee01e0e61837fc8eb273039c5d1e11634b2e56a Mon Sep 17 00:00:00 2001
3627+From: Pavel Shilovsky <pshilov@microsoft.com>
3628+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=aee01e0e61837fc8eb273039c5d1e11634b2e56a
3629+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3630+Date: Fri, 5 Apr 2019 10:01:48 -0700
3631+Subject: [PATCH] smbinfo: use constant for input buffer length
3632+
3633+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
3634+---
3635+ smbinfo.c | 6 +++---
3636+ 1 file changed, 3 insertions(+), 3 deletions(-)
3637+
3638+diff --git a/smbinfo.c b/smbinfo.c
3639+index f9de7fd..4bc503a 100644
3640+--- a/smbinfo.c
3641++++ b/smbinfo.c
3642+@@ -941,12 +941,12 @@ quota(int f)
3643+ char *buf;
3644+ int i;
3645+
3646+- qi = malloc(sizeof(struct smb_query_info) + 16384);
3647+- memset(qi, 0, sizeof(struct smb_query_info) + 16384);
3648++ qi = malloc(sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
3649++ memset(qi, 0, sizeof(struct smb_query_info) + INPUT_BUFFER_LENGTH);
3650+ qi->info_type = 0x04;
3651+ qi->file_info_class = 0;
3652+ qi->additional_information = 0; /* Owner, Group, Dacl */
3653+- qi->input_buffer_length = 16384;
3654++ qi->input_buffer_length = INPUT_BUFFER_LENGTH;
3655+
3656+ buf = (char *)&qi[1];
3657+ buf[0] = 0; /* return single */
3658+--
3659+2.17.1
3660+
3661diff --git a/debian/patches/0014-smbinfo-Improve-help-usage-and-add-h-option.patch b/debian/patches/0014-smbinfo-Improve-help-usage-and-add-h-option.patch
3662new file mode 100644
3663index 0000000..0d5231c
3664--- /dev/null
3665+++ b/debian/patches/0014-smbinfo-Improve-help-usage-and-add-h-option.patch
3666@@ -0,0 +1,108 @@
3667+From 12c2f088fa3d666fc5aa48a700e740523d8d2023 Mon Sep 17 00:00:00 2001
3668+From: Kenneth D'souza <kdsouza@redhat.com>
3669+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=12c2f088fa3d666fc5aa48a700e740523d8d2023
3670+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3671+Date: Wed, 17 Apr 2019 15:36:46 +0530
3672+Subject: [PATCH] smbinfo: Improve help usage and add -h option.
3673+
3674+Call usage only for -h case. This avoids cluttering the screen with long
3675+help output.
3676+As we are adding more options to the utility, the end error is just hidden.
3677+Call short_usage wherever necessary.
3678+
3679+Signed-off-by: Kenneth D'souza <kdsouza@redhat.com>
3680+---
3681+ smbinfo.c | 27 ++++++++++++++++++++++-----
3682+ smbinfo.rst | 5 ++++-
3683+ 2 files changed, 26 insertions(+), 6 deletions(-)
3684+
3685+diff --git a/smbinfo.c b/smbinfo.c
3686+index 4bc503a..6e258c2 100644
3687+--- a/smbinfo.c
3688++++ b/smbinfo.c
3689+@@ -64,6 +64,8 @@ usage(char *name)
3690+ {
3691+ fprintf(stderr, "Usage: %s [-V] <command> <file>\n"
3692+ "-V for verbose output\n"
3693++ "-h display this help text\n"
3694++ "-v print smbinfo version\n"
3695+ "Commands are\n"
3696+ " fileaccessinfo:\n"
3697+ " Prints FileAccessInfo for a cifs file.\n"
3698+@@ -97,6 +99,14 @@ usage(char *name)
3699+ exit(1);
3700+ }
3701+
3702++static void
3703++short_usage(char *name)
3704++{
3705++ fprintf(stderr, "Usage: %s [-v] [-V] <command> <file>\n"
3706++ "Try 'smbinfo -h' for more information.\n", name);
3707++ exit(1);
3708++}
3709++
3710+ static void
3711+ win_to_timeval(uint64_t smb2_time, struct timeval *tv)
3712+ {
3713+@@ -1075,7 +1085,11 @@ int main(int argc, char *argv[])
3714+ int c;
3715+ int f;
3716+
3717+- while ((c = getopt_long(argc, argv, "vV", NULL, NULL)) != -1) {
3718++ if (argc < 2) {
3719++ short_usage(argv[0]);
3720++ }
3721++
3722++ while ((c = getopt_long(argc, argv, "vVh", NULL, NULL)) != -1) {
3723+ switch (c) {
3724+ case 'v':
3725+ printf("smbinfo version %s\n", VERSION);
3726+@@ -1083,15 +1097,18 @@ int main(int argc, char *argv[])
3727+ case 'V':
3728+ verbose = 1;
3729+ break;
3730+- default:
3731++ case 'h':
3732+ usage(argv[0]);
3733++ break;
3734++ default:
3735++ short_usage(argv[0]);
3736+ }
3737+ }
3738+
3739+- if (optind >= argc - 1)
3740+- usage(argv[0]);
3741++ if (optind >= argc -1)
3742++ short_usage(argv[0]);
3743+
3744+- if ((f = open(argv[optind + 1], O_RDONLY)) < 0) {
3745++ if ((f = open(argv[optind + 1 ], O_RDONLY)) < 0) {
3746+ fprintf(stderr, "Failed to open %s\n", argv[optind + 1]);
3747+ exit(1);
3748+ }
3749+diff --git a/smbinfo.rst b/smbinfo.rst
3750+index 0c96050..be4c829 100644
3751+--- a/smbinfo.rst
3752++++ b/smbinfo.rst
3753+@@ -11,7 +11,7 @@ Userspace helper to display SMB-specific file information for the Linux SMB clie
3754+ SYNOPSIS
3755+ ********
3756+
3757+- smbinfo [-v] [-V] {command} {file system object}
3758++ smbinfo [-v] [-h] [-V] {command} {file system object}
3759+
3760+ ***********
3761+ DESCRIPTION
3762+@@ -38,6 +38,9 @@ OPTIONS
3763+ -V
3764+ Verbose output.
3765+
3766++-h
3767++ Print help explaining the command line options.
3768++
3769+ *******
3770+ COMMAND
3771+ *******
3772+--
3773+2.17.1
3774+
3775diff --git a/debian/patches/0015-smbinfo-add-GETCOMPRESSION-support.patch b/debian/patches/0015-smbinfo-add-GETCOMPRESSION-support.patch
3776new file mode 100644
3777index 0000000..e16aba5
3778--- /dev/null
3779+++ b/debian/patches/0015-smbinfo-add-GETCOMPRESSION-support.patch
3780@@ -0,0 +1,102 @@
3781+From 1e4fca25948d52fc29410963663f3af72275bcb6 Mon Sep 17 00:00:00 2001
3782+From: Ronnie Sahlberg <lsahlber@redhat.com>
3783+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=1e4fca25948d52fc29410963663f3af72275bcb6
3784+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3785+Date: Thu, 11 Apr 2019 12:23:06 +1000
3786+Subject: [PATCH] smbinfo: add GETCOMPRESSION support
3787+
3788+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
3789+---
3790+ smbinfo.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
3791+ smbinfo.rst | 2 ++
3792+ 2 files changed, 50 insertions(+)
3793+
3794+diff --git a/smbinfo.c b/smbinfo.c
3795+index 6e258c2..b4d497b 100644
3796+--- a/smbinfo.c
3797++++ b/smbinfo.c
3798+@@ -89,6 +89,8 @@ usage(char *name)
3799+ " Prints FileStandardInfo for a cifs file.\n"
3800+ " fsctl-getobjid:\n"
3801+ " Prints the objectid of the file and GUID of the underlying volume.\n"
3802++ " getcompression:\n"
3803++ " Prints the compression setting for the file.\n"
3804+ " list-snapshots:\n"
3805+ " List the previous versions of the volume that backs this file.\n"
3806+ " quota:\n"
3807+@@ -252,6 +254,50 @@ fsctlgetobjid(int f)
3808+ free(qi);
3809+ }
3810+
3811++static void
3812++print_getcompression(uint8_t *sd)
3813++{
3814++ uint16_t u16;
3815++
3816++ memcpy(&u16, &sd[0], 2);
3817++ u16 = le16toh(u16);
3818++
3819++ printf("Compression: ");
3820++ switch (u16) {
3821++ case 0:
3822++ printf("(0) NONE\n");
3823++ break;
3824++ case 2:
3825++ printf("(2) LZNT1\n");
3826++ break;
3827++ default:
3828++ printf("(%d) UNKNOWN\n", u16);
3829++ break;
3830++ }
3831++}
3832++
3833++static void
3834++getcompression(int f)
3835++{
3836++ struct smb_query_info *qi;
3837++
3838++ qi = malloc(sizeof(struct smb_query_info) + 2);
3839++ memset(qi, 0, sizeof(qi) + 2);
3840++ qi->info_type = 0x9003c;
3841++ qi->file_info_class = 0;
3842++ qi->additional_information = 0;
3843++ qi->input_buffer_length = 2;
3844++ qi->flags = PASSTHRU_FSCTL;
3845++
3846++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
3847++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
3848++ exit(1);
3849++ }
3850++ print_getcompression((uint8_t *)(&qi[1]));
3851++
3852++ free(qi);
3853++}
3854++
3855+ static void
3856+ print_fileaccessinfo(uint8_t *sd, int type)
3857+ {
3858+@@ -1135,6 +1181,8 @@ int main(int argc, char *argv[])
3859+ filestandardinfo(f);
3860+ else if (!strcmp(argv[optind], "fsctl-getobjid"))
3861+ fsctlgetobjid(f);
3862++ else if (!strcmp(argv[optind], "getcompression"))
3863++ getcompression(f);
3864+ else if (!strcmp(argv[optind], "list-snapshots"))
3865+ list_snapshots(f);
3866+ else if (!strcmp(argv[optind], "quota"))
3867+diff --git a/smbinfo.rst b/smbinfo.rst
3868+index be4c829..500ce0e 100644
3869+--- a/smbinfo.rst
3870++++ b/smbinfo.rst
3871+@@ -67,6 +67,8 @@ COMMAND
3872+
3873+ `fsctl-getobjid`: Prints the ObjectID
3874+
3875++`getcompression`: Prints the compression setting for the file.
3876++
3877+ `list-snapshots`: Lists the previous versions of the volume that backs this file
3878+
3879+ `quota`: Print the quota for the volume in the form
3880+--
3881+2.17.1
3882+
3883diff --git a/debian/patches/0016-smbinfo-print-the-security-information-needed-to-dec.patch b/debian/patches/0016-smbinfo-print-the-security-information-needed-to-dec.patch
3884new file mode 100644
3885index 0000000..909cf22
3886--- /dev/null
3887+++ b/debian/patches/0016-smbinfo-print-the-security-information-needed-to-dec.patch
3888@@ -0,0 +1,108 @@
3889+From 6df98da5cd3fbb33f6f535c6784f037bbadadb84 Mon Sep 17 00:00:00 2001
3890+From: Steve French <stfrench@microsoft.com>
3891+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=6df98da5cd3fbb33f6f535c6784f037bbadadb84
3892+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
3893+Date: Thu, 19 Sep 2019 04:21:16 -0500
3894+Subject: [PATCH] smbinfo: print the security information needed to decrypt
3895+ wireshark trace
3896+
3897+CCM encryption
3898+Session Id: e2 3e ea ae 00 00 00 00
3899+Session Key: 65 7e 0e d5 3c 06 5a 06 50 a3 ef 96 c1 64 3d 1f
3900+Server Encryption Key: 5e 42 a7 b5 57 75 d6 56 4a 5d 33 97 e6 45 07 76
3901+Server Decryption Key: 1f 64 db a3 0f 24 e3 4d b6 31 00 ab 9a af 22 47
3902+
3903+Signed-off-by: Steve French <stfrench@microsoft.com>
3904+---
3905+ smbinfo.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
3906+ 1 file changed, 52 insertions(+), 1 deletion(-)
3907+
3908+diff --git a/smbinfo.c b/smbinfo.c
3909+index b4d497b..2aa5eee 100644
3910+--- a/smbinfo.c
3911++++ b/smbinfo.c
3912+@@ -54,7 +54,17 @@ struct smb_query_info {
3913+ /* char buffer[]; */
3914+ } __packed;
3915+
3916++#define SMB3_SIGN_KEY_SIZE 16
3917++struct smb3_key_debug_info {
3918++ uint64_t Suid;
3919++ uint16_t cipher_type;
3920++ uint8_t auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */
3921++ uint8_t smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
3922++ uint8_t smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
3923++} __attribute__((packed));
3924++
3925+ #define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
3926++#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)
3927+ #define INPUT_BUFFER_LENGTH 16384
3928+
3929+ int verbose;
3930+@@ -96,7 +106,9 @@ usage(char *name)
3931+ " quota:\n"
3932+ " Prints the quota for a cifs file.\n"
3933+ " secdesc:\n"
3934+- " Prints the security descriptor for a cifs file.\n",
3935++ " Prints the security descriptor for a cifs file.\n"
3936++ " keys:\n"
3937++ " Prints the decryption information needed to view encrypted network traces.\n",
3938+ name);
3939+ exit(1);
3940+ }
3941+@@ -1071,6 +1083,43 @@ static void print_snapshots(struct smb_snapshot_array *psnap)
3942+ printf("\n");
3943+ }
3944+
3945++static void
3946++dump_keys(int f)
3947++{
3948++ struct smb3_key_debug_info keys_info;
3949++ uint8_t *psess_id;
3950++
3951++ if (ioctl(f, CIFS_DUMP_KEY, &keys_info) < 0) {
3952++ fprintf(stderr, "Querying keys information failed with %s\n", strerror(errno));
3953++ exit(1);
3954++ }
3955++
3956++ if (keys_info.cipher_type == 1)
3957++ printf("CCM encryption");
3958++ else if (keys_info.cipher_type == 2)
3959++ printf("GCM encryption");
3960++ else if (keys_info.cipher_type == 0)
3961++ printf("SMB3.0 CCM encryption");
3962++ else
3963++ printf("unknown encryption type");
3964++
3965++ printf("\nSession Id: ");
3966++ psess_id = (uint8_t *)&keys_info.Suid;
3967++ for (int i = 0; i < 8; i++)
3968++ printf(" %02x", psess_id[i]);
3969++
3970++ printf("\nSession Key: ");
3971++ for (int i = 0; i < 16; i++)
3972++ printf(" %02x", keys_info.auth_key[i]);
3973++ printf("\nServer Encryption Key: ");
3974++ for (int i = 0; i < SMB3_SIGN_KEY_SIZE; i++)
3975++ printf(" %02x", keys_info.smb3encryptionkey[i]);
3976++ printf("\nServer Decryption Key: ");
3977++ for (int i = 0; i < SMB3_SIGN_KEY_SIZE; i++)
3978++ printf(" %02x", keys_info.smb3decryptionkey[i]);
3979++ printf("\n");
3980++}
3981++
3982+ #define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
3983+
3984+ #define MIN_SNAPSHOT_ARRAY_SIZE 16 /* See MS-SMB2 section 3.3.5.15.1 */
3985+@@ -1189,6 +1238,8 @@ int main(int argc, char *argv[])
3986+ quota(f);
3987+ else if (!strcmp(argv[optind], "secdesc"))
3988+ secdesc(f);
3989++ else if (!strcmp(argv[optind], "keys"))
3990++ dump_keys(f);
3991+ else {
3992+ fprintf(stderr, "Unknown command %s\n", argv[optind]);
3993+ exit(1);
3994+--
3995+2.17.1
3996+
3997diff --git a/debian/patches/0017-smbinfo-Add-SETCOMPRESSION-support.patch b/debian/patches/0017-smbinfo-Add-SETCOMPRESSION-support.patch
3998new file mode 100644
3999index 0000000..7068b53
4000--- /dev/null
4001+++ b/debian/patches/0017-smbinfo-Add-SETCOMPRESSION-support.patch
4002@@ -0,0 +1,119 @@
4003+From 07c5812c062ac584511f244f91fcdfd5d08c8b68 Mon Sep 17 00:00:00 2001
4004+From: Ronnie Sahlberg <lsahlber@redhat.com>
4005+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=07c5812c062ac584511f244f91fcdfd5d08c8b68
4006+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
4007+Date: Fri, 4 Oct 2019 09:29:02 +1000
4008+Subject: [PATCH] smbinfo: Add SETCOMPRESSION support
4009+
4010+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
4011+---
4012+ smbinfo.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
4013+ smbinfo.rst | 2 ++
4014+ 2 files changed, 49 insertions(+), 1 deletion(-)
4015+
4016+diff --git a/smbinfo.c b/smbinfo.c
4017+index 2aa5eee..636f1bd 100644
4018+--- a/smbinfo.c
4019++++ b/smbinfo.c
4020+@@ -101,6 +101,8 @@ usage(char *name)
4021+ " Prints the objectid of the file and GUID of the underlying volume.\n"
4022+ " getcompression:\n"
4023+ " Prints the compression setting for the file.\n"
4024++ " setcompression <no|default|lznt1>:\n"
4025++ " Sets the compression level for the file.\n"
4026+ " list-snapshots:\n"
4027+ " List the previous versions of the volume that backs this file.\n"
4028+ " quota:\n"
4029+@@ -310,6 +312,30 @@ getcompression(int f)
4030+ free(qi);
4031+ }
4032+
4033++static void
4034++setcompression(int f, uint16_t level)
4035++{
4036++ struct smb_query_info *qi;
4037++
4038++ qi = malloc(sizeof(struct smb_query_info) + 2);
4039++ memset(qi, 0, sizeof(qi) + 2);
4040++ qi->info_type = 0x9c040;
4041++ qi->file_info_class = 0;
4042++ qi->additional_information = 0;
4043++ qi->output_buffer_length = 2;
4044++ qi->flags = PASSTHRU_FSCTL;
4045++
4046++ level = htole16(level);
4047++ memcpy(&qi[1], &level, 2);
4048++
4049++ if (ioctl(f, CIFS_QUERY_INFO, qi) < 0) {
4050++ fprintf(stderr, "ioctl failed with %s\n", strerror(errno));
4051++ exit(1);
4052++ }
4053++
4054++ free(qi);
4055++}
4056++
4057+ static void
4058+ print_fileaccessinfo(uint8_t *sd, int type)
4059+ {
4060+@@ -1175,17 +1201,35 @@ list_snapshots(int f)
4061+ free(buf);
4062+ }
4063+
4064++static int
4065++parse_compression(const char *arg)
4066++{
4067++ if (!strcmp(arg, "no"))
4068++ return 0;
4069++ else if (!strcmp(arg, "default"))
4070++ return 1;
4071++ else if (!strcmp(arg, "lznt1"))
4072++ return 2;
4073++
4074++ fprintf(stderr, "compression must be no|default|lznt1\n");
4075++ exit(10);
4076++}
4077++
4078+ int main(int argc, char *argv[])
4079+ {
4080+ int c;
4081+ int f;
4082++ int compression = 1;
4083+
4084+ if (argc < 2) {
4085+ short_usage(argv[0]);
4086+ }
4087+
4088+- while ((c = getopt_long(argc, argv, "vVh", NULL, NULL)) != -1) {
4089++ while ((c = getopt_long(argc, argv, "c:vVh", NULL, NULL)) != -1) {
4090+ switch (c) {
4091++ case 'c':
4092++ compression = parse_compression(optarg);
4093++ break;
4094+ case 'v':
4095+ printf("smbinfo version %s\n", VERSION);
4096+ return 0;
4097+@@ -1232,6 +1276,8 @@ int main(int argc, char *argv[])
4098+ fsctlgetobjid(f);
4099+ else if (!strcmp(argv[optind], "getcompression"))
4100+ getcompression(f);
4101++ else if (!strcmp(argv[optind], "setcompression"))
4102++ setcompression(f, compression);
4103+ else if (!strcmp(argv[optind], "list-snapshots"))
4104+ list_snapshots(f);
4105+ else if (!strcmp(argv[optind], "quota"))
4106+diff --git a/smbinfo.rst b/smbinfo.rst
4107+index 500ce0e..c8f76e6 100644
4108+--- a/smbinfo.rst
4109++++ b/smbinfo.rst
4110+@@ -69,6 +69,8 @@ COMMAND
4111+
4112+ `getcompression`: Prints the compression setting for the file.
4113+
4114++`setcompression -c <no|default|lznt1>`: Sets the compression setting for the file.
4115++
4116+ `list-snapshots`: Lists the previous versions of the volume that backs this file
4117+
4118+ `quota`: Print the quota for the volume in the form
4119+--
4120+2.17.1
4121+
4122diff --git a/debian/patches/0018-smbinfo.rst-document-new-keys-command.patch b/debian/patches/0018-smbinfo.rst-document-new-keys-command.patch
4123new file mode 100644
4124index 0000000..cfe48d5
4125--- /dev/null
4126+++ b/debian/patches/0018-smbinfo.rst-document-new-keys-command.patch
4127@@ -0,0 +1,30 @@
4128+From 74a1ced5f706ea6a9cab885693c7755657b81a2a Mon Sep 17 00:00:00 2001
4129+From: Aurelien Aptel <aaptel@suse.com>
4130+Origin: Upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=74a1ced5f706ea6a9cab885693c7755657b81a2a
4131+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1886551
4132+Date: Mon, 14 Oct 2019 19:06:25 +0200
4133+Subject: [PATCH] smbinfo.rst: document new `keys` command
4134+
4135+Signed-off-by: Aurelien Aptel <aaptel@suse.com>
4136+---
4137+ smbinfo.rst | 4 ++++
4138+ 1 file changed, 4 insertions(+)
4139+
4140+diff --git a/smbinfo.rst b/smbinfo.rst
4141+index c8f76e6..7413849 100644
4142+--- a/smbinfo.rst
4143++++ b/smbinfo.rst
4144+@@ -90,6 +90,10 @@ COMMAND
4145+ - File types
4146+ - File flags
4147+
4148++`keys`: Dump session id, encryption keys and decryption keys so that
4149++the SMB3 traffic of this mount can be decryped e.g. via wireshark
4150++(requires root).
4151++
4152+ *****
4153+ NOTES
4154+ *****
4155+--
4156+2.17.1
4157+
4158diff --git a/debian/patches/series b/debian/patches/series
4159index 8e67634..de0e82b 100644
4160--- a/debian/patches/series
4161+++ b/debian/patches/series
4162@@ -1,4 +1,26 @@
4163+<<<<<<< debian/patches/series
4164 0001-Fix-fPIE-casing.patch
4165 0002-destdir.patch
4166 0003-python2or3.patch
4167 0004-Fix-manpage-warning-by-separating-binary-names-using.patch
4168+=======
4169+setcifsacl-fix-adding-ACE-when-owner-sid-in-unexpect.patch
4170+0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch
4171+0002-smbinfo.rst-document-kernel-version.patch
4172+0003-smbinfo-Add-more-File-Information-classes.patch
4173+0004-smbinfo-update-help-text.patch
4174+0005-smbinfo-Update-the-usage-text-with-the-new-infolevel.patch
4175+0006-smbinfo-add-FileFsFullSizeInformation.patch
4176+0007-smbinfo-decode-the-ACEs.patch
4177+0008-smbinfo-fix-code-style.patch
4178+0009-smbinfo-add-fsctl-getobjid-support.patch
4179+0010-smbinfo-missing-help-for-fsctl-getobjid.patch
4180+0011-smbinfo-Add-ability-to-query-snapshots-previous-vers.patch
4181+0012-smbinfo-make-argument-order-consistent.patch
4182+0013-smbinfo-use-constant-for-input-buffer-length.patch
4183+0014-smbinfo-Improve-help-usage-and-add-h-option.patch
4184+0015-smbinfo-add-GETCOMPRESSION-support.patch
4185+0016-smbinfo-print-the-security-information-needed-to-dec.patch
4186+0017-smbinfo-Add-SETCOMPRESSION-support.patch
4187+0018-smbinfo.rst-document-new-keys-command.patch
4188+>>>>>>> debian/patches/series
4189diff --git a/debian/patches/setcifsacl-fix-adding-ACE-when-owner-sid-in-unexpect.patch b/debian/patches/setcifsacl-fix-adding-ACE-when-owner-sid-in-unexpect.patch
4190new file mode 100644
4191index 0000000..6f56099
4192--- /dev/null
4193+++ b/debian/patches/setcifsacl-fix-adding-ACE-when-owner-sid-in-unexpect.patch
4194@@ -0,0 +1,53 @@
4195+Description: setcifsacl: fix adding ACE when owner sid in unexpected location
4196+ If owner information is after the ACEs instead of before (e.g. Azure servers) in the ACL query
4197+ then we would get "invalid argument" returned on setcifsacl -a (adding an ACE).
4198+
4199+ This fixes that.
4200+
4201+ Signed-off-by: Steve French <stfrench@microsoft.com>
4202+
4203+Author: Steve French <stfrench@microsoft.com>
4204+Origin: upstream, https://git.samba.org/?p=cifs-utils.git;a=commit;h=0feb1a80f3777f4c244b46958aa9f730de9e18b6
4205+Bug-Ubuntu: https://launchpad.net/bugs/1886548
4206+Index: cifs-utils-6.8/setcifsacl.c
4207+===================================================================
4208+--- cifs-utils-6.8.orig/setcifsacl.c
4209++++ cifs-utils-6.8/setcifsacl.c
4210+@@ -106,13 +106,32 @@ copy_sec_desc(const struct cifs_ntsd *pn
4211+
4212+ /* copy owner sid */
4213+ owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + osidsoffset);
4214+- nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + osidsoffset);
4215+- size = copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
4216+- bufsize += size;
4217++ group_sid_ptr = (struct cifs_sid *)((char *)pntsd + gsidsoffset);
4218++ /*
4219++ * some servers like Azure return the owner and group SIDs at end rather
4220++ * than at the beginning of the ACL so don't want to overwrite the last ACEs
4221++ */
4222++ if (dacloffset <= osidsoffset) {
4223++ /* owners placed at end of ACL */
4224++ nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + dacloffset + size);
4225++ pnntsd->osidoffset = dacloffset + size;
4226++ size = copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
4227++ bufsize += size;
4228++ /* put group SID after owner SID */
4229++ ngroup_sid_ptr = (struct cifs_sid *)((char *)nowner_sid_ptr + size);
4230++ pnntsd->gsidoffset = pnntsd->osidoffset + size;
4231++ } else {
4232++ /*
4233++ * Most servers put the owner information at the beginning,
4234++ * before the ACL
4235++ */
4236++ nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + osidsoffset);
4237++ size = copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
4238++ bufsize += size;
4239++ ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + gsidsoffset);
4240++ }
4241+
4242+ /* copy group sid */
4243+- group_sid_ptr = (struct cifs_sid *)((char *)pntsd + gsidsoffset);
4244+- ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + gsidsoffset);
4245+ size = copy_cifs_sid(ngroup_sid_ptr, group_sid_ptr);
4246+ bufsize += size;
4247+

Subscribers

People subscribed via source and target branches