Resend: Patch to implement utimes in smbclient along with a test
Jeremy Allison
jra at samba.org
Mon Oct 16 21:03:23 UTC 2017
On Fri, Sep 22, 2017 at 11:54:49AM -0700, Jeremy Allison via samba-technical wrote:
> On Thu, Sep 21, 2017 at 07:22:19PM -0700, Richard Sharpe via samba-technical wrote:
> > > editor shows red for that new line.
> >
> > OK, fixed that one as well.
>
> A few fixes needed:
>
> 1). d_printf("setmode <filename> <create-time> <access-time> "
> should be: d_printf("utimes...").
>
> 2). Split the test into a separate patch to go in after
> the client.c fix (I find that easier to back-port if
> needed).
>
> 3). Needs a docs-xml update for smbclient describing
> the new "utimes" command.
>
> I can do these for you next week if you're busy, but
> I think these need doing before this can go in.
Here's the version I'd like to ship. Richard, are
you happy with this ?
Thanks,
Jeremy.
-------------- next part --------------
From d4d36aa78b5afa883d64ffcb24ab586654ec9c0e Mon Sep 17 00:00:00 2001
From: Richard Sharpe <realrichardsharpe at gmail.com>
Date: Mon, 16 Oct 2017 13:51:51 -0700
Subject: [PATCH 1/2] s3:Add a utimes command to smbclient so we can set the
Windows times.
Add an update to the smbclient man page.
Signed-off-by: Richard Sharpe <realrichardsharpe at gmail.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
docs-xml/manpages/smbclient.1.xml | 8 +++
source3/client/client.c | 122 ++++++++++++++++++++++++++++++++++++++
2 files changed, 130 insertions(+)
diff --git a/docs-xml/manpages/smbclient.1.xml b/docs-xml/manpages/smbclient.1.xml
index 432f60da78a..03259828cbc 100644
--- a/docs-xml/manpages/smbclient.1.xml
+++ b/docs-xml/manpages/smbclient.1.xml
@@ -1175,6 +1175,14 @@
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term>utimes <filename> <create time> <access time> <write time> <
+ change time></term>
+ <listitem><para>Changes the timestamps on a file by name.
+ Times should be specified in the format YY:MM:DD-HH:MM:SS or -1 for no change.
+ </para></listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/source3/client/client.c b/source3/client/client.c
index 5ef9ad52151..df16496ff86 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -4940,6 +4940,126 @@ static int cmd_show_connect( void )
return 0;
}
+/**
+ * set_remote_times - set times of a remote file
+ * @filename: path to the file name
+ * @create_time: New create time
+ * @access_time: New access time
+ * @write_time: New write time
+ * @change_time: New metadata change time
+ *
+ * Update the file times with the ones provided.
+ */
+static int set_remote_times(const char *filename, time_t create_time,
+ time_t access_time, time_t write_time,
+ time_t change_time)
+{
+ extern struct cli_state *cli;
+ NTSTATUS status;
+
+ status = cli_setpathinfo_basic(cli, filename, create_time,
+ access_time, write_time,
+ change_time, -1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("cli_setpathinfo_basic failed: %s\n",
+ nt_errstr(status));
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * cmd_utimes - interactive command to set the four times
+ *
+ * Read a filename and four times from the client command line and update
+ * the file times. A value of -1 for a time means don't change.
+ */
+static int cmd_utimes(void)
+{
+ const extern char *cmd_ptr;
+ char *buf;
+ char *fname = NULL;
+ time_t times[4] = {0, 0, 0, 0};
+ int time_count = 0;
+ int err = 0;
+ bool ok;
+ TALLOC_CTX *ctx = talloc_new(NULL);
+ if (ctx == NULL) {
+ return 1;
+ }
+
+ ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL);
+ if (!ok) {
+ d_printf("utimes <filename> <create-time> <access-time> "
+ "<write-time> <change-time>\n");
+ d_printf("Dates should be in YY:MM:DD-HH:MM:SS format "
+ "or -1 for no change\n");
+ err = 1;
+ goto out;
+ }
+
+ fname = talloc_asprintf(ctx,
+ "%s%s",
+ client_get_cur_dir(),
+ buf);
+ if (fname == NULL) {
+ err = 1;
+ goto out;
+ }
+
+ while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL) &&
+ time_count < 4) {
+ const char *s = buf;
+ struct tm tm = {0,};
+ char *ret;
+
+ if (strlen(s) == 2 && strcmp(s, "-1") == 0) {
+ times[time_count] = 0;
+ time_count++;
+ continue;
+ } else {
+ ret = strptime(s, "%y:%m:%d-%H:%M:%S", &tm);
+ }
+
+ /* We could not match all the chars, so print error */
+ if (ret == NULL || *ret != 0) {
+ d_printf("Invalid date format: %s\n", s);
+ d_printf("utimes <filename> <create-time> "
+ "<access-time> <write-time> <change-time>\n");
+ d_printf("Dates should be in YY:MM:DD-HH:MM:SS format "
+ "or -1 for no change\n");
+ err = 1;
+ goto out;
+ }
+
+ /* Convert tm to a time_t */
+ times[time_count] = mktime(&tm);
+ time_count++;
+ }
+
+ if (time_count < 4) {
+ d_printf("Insufficient dates: %d\n", time_count);
+ d_printf("utimes <filename> <create-time> <access-time> "
+ "<write-time> <change-time>\n");
+ d_printf("Dates should be in YY:MM:DD-HH:MM:SS format "
+ "or -1 for no change\n");
+ err = 1;
+ goto out;
+ }
+
+ DEBUG(10, ("times\nCreate: %sAccess: %s Write: %sChange: %s\n",
+ talloc_strdup(ctx, ctime(×[0])),
+ talloc_strdup(ctx, ctime(×[1])),
+ talloc_strdup(ctx, ctime(×[2])),
+ talloc_strdup(ctx, ctime(×[3]))));
+
+ set_remote_times(fname, times[0], times[1], times[2], times[3]);
+out:
+ talloc_free(ctx);
+ return err;
+}
+
/**
* set_remote_attr - set DOS attributes of a remote file
* @filename: path to the file name
@@ -5254,6 +5374,8 @@ static struct {
{"tcon",cmd_tcon,"connect to a share" ,{COMPL_NONE,COMPL_NONE}},
{"tdis",cmd_tdis,"disconnect from a share",{COMPL_NONE,COMPL_NONE}},
{"tid",cmd_tid,"show or set the current tid (tree-id)",{COMPL_NONE,COMPL_NONE}},
+ {"utimes", cmd_utimes,"<file name> <create_time> <access_time> <mod_time> "
+ "<ctime> set times", {COMPL_REMOTE,COMPL_NONE}},
{"logoff",cmd_logoff,"log off (close the session)",{COMPL_NONE,COMPL_NONE}},
{"..",cmd_cd_oneup,"change the remote directory (up one level)",{COMPL_REMOTE,COMPL_NONE}},
--
2.15.0.rc0.271.g36b669edcc-goog
From 2e3f93738bd0ea67e1686efa4e276dcc9aa337f2 Mon Sep 17 00:00:00 2001
From: Richard Sharpe <realrichardsharpe at gmail.com>
Date: Mon, 16 Oct 2017 14:00:07 -0700
Subject: [PATCH 2/2] s4: tests: Add a test for smbclient utimes command.
Signed-off-by: Richard Sharpe <realrichardsharpe at gmail.com>
Signed-off-by: Jeremy Allison <jra at samba.org>
---
source4/selftest/tests.py | 1 +
testprogs/blackbox/test_smbclient_utimes.sh | 87 +++++++++++++++++++++++++++++
2 files changed, 88 insertions(+)
create mode 100644 testprogs/blackbox/test_smbclient_utimes.sh
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index cdc62cd362b..168852e91fe 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -431,6 +431,7 @@ plantestsuite("samba4.blackbox.client_etypes_all(ad_dc:client)", "ad_dc:client",
plantestsuite("samba4.blackbox.client_etypes_legacy(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'legacy', '23'])
plantestsuite("samba4.blackbox.client_etypes_strong(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'strong', '17_18'])
plantestsuite("samba4.blackbox.net_ads_dns(ad_member:local)", "ad_member:local", [os.path.join(bbdir, "test_net_ads_dns.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$REALM', '$USERNAME', '$PASSWORD'])
+plantestsuite("samba4.blackbox.smbclient_utimes(ad_member:local)", "ad_member:local", [os.path.join(bbdir, "test_smbclient_utimes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$REALM', '$USERNAME', '$PASSWORD'])
plantestsuite_loadlist("samba4.rpc.echo against NetBIOS alias", "ad_dc_ntvfs", [valgrindify(smbtorture4), "$LISTOPT", "$LOADLIST", 'ncacn_np:$NETBIOSALIAS', '-U$DOMAIN/$USERNAME%$PASSWORD', 'rpc.echo'])
# Tests using the "Simple" NTVFS backend
diff --git a/testprogs/blackbox/test_smbclient_utimes.sh b/testprogs/blackbox/test_smbclient_utimes.sh
new file mode 100644
index 00000000000..dba87c6fced
--- /dev/null
+++ b/testprogs/blackbox/test_smbclient_utimes.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+# Blackbox tests for net ads dns register etc.
+# Copyright (C) 2006-2007 Jelmer Vernooij <jelmer at samba.org>
+# Copyright (C) 2006-2008 Andrew Bartlett <abartlet at samba.org>
+
+if [ $# -lt 6 ]; then
+cat <<EOF
+Usage: test_smbclient_utimes.sh SERVER DC_USERNAME DC_PASSWORD REALM USER PASS
+EOF
+exit 1;
+fi
+
+SERVER=$1
+DC_USERNAME=$2
+DC_PASSWORD=$3
+REALM=$4
+USERNAME=$5
+PASSWORD=$6
+shift 6
+failed=0
+
+UNPRIVUSER="unprivuser"
+UNPRIVPPASS="UnPr1vP at ss1"
+
+samba_bindir="$BINDIR"
+smbclient="$samba_bindir/smbclient"
+net_tool="$samba_bindir/net"
+
+SMB_UNC="//$SERVER/tmp"
+
+. `dirname $0`/subunit.sh
+. `dirname $0`/common_test_fns.inc
+
+# These tests check that the smbclient utimes command works.
+# We only test modification of atime and mtime because the server
+# might not support Create_Time and ctime usually cannot be modified.
+
+echo "Starting ..."
+
+err=0
+
+testit "Adding an unprivileged user" $VALGRIND $net_tool user add $UNPRIVUSER $UNPRIVPASS -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+
+res1=`$smbclient "$SMB_UNC" -U"$UNPRIVUSER%$UNPRIVPASS" -c "allinfo test1"`
+if [ x$status != x0 ]
+then
+ err=1
+fi
+
+echo $res1 >> /tmp/$$
+
+testit "Test that we can even connect with $USERNAME $PASSWORD" [ $err == 0 ] || failed=`expr $failed + 1`
+if [ $err != 0 ]
+then
+ exit $failed
+fi
+
+# Now, try to change the access time because Create time is not necessarily
+# handled.
+
+test_smbclient "Set Utimes" "utimes test1 -1 17:01:01-05:10:20 -1 -1" "$SMB_UNC" -U"UNPRIVUSER%$UNPRIVPASS" || failed=`expr $failed + 1`
+
+# Now, get the times again and check they are different from the first result
+res2=`$smbclient "$SMB_UNC" -U"$UNPRIVUSER%$UNPRIVPASS" -c "allinfo test1"`
+if [ x$status != x0 ]
+then
+ err=1
+fi
+
+testit "Test that we can get the info again" [ $err == 0 ] || failed=`expr $failed + 1`
+if [ $err != 0 ]
+then
+ exit $failed
+fi
+
+echo $res2 >> /tmp/$$
+
+# These must be different!
+diff <(echo "$res1") <(echo "$res2")
+if [ x$status == x0 ]
+then
+ err=1
+fi
+
+testit "Test that the two times are different" [ $err == 0 ] || failed=`expr $failed + 1`
+
+exit $failed
--
2.15.0.rc0.271.g36b669edcc-goog
More information about the samba-technical
mailing list