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

Proposed by Andreas Hasenack
Status: Merged
Approved by: Andreas Hasenack
Approved revision: ddfff93e36ec3da362d4b1d58e332e1e48793e02
Merged at revision: ddfff93e36ec3da362d4b1d58e332e1e48793e02
Proposed branch: ~joalif/ubuntu/+source/cifs-utils:lp1886551-bionic
Merge into: ubuntu/+source/cifs-utils:ubuntu/bionic-devel
Diff against target: 4165 lines (+4043/-0)
20 files modified
debian/changelog (+24/-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 (+18/-0)
Reviewer Review Type Date Requested Status
Andreas Hasenack Approve
Review via email: mp+390551@code.launchpad.net

This proposal supersedes a proposal from 2020-09-10.

Description of the change

Retargeting to ubuntu/bionic-devel

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

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

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

First pass, d/changelog comments:

- please use version 2:6.8-1ubuntu1.1 in d/changelog for this update, following the rules from version table example at https://wiki.ubuntu.com/SecurityTeam/UpdatePreparation#Update_the_packaging

- for the overall formatting, I suggest to go with:
  * Add smbinfo utility and 'keys' command (LP: #1886551):
    - d/p/0001-smbinfo-add-a-utility-to-display-smb-specific-inform.patch
    - d/p/0002-smbinfo.rst-document-kernel-version.patch
    ...

review: Needs Fixing
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I updated the test case a bit in the linked bug, and ran through it with a bionic vm, all seems good.

+1 with the changelog changes, and we also need a focal MP before this can be uploaded.

Nice work

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

+1

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Tagging and uploading ddfff93e36ec3da362d4b1d58e332e1e48793e02

$ git push pkg upload/2%6.8-1ubuntu1.1
Enumerating objects: 122, done.
Counting objects: 100% (122/122), done.
Delta compression using up to 4 threads
Compressing objects: 100% (40/40), done.
Writing objects: 100% (117/117), 39.48 KiB | 9.87 MiB/s, done.
Total 117 (delta 80), reused 112 (delta 77)
remote: Resolving deltas: 100% (80/80), completed with 3 local objects.
To ssh://git.launchpad.net/~usd-import-team/ubuntu/+source/cifs-utils
 * [new tag] upload/2%6.8-1ubuntu1.1 -> upload/2%6.8-1ubuntu1.1

$ dput ubuntu ../cifs-utils_6.8-1ubuntu1.1_source.changes
Checking signature on .changes
gpg: ../cifs-utils_6.8-1ubuntu1.1_source.changes: Valid signature from AC983EB5BF6BCBA9
Checking signature on .dsc
gpg: ../cifs-utils_6.8-1ubuntu1.1.dsc: Valid signature from AC983EB5BF6BCBA9
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading cifs-utils_6.8-1ubuntu1.1.dsc: done.
  Uploading cifs-utils_6.8-1ubuntu1.1.debian.tar.xz: done.
  Uploading cifs-utils_6.8-1ubuntu1.1_source.buildinfo: done.
  Uploading cifs-utils_6.8-1ubuntu1.1_source.changes: done.
Successfully uploaded packages.

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

Subscribers

People subscribed via source and target branches