From 32ba2c889fb7eaa0dde8a2951572da7e2a4da3ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Dec 2001 05:21:50 +0000 Subject: added a net time command. Allow display or set of system time based on a SMB server particularly useful for ADS is: net time set -S DOMAIN#1B this makes kerberos clock skew problems go away :) (This used to be commit b3ba2293d0e4eac3b6408c3abc3dcacfa3f67fe4) --- source3/Makefile.in | 5 +- source3/utils/net.c | 26 ++++---- source3/utils/net_rap.c | 2 +- source3/utils/net_time.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 15 deletions(-) create mode 100644 source3/utils/net_time.c (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index e5920600c5..0cd2e53225 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -326,8 +326,9 @@ CLIENT_OBJ = client/client.o client/clitar.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(READLINE_OBJ) -NET_OBJ = utils/net.o utils/net_ads.o utils/net_rap.o utils/net_rpc.o \ - utils/net_rpc_join.o \ +NET_OBJ = utils/net.o utils/net_ads.o \ + utils/net_rap.o utils/net_rpc.o \ + utils/net_rpc_join.o utils/net_time.o \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \ $(GROUPDB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) diff --git a/source3/utils/net.c b/source3/utils/net.c index dab68ebefe..5a1bace8f1 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -71,8 +71,8 @@ int opt_jobid = 0; char *opt_target_workgroup = NULL; static BOOL got_pass = False; -static BOOL have_ip = False; -static struct in_addr dest_ip; +BOOL opt_have_ip = False; +struct in_addr opt_dest_ip; extern pstring global_myname; @@ -156,10 +156,10 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se *server_name = strdup(opt_host); } - if (have_ip) { - *server_ip = dest_ip; + if (opt_have_ip) { + *server_ip = opt_dest_ip; if (!*server_name) { - *server_name = strdup(inet_ntoa(dest_ip)); + *server_name = strdup(inet_ntoa(opt_dest_ip)); } } else if (*server_name) { /* resolve the IP address */ @@ -196,7 +196,7 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se } else { *server_ip = msbrow_ip; } - *server_name = strdup(inet_ntoa(dest_ip)); + *server_name = strdup(inet_ntoa(opt_dest_ip)); } else if (flags & NET_FLAGS_MASTER) { struct in_addr brow_ips; if (!resolve_name(opt_target_workgroup, &brow_ips, 0x1D)) { @@ -206,7 +206,7 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se } else { *server_ip = brow_ips; } - *server_name = strdup(inet_ntoa(dest_ip)); + *server_name = strdup(inet_ntoa(opt_dest_ip)); } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) { extern struct in_addr loopback_ip; *server_ip = loopback_ip; @@ -264,7 +264,7 @@ static int help_usage(int argc, const char **argv) "\n"\ "Valid functions are:\n"\ " RPC RAP ADS FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP VALIDATE\n"\ -" GROUPMEMBER ADMIN SERVICE PASSWORD\n"); +" GROUPMEMBER ADMIN SERVICE PASSWORD TIME\n"); return -1; } @@ -291,6 +291,7 @@ static int net_help(int argc, const char **argv) {"ADMIN", net_rap_admin_usage}, {"SERVICE", net_rap_service_usage}, {"PASSWORD", net_rap_password_usage}, + {"TIME", net_time_usage}, {"HELP", help_usage}, {NULL, NULL}}; @@ -318,6 +319,7 @@ static struct functable net_func[] = { {"ADMIN", net_rap_admin}, {"SERVICE", net_rap_service}, {"PASSWORD", net_rap_password}, + {"TIME", net_time}, {"HELP", net_help}, {NULL, NULL} @@ -359,7 +361,7 @@ static struct functable net_func[] = { }; got_pass = 0; - zero_ip(&dest_ip); + zero_ip(&opt_dest_ip); dbf = x_stdout; @@ -373,11 +375,11 @@ static struct functable net_func[] = { exit(0); break; case 'I': - dest_ip = *interpret_addr2(poptGetOptArg(pc)); - if (is_zero_ip(dest_ip)) + opt_dest_ip = *interpret_addr2(poptGetOptArg(pc)); + if (is_zero_ip(opt_dest_ip)) d_printf("\nInvalid ip address specified\n"); else - have_ip = True; + opt_have_ip = True; break; case 'U': opt_user_name = strdup(opt_user_name); diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c index 242d1ac9a1..b658c46d14 100644 --- a/source3/utils/net_rap.c +++ b/source3/utils/net_rap.c @@ -214,7 +214,7 @@ static const char *share_type[] = { /* End of weird 'strings at top of file' section */ -static int general_rap_usage(int argc, const char **argv) +int general_rap_usage(int argc, const char **argv) { d_printf("Valid targets: choose one (none defaults to using localhost)\n"); diff --git a/source3/utils/net_time.c b/source3/utils/net_time.c new file mode 100644 index 0000000000..f7f3f894b0 --- /dev/null +++ b/source3/utils/net_time.c @@ -0,0 +1,151 @@ +/* + Samba Unix/Linux SMB client library + Version 3.0 + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "includes.h" +#include "../utils/net.h" + + +/* + return the time on a server. This does not require any authentication +*/ +static time_t cli_servertime(const char *host, struct in_addr *ip) +{ + struct nmb_name calling, called; + time_t ret = 0; + extern pstring global_myname; + struct cli_state *cli = NULL; + + cli = cli_initialise(NULL); + if (!cli || !cli_connect(cli, host, ip)) goto done; + + make_nmb_name(&calling, global_myname, 0x0); + if (host) { + make_nmb_name(&called, host, 0x20); + } else { + make_nmb_name(&called, "*SMBSERVER", 0x20); + } + + if (!cli_session_request(cli, &calling, &called)) goto done; + if (!cli_negprot(cli)) goto done; + + ret = cli->servertime; + + cli_shutdown(cli); + +done: + if (cli) cli_shutdown(cli); + return ret; +} + +/* find the servers time on the opt_host host */ +static time_t nettime(void) +{ + extern BOOL opt_have_ip; + extern struct in_addr opt_dest_ip; + extern char *opt_host; + return cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL); +} + +/* return a time as a string ready to be passed to date -u */ +static char *systime(time_t t) +{ + static char s[100]; + struct tm *tm; + + tm = gmtime(&t); + + snprintf(s, sizeof(s), "%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); + return s; +} + +int net_time_usage(int argc, const char **argv) +{ + d_printf( +"net time\n\tdisplays time on a server\n\n"\ +"net time system\n\tdisplays time on a server in a format ready for /bin/date\n\n"\ +"net time set\n\truns /bin/date -u with the time from the server\n\n"\ +"\n"); + general_rap_usage(argc, argv); + return -1; +} + +/* try to set the system clock using /bin/date */ +static int net_time_set(int argc, const char **argv) +{ + time_t t = nettime(); + char *cmd; + + if (t == 0) { + d_printf("Can't contact server\n"); + return -1; + } + + asprintf(&cmd, "/bin/date -u %s", systime(t)); + system(cmd); + free(cmd); + + return 0; +} + +/* display the time on a remote box in a format ready for /bin/date */ +static int net_time_system(int argc, const char **argv) +{ + time_t t = nettime(); + + if (t == 0) { + d_printf("Can't contact server\n"); + return -1; + } + + printf("%s\n", systime(t)); + + return 0; +} + +/* display or set the time on a host */ +int net_time(int argc, const char **argv) +{ + time_t t; + extern BOOL opt_have_ip; + extern struct in_addr opt_dest_ip; + extern char *opt_host; + struct functable func[] = { + {"SYSTEM", net_time_system}, + {"SET", net_time_set}, + {NULL, NULL} + }; + + if (!opt_host && !opt_have_ip) { + d_printf("You must specify a hostname or IP\n"); + return -1; + } + + if (argc != 0) { + return net_run_function(argc, argv, func, net_time_usage); + } + + /* default - print the time */ + t = cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL); + + d_printf("%s", ctime(&t)); + return 0; +} -- cgit