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