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
;
36 /* prepare connect to the SRVSVC pipe of a timeserver */
37 c
.level
= LIBNET_RPC_CONNECT_SERVER
;
38 c
.in
.name
= r
->srvsvc
.in
.server_name
;
39 c
.in
.dcerpc_iface
= &ndr_table_srvsvc
;
41 /* 1. connect to the SRVSVC pipe of a timeserver */
42 status
= libnet_RpcConnect(ctx
, mem_ctx
, &c
);
43 if (!NT_STATUS_IS_OK(status
)) {
44 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
45 "Connection to SRVSVC pipe of server '%s' failed: %s",
46 r
->srvsvc
.in
.server_name
, nt_errstr(status
));
50 /* prepare srvsvc_NetrRemoteTOD */
51 tod
.in
.server_unc
= talloc_asprintf(mem_ctx
, "\\%s", c
.in
.name
);
54 /* 2. try srvsvc_NetRemoteTOD */
55 status
= dcerpc_srvsvc_NetRemoteTOD(c
.out
.dcerpc_pipe
, mem_ctx
, &tod
);
56 if (!NT_STATUS_IS_OK(status
)) {
57 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
58 "srvsvc_NetrRemoteTOD on server '%s' failed: %s",
59 r
->srvsvc
.in
.server_name
, nt_errstr(status
));
63 /* check result of srvsvc_NetrRemoteTOD */
64 if (!W_ERROR_IS_OK(tod
.out
.result
)) {
65 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
66 "srvsvc_NetrRemoteTOD on server '%s' failed: %s",
67 r
->srvsvc
.in
.server_name
, win_errstr(tod
.out
.result
));
68 status
= werror_to_ntstatus(tod
.out
.result
);
72 /* need to set the out parameters */
73 tm
.tm_sec
= (int)info
->secs
;
74 tm
.tm_min
= (int)info
->mins
;
75 tm
.tm_hour
= (int)info
->hours
;
76 tm
.tm_mday
= (int)info
->day
;
77 tm
.tm_mon
= (int)info
->month
-1;
78 tm
.tm_year
= (int)info
->year
- 1900;
83 r
->srvsvc
.out
.time
= timegm(&tm
);
84 r
->srvsvc
.out
.time_zone
= info
->timezone
* 60;
89 /* close connection */
90 talloc_free(c
.out
.dcerpc_pipe
);
95 static NTSTATUS
libnet_RemoteTOD_generic(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
98 union libnet_RemoteTOD r2
;
100 r2
.srvsvc
.level
= LIBNET_REMOTE_TOD_SRVSVC
;
101 r2
.srvsvc
.in
.server_name
= r
->generic
.in
.server_name
;
103 status
= libnet_RemoteTOD(ctx
, mem_ctx
, &r2
);
105 r
->generic
.out
.time
= r2
.srvsvc
.out
.time
;
106 r
->generic
.out
.time_zone
= r2
.srvsvc
.out
.time_zone
;
108 r
->generic
.out
.error_string
= r2
.srvsvc
.out
.error_string
;
113 NTSTATUS
libnet_RemoteTOD(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
115 switch (r
->generic
.level
) {
116 case LIBNET_REMOTE_TOD_GENERIC
:
117 return libnet_RemoteTOD_generic(ctx
, mem_ctx
, r
);
118 case LIBNET_REMOTE_TOD_SRVSVC
:
119 return libnet_RemoteTOD_srvsvc(ctx
, mem_ctx
, r
);
122 return NT_STATUS_INVALID_LEVEL
;