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