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 12 : static time_t cli_servertime(const char *host,
30 : const struct sockaddr_storage *dest_ss,
31 : int *zone)
32 : {
33 12 : time_t ret = 0;
34 12 : struct cli_state *cli = NULL;
35 0 : NTSTATUS status;
36 :
37 12 : status = cli_connect_nb(host, dest_ss, 0, 0x20, lp_netbios_name(),
38 : SMB_SIGNING_DEFAULT, 0, &cli);
39 12 : 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 12 : status = smbXcli_negprot(cli->conn,
51 12 : cli->timeout,
52 12 : lp_client_min_protocol(),
53 12 : lp_client_max_protocol(),
54 : NULL,
55 : NULL,
56 : NULL);
57 12 : if (!NT_STATUS_IS_OK(status)) {
58 0 : fprintf(stderr, _("Protocol negotiation failed: %s\n"),
59 : nt_errstr(status));
60 0 : goto done;
61 : }
62 :
63 12 : ret = cli_state_server_time(cli);
64 12 : if (zone) *zone = smb1cli_conn_server_time_zone(cli->conn);
65 :
66 8 : done:
67 12 : if (cli) {
68 12 : cli_shutdown(cli);
69 : }
70 12 : return ret;
71 : }
72 :
73 : /* find the servers time on the opt_host host */
74 8 : static time_t nettime(struct net_context *c, int *zone)
75 : {
76 8 : return cli_servertime(c->opt_host,
77 8 : c->opt_have_ip? &c->opt_dest_ip : NULL, zone);
78 : }
79 :
80 : /* return a time as a string ready to be passed to /bin/date */
81 4 : static const char *systime(time_t t)
82 : {
83 0 : struct tm *tm;
84 :
85 4 : tm = localtime(&t);
86 4 : if (!tm) {
87 0 : return "unknown";
88 : }
89 :
90 4 : return talloc_asprintf(talloc_tos(), "%02d%02d%02d%02d%04d.%02d",
91 4 : tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
92 4 : tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
93 : }
94 :
95 0 : int net_time_usage(struct net_context *c, int argc, const char **argv)
96 : {
97 0 : d_printf(_(
98 : "net time\n\tdisplays time on a server (-S server)\n\n"
99 : "net time system\n\tdisplays time on a server (-S server) in a format ready for /bin/date\n\n"
100 : "net time set\n\truns /bin/date with the time from the server (-S server)\n\n"
101 : "net time zone\n\tdisplays the timezone in hours from GMT on the remote server (-S server)\n\n"
102 : "\n"));
103 0 : net_common_flags_usage(c, argc, argv);
104 0 : return -1;
105 : }
106 :
107 : /* try to set the system clock */
108 0 : static int net_time_set(struct net_context *c, int argc, const char **argv)
109 : {
110 0 : struct timeval tv;
111 0 : int result;
112 :
113 0 : if (c->display_usage || c->opt_host == NULL) {
114 0 : d_printf( "%s\n"
115 : "net time set\n"
116 : " %s\n",
117 : _("Usage:"),
118 : _("Set local time to that of remote time "
119 : "server (-S server) "));
120 0 : return 0;
121 : }
122 :
123 0 : tv.tv_sec = nettime(c, NULL);
124 0 : tv.tv_usec=0;
125 :
126 0 : if (tv.tv_sec == 0) return -1;
127 :
128 0 : result = settimeofday(&tv,NULL);
129 :
130 0 : if (result)
131 0 : d_fprintf(stderr, _("setting system clock failed. Error was (%s)\n"),
132 0 : strerror(errno));
133 :
134 0 : return result;
135 : }
136 :
137 : /* display the time on a remote box in a format ready for /bin/date */
138 4 : static int net_time_system(struct net_context *c, int argc, const char **argv)
139 : {
140 0 : time_t t;
141 :
142 4 : if (c->display_usage || c->opt_host == NULL) {
143 0 : d_printf( "%s\n"
144 : "net time system\n"
145 : " %s\n",
146 : _("Usage:"),
147 : _("Output remote time server (-S server) "
148 : "time in a format ready for /bin/date"));
149 0 : return 0;
150 : }
151 :
152 4 : t = nettime(c, NULL);
153 4 : if (t == 0) return -1;
154 :
155 4 : printf("%s\n", systime(t));
156 :
157 4 : return 0;
158 : }
159 :
160 : /* display the remote time server's offset to UTC */
161 4 : static int net_time_zone(struct net_context *c, int argc, const char **argv)
162 : {
163 4 : int zone = 0;
164 0 : int hours, mins;
165 0 : char zsign;
166 0 : time_t t;
167 :
168 4 : if (c->display_usage || c->opt_host == NULL) {
169 0 : d_printf( "%s\n"
170 : "net time zone\n"
171 : " %s\n",
172 : _("Usage:"),
173 : _("Display the remote time server's (-S server) "
174 : "offset to UTC"));
175 0 : return 0;
176 : }
177 :
178 4 : t = nettime(c, &zone);
179 :
180 4 : if (t == 0) return -1;
181 :
182 4 : zsign = (zone > 0) ? '-' : '+';
183 4 : if (zone < 0) zone = -zone;
184 :
185 4 : zone /= 60;
186 4 : hours = zone / 60;
187 4 : mins = zone % 60;
188 :
189 4 : printf("%c%02d%02d\n", zsign, hours, mins);
190 :
191 4 : return 0;
192 : }
193 :
194 : /* display or set the time on a host */
195 12 : int net_time(struct net_context *c, int argc, const char **argv)
196 : {
197 0 : time_t t;
198 12 : struct functable func[] = {
199 : {
200 : "system",
201 : net_time_system,
202 : NET_TRANSPORT_LOCAL,
203 : N_("Display time ready for /bin/date"),
204 : N_("net time system\n"
205 : " Display time ready for /bin/date")
206 : },
207 : {
208 : "set",
209 : net_time_set,
210 : NET_TRANSPORT_LOCAL,
211 : N_("Set the system time from time server"),
212 : N_("net time set\n"
213 : " Set the system time from time server")
214 : },
215 : {
216 : "zone",
217 : net_time_zone,
218 : NET_TRANSPORT_LOCAL,
219 : N_("Display timezone offset from UTC"),
220 : N_("net time zone\n"
221 : " Display timezone offset from UTC")
222 : },
223 : {NULL, NULL, 0, NULL, NULL}
224 : };
225 :
226 12 : if (argc != 0) {
227 8 : return net_run_function(c, argc, argv, "net time", func);
228 : }
229 :
230 4 : if (c->display_usage) {
231 0 : d_printf( "%s\n"
232 : "net time\n"
233 : " %s\n",
234 : _("Usage:"),
235 : _("Display the remote time server's time"));
236 0 : net_display_usage_from_functable(func);
237 0 : return 0;
238 : }
239 :
240 4 : if (c->opt_host == NULL && !c->opt_have_ip) {
241 0 : bool ok;
242 :
243 0 : ok = find_master_ip(c->opt_target_workgroup, &c->opt_dest_ip);
244 0 : if (!ok) {
245 0 : d_fprintf(stderr,
246 0 : _("Could not locate a time server. "
247 : "Try specifying a target host.\n"));
248 0 : net_time_usage(c, argc, argv);
249 0 : return -1;
250 : }
251 0 : c->opt_have_ip = true;
252 : }
253 :
254 : /* default - print the time */
255 4 : t = cli_servertime(c->opt_host,
256 4 : c->opt_have_ip? &c->opt_dest_ip : NULL,
257 : NULL);
258 4 : if (t == 0) return -1;
259 :
260 4 : d_printf("%s", ctime(&t));
261 4 : return 0;
262 : }
|