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