s4: lib: auth: If NTLMSSP_NEGOTIATE_TARGET_INFO isn't set, cope with servers that...
[Samba.git] / source3 / lib / netapi / netlogon.c
bloba046fb77e91db821b49cfd37f93120cefa80ebee
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/ndr_netlogon_c.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 union netr_CONTROL_QUERY_INFORMATION query;
133 struct dcerpc_binding_handle *b;
135 werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
136 &ndr_table_netlogon.syntax_id,
137 &b);
138 if (!W_ERROR_IS_OK(werr)) {
139 goto done;
142 status = dcerpc_netr_LogonControl(b, 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;
152 if (!W_ERROR_IS_OK(werr)) {
153 goto done;
156 werr = construct_buffer(ctx, r->in.query_level, &query,
157 r->out.buffer);
158 if (!W_ERROR_IS_OK(werr)) {
159 goto done;
162 done:
163 return werr;
166 /****************************************************************
167 ****************************************************************/
169 WERROR I_NetLogonControl_l(struct libnetapi_ctx *ctx,
170 struct I_NetLogonControl *r)
172 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl);
175 /****************************************************************
176 ****************************************************************/
178 WERROR I_NetLogonControl2_r(struct libnetapi_ctx *ctx,
179 struct I_NetLogonControl2 *r)
181 WERROR werr;
182 NTSTATUS status;
183 union netr_CONTROL_DATA_INFORMATION data;
184 union netr_CONTROL_QUERY_INFORMATION query;
185 struct dcerpc_binding_handle *b;
187 werr = construct_data(r->in.function_code, r->in.data, &data);
188 if (!W_ERROR_IS_OK(werr)) {
189 goto done;
192 werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
193 &ndr_table_netlogon.syntax_id,
194 &b);
195 if (!W_ERROR_IS_OK(werr)) {
196 goto done;
199 switch (r->in.function_code) {
200 case NETLOGON_CONTROL_TC_VERIFY:
201 case NETLOGON_CONTROL_SET_DBFLAG:
202 case NETLOGON_CONTROL_FORCE_DNS_REG:
203 status = dcerpc_netr_LogonControl2Ex(b, talloc_tos(),
204 r->in.server_name,
205 r->in.function_code,
206 r->in.query_level,
207 &data,
208 &query,
209 &werr);
210 break;
211 default:
212 status = dcerpc_netr_LogonControl2(b, talloc_tos(),
213 r->in.server_name,
214 r->in.function_code,
215 r->in.query_level,
216 &data,
217 &query,
218 &werr);
219 break;
222 if (!NT_STATUS_IS_OK(status)) {
223 werr = ntstatus_to_werror(status);
224 goto done;
227 if (!W_ERROR_IS_OK(werr)) {
228 goto done;
231 werr = construct_buffer(ctx, r->in.query_level, &query,
232 r->out.buffer);
233 if (!W_ERROR_IS_OK(werr)) {
234 goto done;
237 done:
238 return werr;
241 /****************************************************************
242 ****************************************************************/
244 WERROR I_NetLogonControl2_l(struct libnetapi_ctx *ctx,
245 struct I_NetLogonControl2 *r)
247 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl2);