Line data Source code
1 : /*
2 : Samba Unix/Linux SMB client library
3 : net time command
4 : Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 : #include "includes.h"
20 : #include "utils/net.h"
21 : #include "libsmb/nmblib.h"
22 : #include "libsmb/namequery.h"
23 : #include "libsmb/libsmb.h"
24 : #include "../libcli/smb/smbXcli_base.h"
25 :
26 : /*
27 : return the time on a server. This does not require any authentication
28 : */
29 0 : static time_t cli_servertime(const char *host,
30 : const struct sockaddr_storage *dest_ss,
31 : int *zone)
32 : {
33 0 : time_t ret = 0;
34 0 : struct cli_state *cli = NULL;
35 : NTSTATUS status;
36 :
37 0 : status = cli_connect_nb(host, dest_ss, 0, 0x20, lp_netbios_name(),
38 : SMB_SIGNING_DEFAULT, 0, &cli);
39 0 : if (!NT_STATUS_IS_OK(status)) {
40 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
41 0 : fprintf(stderr, "Can't contact server %s. NetBIOS support disabled,"
42 : " Error %s\n", host, nt_errstr(status));
43 : } else {
44 0 : fprintf(stderr, "Can't contact server %s. Error %s\n",
45 : host, nt_errstr(status));
46 : }
47 0 : goto done;
48 : }
49 :
50 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
51 0 : lp_client_min_protocol(),
52 0 : lp_client_max_protocol());
53 0 : if (!NT_STATUS_IS_OK(status)) {
54 0 : fprintf(stderr, _("Protocol negotiation failed: %s\n"),
55 : nt_errstr(status));
56 0 : goto done;
57 : }
58 :
59 0 : ret = cli_state_server_time(cli);
60 0 : if (zone) *zone = smb1cli_conn_server_time_zone(cli->conn);
61 :
62 0 : done:
63 0 : if (cli) {
64 0 : cli_shutdown(cli);
65 : }
66 0 : return ret;
67 : }
68 :
69 : /* find the servers time on the opt_host host */
70 0 : static time_t nettime(struct net_context *c, int *zone)
71 : {
72 0 : return cli_servertime(c->opt_host,
73 0 : c->opt_have_ip? &c->opt_dest_ip : NULL, zone);
74 : }
75 :
76 : /* return a time as a string ready to be passed to /bin/date */
77 0 : static const char *systime(time_t t)
78 : {
79 : struct tm *tm;
80 :
81 0 : tm = localtime(&t);
82 0 : if (!tm) {
83 0 : return "unknown";
84 : }
85 :
86 0 : return talloc_asprintf(talloc_tos(), "%02d%02d%02d%02d%04d.%02d",
87 0 : tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
88 0 : tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
89 : }
90 :
91 0 : int net_time_usage(struct net_context *c, int argc, const char **argv)
92 : {
93 0 : d_printf(_(
94 : "net time\n\tdisplays time on a server (-S server)\n\n"
95 : "net time system\n\tdisplays time on a server (-S server) in a format ready for /bin/date\n\n"
96 : "net time set\n\truns /bin/date with the time from the server (-S server)\n\n"
97 : "net time zone\n\tdisplays the timezone in hours from GMT on the remote server (-S server)\n\n"
98 : "\n"));
99 0 : net_common_flags_usage(c, argc, argv);
100 0 : return -1;
101 : }
102 :
103 : /* try to set the system clock */
104 0 : static int net_time_set(struct net_context *c, int argc, const char **argv)
105 : {
106 : struct timeval tv;
107 : int result;
108 :
109 0 : if (c->display_usage || c->opt_host == NULL) {
110 0 : d_printf( "%s\n"
111 : "net time set\n"
112 : " %s\n",
113 : _("Usage:"),
114 : _("Set local time to that of remote time "
115 : "server (-S server) "));
116 0 : return 0;
117 : }
118 :
119 0 : tv.tv_sec = nettime(c, NULL);
120 0 : tv.tv_usec=0;
121 :
122 0 : if (tv.tv_sec == 0) return -1;
123 :
124 0 : result = settimeofday(&tv,NULL);
125 :
126 0 : if (result)
127 0 : d_fprintf(stderr, _("setting system clock failed. Error was (%s)\n"),
128 0 : strerror(errno));
129 :
130 0 : return result;
131 : }
132 :
133 : /* display the time on a remote box in a format ready for /bin/date */
134 0 : static int net_time_system(struct net_context *c, int argc, const char **argv)
135 : {
136 : time_t t;
137 :
138 0 : if (c->display_usage || c->opt_host == NULL) {
139 0 : d_printf( "%s\n"
140 : "net time system\n"
141 : " %s\n",
142 : _("Usage:"),
143 : _("Output remote time server (-S server) "
144 : "time in a format ready for /bin/date"));
145 0 : return 0;
146 : }
147 :
148 0 : t = nettime(c, NULL);
149 0 : if (t == 0) return -1;
150 :
151 0 : printf("%s\n", systime(t));
152 :
153 0 : return 0;
154 : }
155 :
156 : /* display the remote time server's offset to UTC */
157 0 : static int net_time_zone(struct net_context *c, int argc, const char **argv)
158 : {
159 0 : int zone = 0;
160 : int hours, mins;
161 : char zsign;
162 : time_t t;
163 :
164 0 : if (c->display_usage || c->opt_host == NULL) {
165 0 : d_printf( "%s\n"
166 : "net time zone\n"
167 : " %s\n",
168 : _("Usage:"),
169 : _("Display the remote time server's (-S server) "
170 : "offset to UTC"));
171 0 : return 0;
172 : }
173 :
174 0 : t = nettime(c, &zone);
175 :
176 0 : if (t == 0) return -1;
177 :
178 0 : zsign = (zone > 0) ? '-' : '+';
179 0 : if (zone < 0) zone = -zone;
180 :
181 0 : zone /= 60;
182 0 : hours = zone / 60;
183 0 : mins = zone % 60;
184 :
185 0 : printf("%c%02d%02d\n", zsign, hours, mins);
186 :
187 0 : return 0;
188 : }
189 :
190 : /* display or set the time on a host */
191 0 : int net_time(struct net_context *c, int argc, const char **argv)
192 : {
193 : time_t t;
194 0 : struct functable func[] = {
195 : {
196 : "system",
197 : net_time_system,
198 : NET_TRANSPORT_LOCAL,
199 : N_("Display time ready for /bin/date"),
200 : N_("net time system\n"
201 : " Display time ready for /bin/date")
202 : },
203 : {
204 : "set",
205 : net_time_set,
206 : NET_TRANSPORT_LOCAL,
207 : N_("Set the system time from time server"),
208 : N_("net time set\n"
209 : " Set the system time from time server")
210 : },
211 : {
212 : "zone",
213 : net_time_zone,
214 : NET_TRANSPORT_LOCAL,
215 : N_("Display timezone offset from UTC"),
216 : N_("net time zone\n"
217 : " Display timezone offset from UTC")
218 : },
219 : {NULL, NULL, 0, NULL, NULL}
220 : };
221 :
222 0 : if (argc != 0) {
223 0 : return net_run_function(c, argc, argv, "net time", func);
224 : }
225 :
226 0 : if (c->display_usage) {
227 0 : d_printf( "%s\n"
228 : "net time\n"
229 : " %s\n",
230 : _("Usage:"),
231 : _("Display the remote time server's time"));
232 0 : net_display_usage_from_functable(func);
233 0 : return 0;
234 : }
235 :
236 0 : if (c->opt_host == NULL && !c->opt_have_ip) {
237 : bool ok;
238 :
239 0 : ok = find_master_ip(c->opt_target_workgroup, &c->opt_dest_ip);
240 0 : if (!ok) {
241 0 : d_fprintf(stderr,
242 0 : _("Could not locate a time server. "
243 : "Try specifying a target host.\n"));
244 0 : net_time_usage(c, argc, argv);
245 0 : return -1;
246 : }
247 0 : c->opt_have_ip = true;
248 : }
249 :
250 : /* default - print the time */
251 0 : t = cli_servertime(c->opt_host,
252 0 : c->opt_have_ip? &c->opt_dest_ip : NULL,
253 : NULL);
254 0 : if (t == 0) return -1;
255 :
256 0 : d_printf("%s", ctime(&t));
257 0 : return 0;
258 : }
|