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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libnet/libnet.h"
23 #include "system/time.h"
24 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
27 * get the remote time of a server via srvsvc_NetRemoteTOD
29 static NTSTATUS
libnet_RemoteTOD_srvsvc(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
32 struct libnet_RpcConnect c
;
33 struct srvsvc_NetRemoteTOD tod
;
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
= &dcerpc_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\n",
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
);
53 /* 2. try srvsvc_NetRemoteTOD */
54 status
= dcerpc_srvsvc_NetRemoteTOD(c
.out
.dcerpc_pipe
, mem_ctx
, &tod
);
55 if (!NT_STATUS_IS_OK(status
)) {
56 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
57 "srvsvc_NetrRemoteTOD on server '%s' failed: %s\n",
58 r
->srvsvc
.in
.server_name
, nt_errstr(status
));
62 /* check result of srvsvc_NetrRemoteTOD */
63 if (!W_ERROR_IS_OK(tod
.out
.result
)) {
64 r
->srvsvc
.out
.error_string
= talloc_asprintf(mem_ctx
,
65 "srvsvc_NetrRemoteTOD on server '%s' failed: %s\n",
66 r
->srvsvc
.in
.server_name
, win_errstr(tod
.out
.result
));
67 status
= werror_to_ntstatus(tod
.out
.result
);
71 /* need to set the out parameters */
72 tm
.tm_sec
= (int)tod
.out
.info
->secs
;
73 tm
.tm_min
= (int)tod
.out
.info
->mins
;
74 tm
.tm_hour
= (int)tod
.out
.info
->hours
;
75 tm
.tm_mday
= (int)tod
.out
.info
->day
;
76 tm
.tm_mon
= (int)tod
.out
.info
->month
-1;
77 tm
.tm_year
= (int)tod
.out
.info
->year
- 1900;
82 r
->srvsvc
.out
.time
= timegm(&tm
);
83 r
->srvsvc
.out
.time_zone
= tod
.out
.info
->timezone
* 60;
88 /* close connection */
89 talloc_free(c
.out
.dcerpc_pipe
);
94 static NTSTATUS
libnet_RemoteTOD_generic(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
97 union libnet_RemoteTOD r2
;
99 r2
.srvsvc
.level
= LIBNET_REMOTE_TOD_SRVSVC
;
100 r2
.srvsvc
.in
.server_name
= r
->generic
.in
.server_name
;
102 status
= libnet_RemoteTOD(ctx
, mem_ctx
, &r2
);
104 r
->generic
.out
.time
= r2
.srvsvc
.out
.time
;
105 r
->generic
.out
.time_zone
= r2
.srvsvc
.out
.time_zone
;
107 r
->generic
.out
.error_string
= r2
.srvsvc
.out
.error_string
;
112 NTSTATUS
libnet_RemoteTOD(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
, union libnet_RemoteTOD
*r
)
114 switch (r
->generic
.level
) {
115 case LIBNET_REMOTE_TOD_GENERIC
:
116 return libnet_RemoteTOD_generic(ctx
, mem_ctx
, r
);
117 case LIBNET_REMOTE_TOD_SRVSVC
:
118 return libnet_RemoteTOD_srvsvc(ctx
, mem_ctx
, r
);
121 return NT_STATUS_INVALID_LEVEL
;