Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * NetApi LogonControl Support
4 : * Copyright (C) Guenther Deschner 2009
5 : *
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.
10 : *
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.
15 : *
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/>.
18 : */
19 :
20 : #include "includes.h"
21 :
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"
27 :
28 0 : static WERROR construct_data(enum netr_LogonControlCode function_code,
29 : const uint8_t *data_in,
30 : union netr_CONTROL_DATA_INFORMATION *data_out)
31 : {
32 0 : switch (function_code) {
33 0 : 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 0 : data_out->domain = (const char *)data_in;
39 0 : break;
40 0 : case NETLOGON_CONTROL_FIND_USER:
41 0 : data_out->user = (const char *)data_in;
42 0 : break;
43 0 : case NETLOGON_CONTROL_SET_DBFLAG:
44 0 : data_out->debug_level = atoi((const char *)data_in);
45 0 : break;
46 0 : case NETLOGON_CONTROL_FORCE_DNS_REG:
47 0 : ZERO_STRUCTP(data_out);
48 0 : break;
49 0 : default:
50 0 : return WERR_INVALID_PARAMETER;
51 : }
52 :
53 0 : return WERR_OK;
54 : }
55 :
56 0 : static WERROR construct_buffer(TALLOC_CTX *mem_ctx,
57 : uint32_t level,
58 : union netr_CONTROL_QUERY_INFORMATION *q,
59 : uint8_t **buffer)
60 : {
61 0 : struct NETLOGON_INFO_1 *i1;
62 0 : struct NETLOGON_INFO_2 *i2;
63 0 : struct NETLOGON_INFO_3 *i3;
64 0 : struct NETLOGON_INFO_4 *i4;
65 :
66 0 : if (!q) {
67 0 : return WERR_INVALID_PARAMETER;
68 : }
69 :
70 0 : switch (level) {
71 0 : case 1:
72 0 : i1 = talloc(mem_ctx, struct NETLOGON_INFO_1);
73 0 : W_ERROR_HAVE_NO_MEMORY(i1);
74 :
75 0 : i1->netlog1_flags = q->info1->flags;
76 0 : i1->netlog1_pdc_connection_status = W_ERROR_V(q->info1->pdc_connection_status);
77 :
78 0 : *buffer = (uint8_t *)i1;
79 :
80 0 : break;
81 0 : case 2:
82 0 : i2 = talloc(mem_ctx, struct NETLOGON_INFO_2);
83 0 : W_ERROR_HAVE_NO_MEMORY(i2);
84 :
85 0 : i2->netlog2_flags = q->info2->flags;
86 0 : i2->netlog2_pdc_connection_status = W_ERROR_V(q->info2->pdc_connection_status);
87 0 : i2->netlog2_trusted_dc_name = talloc_strdup(mem_ctx, q->info2->trusted_dc_name);
88 0 : i2->netlog2_tc_connection_status = W_ERROR_V(q->info2->tc_connection_status);
89 :
90 0 : *buffer = (uint8_t *)i2;
91 :
92 0 : break;
93 0 : case 3:
94 0 : i3 = talloc(mem_ctx, struct NETLOGON_INFO_3);
95 0 : W_ERROR_HAVE_NO_MEMORY(i3);
96 :
97 0 : i3->netlog1_flags = q->info3->flags;
98 0 : i3->netlog3_logon_attempts = q->info3->logon_attempts;
99 0 : i3->netlog3_reserved1 = q->info3->unknown1;
100 0 : i3->netlog3_reserved2 = q->info3->unknown2;
101 0 : i3->netlog3_reserved3 = q->info3->unknown3;
102 0 : i3->netlog3_reserved4 = q->info3->unknown4;
103 0 : i3->netlog3_reserved5 = q->info3->unknown5;
104 :
105 0 : *buffer = (uint8_t *)i3;
106 :
107 0 : break;
108 0 : case 4:
109 0 : i4 = talloc(mem_ctx, struct NETLOGON_INFO_4);
110 0 : W_ERROR_HAVE_NO_MEMORY(i4);
111 :
112 0 : i4->netlog4_trusted_dc_name = talloc_strdup(mem_ctx, q->info4->trusted_dc_name);
113 0 : i4->netlog4_trusted_domain_name = talloc_strdup(mem_ctx, q->info4->trusted_domain_name);
114 :
115 0 : *buffer = (uint8_t *)i4;
116 :
117 0 : break;
118 0 : default:
119 0 : return WERR_INVALID_LEVEL;
120 : }
121 0 : return WERR_OK;
122 : }
123 :
124 : /****************************************************************
125 : ****************************************************************/
126 :
127 0 : WERROR I_NetLogonControl_r(struct libnetapi_ctx *ctx,
128 : struct I_NetLogonControl *r)
129 : {
130 0 : WERROR werr;
131 0 : NTSTATUS status;
132 0 : union netr_CONTROL_QUERY_INFORMATION query;
133 0 : struct dcerpc_binding_handle *b;
134 :
135 0 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
136 : &ndr_table_netlogon,
137 : &b);
138 0 : if (!W_ERROR_IS_OK(werr)) {
139 0 : goto done;
140 : }
141 :
142 0 : status = dcerpc_netr_LogonControl(b, talloc_tos(),
143 : r->in.server_name,
144 0 : r->in.function_code,
145 : r->in.query_level,
146 : &query,
147 : &werr);
148 0 : if (!NT_STATUS_IS_OK(status)) {
149 0 : werr = ntstatus_to_werror(status);
150 0 : goto done;
151 : }
152 0 : if (!W_ERROR_IS_OK(werr)) {
153 0 : goto done;
154 : }
155 :
156 0 : werr = construct_buffer(ctx, r->in.query_level, &query,
157 : r->out.buffer);
158 0 : if (!W_ERROR_IS_OK(werr)) {
159 0 : goto done;
160 : }
161 :
162 0 : done:
163 0 : return werr;
164 : }
165 :
166 : /****************************************************************
167 : ****************************************************************/
168 :
169 0 : WERROR I_NetLogonControl_l(struct libnetapi_ctx *ctx,
170 : struct I_NetLogonControl *r)
171 : {
172 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl);
173 : }
174 :
175 : /****************************************************************
176 : ****************************************************************/
177 :
178 0 : WERROR I_NetLogonControl2_r(struct libnetapi_ctx *ctx,
179 : struct I_NetLogonControl2 *r)
180 : {
181 0 : WERROR werr;
182 0 : NTSTATUS status;
183 0 : union netr_CONTROL_DATA_INFORMATION data;
184 0 : union netr_CONTROL_QUERY_INFORMATION query;
185 0 : struct dcerpc_binding_handle *b;
186 :
187 0 : werr = construct_data(r->in.function_code, r->in.data, &data);
188 0 : if (!W_ERROR_IS_OK(werr)) {
189 0 : goto done;
190 : }
191 :
192 0 : werr = libnetapi_get_binding_handle(ctx, r->in.server_name,
193 : &ndr_table_netlogon,
194 : &b);
195 0 : if (!W_ERROR_IS_OK(werr)) {
196 0 : goto done;
197 : }
198 :
199 0 : switch (r->in.function_code) {
200 0 : case NETLOGON_CONTROL_TC_VERIFY:
201 : case NETLOGON_CONTROL_SET_DBFLAG:
202 : case NETLOGON_CONTROL_FORCE_DNS_REG:
203 0 : status = dcerpc_netr_LogonControl2Ex(b, talloc_tos(),
204 : r->in.server_name,
205 0 : r->in.function_code,
206 : r->in.query_level,
207 : &data,
208 : &query,
209 : &werr);
210 0 : break;
211 0 : default:
212 0 : status = dcerpc_netr_LogonControl2(b, talloc_tos(),
213 : r->in.server_name,
214 0 : r->in.function_code,
215 : r->in.query_level,
216 : &data,
217 : &query,
218 : &werr);
219 0 : break;
220 : }
221 :
222 0 : if (!NT_STATUS_IS_OK(status)) {
223 0 : werr = ntstatus_to_werror(status);
224 0 : goto done;
225 : }
226 :
227 0 : if (!W_ERROR_IS_OK(werr)) {
228 0 : goto done;
229 : }
230 :
231 0 : werr = construct_buffer(ctx, r->in.query_level, &query,
232 : r->out.buffer);
233 0 : if (!W_ERROR_IS_OK(werr)) {
234 0 : goto done;
235 : }
236 :
237 0 : done:
238 0 : return werr;
239 : }
240 :
241 : /****************************************************************
242 : ****************************************************************/
243 :
244 0 : WERROR I_NetLogonControl2_l(struct libnetapi_ctx *ctx,
245 : struct I_NetLogonControl2 *r)
246 : {
247 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl2);
248 : }
|