2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2004
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.
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.
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/>.
21 #include "libnet/libnet.h"
22 #include "system/time.h"
23 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
26 * get the remote time of a server via srvsvc_NetRemoteTOD
28 static NTSTATUS
libnet_RemoteTOD_srvsvc(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
31 struct libnet_RpcConnect c
;
32 struct srvsvc_NetRemoteTOD tod
;
33 struct srvsvc_NetRemoteTODInfo
*info
= NULL
;
38 /* prepare connect to the SRVSVC pipe of a timeserver */
39 c
.level
= LIBNET_RPC_CONNECT_SERVER
;
40 c
.in
.name
= r
->srvsvc
.in
.server_name
;
41 c
.in
.dcerpc_iface
= &ndr_table_srvsvc
;
43 /* 1. connect to the SRVSVC pipe of a timeserver */
44 status
= libnet_RpcConnect(ctx
, mem_ctx
, &c
);
45 if (!NT_STATUS_IS_OK(status
)) {
46 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
47 "Connection to SRVSVC pipe of server '%s' failed: %s",
48 r
->srvsvc
.in
.server_name
, nt_errstr(status
));
52 /* prepare srvsvc_NetrRemoteTOD */
53 tod
.in
.server_unc
= talloc_asprintf(mem_ctx
, "\\%s", c
.in
.name
);
56 /* 2. try srvsvc_NetRemoteTOD */
57 status
= dcerpc_srvsvc_NetRemoteTOD_r(c
.out
.dcerpc_pipe
->binding_handle
, mem_ctx
, &tod
);
58 if (!NT_STATUS_IS_OK(status
)) {
59 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
60 "srvsvc_NetrRemoteTOD on server '%s' failed: %s",
61 r
->srvsvc
.in
.server_name
, nt_errstr(status
));
65 /* check result of srvsvc_NetrRemoteTOD */
66 if (!W_ERROR_IS_OK(tod
.out
.result
)) {
67 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
68 "srvsvc_NetrRemoteTOD on server '%s' failed: %s",
69 r
->srvsvc
.in
.server_name
, win_errstr(tod
.out
.result
));
70 status
= werror_to_ntstatus(tod
.out
.result
);
74 /* need to set the out parameters */
75 tm
.tm_sec
= (int)info
->secs
;
76 tm
.tm_min
= (int)info
->mins
;
77 tm
.tm_hour
= (int)info
->hours
;
78 tm
.tm_mday
= (int)info
->day
;
79 tm
.tm_mon
= (int)info
->month
-1;
80 tm
.tm_year
= (int)info
->year
- 1900;
85 r
->srvsvc
.out
.time
= timegm(&tm
);
86 r
->srvsvc
.out
.time_zone
= info
->timezone
* 60;
91 /* close connection */
92 talloc_free(c
.out
.dcerpc_pipe
);
97 static NTSTATUS
libnet_RemoteTOD_generic(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
100 union libnet_RemoteTOD r2
;
102 r2
.srvsvc
.level
= LIBNET_REMOTE_TOD_SRVSVC
;
103 r2
.srvsvc
.in
.server_name
= r
->generic
.in
.server_name
;
105 status
= libnet_RemoteTOD(ctx
, mem_ctx
, &r2
);
107 r
->generic
.out
.time
= r2
.srvsvc
.out
.time
;
108 r
->generic
.out
.time_zone
= r2
.srvsvc
.out
.time_zone
;
110 r
->generic
.out
.error_string
= r2
.srvsvc
.out
.error_string
;
115 NTSTATUS
libnet_RemoteTOD(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
117 switch (r
->generic
.level
) {
118 case LIBNET_REMOTE_TOD_GENERIC
:
119 return libnet_RemoteTOD_generic(ctx
, mem_ctx
, r
);
120 case LIBNET_REMOTE_TOD_SRVSVC
:
121 return libnet_RemoteTOD_srvsvc(ctx
, mem_ctx
, r
);
124 return NT_STATUS_INVALID_LEVEL
;