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