WHATSNEW: Update changed parameters.
[Samba/gbeck.git] / source3 / lib / netapi / netlogon.c
blob8c30d6caab1000308b383b349d472f8b8020bb6c
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi LogonControl Support
4 * Copyright (C) Guenther Deschner 2009
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/>.
20 #include "includes.h"
22 #include "../librpc/gen_ndr/cli_netlogon.h"
23 #include "librpc/gen_ndr/libnetapi.h"
24 #include "lib/netapi/netapi.h"
25 #include "lib/netapi/netapi_private.h"
26 #include "lib/netapi/libnetapi.h"
28 static WERROR construct_data(enum netr_LogonControlCode function_code,
29 const uint8_t *data_in,
30 union netr_CONTROL_DATA_INFORMATION *data_out)
32 switch (function_code) {
33 case NETLOGON_CONTROL_QUERY:
34 case NETLOGON_CONTROL_REDISCOVER:
35 case NETLOGON_CONTROL_TC_QUERY:
36 case NETLOGON_CONTROL_CHANGE_PASSWORD:
37 case NETLOGON_CONTROL_TC_VERIFY:
38 data_out->domain = (const char *)data_in;
39 break;
40 case NETLOGON_CONTROL_FIND_USER:
41 data_out->user = (const char *)data_in;
42 break;
43 case NETLOGON_CONTROL_SET_DBFLAG:
44 data_out->debug_level = atoi((const char *)data_in);
45 break;
46 case NETLOGON_CONTROL_FORCE_DNS_REG:
47 ZERO_STRUCTP(data_out);
48 break;
49 default:
50 return WERR_INVALID_PARAM;
53 return WERR_OK;
56 static WERROR construct_buffer(TALLOC_CTX *mem_ctx,
57 uint32_t level,
58 union netr_CONTROL_QUERY_INFORMATION *q,
59 uint8_t **buffer)
61 struct NETLOGON_INFO_1 *i1;
62 struct NETLOGON_INFO_2 *i2;
63 struct NETLOGON_INFO_3 *i3;
64 struct NETLOGON_INFO_4 *i4;
66 if (!q) {
67 return WERR_INVALID_PARAM;
70 switch (level) {
71 case 1:
72 i1 = talloc(mem_ctx, struct NETLOGON_INFO_1);
73 W_ERROR_HAVE_NO_MEMORY(i1);
75 i1->netlog1_flags = q->info1->flags;
76 i1->netlog1_pdc_connection_status = W_ERROR_V(q->info1->pdc_connection_status);
78 *buffer = (uint8_t *)i1;
80 break;
81 case 2:
82 i2 = talloc(mem_ctx, struct NETLOGON_INFO_2);
83 W_ERROR_HAVE_NO_MEMORY(i2);
85 i2->netlog2_flags = q->info2->flags;
86 i2->netlog2_pdc_connection_status = W_ERROR_V(q->info2->pdc_connection_status);
87 i2->netlog2_trusted_dc_name = talloc_strdup(mem_ctx, q->info2->trusted_dc_name);
88 i2->netlog2_tc_connection_status = W_ERROR_V(q->info2->tc_connection_status);
90 *buffer = (uint8_t *)i2;
92 break;
93 case 3:
94 i3 = talloc(mem_ctx, struct NETLOGON_INFO_3);
95 W_ERROR_HAVE_NO_MEMORY(i3);
97 i3->netlog1_flags = q->info3->flags;
98 i3->netlog3_logon_attempts = q->info3->logon_attempts;
99 i3->netlog3_reserved1 = q->info3->unknown1;
100 i3->netlog3_reserved2 = q->info3->unknown2;
101 i3->netlog3_reserved3 = q->info3->unknown3;
102 i3->netlog3_reserved4 = q->info3->unknown4;
103 i3->netlog3_reserved5 = q->info3->unknown5;
105 *buffer = (uint8_t *)i3;
107 break;
108 case 4:
109 i4 = talloc(mem_ctx, struct NETLOGON_INFO_4);
110 W_ERROR_HAVE_NO_MEMORY(i4);
112 i4->netlog4_trusted_dc_name = talloc_strdup(mem_ctx, q->info4->trusted_dc_name);
113 i4->netlog4_trusted_domain_name = talloc_strdup(mem_ctx, q->info4->trusted_domain_name);
115 *buffer = (uint8_t *)i4;
117 break;
118 default:
119 return WERR_UNKNOWN_LEVEL;
121 return WERR_OK;
124 /****************************************************************
125 ****************************************************************/
127 WERROR I_NetLogonControl_r(struct libnetapi_ctx *ctx,
128 struct I_NetLogonControl *r)
130 WERROR werr;
131 NTSTATUS status;
132 struct rpc_pipe_client *pipe_cli = NULL;
133 union netr_CONTROL_QUERY_INFORMATION query;
135 werr = libnetapi_open_pipe(ctx, r->in.server_name,
136 &ndr_table_netlogon.syntax_id,
137 &pipe_cli);
138 if (!W_ERROR_IS_OK(werr)) {
139 goto done;
142 status = rpccli_netr_LogonControl(pipe_cli, talloc_tos(),
143 r->in.server_name,
144 r->in.function_code,
145 r->in.query_level,
146 &query,
147 &werr);
148 if (!NT_STATUS_IS_OK(status)) {
149 werr = ntstatus_to_werror(status);
150 goto done;
153 werr = construct_buffer(ctx, r->in.query_level, &query,
154 r->out.buffer);
155 if (!W_ERROR_IS_OK(werr)) {
156 goto done;
159 done:
160 return werr;
163 /****************************************************************
164 ****************************************************************/
166 WERROR I_NetLogonControl_l(struct libnetapi_ctx *ctx,
167 struct I_NetLogonControl *r)
169 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl);
172 /****************************************************************
173 ****************************************************************/
175 WERROR I_NetLogonControl2_r(struct libnetapi_ctx *ctx,
176 struct I_NetLogonControl2 *r)
178 WERROR werr;
179 NTSTATUS status;
180 struct rpc_pipe_client *pipe_cli = NULL;
181 union netr_CONTROL_DATA_INFORMATION data;
182 union netr_CONTROL_QUERY_INFORMATION query;
184 werr = construct_data(r->in.function_code, r->in.data, &data);
185 if (!W_ERROR_IS_OK(werr)) {
186 goto done;
189 werr = libnetapi_open_pipe(ctx, r->in.server_name,
190 &ndr_table_netlogon.syntax_id,
191 &pipe_cli);
192 if (!W_ERROR_IS_OK(werr)) {
193 goto done;
196 switch (r->in.function_code) {
197 case NETLOGON_CONTROL_TC_VERIFY:
198 case NETLOGON_CONTROL_SET_DBFLAG:
199 case NETLOGON_CONTROL_FORCE_DNS_REG:
200 status = rpccli_netr_LogonControl2Ex(pipe_cli, talloc_tos(),
201 r->in.server_name,
202 r->in.function_code,
203 r->in.query_level,
204 &data,
205 &query,
206 &werr);
207 break;
208 default:
209 status = rpccli_netr_LogonControl2(pipe_cli, talloc_tos(),
210 r->in.server_name,
211 r->in.function_code,
212 r->in.query_level,
213 &data,
214 &query,
215 &werr);
216 break;
219 if (!W_ERROR_IS_OK(werr)) {
220 goto done;
223 if (!NT_STATUS_IS_OK(status)) {
224 werr = ntstatus_to_werror(status);
225 goto done;
228 werr = construct_buffer(ctx, r->in.query_level, &query,
229 r->out.buffer);
230 if (!W_ERROR_IS_OK(werr)) {
231 goto done;
234 done:
235 return werr;
238 /****************************************************************
239 ****************************************************************/
241 WERROR I_NetLogonControl2_l(struct libnetapi_ctx *ctx,
242 struct I_NetLogonControl2 *r)
244 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl2);