added a net time command. Allow display or set of system time based on
authorAndrew Tridgell <tridge@samba.org>
Tue, 11 Dec 2001 05:21:50 +0000 (05:21 +0000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 11 Dec 2001 05:21:50 +0000 (05:21 +0000)
a SMB server

particularly useful for ADS is:

net time set -S DOMAIN#1B

this makes kerberos clock skew problems go away :)

source/Makefile.in
source/utils/net.c
source/utils/net_rap.c
source/utils/net_time.c [new file with mode: 0644]

index e5920600c581c58363987540e9a3abc4a0117679..0cd2e5322577881175bf820f14d7f7c873e3c973 100644 (file)
@@ -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) 
 
index dab68ebefe6e42d9bb2ad47af07599579ca3a4ea..5a1bace8f1de99d62762dd06cae3ea6b00fa02ac 100644 (file)
@@ -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);
index 242d1ac9a1629f73a4ccc1514426f684a9f800cb..b658c46d141e995b53031be1e4c27fd7f0132947 100644 (file)
@@ -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/source/utils/net_time.c b/source/utils/net_time.c
new file mode 100644 (file)
index 0000000..f7f3f89
--- /dev/null
@@ -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;
+}