From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- source3/utils/net_time.c | 262 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 source3/utils/net_time.c (limited to 'source3/utils/net_time.c') diff --git a/source3/utils/net_time.c b/source3/utils/net_time.c new file mode 100644 index 0000000..f58d62b --- /dev/null +++ b/source3/utils/net_time.c @@ -0,0 +1,262 @@ +/* + Samba Unix/Linux SMB client library + net time command + Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include "includes.h" +#include "utils/net.h" +#include "libsmb/nmblib.h" +#include "libsmb/namequery.h" +#include "libsmb/libsmb.h" +#include "../libcli/smb/smbXcli_base.h" + +/* + return the time on a server. This does not require any authentication +*/ +static time_t cli_servertime(const char *host, + const struct sockaddr_storage *dest_ss, + int *zone) +{ + time_t ret = 0; + struct cli_state *cli = NULL; + NTSTATUS status; + + status = cli_connect_nb(host, dest_ss, 0, 0x20, lp_netbios_name(), + SMB_SIGNING_DEFAULT, 0, &cli); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + fprintf(stderr, "Can't contact server %s. NetBIOS support disabled," + " Error %s\n", host, nt_errstr(status)); + } else { + fprintf(stderr, "Can't contact server %s. Error %s\n", + host, nt_errstr(status)); + } + goto done; + } + + status = smbXcli_negprot(cli->conn, + cli->timeout, + lp_client_min_protocol(), + lp_client_max_protocol(), + NULL, + NULL, + NULL); + if (!NT_STATUS_IS_OK(status)) { + fprintf(stderr, _("Protocol negotiation failed: %s\n"), + nt_errstr(status)); + goto done; + } + + ret = cli_state_server_time(cli); + if (zone) *zone = smb1cli_conn_server_time_zone(cli->conn); + +done: + if (cli) { + cli_shutdown(cli); + } + return ret; +} + +/* find the servers time on the opt_host host */ +static time_t nettime(struct net_context *c, int *zone) +{ + return cli_servertime(c->opt_host, + c->opt_have_ip? &c->opt_dest_ip : NULL, zone); +} + +/* return a time as a string ready to be passed to /bin/date */ +static const char *systime(time_t t) +{ + struct tm *tm; + + tm = localtime(&t); + if (!tm) { + return "unknown"; + } + + return talloc_asprintf(talloc_tos(), "%02d%02d%02d%02d%04d.%02d", + tm->tm_mon+1, tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_year + 1900, tm->tm_sec); +} + +int net_time_usage(struct net_context *c, int argc, const char **argv) +{ + d_printf(_( +"net time\n\tdisplays time on a server (-S server)\n\n" +"net time system\n\tdisplays time on a server (-S server) in a format ready for /bin/date\n\n" +"net time set\n\truns /bin/date with the time from the server (-S server)\n\n" +"net time zone\n\tdisplays the timezone in hours from GMT on the remote server (-S server)\n\n" +"\n")); + net_common_flags_usage(c, argc, argv); + return -1; +} + +/* try to set the system clock */ +static int net_time_set(struct net_context *c, int argc, const char **argv) +{ + struct timeval tv; + int result; + + if (c->display_usage || c->opt_host == NULL) { + d_printf( "%s\n" + "net time set\n" + " %s\n", + _("Usage:"), + _("Set local time to that of remote time " + "server (-S server) ")); + return 0; + } + + tv.tv_sec = nettime(c, NULL); + tv.tv_usec=0; + + if (tv.tv_sec == 0) return -1; + + result = settimeofday(&tv,NULL); + + if (result) + d_fprintf(stderr, _("setting system clock failed. Error was (%s)\n"), + strerror(errno)); + + return result; +} + +/* display the time on a remote box in a format ready for /bin/date */ +static int net_time_system(struct net_context *c, int argc, const char **argv) +{ + time_t t; + + if (c->display_usage || c->opt_host == NULL) { + d_printf( "%s\n" + "net time system\n" + " %s\n", + _("Usage:"), + _("Output remote time server (-S server) " + "time in a format ready for /bin/date")); + return 0; + } + + t = nettime(c, NULL); + if (t == 0) return -1; + + printf("%s\n", systime(t)); + + return 0; +} + +/* display the remote time server's offset to UTC */ +static int net_time_zone(struct net_context *c, int argc, const char **argv) +{ + int zone = 0; + int hours, mins; + char zsign; + time_t t; + + if (c->display_usage || c->opt_host == NULL) { + d_printf( "%s\n" + "net time zone\n" + " %s\n", + _("Usage:"), + _("Display the remote time server's (-S server) " + "offset to UTC")); + return 0; + } + + t = nettime(c, &zone); + + if (t == 0) return -1; + + zsign = (zone > 0) ? '-' : '+'; + if (zone < 0) zone = -zone; + + zone /= 60; + hours = zone / 60; + mins = zone % 60; + + printf("%c%02d%02d\n", zsign, hours, mins); + + return 0; +} + +/* display or set the time on a host */ +int net_time(struct net_context *c, int argc, const char **argv) +{ + time_t t; + struct functable func[] = { + { + "system", + net_time_system, + NET_TRANSPORT_LOCAL, + N_("Display time ready for /bin/date"), + N_("net time system\n" + " Display time ready for /bin/date") + }, + { + "set", + net_time_set, + NET_TRANSPORT_LOCAL, + N_("Set the system time from time server"), + N_("net time set\n" + " Set the system time from time server") + }, + { + "zone", + net_time_zone, + NET_TRANSPORT_LOCAL, + N_("Display timezone offset from UTC"), + N_("net time zone\n" + " Display timezone offset from UTC") + }, + {NULL, NULL, 0, NULL, NULL} + }; + + if (argc != 0) { + return net_run_function(c, argc, argv, "net time", func); + } + + if (c->display_usage) { + d_printf( "%s\n" + "net time\n" + " %s\n", + _("Usage:"), + _("Display the remote time server's time")); + net_display_usage_from_functable(func); + return 0; + } + + if (c->opt_host == NULL && !c->opt_have_ip) { + bool ok; + + ok = find_master_ip(c->opt_target_workgroup, &c->opt_dest_ip); + if (!ok) { + d_fprintf(stderr, + _("Could not locate a time server. " + "Try specifying a target host.\n")); + net_time_usage(c, argc, argv); + return -1; + } + c->opt_have_ip = true; + } + + /* default - print the time */ + t = cli_servertime(c->opt_host, + c->opt_have_ip? &c->opt_dest_ip : NULL, + NULL); + if (t == 0) return -1; + + d_printf("%s", ctime(&t)); + return 0; +} -- cgit v1.2.3