Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * NetApi User Support
4 : * Copyright (C) Guenther Deschner 2008
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 : #include "../librpc/gen_ndr/ndr_samr_c.h"
27 : #include "rpc_client/init_samr.h"
28 : #include "../libds/common/flags.h"
29 : #include "rpc_client/init_lsa.h"
30 : #include "../libcli/security/security.h"
31 : #include "../libds/common/flag_mapping.h"
32 : #include "rpc_client/cli_pipe.h"
33 :
34 : /****************************************************************
35 : ****************************************************************/
36 :
37 10 : static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX,
38 : struct samr_UserInfo21 *info21)
39 : {
40 10 : uint32_t fields_present = 0;
41 0 : struct samr_LogonHours zero_logon_hours;
42 0 : struct lsa_BinaryString zero_parameters;
43 0 : NTTIME password_age;
44 :
45 10 : ZERO_STRUCTP(info21);
46 10 : ZERO_STRUCT(zero_logon_hours);
47 10 : ZERO_STRUCT(zero_parameters);
48 :
49 10 : if (infoX->usriX_flags) {
50 6 : fields_present |= SAMR_FIELD_ACCT_FLAGS;
51 : }
52 10 : if (infoX->usriX_name) {
53 7 : fields_present |= SAMR_FIELD_ACCOUNT_NAME;
54 : }
55 10 : if (infoX->usriX_password) {
56 8 : fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
57 : }
58 10 : if (infoX->usriX_flags) {
59 6 : fields_present |= SAMR_FIELD_ACCT_FLAGS;
60 : }
61 10 : if (infoX->usriX_home_dir) {
62 0 : fields_present |= SAMR_FIELD_HOME_DIRECTORY;
63 : }
64 10 : if (infoX->usriX_script_path) {
65 0 : fields_present |= SAMR_FIELD_LOGON_SCRIPT;
66 : }
67 10 : if (infoX->usriX_comment) {
68 3 : fields_present |= SAMR_FIELD_DESCRIPTION;
69 : }
70 10 : if (infoX->usriX_password_age) {
71 0 : fields_present |= SAMR_FIELD_EXPIRED_FLAG;
72 : }
73 10 : if (infoX->usriX_full_name) {
74 0 : fields_present |= SAMR_FIELD_FULL_NAME;
75 : }
76 10 : if (infoX->usriX_usr_comment) {
77 0 : fields_present |= SAMR_FIELD_COMMENT;
78 : }
79 10 : if (infoX->usriX_profile) {
80 0 : fields_present |= SAMR_FIELD_PROFILE_PATH;
81 : }
82 10 : if (infoX->usriX_home_dir_drive) {
83 0 : fields_present |= SAMR_FIELD_HOME_DRIVE;
84 : }
85 10 : if (infoX->usriX_primary_group_id) {
86 0 : fields_present |= SAMR_FIELD_PRIMARY_GID;
87 : }
88 10 : if (infoX->usriX_country_code) {
89 0 : fields_present |= SAMR_FIELD_COUNTRY_CODE;
90 : }
91 10 : if (infoX->usriX_workstations) {
92 0 : fields_present |= SAMR_FIELD_WORKSTATIONS;
93 : }
94 :
95 10 : unix_to_nt_time_abs(&password_age, infoX->usriX_password_age);
96 :
97 : /* TODO: infoX->usriX_priv */
98 :
99 10 : info21->last_logon = 0;
100 10 : info21->last_logoff = 0;
101 10 : info21->last_password_change = 0;
102 10 : info21->acct_expiry = 0;
103 10 : info21->allow_password_change = 0;
104 10 : info21->force_password_change = 0;
105 10 : info21->account_name.string = infoX->usriX_name;
106 10 : info21->full_name.string = infoX->usriX_full_name;
107 10 : info21->home_directory.string = infoX->usriX_home_dir;
108 10 : info21->home_drive.string = infoX->usriX_home_dir_drive;
109 10 : info21->logon_script.string = infoX->usriX_script_path;
110 10 : info21->profile_path.string = infoX->usriX_profile;
111 10 : info21->description.string = infoX->usriX_comment;
112 10 : info21->workstations.string = infoX->usriX_workstations;
113 10 : info21->comment.string = infoX->usriX_usr_comment;
114 10 : info21->parameters = zero_parameters;
115 10 : info21->lm_owf_password = zero_parameters;
116 10 : info21->nt_owf_password = zero_parameters;
117 10 : info21->private_data.string = NULL;
118 10 : info21->buf_count = 0;
119 10 : info21->buffer = NULL;
120 10 : info21->rid = infoX->usriX_user_id;
121 10 : info21->primary_gid = infoX->usriX_primary_group_id;
122 10 : info21->acct_flags = infoX->usriX_flags;
123 10 : info21->fields_present = fields_present;
124 10 : info21->logon_hours = zero_logon_hours;
125 10 : info21->bad_password_count = infoX->usriX_bad_pw_count;
126 10 : info21->logon_count = infoX->usriX_num_logons;
127 10 : info21->country_code = infoX->usriX_country_code;
128 10 : info21->code_page = infoX->usriX_code_page;
129 10 : info21->lm_password_set = 0;
130 10 : info21->nt_password_set = 0;
131 10 : info21->password_expired = infoX->usriX_password_expired;
132 10 : info21->private_data_sensitive = 0;
133 10 : }
134 :
135 : /****************************************************************
136 : ****************************************************************/
137 :
138 10 : static NTSTATUS construct_USER_INFO_X(uint32_t level,
139 : uint8_t *buffer,
140 : struct USER_INFO_X *uX)
141 : {
142 10 : struct USER_INFO_0 *u0 = NULL;
143 10 : struct USER_INFO_1 *u1 = NULL;
144 10 : struct USER_INFO_2 *u2 = NULL;
145 10 : struct USER_INFO_3 *u3 = NULL;
146 10 : struct USER_INFO_1003 *u1003 = NULL;
147 10 : struct USER_INFO_1006 *u1006 = NULL;
148 10 : struct USER_INFO_1007 *u1007 = NULL;
149 10 : struct USER_INFO_1009 *u1009 = NULL;
150 10 : struct USER_INFO_1011 *u1011 = NULL;
151 10 : struct USER_INFO_1012 *u1012 = NULL;
152 10 : struct USER_INFO_1014 *u1014 = NULL;
153 10 : struct USER_INFO_1024 *u1024 = NULL;
154 10 : struct USER_INFO_1051 *u1051 = NULL;
155 10 : struct USER_INFO_1052 *u1052 = NULL;
156 10 : struct USER_INFO_1053 *u1053 = NULL;
157 :
158 10 : if (!buffer || !uX) {
159 0 : return NT_STATUS_INVALID_PARAMETER;
160 : }
161 :
162 10 : ZERO_STRUCTP(uX);
163 :
164 10 : switch (level) {
165 1 : case 0:
166 1 : u0 = (struct USER_INFO_0 *)buffer;
167 1 : uX->usriX_name = u0->usri0_name;
168 1 : break;
169 6 : case 1:
170 6 : u1 = (struct USER_INFO_1 *)buffer;
171 6 : uX->usriX_name = u1->usri1_name;
172 6 : uX->usriX_password = u1->usri1_password;
173 6 : uX->usriX_password_age = u1->usri1_password_age;
174 6 : uX->usriX_priv = u1->usri1_priv;
175 6 : uX->usriX_home_dir = u1->usri1_home_dir;
176 6 : uX->usriX_comment = u1->usri1_comment;
177 6 : uX->usriX_flags = u1->usri1_flags;
178 6 : uX->usriX_script_path = u1->usri1_script_path;
179 6 : break;
180 0 : case 2:
181 0 : u2 = (struct USER_INFO_2 *)buffer;
182 0 : uX->usriX_name = u2->usri2_name;
183 0 : uX->usriX_password = u2->usri2_password;
184 0 : uX->usriX_password_age = u2->usri2_password_age;
185 0 : uX->usriX_priv = u2->usri2_priv;
186 0 : uX->usriX_home_dir = u2->usri2_home_dir;
187 0 : uX->usriX_comment = u2->usri2_comment;
188 0 : uX->usriX_flags = u2->usri2_flags;
189 0 : uX->usriX_script_path = u2->usri2_script_path;
190 0 : uX->usriX_auth_flags = u2->usri2_auth_flags;
191 0 : uX->usriX_full_name = u2->usri2_full_name;
192 0 : uX->usriX_usr_comment = u2->usri2_usr_comment;
193 0 : uX->usriX_parms = u2->usri2_parms;
194 0 : uX->usriX_workstations = u2->usri2_workstations;
195 0 : uX->usriX_last_logon = u2->usri2_last_logon;
196 0 : uX->usriX_last_logoff = u2->usri2_last_logoff;
197 0 : uX->usriX_acct_expires = u2->usri2_acct_expires;
198 0 : uX->usriX_max_storage = u2->usri2_max_storage;
199 0 : uX->usriX_units_per_week= u2->usri2_units_per_week;
200 0 : uX->usriX_logon_hours = u2->usri2_logon_hours;
201 0 : uX->usriX_bad_pw_count = u2->usri2_bad_pw_count;
202 0 : uX->usriX_num_logons = u2->usri2_num_logons;
203 0 : uX->usriX_logon_server = u2->usri2_logon_server;
204 0 : uX->usriX_country_code = u2->usri2_country_code;
205 0 : uX->usriX_code_page = u2->usri2_code_page;
206 0 : break;
207 0 : case 3:
208 0 : u3 = (struct USER_INFO_3 *)buffer;
209 0 : uX->usriX_name = u3->usri3_name;
210 0 : uX->usriX_password_age = u3->usri3_password_age;
211 0 : uX->usriX_priv = u3->usri3_priv;
212 0 : uX->usriX_home_dir = u3->usri3_home_dir;
213 0 : uX->usriX_comment = u3->usri3_comment;
214 0 : uX->usriX_flags = u3->usri3_flags;
215 0 : uX->usriX_script_path = u3->usri3_script_path;
216 0 : uX->usriX_auth_flags = u3->usri3_auth_flags;
217 0 : uX->usriX_full_name = u3->usri3_full_name;
218 0 : uX->usriX_usr_comment = u3->usri3_usr_comment;
219 0 : uX->usriX_parms = u3->usri3_parms;
220 0 : uX->usriX_workstations = u3->usri3_workstations;
221 0 : uX->usriX_last_logon = u3->usri3_last_logon;
222 0 : uX->usriX_last_logoff = u3->usri3_last_logoff;
223 0 : uX->usriX_acct_expires = u3->usri3_acct_expires;
224 0 : uX->usriX_max_storage = u3->usri3_max_storage;
225 0 : uX->usriX_units_per_week= u3->usri3_units_per_week;
226 0 : uX->usriX_logon_hours = u3->usri3_logon_hours;
227 0 : uX->usriX_bad_pw_count = u3->usri3_bad_pw_count;
228 0 : uX->usriX_num_logons = u3->usri3_num_logons;
229 0 : uX->usriX_logon_server = u3->usri3_logon_server;
230 0 : uX->usriX_country_code = u3->usri3_country_code;
231 0 : uX->usriX_code_page = u3->usri3_code_page;
232 0 : uX->usriX_user_id = u3->usri3_user_id;
233 0 : uX->usriX_primary_group_id = u3->usri3_primary_group_id;
234 0 : uX->usriX_profile = u3->usri3_profile;
235 0 : uX->usriX_home_dir_drive = u3->usri3_home_dir_drive;
236 0 : uX->usriX_password_expired = u3->usri3_password_expired;
237 0 : break;
238 2 : case 1003:
239 2 : u1003 = (struct USER_INFO_1003 *)buffer;
240 2 : uX->usriX_password = u1003->usri1003_password;
241 2 : break;
242 0 : case 1006:
243 0 : u1006 = (struct USER_INFO_1006 *)buffer;
244 0 : uX->usriX_home_dir = u1006->usri1006_home_dir;
245 0 : break;
246 1 : case 1007:
247 1 : u1007 = (struct USER_INFO_1007 *)buffer;
248 1 : uX->usriX_comment = u1007->usri1007_comment;
249 1 : break;
250 0 : case 1009:
251 0 : u1009 = (struct USER_INFO_1009 *)buffer;
252 0 : uX->usriX_script_path = u1009->usri1009_script_path;
253 0 : break;
254 0 : case 1011:
255 0 : u1011 = (struct USER_INFO_1011 *)buffer;
256 0 : uX->usriX_full_name = u1011->usri1011_full_name;
257 0 : break;
258 0 : case 1012:
259 0 : u1012 = (struct USER_INFO_1012 *)buffer;
260 0 : uX->usriX_usr_comment = u1012->usri1012_usr_comment;
261 0 : break;
262 0 : case 1014:
263 0 : u1014 = (struct USER_INFO_1014 *)buffer;
264 0 : uX->usriX_workstations = u1014->usri1014_workstations;
265 0 : break;
266 0 : case 1024:
267 0 : u1024 = (struct USER_INFO_1024 *)buffer;
268 0 : uX->usriX_country_code = u1024->usri1024_country_code;
269 0 : break;
270 0 : case 1051:
271 0 : u1051 = (struct USER_INFO_1051 *)buffer;
272 0 : uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
273 0 : break;
274 0 : case 1052:
275 0 : u1052 = (struct USER_INFO_1052 *)buffer;
276 0 : uX->usriX_profile = u1052->usri1052_profile;
277 0 : break;
278 0 : case 1053:
279 0 : u1053 = (struct USER_INFO_1053 *)buffer;
280 0 : uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
281 0 : break;
282 0 : case 4:
283 : default:
284 0 : return NT_STATUS_INVALID_INFO_CLASS;
285 : }
286 :
287 10 : return NT_STATUS_OK;
288 : }
289 :
290 : /****************************************************************
291 : ****************************************************************/
292 :
293 10 : static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *mem_ctx,
294 : struct rpc_pipe_client *pipe_cli,
295 : DATA_BLOB *session_key,
296 : struct policy_handle *user_handle,
297 : struct USER_INFO_X *uX)
298 : {
299 0 : union samr_UserInfo user_info;
300 0 : struct samr_UserInfo21 info21;
301 0 : NTSTATUS status, result;
302 10 : struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
303 :
304 10 : if (!uX) {
305 0 : return NT_STATUS_INVALID_PARAMETER;
306 : }
307 :
308 10 : convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
309 :
310 10 : ZERO_STRUCT(user_info);
311 :
312 10 : if (uX->usriX_password) {
313 :
314 8 : user_info.info25.info = info21;
315 :
316 8 : status = init_samr_CryptPasswordEx(uX->usriX_password,
317 : session_key,
318 : &user_info.info25.password);
319 8 : if (!NT_STATUS_IS_OK(status)) {
320 0 : return status;
321 : }
322 :
323 8 : status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
324 : user_handle,
325 : 25,
326 : &user_info,
327 : &result);
328 8 : if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
329 :
330 0 : user_info.info23.info = info21;
331 :
332 0 : status = init_samr_CryptPassword(uX->usriX_password,
333 : session_key,
334 : &user_info.info23.password);
335 0 : if (!NT_STATUS_IS_OK(status)) {
336 0 : return status;
337 : }
338 :
339 0 : status = dcerpc_samr_SetUserInfo2(b, mem_ctx,
340 : user_handle,
341 : 23,
342 : &user_info,
343 : &result);
344 0 : if (!NT_STATUS_IS_OK(status)) {
345 0 : return status;
346 : }
347 : }
348 :
349 8 : if (!NT_STATUS_IS_OK(status)) {
350 0 : return status;
351 : }
352 : } else {
353 :
354 2 : user_info.info21 = info21;
355 :
356 2 : status = dcerpc_samr_SetUserInfo(b, mem_ctx,
357 : user_handle,
358 : 21,
359 : &user_info,
360 : &result);
361 2 : if (!NT_STATUS_IS_OK(status)) {
362 0 : return status;
363 : }
364 : }
365 :
366 10 : return result;
367 : }
368 :
369 : /****************************************************************
370 : ****************************************************************/
371 :
372 6 : WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
373 : struct NetUserAdd *r)
374 : {
375 6 : struct rpc_pipe_client *pipe_cli = NULL;
376 0 : NTSTATUS status, result;
377 0 : WERROR werr;
378 0 : struct policy_handle connect_handle, domain_handle, user_handle;
379 0 : struct lsa_String lsa_account_name;
380 6 : struct dom_sid2 *domain_sid = NULL;
381 6 : union samr_UserInfo *user_info = NULL;
382 0 : struct samr_PwInfo pw_info;
383 6 : uint32_t access_granted = 0;
384 6 : uint32_t rid = 0;
385 0 : struct USER_INFO_X uX;
386 6 : struct dcerpc_binding_handle *b = NULL;
387 0 : DATA_BLOB session_key;
388 :
389 6 : ZERO_STRUCT(connect_handle);
390 6 : ZERO_STRUCT(domain_handle);
391 6 : ZERO_STRUCT(user_handle);
392 :
393 6 : if (!r->in.buffer) {
394 0 : return WERR_INVALID_PARAMETER;
395 : }
396 :
397 6 : switch (r->in.level) {
398 6 : case 1:
399 6 : break;
400 0 : case 2:
401 : case 3:
402 : case 4:
403 : default:
404 0 : werr = WERR_NOT_SUPPORTED;
405 0 : goto done;
406 : }
407 :
408 6 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
409 : &ndr_table_samr,
410 : &pipe_cli);
411 6 : if (!W_ERROR_IS_OK(werr)) {
412 0 : goto done;
413 : }
414 :
415 6 : b = pipe_cli->binding_handle;
416 :
417 6 : status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
418 6 : if (!NT_STATUS_IS_OK(status)) {
419 0 : werr = ntstatus_to_werror(status);
420 0 : goto done;
421 : }
422 :
423 6 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
424 : SAMR_ACCESS_ENUM_DOMAINS |
425 : SAMR_ACCESS_LOOKUP_DOMAIN,
426 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
427 : SAMR_DOMAIN_ACCESS_CREATE_USER |
428 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
429 : &connect_handle,
430 : &domain_handle,
431 : &domain_sid);
432 6 : if (!W_ERROR_IS_OK(werr)) {
433 0 : goto done;
434 : }
435 :
436 6 : init_lsa_String(&lsa_account_name, uX.usriX_name);
437 :
438 6 : status = dcerpc_samr_CreateUser2(b, talloc_tos(),
439 : &domain_handle,
440 : &lsa_account_name,
441 : ACB_NORMAL,
442 : SEC_STD_WRITE_DAC |
443 : SEC_STD_DELETE |
444 : SAMR_USER_ACCESS_SET_PASSWORD |
445 : SAMR_USER_ACCESS_SET_ATTRIBUTES |
446 : SAMR_USER_ACCESS_GET_ATTRIBUTES,
447 : &user_handle,
448 : &access_granted,
449 : &rid,
450 : &result);
451 6 : if (any_nt_status_not_ok(status, result, &status)) {
452 0 : werr = ntstatus_to_werror(status);
453 0 : goto done;
454 : }
455 :
456 6 : status = dcerpc_samr_QueryUserInfo(b, talloc_tos(),
457 : &user_handle,
458 : 16,
459 : &user_info,
460 : &result);
461 6 : if (any_nt_status_not_ok(status, result, &status)) {
462 0 : werr = ntstatus_to_werror(status);
463 0 : goto done;
464 : }
465 :
466 6 : if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
467 0 : werr = WERR_INVALID_PARAMETER;
468 0 : goto done;
469 : }
470 :
471 6 : status = dcerpc_samr_GetUserPwInfo(b, talloc_tos(),
472 : &user_handle,
473 : &pw_info,
474 : &result);
475 6 : if (any_nt_status_not_ok(status, result, &status)) {
476 0 : werr = ntstatus_to_werror(status);
477 0 : goto done;
478 : }
479 :
480 6 : status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
481 6 : if (!NT_STATUS_IS_OK(status)) {
482 0 : werr = ntstatus_to_werror(status);
483 0 : goto done;
484 : }
485 :
486 6 : uX.usriX_flags |= ACB_NORMAL;
487 :
488 6 : status = set_user_info_USER_INFO_X(ctx, pipe_cli,
489 : &session_key,
490 : &user_handle,
491 : &uX);
492 6 : if (!NT_STATUS_IS_OK(status)) {
493 0 : werr = ntstatus_to_werror(status);
494 0 : goto failed;
495 : }
496 :
497 6 : werr = WERR_OK;
498 6 : goto done;
499 :
500 0 : failed:
501 0 : dcerpc_samr_DeleteUser(b, talloc_tos(),
502 : &user_handle,
503 : &result);
504 :
505 6 : done:
506 6 : if (is_valid_policy_hnd(&user_handle) && b) {
507 6 : dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
508 : }
509 :
510 6 : if (ctx->disable_policy_handle_cache) {
511 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
512 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
513 : }
514 :
515 6 : return werr;
516 : }
517 :
518 : /****************************************************************
519 : ****************************************************************/
520 :
521 0 : WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
522 : struct NetUserAdd *r)
523 : {
524 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
525 : }
526 :
527 : /****************************************************************
528 : ****************************************************************/
529 :
530 11 : WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
531 : struct NetUserDel *r)
532 : {
533 11 : struct rpc_pipe_client *pipe_cli = NULL;
534 0 : NTSTATUS status, result;
535 0 : WERROR werr;
536 0 : struct policy_handle connect_handle, builtin_handle, domain_handle, user_handle;
537 0 : struct lsa_String lsa_account_name;
538 0 : struct samr_Ids user_rids, name_types;
539 11 : struct dom_sid2 *domain_sid = NULL;
540 0 : struct dom_sid2 user_sid;
541 11 : struct dcerpc_binding_handle *b = NULL;
542 :
543 11 : ZERO_STRUCT(connect_handle);
544 11 : ZERO_STRUCT(builtin_handle);
545 11 : ZERO_STRUCT(domain_handle);
546 11 : ZERO_STRUCT(user_handle);
547 :
548 11 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
549 : &ndr_table_samr,
550 : &pipe_cli);
551 :
552 11 : if (!W_ERROR_IS_OK(werr)) {
553 0 : goto done;
554 : }
555 :
556 11 : b = pipe_cli->binding_handle;
557 :
558 11 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
559 : SAMR_ACCESS_ENUM_DOMAINS |
560 : SAMR_ACCESS_LOOKUP_DOMAIN,
561 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
562 : &connect_handle,
563 : &domain_handle,
564 : &domain_sid);
565 11 : if (!W_ERROR_IS_OK(werr)) {
566 0 : goto done;
567 : }
568 :
569 11 : status = dcerpc_samr_OpenDomain(b, talloc_tos(),
570 : &connect_handle,
571 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
572 : discard_const_p(struct dom_sid, &global_sid_Builtin),
573 : &builtin_handle,
574 : &result);
575 11 : if (any_nt_status_not_ok(status, result, &status)) {
576 0 : werr = ntstatus_to_werror(status);
577 0 : goto done;
578 : }
579 :
580 11 : init_lsa_String(&lsa_account_name, r->in.user_name);
581 :
582 11 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
583 : &domain_handle,
584 : 1,
585 : &lsa_account_name,
586 : &user_rids,
587 : &name_types,
588 : &result);
589 11 : if (any_nt_status_not_ok(status, result, &status)) {
590 5 : werr = ntstatus_to_werror(status);
591 5 : goto done;
592 : }
593 6 : if (user_rids.count != 1) {
594 0 : werr = WERR_BAD_NET_RESP;
595 0 : goto done;
596 : }
597 6 : if (name_types.count != 1) {
598 0 : werr = WERR_BAD_NET_RESP;
599 0 : goto done;
600 : }
601 :
602 6 : status = dcerpc_samr_OpenUser(b, talloc_tos(),
603 : &domain_handle,
604 : SEC_STD_DELETE,
605 6 : user_rids.ids[0],
606 : &user_handle,
607 : &result);
608 6 : if (any_nt_status_not_ok(status, result, &status)) {
609 0 : werr = ntstatus_to_werror(status);
610 0 : goto done;
611 : }
612 :
613 6 : sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
614 :
615 6 : status = dcerpc_samr_RemoveMemberFromForeignDomain(b, talloc_tos(),
616 : &builtin_handle,
617 : &user_sid,
618 : &result);
619 6 : if (any_nt_status_not_ok(status, result, &status)) {
620 0 : werr = ntstatus_to_werror(status);
621 0 : goto done;
622 : }
623 :
624 6 : status = dcerpc_samr_DeleteUser(b, talloc_tos(),
625 : &user_handle,
626 : &result);
627 6 : if (any_nt_status_not_ok(status, result, &status)) {
628 0 : werr = ntstatus_to_werror(status);
629 0 : goto done;
630 : }
631 :
632 6 : werr = WERR_OK;
633 :
634 11 : done:
635 11 : if (is_valid_policy_hnd(&user_handle)) {
636 0 : dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
637 : }
638 :
639 11 : if (ctx->disable_policy_handle_cache) {
640 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
641 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
642 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
643 : }
644 :
645 11 : return werr;
646 : }
647 :
648 : /****************************************************************
649 : ****************************************************************/
650 :
651 0 : WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
652 : struct NetUserDel *r)
653 : {
654 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
655 : }
656 :
657 : /****************************************************************
658 : ****************************************************************/
659 :
660 136 : static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
661 : struct rpc_pipe_client *pipe_cli,
662 : struct policy_handle *domain_handle,
663 : struct policy_handle *builtin_handle,
664 : const char *user_name,
665 : const struct dom_sid *domain_sid,
666 : uint32_t rid,
667 : uint32_t level,
668 : struct samr_UserInfo21 **info21,
669 : struct sec_desc_buf **sec_desc,
670 : uint32_t *auth_flag_p)
671 : {
672 0 : NTSTATUS status, result;
673 :
674 0 : struct policy_handle user_handle;
675 136 : union samr_UserInfo *user_info = NULL;
676 136 : struct samr_RidWithAttributeArray *rid_array = NULL;
677 136 : uint32_t access_mask = SEC_STD_READ_CONTROL |
678 : SAMR_USER_ACCESS_GET_ATTRIBUTES |
679 : SAMR_USER_ACCESS_GET_NAME_ETC;
680 136 : struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
681 :
682 136 : ZERO_STRUCT(user_handle);
683 :
684 136 : switch (level) {
685 0 : case 0:
686 0 : break;
687 17 : case 1:
688 17 : access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
689 : SAMR_USER_ACCESS_GET_GROUPS;
690 17 : break;
691 68 : case 2:
692 : case 3:
693 : case 4:
694 : case 11:
695 68 : access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO |
696 : SAMR_USER_ACCESS_GET_GROUPS |
697 : SAMR_USER_ACCESS_GET_LOCALE;
698 68 : break;
699 51 : case 10:
700 : case 20:
701 : case 23:
702 51 : break;
703 0 : default:
704 0 : return NT_STATUS_INVALID_LEVEL;
705 : }
706 :
707 136 : if (level == 0) {
708 0 : return NT_STATUS_OK;
709 : }
710 :
711 136 : status = dcerpc_samr_OpenUser(b, mem_ctx,
712 : domain_handle,
713 : access_mask,
714 : rid,
715 : &user_handle,
716 : &result);
717 136 : if (any_nt_status_not_ok(status, result, &status)) {
718 0 : goto done;
719 : }
720 :
721 136 : status = dcerpc_samr_QueryUserInfo(b, mem_ctx,
722 : &user_handle,
723 : 21,
724 : &user_info,
725 : &result);
726 136 : if (any_nt_status_not_ok(status, result, &status)) {
727 0 : goto done;
728 : }
729 :
730 136 : status = dcerpc_samr_QuerySecurity(b, mem_ctx,
731 : &user_handle,
732 : SECINFO_DACL,
733 : sec_desc,
734 : &result);
735 136 : if (any_nt_status_not_ok(status, result, &status)) {
736 0 : goto done;
737 : }
738 :
739 136 : if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) {
740 :
741 0 : struct lsa_SidArray sid_array;
742 0 : struct samr_Ids alias_rids;
743 0 : int i;
744 85 : uint32_t auth_flag = 0;
745 0 : struct dom_sid sid;
746 :
747 85 : status = dcerpc_samr_GetGroupsForUser(b, mem_ctx,
748 : &user_handle,
749 : &rid_array,
750 : &result);
751 85 : if (any_nt_status_not_ok(status, result, &status)) {
752 0 : goto done;
753 : }
754 :
755 85 : sid_array.num_sids = rid_array->count + 1;
756 85 : sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr,
757 : sid_array.num_sids);
758 85 : NT_STATUS_HAVE_NO_MEMORY(sid_array.sids);
759 :
760 195 : for (i=0; i<rid_array->count; i++) {
761 110 : sid_compose(&sid, domain_sid, rid_array->rids[i].rid);
762 110 : sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
763 110 : NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
764 : }
765 :
766 85 : sid_compose(&sid, domain_sid, rid);
767 85 : sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid);
768 85 : NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid);
769 :
770 85 : status = dcerpc_samr_GetAliasMembership(b, mem_ctx,
771 : builtin_handle,
772 : &sid_array,
773 : &alias_rids,
774 : &result);
775 85 : if (any_nt_status_not_ok(status, result, &status)) {
776 0 : goto done;
777 : }
778 :
779 175 : for (i=0; i<alias_rids.count; i++) {
780 90 : switch (alias_rids.ids[i]) {
781 0 : case 550: /* Print Operators */
782 0 : auth_flag |= AF_OP_PRINT;
783 0 : break;
784 0 : case 549: /* Server Operators */
785 0 : auth_flag |= AF_OP_SERVER;
786 0 : break;
787 0 : case 548: /* Account Operators */
788 0 : auth_flag |= AF_OP_ACCOUNTS;
789 0 : break;
790 90 : default:
791 90 : break;
792 : }
793 : }
794 :
795 85 : if (auth_flag_p) {
796 85 : *auth_flag_p = auth_flag;
797 : }
798 : }
799 :
800 136 : *info21 = &user_info->info21;
801 :
802 136 : done:
803 136 : if (is_valid_policy_hnd(&user_handle)) {
804 136 : dcerpc_samr_Close(b, mem_ctx, &user_handle, &result);
805 : }
806 :
807 136 : return status;
808 : }
809 :
810 : /****************************************************************
811 : ****************************************************************/
812 :
813 85 : static uint32_t samr_rid_to_priv_level(uint32_t rid)
814 : {
815 85 : switch (rid) {
816 5 : case DOMAIN_RID_ADMINISTRATOR:
817 5 : return USER_PRIV_ADMIN;
818 5 : case DOMAIN_RID_GUEST:
819 5 : return USER_PRIV_GUEST;
820 75 : default:
821 75 : return USER_PRIV_USER;
822 : }
823 : }
824 :
825 : /****************************************************************
826 : ****************************************************************/
827 :
828 102 : static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
829 : {
830 102 : uint32_t fl = UF_SCRIPT; /* god knows why */
831 :
832 102 : fl |= ds_acb2uf(acb);
833 :
834 102 : return fl;
835 : }
836 :
837 : /****************************************************************
838 : ****************************************************************/
839 :
840 17 : static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx,
841 : const struct samr_UserInfo21 *i21,
842 : struct USER_INFO_1 *i)
843 : {
844 17 : ZERO_STRUCTP(i);
845 17 : i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string);
846 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri1_name);
847 17 : i->usri1_password = NULL;
848 17 : i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
849 17 : i->usri1_priv = samr_rid_to_priv_level(i21->rid);
850 17 : i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
851 17 : i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string);
852 17 : i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
853 17 : i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
854 :
855 17 : return NT_STATUS_OK;
856 : }
857 :
858 : /****************************************************************
859 : ****************************************************************/
860 :
861 17 : static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx,
862 : const struct samr_UserInfo21 *i21,
863 : uint32_t auth_flag,
864 : struct USER_INFO_2 *i)
865 : {
866 17 : ZERO_STRUCTP(i);
867 :
868 17 : i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string);
869 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri2_name);
870 17 : i->usri2_password = NULL;
871 17 : i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
872 17 : i->usri2_priv = samr_rid_to_priv_level(i21->rid);
873 17 : i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
874 17 : i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string);
875 17 : i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
876 17 : i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
877 17 : i->usri2_auth_flags = auth_flag;
878 17 : i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
879 17 : i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
880 17 : i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
881 17 : i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
882 17 : i->usri2_last_logon = nt_time_to_unix(i21->last_logon);
883 17 : i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff);
884 17 : i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry);
885 17 : i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
886 17 : i->usri2_units_per_week = i21->logon_hours.units_per_week;
887 17 : i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
888 17 : i->usri2_bad_pw_count = i21->bad_password_count;
889 17 : i->usri2_num_logons = i21->logon_count;
890 17 : i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*");
891 17 : i->usri2_country_code = i21->country_code;
892 17 : i->usri2_code_page = i21->code_page;
893 :
894 17 : return NT_STATUS_OK;
895 : }
896 :
897 : /****************************************************************
898 : ****************************************************************/
899 :
900 17 : static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx,
901 : const struct samr_UserInfo21 *i21,
902 : uint32_t auth_flag,
903 : struct USER_INFO_3 *i)
904 : {
905 17 : ZERO_STRUCTP(i);
906 :
907 17 : i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string);
908 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri3_name);
909 17 : i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
910 17 : i->usri3_priv = samr_rid_to_priv_level(i21->rid);
911 17 : i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
912 17 : i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string);
913 17 : i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
914 17 : i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
915 17 : i->usri3_auth_flags = auth_flag;
916 17 : i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
917 17 : i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
918 17 : i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
919 17 : i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
920 17 : i->usri3_last_logon = nt_time_to_unix(i21->last_logon);
921 17 : i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff);
922 17 : i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry);
923 17 : i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
924 17 : i->usri3_units_per_week = i21->logon_hours.units_per_week;
925 17 : i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
926 17 : i->usri3_bad_pw_count = i21->bad_password_count;
927 17 : i->usri3_num_logons = i21->logon_count;
928 17 : i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*");
929 17 : i->usri3_country_code = i21->country_code;
930 17 : i->usri3_code_page = i21->code_page;
931 17 : i->usri3_user_id = i21->rid;
932 17 : i->usri3_primary_group_id = i21->primary_gid;
933 17 : i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
934 17 : i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
935 17 : i->usri3_password_expired = i21->password_expired;
936 :
937 17 : return NT_STATUS_OK;
938 : }
939 :
940 : /****************************************************************
941 : ****************************************************************/
942 :
943 17 : static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx,
944 : const struct samr_UserInfo21 *i21,
945 : uint32_t auth_flag,
946 : struct dom_sid *domain_sid,
947 : struct USER_INFO_4 *i)
948 : {
949 0 : struct dom_sid sid;
950 :
951 17 : ZERO_STRUCTP(i);
952 :
953 17 : i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string);
954 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri4_name);
955 17 : i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
956 17 : i->usri4_password = NULL;
957 17 : i->usri4_priv = samr_rid_to_priv_level(i21->rid);
958 17 : i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
959 17 : i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string);
960 17 : i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
961 17 : i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string);
962 17 : i->usri4_auth_flags = auth_flag;
963 17 : i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
964 17 : i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
965 17 : i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
966 17 : i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
967 17 : i->usri4_last_logon = nt_time_to_unix(i21->last_logon);
968 17 : i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff);
969 17 : i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry);
970 17 : i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
971 17 : i->usri4_units_per_week = i21->logon_hours.units_per_week;
972 17 : i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
973 17 : i->usri4_bad_pw_count = i21->bad_password_count;
974 17 : i->usri4_num_logons = i21->logon_count;
975 17 : i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*");
976 17 : i->usri4_country_code = i21->country_code;
977 17 : i->usri4_code_page = i21->code_page;
978 17 : if (!sid_compose(&sid, domain_sid, i21->rid)) {
979 0 : return NT_STATUS_NO_MEMORY;
980 : }
981 17 : i->usri4_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
982 17 : i->usri4_primary_group_id = i21->primary_gid;
983 17 : i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string);
984 17 : i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string);
985 17 : i->usri4_password_expired = i21->password_expired;
986 :
987 17 : return NT_STATUS_OK;
988 : }
989 :
990 : /****************************************************************
991 : ****************************************************************/
992 :
993 17 : static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx,
994 : const struct samr_UserInfo21 *i21,
995 : struct USER_INFO_10 *i)
996 : {
997 17 : ZERO_STRUCTP(i);
998 :
999 17 : i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string);
1000 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri10_name);
1001 17 : i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string);
1002 17 : i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1003 17 : i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1004 :
1005 17 : return NT_STATUS_OK;
1006 : }
1007 :
1008 : /****************************************************************
1009 : ****************************************************************/
1010 :
1011 17 : static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx,
1012 : const struct samr_UserInfo21 *i21,
1013 : uint32_t auth_flag,
1014 : struct USER_INFO_11 *i)
1015 : {
1016 17 : ZERO_STRUCTP(i);
1017 :
1018 17 : i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string);
1019 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri11_name);
1020 17 : i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string);
1021 17 : i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string);
1022 17 : i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1023 17 : i->usri11_priv = samr_rid_to_priv_level(i21->rid);
1024 17 : i->usri11_auth_flags = auth_flag;
1025 17 : i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change);
1026 17 : i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string);
1027 17 : i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2);
1028 17 : i->usri11_last_logon = nt_time_to_unix(i21->last_logon);
1029 17 : i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff);
1030 17 : i->usri11_bad_pw_count = i21->bad_password_count;
1031 17 : i->usri11_num_logons = i21->logon_count;
1032 17 : i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*");
1033 17 : i->usri11_country_code = i21->country_code;
1034 17 : i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string);
1035 17 : i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */
1036 17 : i->usri11_units_per_week = i21->logon_hours.units_per_week;
1037 17 : i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21);
1038 17 : i->usri11_code_page = i21->code_page;
1039 :
1040 17 : return NT_STATUS_OK;
1041 : }
1042 :
1043 : /****************************************************************
1044 : ****************************************************************/
1045 :
1046 17 : static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx,
1047 : const struct samr_UserInfo21 *i21,
1048 : struct USER_INFO_20 *i)
1049 : {
1050 17 : ZERO_STRUCTP(i);
1051 :
1052 17 : i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string);
1053 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri20_name);
1054 17 : i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string);
1055 17 : i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1056 17 : i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1057 17 : i->usri20_user_id = i21->rid;
1058 :
1059 17 : return NT_STATUS_OK;
1060 : }
1061 :
1062 : /****************************************************************
1063 : ****************************************************************/
1064 :
1065 17 : static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx,
1066 : const struct samr_UserInfo21 *i21,
1067 : struct dom_sid *domain_sid,
1068 : struct USER_INFO_23 *i)
1069 : {
1070 0 : struct dom_sid sid;
1071 :
1072 17 : ZERO_STRUCTP(i);
1073 :
1074 17 : i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string);
1075 17 : NT_STATUS_HAVE_NO_MEMORY(i->usri23_name);
1076 17 : i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string);
1077 17 : i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string);
1078 17 : i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags);
1079 17 : if (!sid_compose(&sid, domain_sid, i21->rid)) {
1080 0 : return NT_STATUS_NO_MEMORY;
1081 : }
1082 17 : i->usri23_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
1083 :
1084 17 : return NT_STATUS_OK;
1085 : }
1086 :
1087 : /****************************************************************
1088 : ****************************************************************/
1089 :
1090 153 : static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
1091 : struct rpc_pipe_client *pipe_cli,
1092 : struct dom_sid *domain_sid,
1093 : struct policy_handle *domain_handle,
1094 : struct policy_handle *builtin_handle,
1095 : const char *user_name,
1096 : uint32_t rid,
1097 : uint32_t level,
1098 : uint8_t **buffer,
1099 : uint32_t *num_entries)
1100 : {
1101 0 : NTSTATUS status;
1102 :
1103 153 : struct samr_UserInfo21 *info21 = NULL;
1104 153 : struct sec_desc_buf *sec_desc = NULL;
1105 153 : uint32_t auth_flag = 0;
1106 :
1107 0 : struct USER_INFO_0 info0;
1108 0 : struct USER_INFO_1 info1;
1109 0 : struct USER_INFO_2 info2;
1110 0 : struct USER_INFO_3 info3;
1111 0 : struct USER_INFO_4 info4;
1112 0 : struct USER_INFO_10 info10;
1113 0 : struct USER_INFO_11 info11;
1114 0 : struct USER_INFO_20 info20;
1115 0 : struct USER_INFO_23 info23;
1116 :
1117 153 : switch (level) {
1118 153 : case 0:
1119 : case 1:
1120 : case 2:
1121 : case 3:
1122 : case 4:
1123 : case 10:
1124 : case 11:
1125 : case 20:
1126 : case 23:
1127 153 : break;
1128 0 : default:
1129 0 : return NT_STATUS_INVALID_LEVEL;
1130 : }
1131 :
1132 153 : if (level == 0) {
1133 17 : info0.usri0_name = talloc_strdup(mem_ctx, user_name);
1134 17 : NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
1135 :
1136 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
1137 : (struct USER_INFO_0 **)buffer, num_entries);
1138 :
1139 17 : return NT_STATUS_OK;
1140 : }
1141 :
1142 136 : status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
1143 : domain_handle,
1144 : builtin_handle,
1145 : user_name,
1146 : domain_sid,
1147 : rid,
1148 : level,
1149 : &info21,
1150 : &sec_desc,
1151 : &auth_flag);
1152 :
1153 136 : if (!NT_STATUS_IS_OK(status)) {
1154 0 : goto done;
1155 : }
1156 :
1157 136 : switch (level) {
1158 17 : case 1:
1159 17 : status = info21_to_USER_INFO_1(mem_ctx, info21, &info1);
1160 17 : NT_STATUS_NOT_OK_RETURN(status);
1161 :
1162 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1,
1163 : (struct USER_INFO_1 **)buffer, num_entries);
1164 :
1165 136 : break;
1166 17 : case 2:
1167 17 : status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2);
1168 17 : NT_STATUS_NOT_OK_RETURN(status);
1169 :
1170 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2,
1171 : (struct USER_INFO_2 **)buffer, num_entries);
1172 :
1173 17 : break;
1174 17 : case 3:
1175 17 : status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3);
1176 17 : NT_STATUS_NOT_OK_RETURN(status);
1177 :
1178 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3,
1179 : (struct USER_INFO_3 **)buffer, num_entries);
1180 :
1181 17 : break;
1182 17 : case 4:
1183 17 : status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4);
1184 17 : NT_STATUS_NOT_OK_RETURN(status);
1185 :
1186 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4,
1187 : (struct USER_INFO_4 **)buffer, num_entries);
1188 :
1189 17 : break;
1190 17 : case 10:
1191 17 : status = info21_to_USER_INFO_10(mem_ctx, info21, &info10);
1192 17 : NT_STATUS_NOT_OK_RETURN(status);
1193 :
1194 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
1195 : (struct USER_INFO_10 **)buffer, num_entries);
1196 :
1197 17 : break;
1198 17 : case 11:
1199 17 : status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11);
1200 17 : NT_STATUS_NOT_OK_RETURN(status);
1201 :
1202 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11,
1203 : (struct USER_INFO_11 **)buffer, num_entries);
1204 :
1205 17 : break;
1206 17 : case 20:
1207 17 : status = info21_to_USER_INFO_20(mem_ctx, info21, &info20);
1208 17 : NT_STATUS_NOT_OK_RETURN(status);
1209 :
1210 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
1211 : (struct USER_INFO_20 **)buffer, num_entries);
1212 :
1213 17 : break;
1214 17 : case 23:
1215 17 : status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23);
1216 17 : NT_STATUS_NOT_OK_RETURN(status);
1217 :
1218 17 : ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
1219 : (struct USER_INFO_23 **)buffer, num_entries);
1220 17 : break;
1221 0 : default:
1222 0 : return NT_STATUS_INVALID_LEVEL;
1223 : }
1224 :
1225 136 : done:
1226 136 : return status;
1227 : }
1228 :
1229 : /****************************************************************
1230 : ****************************************************************/
1231 :
1232 9 : WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
1233 : struct NetUserEnum *r)
1234 : {
1235 9 : struct rpc_pipe_client *pipe_cli = NULL;
1236 0 : struct policy_handle connect_handle;
1237 9 : struct dom_sid2 *domain_sid = NULL;
1238 0 : struct policy_handle domain_handle, builtin_handle;
1239 9 : struct samr_SamArray *sam = NULL;
1240 9 : uint32_t filter = ACB_NORMAL;
1241 0 : int i;
1242 9 : uint32_t entries_read = 0;
1243 :
1244 0 : NTSTATUS status;
1245 9 : NTSTATUS result = NT_STATUS_OK;
1246 0 : WERROR werr;
1247 9 : struct dcerpc_binding_handle *b = NULL;
1248 :
1249 9 : ZERO_STRUCT(connect_handle);
1250 9 : ZERO_STRUCT(domain_handle);
1251 9 : ZERO_STRUCT(builtin_handle);
1252 :
1253 9 : if (!r->out.buffer) {
1254 0 : return WERR_INVALID_PARAMETER;
1255 : }
1256 :
1257 9 : *r->out.buffer = NULL;
1258 9 : *r->out.entries_read = 0;
1259 :
1260 9 : switch (r->in.level) {
1261 9 : case 0:
1262 : case 1:
1263 : case 2:
1264 : case 3:
1265 : case 4:
1266 : case 10:
1267 : case 11:
1268 : case 20:
1269 : case 23:
1270 9 : break;
1271 0 : default:
1272 0 : return WERR_INVALID_LEVEL;
1273 : }
1274 :
1275 9 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
1276 : &ndr_table_samr,
1277 : &pipe_cli);
1278 9 : if (!W_ERROR_IS_OK(werr)) {
1279 0 : goto done;
1280 : }
1281 :
1282 9 : b = pipe_cli->binding_handle;
1283 :
1284 9 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1285 : SAMR_ACCESS_ENUM_DOMAINS |
1286 : SAMR_ACCESS_LOOKUP_DOMAIN,
1287 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1288 : SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1289 : &connect_handle,
1290 : &builtin_handle);
1291 9 : if (!W_ERROR_IS_OK(werr)) {
1292 0 : goto done;
1293 : }
1294 :
1295 9 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1296 : SAMR_ACCESS_ENUM_DOMAINS |
1297 : SAMR_ACCESS_LOOKUP_DOMAIN,
1298 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1299 : SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1300 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1301 : &connect_handle,
1302 : &domain_handle,
1303 : &domain_sid);
1304 9 : if (!W_ERROR_IS_OK(werr)) {
1305 0 : goto done;
1306 : }
1307 :
1308 9 : switch (r->in.filter) {
1309 9 : case FILTER_NORMAL_ACCOUNT:
1310 9 : filter = ACB_NORMAL;
1311 9 : break;
1312 0 : case FILTER_TEMP_DUPLICATE_ACCOUNT:
1313 0 : filter = ACB_TEMPDUP;
1314 0 : break;
1315 0 : case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
1316 0 : filter = ACB_DOMTRUST;
1317 0 : break;
1318 0 : case FILTER_WORKSTATION_TRUST_ACCOUNT:
1319 0 : filter = ACB_WSTRUST;
1320 0 : break;
1321 0 : case FILTER_SERVER_TRUST_ACCOUNT:
1322 0 : filter = ACB_SVRTRUST;
1323 0 : break;
1324 0 : default:
1325 0 : break;
1326 : }
1327 :
1328 9 : status = dcerpc_samr_EnumDomainUsers(b,
1329 : ctx,
1330 : &domain_handle,
1331 : r->in.resume_handle,
1332 : filter,
1333 : &sam,
1334 : r->in.prefmaxlen,
1335 : &entries_read,
1336 : &result);
1337 9 : if (!NT_STATUS_IS_OK(status)) {
1338 0 : werr = ntstatus_to_werror(status);
1339 0 : goto done;
1340 : }
1341 9 : werr = ntstatus_to_werror(result);
1342 9 : if (NT_STATUS_IS_ERR(result)) {
1343 0 : goto done;
1344 : }
1345 :
1346 144 : for (i=0; i < sam->count; i++) {
1347 :
1348 135 : status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1349 : domain_sid,
1350 : &domain_handle,
1351 : &builtin_handle,
1352 135 : sam->entries[i].name.string,
1353 135 : sam->entries[i].idx,
1354 : r->in.level,
1355 : r->out.buffer,
1356 : r->out.entries_read);
1357 135 : if (!NT_STATUS_IS_OK(status)) {
1358 0 : werr = ntstatus_to_werror(status);
1359 0 : goto done;
1360 : }
1361 : }
1362 :
1363 9 : done:
1364 : /* if last query */
1365 9 : if (NT_STATUS_IS_OK(result) ||
1366 0 : NT_STATUS_IS_ERR(result)) {
1367 :
1368 9 : if (ctx->disable_policy_handle_cache) {
1369 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1370 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1371 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1372 : }
1373 : }
1374 :
1375 9 : return werr;
1376 : }
1377 :
1378 : /****************************************************************
1379 : ****************************************************************/
1380 :
1381 0 : WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
1382 : struct NetUserEnum *r)
1383 : {
1384 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
1385 : }
1386 :
1387 : /****************************************************************
1388 : ****************************************************************/
1389 :
1390 0 : static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
1391 : struct samr_DispInfoGeneral *info,
1392 : uint32_t *entries_read,
1393 : void **buffer)
1394 : {
1395 0 : struct NET_DISPLAY_USER *user = NULL;
1396 0 : int i;
1397 :
1398 0 : user = talloc_zero_array(mem_ctx,
1399 : struct NET_DISPLAY_USER,
1400 : info->count);
1401 0 : W_ERROR_HAVE_NO_MEMORY(user);
1402 :
1403 0 : for (i = 0; i < info->count; i++) {
1404 0 : user[i].usri1_name = talloc_strdup(mem_ctx,
1405 0 : info->entries[i].account_name.string);
1406 0 : user[i].usri1_comment = talloc_strdup(mem_ctx,
1407 0 : info->entries[i].description.string);
1408 0 : user[i].usri1_flags =
1409 0 : info->entries[i].acct_flags;
1410 0 : user[i].usri1_full_name = talloc_strdup(mem_ctx,
1411 0 : info->entries[i].full_name.string);
1412 0 : user[i].usri1_user_id =
1413 0 : info->entries[i].rid;
1414 0 : user[i].usri1_next_index =
1415 0 : info->entries[i].idx;
1416 :
1417 0 : if (!user[i].usri1_name) {
1418 0 : return WERR_NOT_ENOUGH_MEMORY;
1419 : }
1420 : }
1421 :
1422 0 : *buffer = talloc_memdup(mem_ctx, user,
1423 : sizeof(struct NET_DISPLAY_USER) * info->count);
1424 0 : W_ERROR_HAVE_NO_MEMORY(*buffer);
1425 :
1426 0 : *entries_read = info->count;
1427 :
1428 0 : return WERR_OK;
1429 : }
1430 :
1431 : /****************************************************************
1432 : ****************************************************************/
1433 :
1434 0 : static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1435 : struct samr_DispInfoFull *info,
1436 : uint32_t *entries_read,
1437 : void **buffer)
1438 : {
1439 0 : struct NET_DISPLAY_MACHINE *machine = NULL;
1440 0 : int i;
1441 :
1442 0 : machine = talloc_zero_array(mem_ctx,
1443 : struct NET_DISPLAY_MACHINE,
1444 : info->count);
1445 0 : W_ERROR_HAVE_NO_MEMORY(machine);
1446 :
1447 0 : for (i = 0; i < info->count; i++) {
1448 0 : machine[i].usri2_name = talloc_strdup(mem_ctx,
1449 0 : info->entries[i].account_name.string);
1450 0 : machine[i].usri2_comment = talloc_strdup(mem_ctx,
1451 0 : info->entries[i].description.string);
1452 0 : machine[i].usri2_flags =
1453 0 : info->entries[i].acct_flags;
1454 0 : machine[i].usri2_user_id =
1455 0 : info->entries[i].rid;
1456 0 : machine[i].usri2_next_index =
1457 0 : info->entries[i].idx;
1458 :
1459 0 : if (!machine[i].usri2_name) {
1460 0 : return WERR_NOT_ENOUGH_MEMORY;
1461 : }
1462 : }
1463 :
1464 0 : *buffer = talloc_memdup(mem_ctx, machine,
1465 : sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1466 0 : W_ERROR_HAVE_NO_MEMORY(*buffer);
1467 :
1468 0 : *entries_read = info->count;
1469 :
1470 0 : return WERR_OK;
1471 : }
1472 :
1473 : /****************************************************************
1474 : ****************************************************************/
1475 :
1476 0 : static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1477 : struct samr_DispInfoFullGroups *info,
1478 : uint32_t *entries_read,
1479 : void **buffer)
1480 : {
1481 0 : struct NET_DISPLAY_GROUP *group = NULL;
1482 0 : int i;
1483 :
1484 0 : group = talloc_zero_array(mem_ctx,
1485 : struct NET_DISPLAY_GROUP,
1486 : info->count);
1487 0 : W_ERROR_HAVE_NO_MEMORY(group);
1488 :
1489 0 : for (i = 0; i < info->count; i++) {
1490 0 : group[i].grpi3_name = talloc_strdup(mem_ctx,
1491 0 : info->entries[i].account_name.string);
1492 0 : group[i].grpi3_comment = talloc_strdup(mem_ctx,
1493 0 : info->entries[i].description.string);
1494 0 : group[i].grpi3_group_id =
1495 0 : info->entries[i].rid;
1496 0 : group[i].grpi3_attributes =
1497 0 : info->entries[i].acct_flags;
1498 0 : group[i].grpi3_next_index =
1499 0 : info->entries[i].idx;
1500 :
1501 0 : if (!group[i].grpi3_name) {
1502 0 : return WERR_NOT_ENOUGH_MEMORY;
1503 : }
1504 : }
1505 :
1506 0 : *buffer = talloc_memdup(mem_ctx, group,
1507 : sizeof(struct NET_DISPLAY_GROUP) * info->count);
1508 0 : W_ERROR_HAVE_NO_MEMORY(*buffer);
1509 :
1510 0 : *entries_read = info->count;
1511 :
1512 0 : return WERR_OK;
1513 :
1514 : }
1515 :
1516 : /****************************************************************
1517 : ****************************************************************/
1518 :
1519 0 : static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1520 : union samr_DispInfo *info,
1521 : uint32_t level,
1522 : uint32_t *entries_read,
1523 : void **buffer)
1524 : {
1525 0 : switch (level) {
1526 0 : case 1:
1527 0 : return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1528 : &info->info1,
1529 : entries_read,
1530 : buffer);
1531 0 : case 2:
1532 0 : return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1533 : &info->info2,
1534 : entries_read,
1535 : buffer);
1536 0 : case 3:
1537 0 : return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1538 : &info->info3,
1539 : entries_read,
1540 : buffer);
1541 0 : default:
1542 0 : break;
1543 : }
1544 :
1545 0 : return WERR_INVALID_LEVEL;
1546 : }
1547 :
1548 : /****************************************************************
1549 : ****************************************************************/
1550 :
1551 0 : WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1552 : struct NetQueryDisplayInformation *r)
1553 : {
1554 0 : struct rpc_pipe_client *pipe_cli = NULL;
1555 0 : struct policy_handle connect_handle;
1556 0 : struct dom_sid2 *domain_sid = NULL;
1557 0 : struct policy_handle domain_handle;
1558 0 : union samr_DispInfo info;
1559 0 : struct dcerpc_binding_handle *b = NULL;
1560 :
1561 0 : uint32_t total_size = 0;
1562 0 : uint32_t returned_size = 0;
1563 :
1564 0 : NTSTATUS status;
1565 0 : NTSTATUS result = NT_STATUS_OK;
1566 0 : WERROR werr;
1567 0 : WERROR werr_tmp;
1568 :
1569 0 : *r->out.entries_read = 0;
1570 :
1571 0 : ZERO_STRUCT(connect_handle);
1572 0 : ZERO_STRUCT(domain_handle);
1573 :
1574 0 : switch (r->in.level) {
1575 0 : case 1:
1576 : case 2:
1577 : case 3:
1578 0 : break;
1579 0 : default:
1580 0 : return WERR_INVALID_LEVEL;
1581 : }
1582 :
1583 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
1584 : &ndr_table_samr,
1585 : &pipe_cli);
1586 0 : if (!W_ERROR_IS_OK(werr)) {
1587 0 : goto done;
1588 : }
1589 :
1590 0 : b = pipe_cli->binding_handle;
1591 :
1592 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1593 : SAMR_ACCESS_ENUM_DOMAINS |
1594 : SAMR_ACCESS_LOOKUP_DOMAIN,
1595 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1596 : SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1597 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1598 : &connect_handle,
1599 : &domain_handle,
1600 : &domain_sid);
1601 0 : if (!W_ERROR_IS_OK(werr)) {
1602 0 : goto done;
1603 : }
1604 :
1605 0 : status = dcerpc_samr_QueryDisplayInfo2(b,
1606 : ctx,
1607 : &domain_handle,
1608 0 : r->in.level,
1609 : r->in.idx,
1610 : r->in.entries_requested,
1611 : r->in.prefmaxlen,
1612 : &total_size,
1613 : &returned_size,
1614 : &info,
1615 : &result);
1616 0 : if (!NT_STATUS_IS_OK(status)) {
1617 0 : werr = ntstatus_to_werror(status);
1618 0 : goto done;
1619 : }
1620 0 : werr = ntstatus_to_werror(result);
1621 0 : if (NT_STATUS_IS_ERR(result)) {
1622 0 : goto done;
1623 : }
1624 :
1625 0 : werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1626 : r->in.level,
1627 : r->out.entries_read,
1628 : r->out.buffer);
1629 0 : if (!W_ERROR_IS_OK(werr_tmp)) {
1630 0 : werr = werr_tmp;
1631 : }
1632 0 : done:
1633 : /* if last query */
1634 0 : if (NT_STATUS_IS_OK(result) ||
1635 0 : NT_STATUS_IS_ERR(result)) {
1636 :
1637 0 : if (ctx->disable_policy_handle_cache) {
1638 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1639 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1640 : }
1641 : }
1642 :
1643 0 : return werr;
1644 :
1645 : }
1646 :
1647 : /****************************************************************
1648 : ****************************************************************/
1649 :
1650 :
1651 0 : WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1652 : struct NetQueryDisplayInformation *r)
1653 : {
1654 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1655 : }
1656 :
1657 : /****************************************************************
1658 : ****************************************************************/
1659 :
1660 0 : WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1661 : struct NetUserChangePassword *r)
1662 : {
1663 0 : return WERR_NOT_SUPPORTED;
1664 : }
1665 :
1666 : /****************************************************************
1667 : ****************************************************************/
1668 :
1669 0 : WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1670 : struct NetUserChangePassword *r)
1671 : {
1672 0 : return WERR_NOT_SUPPORTED;
1673 : }
1674 :
1675 : /****************************************************************
1676 : ****************************************************************/
1677 :
1678 19 : WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1679 : struct NetUserGetInfo *r)
1680 : {
1681 19 : struct rpc_pipe_client *pipe_cli = NULL;
1682 0 : NTSTATUS status, result;
1683 0 : WERROR werr;
1684 :
1685 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1686 0 : struct lsa_String lsa_account_name;
1687 19 : struct dom_sid2 *domain_sid = NULL;
1688 0 : struct samr_Ids user_rids, name_types;
1689 19 : uint32_t num_entries = 0;
1690 19 : struct dcerpc_binding_handle *b = NULL;
1691 :
1692 19 : ZERO_STRUCT(connect_handle);
1693 19 : ZERO_STRUCT(domain_handle);
1694 19 : ZERO_STRUCT(builtin_handle);
1695 19 : ZERO_STRUCT(user_handle);
1696 :
1697 19 : if (!r->out.buffer) {
1698 0 : return WERR_INVALID_PARAMETER;
1699 : }
1700 :
1701 19 : switch (r->in.level) {
1702 19 : case 0:
1703 : case 1:
1704 : case 2:
1705 : case 3:
1706 : case 4:
1707 : case 10:
1708 : case 11:
1709 : case 20:
1710 : case 23:
1711 19 : break;
1712 0 : default:
1713 0 : werr = WERR_INVALID_LEVEL;
1714 0 : goto done;
1715 : }
1716 :
1717 19 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
1718 : &ndr_table_samr,
1719 : &pipe_cli);
1720 19 : if (!W_ERROR_IS_OK(werr)) {
1721 0 : goto done;
1722 : }
1723 :
1724 19 : b = pipe_cli->binding_handle;
1725 :
1726 19 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1727 : SAMR_ACCESS_ENUM_DOMAINS |
1728 : SAMR_ACCESS_LOOKUP_DOMAIN,
1729 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1730 : &connect_handle,
1731 : &domain_handle,
1732 : &domain_sid);
1733 19 : if (!W_ERROR_IS_OK(werr)) {
1734 0 : goto done;
1735 : }
1736 :
1737 19 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1738 : SAMR_ACCESS_ENUM_DOMAINS |
1739 : SAMR_ACCESS_LOOKUP_DOMAIN,
1740 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1741 : SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1742 : &connect_handle,
1743 : &builtin_handle);
1744 19 : if (!W_ERROR_IS_OK(werr)) {
1745 0 : goto done;
1746 : }
1747 :
1748 19 : init_lsa_String(&lsa_account_name, r->in.user_name);
1749 :
1750 19 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
1751 : &domain_handle,
1752 : 1,
1753 : &lsa_account_name,
1754 : &user_rids,
1755 : &name_types,
1756 : &result);
1757 19 : if (any_nt_status_not_ok(status, result, &status)) {
1758 1 : werr = ntstatus_to_werror(status);
1759 1 : goto done;
1760 : }
1761 18 : if (user_rids.count != 1) {
1762 0 : werr = WERR_BAD_NET_RESP;
1763 0 : goto done;
1764 : }
1765 18 : if (name_types.count != 1) {
1766 0 : werr = WERR_BAD_NET_RESP;
1767 0 : goto done;
1768 : }
1769 :
1770 18 : status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1771 : domain_sid,
1772 : &domain_handle,
1773 : &builtin_handle,
1774 : r->in.user_name,
1775 18 : user_rids.ids[0],
1776 : r->in.level,
1777 : r->out.buffer,
1778 : &num_entries);
1779 18 : if (!NT_STATUS_IS_OK(status)) {
1780 0 : werr = ntstatus_to_werror(status);
1781 0 : goto done;
1782 : }
1783 :
1784 18 : done:
1785 19 : if (is_valid_policy_hnd(&user_handle) && b) {
1786 0 : dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1787 : }
1788 :
1789 19 : if (ctx->disable_policy_handle_cache) {
1790 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1791 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1792 : }
1793 :
1794 19 : return werr;
1795 : }
1796 :
1797 : /****************************************************************
1798 : ****************************************************************/
1799 :
1800 0 : WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1801 : struct NetUserGetInfo *r)
1802 : {
1803 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1804 : }
1805 :
1806 : /****************************************************************
1807 : ****************************************************************/
1808 :
1809 4 : WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1810 : struct NetUserSetInfo *r)
1811 : {
1812 4 : struct rpc_pipe_client *pipe_cli = NULL;
1813 0 : NTSTATUS status, result;
1814 0 : WERROR werr;
1815 :
1816 0 : struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1817 0 : struct lsa_String lsa_account_name;
1818 4 : struct dom_sid2 *domain_sid = NULL;
1819 0 : struct samr_Ids user_rids, name_types;
1820 4 : uint32_t user_mask = 0;
1821 :
1822 0 : struct USER_INFO_X uX;
1823 4 : struct dcerpc_binding_handle *b = NULL;
1824 0 : DATA_BLOB session_key;
1825 :
1826 4 : ZERO_STRUCT(connect_handle);
1827 4 : ZERO_STRUCT(domain_handle);
1828 4 : ZERO_STRUCT(builtin_handle);
1829 4 : ZERO_STRUCT(user_handle);
1830 :
1831 4 : if (!r->in.buffer) {
1832 0 : return WERR_INVALID_PARAMETER;
1833 : }
1834 :
1835 4 : switch (r->in.level) {
1836 1 : case 0:
1837 1 : user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1838 1 : break;
1839 2 : case 1003:
1840 2 : user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1841 2 : break;
1842 1 : case 1006:
1843 : case 1007:
1844 : case 1009:
1845 : case 1011:
1846 : case 1014:
1847 : case 1052:
1848 : case 1053:
1849 1 : user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1850 1 : break;
1851 0 : case 1012:
1852 : case 1024:
1853 0 : user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1854 0 : break;
1855 0 : case 1051:
1856 0 : user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1857 : SAMR_USER_ACCESS_GET_GROUPS;
1858 0 : break;
1859 0 : case 3:
1860 0 : user_mask = SEC_STD_READ_CONTROL |
1861 : SEC_STD_WRITE_DAC |
1862 : SAMR_USER_ACCESS_GET_GROUPS |
1863 : SAMR_USER_ACCESS_SET_PASSWORD |
1864 : SAMR_USER_ACCESS_SET_ATTRIBUTES |
1865 : SAMR_USER_ACCESS_GET_ATTRIBUTES |
1866 : SAMR_USER_ACCESS_SET_LOC_COM;
1867 0 : break;
1868 0 : case 1:
1869 : case 2:
1870 : case 4:
1871 : case 21:
1872 : case 22:
1873 : case 1005:
1874 : case 1008:
1875 : case 1010:
1876 : case 1017:
1877 : case 1020:
1878 0 : werr = WERR_NOT_SUPPORTED;
1879 0 : goto done;
1880 0 : default:
1881 0 : werr = WERR_INVALID_LEVEL;
1882 0 : goto done;
1883 : }
1884 :
1885 4 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
1886 : &ndr_table_samr,
1887 : &pipe_cli);
1888 4 : if (!W_ERROR_IS_OK(werr)) {
1889 0 : goto done;
1890 : }
1891 :
1892 4 : b = pipe_cli->binding_handle;
1893 :
1894 4 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1895 : SAMR_ACCESS_ENUM_DOMAINS |
1896 : SAMR_ACCESS_LOOKUP_DOMAIN,
1897 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1898 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1899 : &connect_handle,
1900 : &domain_handle,
1901 : &domain_sid);
1902 4 : if (!W_ERROR_IS_OK(werr)) {
1903 0 : goto done;
1904 : }
1905 :
1906 4 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1907 : SAMR_ACCESS_ENUM_DOMAINS |
1908 : SAMR_ACCESS_LOOKUP_DOMAIN,
1909 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1910 : SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1911 : &connect_handle,
1912 : &builtin_handle);
1913 4 : if (!W_ERROR_IS_OK(werr)) {
1914 0 : goto done;
1915 : }
1916 :
1917 4 : init_lsa_String(&lsa_account_name, r->in.user_name);
1918 :
1919 4 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
1920 : &domain_handle,
1921 : 1,
1922 : &lsa_account_name,
1923 : &user_rids,
1924 : &name_types,
1925 : &result);
1926 4 : if (any_nt_status_not_ok(status, result, &status)) {
1927 0 : werr = ntstatus_to_werror(status);
1928 0 : goto done;
1929 : }
1930 4 : if (user_rids.count != 1) {
1931 0 : werr = WERR_BAD_NET_RESP;
1932 0 : goto done;
1933 : }
1934 4 : if (name_types.count != 1) {
1935 0 : werr = WERR_BAD_NET_RESP;
1936 0 : goto done;
1937 : }
1938 :
1939 4 : status = dcerpc_samr_OpenUser(b, talloc_tos(),
1940 : &domain_handle,
1941 : user_mask,
1942 4 : user_rids.ids[0],
1943 : &user_handle,
1944 : &result);
1945 4 : if (any_nt_status_not_ok(status, result, &status)) {
1946 0 : werr = ntstatus_to_werror(status);
1947 0 : goto done;
1948 : }
1949 :
1950 4 : status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1951 4 : if (!NT_STATUS_IS_OK(status)) {
1952 0 : werr = ntstatus_to_werror(status);
1953 0 : goto done;
1954 : }
1955 :
1956 4 : status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
1957 4 : if (!NT_STATUS_IS_OK(status)) {
1958 0 : werr = ntstatus_to_werror(status);
1959 0 : goto done;
1960 : }
1961 :
1962 4 : status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1963 : &session_key,
1964 : &user_handle,
1965 : &uX);
1966 4 : if (!NT_STATUS_IS_OK(status)) {
1967 0 : werr = ntstatus_to_werror(status);
1968 0 : goto done;
1969 : }
1970 :
1971 4 : werr = WERR_OK;
1972 :
1973 4 : done:
1974 4 : if (is_valid_policy_hnd(&user_handle) && b) {
1975 4 : dcerpc_samr_Close(b, talloc_tos(), &user_handle, &result);
1976 : }
1977 :
1978 4 : if (ctx->disable_policy_handle_cache) {
1979 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1980 0 : libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1981 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1982 : }
1983 :
1984 4 : return werr;
1985 : }
1986 :
1987 : /****************************************************************
1988 : ****************************************************************/
1989 :
1990 0 : WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1991 : struct NetUserSetInfo *r)
1992 : {
1993 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1994 : }
1995 :
1996 : /****************************************************************
1997 : ****************************************************************/
1998 :
1999 7 : static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2000 : struct rpc_pipe_client *pipe_cli,
2001 : struct policy_handle *domain_handle,
2002 : struct samr_DomInfo1 *info1,
2003 : struct samr_DomInfo3 *info3,
2004 : struct samr_DomInfo5 *info5,
2005 : struct samr_DomInfo6 *info6,
2006 : struct samr_DomInfo7 *info7,
2007 : struct samr_DomInfo12 *info12)
2008 : {
2009 0 : NTSTATUS status, result;
2010 7 : union samr_DomainInfo *dom_info = NULL;
2011 7 : struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2012 :
2013 7 : if (info1) {
2014 4 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2015 : domain_handle,
2016 : 1,
2017 : &dom_info,
2018 : &result);
2019 4 : NT_STATUS_NOT_OK_RETURN(status);
2020 4 : NT_STATUS_NOT_OK_RETURN(result);
2021 :
2022 4 : *info1 = dom_info->info1;
2023 : }
2024 :
2025 7 : if (info3) {
2026 4 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2027 : domain_handle,
2028 : 3,
2029 : &dom_info,
2030 : &result);
2031 4 : NT_STATUS_NOT_OK_RETURN(status);
2032 4 : NT_STATUS_NOT_OK_RETURN(result);
2033 :
2034 4 : *info3 = dom_info->info3;
2035 : }
2036 :
2037 7 : if (info5) {
2038 1 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2039 : domain_handle,
2040 : 5,
2041 : &dom_info,
2042 : &result);
2043 1 : NT_STATUS_NOT_OK_RETURN(status);
2044 1 : NT_STATUS_NOT_OK_RETURN(result);
2045 :
2046 1 : *info5 = dom_info->info5;
2047 : }
2048 :
2049 7 : if (info6) {
2050 1 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2051 : domain_handle,
2052 : 6,
2053 : &dom_info,
2054 : &result);
2055 1 : NT_STATUS_NOT_OK_RETURN(status);
2056 1 : NT_STATUS_NOT_OK_RETURN(result);
2057 :
2058 1 : *info6 = dom_info->info6;
2059 : }
2060 :
2061 7 : if (info7) {
2062 1 : status = dcerpc_samr_QueryDomainInfo(b, mem_ctx,
2063 : domain_handle,
2064 : 7,
2065 : &dom_info,
2066 : &result);
2067 1 : NT_STATUS_NOT_OK_RETURN(status);
2068 1 : NT_STATUS_NOT_OK_RETURN(result);
2069 :
2070 1 : *info7 = dom_info->info7;
2071 : }
2072 :
2073 7 : if (info12) {
2074 1 : status = dcerpc_samr_QueryDomainInfo2(b, mem_ctx,
2075 : domain_handle,
2076 : 12,
2077 : &dom_info,
2078 : &result);
2079 1 : NT_STATUS_NOT_OK_RETURN(status);
2080 1 : NT_STATUS_NOT_OK_RETURN(result);
2081 :
2082 1 : *info12 = dom_info->info12;
2083 : }
2084 :
2085 7 : return NT_STATUS_OK;
2086 : }
2087 :
2088 : /****************************************************************
2089 : ****************************************************************/
2090 :
2091 3 : static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
2092 : struct rpc_pipe_client *pipe_cli,
2093 : struct policy_handle *domain_handle,
2094 : struct USER_MODALS_INFO_0 *info0)
2095 : {
2096 0 : NTSTATUS status;
2097 0 : struct samr_DomInfo1 dom_info1;
2098 0 : struct samr_DomInfo3 dom_info3;
2099 :
2100 3 : ZERO_STRUCTP(info0);
2101 :
2102 3 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2103 : pipe_cli,
2104 : domain_handle,
2105 : &dom_info1,
2106 : &dom_info3,
2107 : NULL,
2108 : NULL,
2109 : NULL,
2110 : NULL);
2111 3 : NT_STATUS_NOT_OK_RETURN(status);
2112 :
2113 3 : info0->usrmod0_min_passwd_len =
2114 3 : dom_info1.min_password_length;
2115 3 : info0->usrmod0_max_passwd_age =
2116 3 : nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
2117 3 : info0->usrmod0_min_passwd_age =
2118 3 : nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
2119 3 : info0->usrmod0_password_hist_len =
2120 3 : dom_info1.password_history_length;
2121 :
2122 3 : info0->usrmod0_force_logoff =
2123 3 : nt_time_to_unix_abs(&dom_info3.force_logoff_time);
2124 :
2125 3 : return NT_STATUS_OK;
2126 : }
2127 :
2128 : /****************************************************************
2129 : ****************************************************************/
2130 :
2131 1 : static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
2132 : struct rpc_pipe_client *pipe_cli,
2133 : struct policy_handle *domain_handle,
2134 : struct USER_MODALS_INFO_1 *info1)
2135 : {
2136 0 : NTSTATUS status;
2137 0 : struct samr_DomInfo6 dom_info6;
2138 0 : struct samr_DomInfo7 dom_info7;
2139 :
2140 1 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2141 : pipe_cli,
2142 : domain_handle,
2143 : NULL,
2144 : NULL,
2145 : NULL,
2146 : &dom_info6,
2147 : &dom_info7,
2148 : NULL);
2149 1 : NT_STATUS_NOT_OK_RETURN(status);
2150 :
2151 1 : info1->usrmod1_primary =
2152 1 : talloc_strdup(mem_ctx, dom_info6.primary.string);
2153 :
2154 1 : info1->usrmod1_role = dom_info7.role;
2155 :
2156 1 : return NT_STATUS_OK;
2157 : }
2158 :
2159 : /****************************************************************
2160 : ****************************************************************/
2161 :
2162 1 : static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
2163 : struct rpc_pipe_client *pipe_cli,
2164 : struct policy_handle *domain_handle,
2165 : struct dom_sid *domain_sid,
2166 : struct USER_MODALS_INFO_2 *info2)
2167 : {
2168 0 : NTSTATUS status;
2169 0 : struct samr_DomInfo5 dom_info5;
2170 :
2171 1 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2172 : pipe_cli,
2173 : domain_handle,
2174 : NULL,
2175 : NULL,
2176 : &dom_info5,
2177 : NULL,
2178 : NULL,
2179 : NULL);
2180 1 : NT_STATUS_NOT_OK_RETURN(status);
2181 :
2182 1 : info2->usrmod2_domain_name =
2183 1 : talloc_strdup(mem_ctx, dom_info5.domain_name.string);
2184 1 : info2->usrmod2_domain_id =
2185 1 : (struct domsid *)dom_sid_dup(mem_ctx, domain_sid);
2186 :
2187 1 : NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
2188 1 : NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
2189 :
2190 1 : return NT_STATUS_OK;
2191 : }
2192 :
2193 : /****************************************************************
2194 : ****************************************************************/
2195 :
2196 1 : static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
2197 : struct rpc_pipe_client *pipe_cli,
2198 : struct policy_handle *domain_handle,
2199 : struct USER_MODALS_INFO_3 *info3)
2200 : {
2201 0 : NTSTATUS status;
2202 0 : struct samr_DomInfo12 dom_info12;
2203 :
2204 1 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2205 : pipe_cli,
2206 : domain_handle,
2207 : NULL,
2208 : NULL,
2209 : NULL,
2210 : NULL,
2211 : NULL,
2212 : &dom_info12);
2213 1 : NT_STATUS_NOT_OK_RETURN(status);
2214 :
2215 1 : info3->usrmod3_lockout_duration =
2216 1 : nt_time_to_unix_abs(&dom_info12.lockout_duration);
2217 1 : info3->usrmod3_lockout_observation_window =
2218 1 : nt_time_to_unix_abs(&dom_info12.lockout_window);
2219 1 : info3->usrmod3_lockout_threshold =
2220 1 : dom_info12.lockout_threshold;
2221 :
2222 1 : return NT_STATUS_OK;
2223 : }
2224 :
2225 : /****************************************************************
2226 : ****************************************************************/
2227 :
2228 6 : static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
2229 : struct rpc_pipe_client *pipe_cli,
2230 : uint32_t level,
2231 : struct policy_handle *domain_handle,
2232 : struct dom_sid *domain_sid,
2233 : uint8_t **buffer)
2234 : {
2235 0 : NTSTATUS status;
2236 :
2237 0 : struct USER_MODALS_INFO_0 info0;
2238 0 : struct USER_MODALS_INFO_1 info1;
2239 0 : struct USER_MODALS_INFO_2 info2;
2240 0 : struct USER_MODALS_INFO_3 info3;
2241 :
2242 6 : if (!buffer) {
2243 0 : return ERROR_INSUFFICIENT_BUFFER;
2244 : }
2245 :
2246 6 : switch (level) {
2247 3 : case 0:
2248 3 : status = query_USER_MODALS_INFO_0(mem_ctx,
2249 : pipe_cli,
2250 : domain_handle,
2251 : &info0);
2252 3 : NT_STATUS_NOT_OK_RETURN(status);
2253 :
2254 3 : *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
2255 : sizeof(info0));
2256 3 : break;
2257 :
2258 1 : case 1:
2259 1 : status = query_USER_MODALS_INFO_1(mem_ctx,
2260 : pipe_cli,
2261 : domain_handle,
2262 : &info1);
2263 1 : NT_STATUS_NOT_OK_RETURN(status);
2264 :
2265 1 : *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
2266 : sizeof(info1));
2267 1 : break;
2268 1 : case 2:
2269 1 : status = query_USER_MODALS_INFO_2(mem_ctx,
2270 : pipe_cli,
2271 : domain_handle,
2272 : domain_sid,
2273 : &info2);
2274 1 : NT_STATUS_NOT_OK_RETURN(status);
2275 :
2276 1 : *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
2277 : sizeof(info2));
2278 1 : break;
2279 1 : case 3:
2280 1 : status = query_USER_MODALS_INFO_3(mem_ctx,
2281 : pipe_cli,
2282 : domain_handle,
2283 : &info3);
2284 1 : NT_STATUS_NOT_OK_RETURN(status);
2285 :
2286 1 : *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
2287 : sizeof(info3));
2288 1 : break;
2289 0 : default:
2290 0 : break;
2291 : }
2292 :
2293 6 : NT_STATUS_HAVE_NO_MEMORY(*buffer);
2294 :
2295 6 : return NT_STATUS_OK;
2296 : }
2297 :
2298 : /****************************************************************
2299 : ****************************************************************/
2300 :
2301 6 : WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
2302 : struct NetUserModalsGet *r)
2303 : {
2304 6 : struct rpc_pipe_client *pipe_cli = NULL;
2305 0 : NTSTATUS status;
2306 0 : WERROR werr;
2307 :
2308 0 : struct policy_handle connect_handle, domain_handle;
2309 6 : struct dom_sid2 *domain_sid = NULL;
2310 6 : uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2311 :
2312 6 : ZERO_STRUCT(connect_handle);
2313 6 : ZERO_STRUCT(domain_handle);
2314 :
2315 6 : if (!r->out.buffer) {
2316 0 : return WERR_INVALID_PARAMETER;
2317 : }
2318 :
2319 6 : switch (r->in.level) {
2320 3 : case 0:
2321 3 : access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2322 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2323 3 : break;
2324 2 : case 1:
2325 : case 2:
2326 2 : access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
2327 2 : break;
2328 1 : case 3:
2329 1 : access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
2330 1 : break;
2331 0 : default:
2332 0 : werr = WERR_INVALID_LEVEL;
2333 0 : goto done;
2334 : }
2335 :
2336 6 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
2337 : &ndr_table_samr,
2338 : &pipe_cli);
2339 6 : if (!W_ERROR_IS_OK(werr)) {
2340 0 : goto done;
2341 : }
2342 :
2343 6 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2344 : SAMR_ACCESS_ENUM_DOMAINS |
2345 : SAMR_ACCESS_LOOKUP_DOMAIN,
2346 : access_mask,
2347 : &connect_handle,
2348 : &domain_handle,
2349 : &domain_sid);
2350 6 : if (!W_ERROR_IS_OK(werr)) {
2351 0 : goto done;
2352 : }
2353 :
2354 : /* 0: 1 + 3 */
2355 : /* 1: 6 + 7 */
2356 : /* 2: 5 */
2357 : /* 3: 12 (DomainInfo2) */
2358 :
2359 6 : status = query_USER_MODALS_INFO_to_buffer(ctx,
2360 : pipe_cli,
2361 : r->in.level,
2362 : &domain_handle,
2363 : domain_sid,
2364 : r->out.buffer);
2365 6 : if (!NT_STATUS_IS_OK(status)) {
2366 0 : werr = ntstatus_to_werror(status);
2367 0 : goto done;
2368 : }
2369 :
2370 6 : done:
2371 6 : if (ctx->disable_policy_handle_cache) {
2372 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2373 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2374 : }
2375 :
2376 6 : return werr;
2377 : }
2378 :
2379 : /****************************************************************
2380 : ****************************************************************/
2381 :
2382 0 : WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
2383 : struct NetUserModalsGet *r)
2384 : {
2385 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
2386 : }
2387 :
2388 : /****************************************************************
2389 : ****************************************************************/
2390 :
2391 1 : static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
2392 : struct rpc_pipe_client *pipe_cli,
2393 : struct policy_handle *domain_handle,
2394 : struct samr_DomInfo1 *info1,
2395 : struct samr_DomInfo3 *info3,
2396 : struct samr_DomInfo12 *info12)
2397 : {
2398 0 : NTSTATUS status, result;
2399 0 : union samr_DomainInfo dom_info;
2400 1 : struct dcerpc_binding_handle *b = pipe_cli->binding_handle;
2401 :
2402 1 : if (info1) {
2403 :
2404 1 : ZERO_STRUCT(dom_info);
2405 :
2406 1 : dom_info.info1 = *info1;
2407 :
2408 1 : status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2409 : domain_handle,
2410 : 1,
2411 : &dom_info,
2412 : &result);
2413 1 : NT_STATUS_NOT_OK_RETURN(status);
2414 1 : NT_STATUS_NOT_OK_RETURN(result);
2415 : }
2416 :
2417 1 : if (info3) {
2418 :
2419 1 : ZERO_STRUCT(dom_info);
2420 :
2421 1 : dom_info.info3 = *info3;
2422 :
2423 1 : status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2424 : domain_handle,
2425 : 3,
2426 : &dom_info,
2427 : &result);
2428 :
2429 1 : NT_STATUS_NOT_OK_RETURN(status);
2430 1 : NT_STATUS_NOT_OK_RETURN(result);
2431 : }
2432 :
2433 1 : if (info12) {
2434 :
2435 0 : ZERO_STRUCT(dom_info);
2436 :
2437 0 : dom_info.info12 = *info12;
2438 :
2439 0 : status = dcerpc_samr_SetDomainInfo(b, mem_ctx,
2440 : domain_handle,
2441 : 12,
2442 : &dom_info,
2443 : &result);
2444 :
2445 0 : NT_STATUS_NOT_OK_RETURN(status);
2446 0 : NT_STATUS_NOT_OK_RETURN(result);
2447 : }
2448 :
2449 1 : return NT_STATUS_OK;
2450 : }
2451 :
2452 : /****************************************************************
2453 : ****************************************************************/
2454 :
2455 1 : static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
2456 : struct rpc_pipe_client *pipe_cli,
2457 : struct policy_handle *domain_handle,
2458 : struct USER_MODALS_INFO_0 *info0)
2459 : {
2460 0 : NTSTATUS status;
2461 0 : struct samr_DomInfo1 dom_info_1;
2462 0 : struct samr_DomInfo3 dom_info_3;
2463 :
2464 1 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2465 : pipe_cli,
2466 : domain_handle,
2467 : &dom_info_1,
2468 : &dom_info_3,
2469 : NULL,
2470 : NULL,
2471 : NULL,
2472 : NULL);
2473 1 : NT_STATUS_NOT_OK_RETURN(status);
2474 :
2475 1 : dom_info_1.min_password_length =
2476 1 : info0->usrmod0_min_passwd_len;
2477 1 : dom_info_1.password_history_length =
2478 1 : info0->usrmod0_password_hist_len;
2479 :
2480 1 : unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2481 1 : info0->usrmod0_max_passwd_age);
2482 1 : unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2483 1 : info0->usrmod0_min_passwd_age);
2484 :
2485 1 : unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2486 1 : info0->usrmod0_force_logoff);
2487 :
2488 1 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2489 : pipe_cli,
2490 : domain_handle,
2491 : &dom_info_1,
2492 : &dom_info_3,
2493 : NULL);
2494 : }
2495 :
2496 : /****************************************************************
2497 : ****************************************************************/
2498 :
2499 0 : static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2500 : struct rpc_pipe_client *pipe_cli,
2501 : struct policy_handle *domain_handle,
2502 : struct USER_MODALS_INFO_3 *info3)
2503 : {
2504 0 : NTSTATUS status;
2505 0 : struct samr_DomInfo12 dom_info_12;
2506 :
2507 0 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2508 : pipe_cli,
2509 : domain_handle,
2510 : NULL,
2511 : NULL,
2512 : NULL,
2513 : NULL,
2514 : NULL,
2515 : &dom_info_12);
2516 0 : NT_STATUS_NOT_OK_RETURN(status);
2517 :
2518 0 : unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2519 0 : info3->usrmod3_lockout_duration);
2520 0 : unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2521 0 : info3->usrmod3_lockout_observation_window);
2522 0 : dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2523 :
2524 0 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2525 : pipe_cli,
2526 : domain_handle,
2527 : NULL,
2528 : NULL,
2529 : &dom_info_12);
2530 : }
2531 :
2532 : /****************************************************************
2533 : ****************************************************************/
2534 :
2535 0 : static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2536 : struct rpc_pipe_client *pipe_cli,
2537 : struct policy_handle *domain_handle,
2538 : struct USER_MODALS_INFO_1001 *info1001)
2539 : {
2540 0 : NTSTATUS status;
2541 0 : struct samr_DomInfo1 dom_info_1;
2542 :
2543 0 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2544 : pipe_cli,
2545 : domain_handle,
2546 : &dom_info_1,
2547 : NULL,
2548 : NULL,
2549 : NULL,
2550 : NULL,
2551 : NULL);
2552 0 : NT_STATUS_NOT_OK_RETURN(status);
2553 :
2554 0 : dom_info_1.min_password_length =
2555 0 : info1001->usrmod1001_min_passwd_len;
2556 :
2557 0 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2558 : pipe_cli,
2559 : domain_handle,
2560 : &dom_info_1,
2561 : NULL,
2562 : NULL);
2563 : }
2564 :
2565 : /****************************************************************
2566 : ****************************************************************/
2567 :
2568 0 : static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2569 : struct rpc_pipe_client *pipe_cli,
2570 : struct policy_handle *domain_handle,
2571 : struct USER_MODALS_INFO_1002 *info1002)
2572 : {
2573 0 : NTSTATUS status;
2574 0 : struct samr_DomInfo1 dom_info_1;
2575 :
2576 0 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2577 : pipe_cli,
2578 : domain_handle,
2579 : &dom_info_1,
2580 : NULL,
2581 : NULL,
2582 : NULL,
2583 : NULL,
2584 : NULL);
2585 0 : NT_STATUS_NOT_OK_RETURN(status);
2586 :
2587 0 : unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2588 0 : info1002->usrmod1002_max_passwd_age);
2589 :
2590 0 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2591 : pipe_cli,
2592 : domain_handle,
2593 : &dom_info_1,
2594 : NULL,
2595 : NULL);
2596 : }
2597 :
2598 : /****************************************************************
2599 : ****************************************************************/
2600 :
2601 0 : static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2602 : struct rpc_pipe_client *pipe_cli,
2603 : struct policy_handle *domain_handle,
2604 : struct USER_MODALS_INFO_1003 *info1003)
2605 : {
2606 0 : NTSTATUS status;
2607 0 : struct samr_DomInfo1 dom_info_1;
2608 :
2609 0 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2610 : pipe_cli,
2611 : domain_handle,
2612 : &dom_info_1,
2613 : NULL,
2614 : NULL,
2615 : NULL,
2616 : NULL,
2617 : NULL);
2618 0 : NT_STATUS_NOT_OK_RETURN(status);
2619 :
2620 0 : unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2621 0 : info1003->usrmod1003_min_passwd_age);
2622 :
2623 0 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2624 : pipe_cli,
2625 : domain_handle,
2626 : &dom_info_1,
2627 : NULL,
2628 : NULL);
2629 : }
2630 :
2631 : /****************************************************************
2632 : ****************************************************************/
2633 :
2634 0 : static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2635 : struct rpc_pipe_client *pipe_cli,
2636 : struct policy_handle *domain_handle,
2637 : struct USER_MODALS_INFO_1004 *info1004)
2638 : {
2639 0 : NTSTATUS status;
2640 0 : struct samr_DomInfo3 dom_info_3;
2641 :
2642 0 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2643 : pipe_cli,
2644 : domain_handle,
2645 : NULL,
2646 : &dom_info_3,
2647 : NULL,
2648 : NULL,
2649 : NULL,
2650 : NULL);
2651 0 : NT_STATUS_NOT_OK_RETURN(status);
2652 :
2653 0 : unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2654 0 : info1004->usrmod1004_force_logoff);
2655 :
2656 0 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2657 : pipe_cli,
2658 : domain_handle,
2659 : NULL,
2660 : &dom_info_3,
2661 : NULL);
2662 : }
2663 :
2664 : /****************************************************************
2665 : ****************************************************************/
2666 :
2667 0 : static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2668 : struct rpc_pipe_client *pipe_cli,
2669 : struct policy_handle *domain_handle,
2670 : struct USER_MODALS_INFO_1005 *info1005)
2671 : {
2672 0 : NTSTATUS status;
2673 0 : struct samr_DomInfo1 dom_info_1;
2674 :
2675 0 : status = query_USER_MODALS_INFO_rpc(mem_ctx,
2676 : pipe_cli,
2677 : domain_handle,
2678 : &dom_info_1,
2679 : NULL,
2680 : NULL,
2681 : NULL,
2682 : NULL,
2683 : NULL);
2684 0 : NT_STATUS_NOT_OK_RETURN(status);
2685 :
2686 0 : dom_info_1.password_history_length =
2687 0 : info1005->usrmod1005_password_hist_len;
2688 :
2689 0 : return set_USER_MODALS_INFO_rpc(mem_ctx,
2690 : pipe_cli,
2691 : domain_handle,
2692 : &dom_info_1,
2693 : NULL,
2694 : NULL);
2695 : }
2696 :
2697 : /****************************************************************
2698 : ****************************************************************/
2699 :
2700 1 : static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2701 : struct rpc_pipe_client *pipe_cli,
2702 : uint32_t level,
2703 : struct policy_handle *domain_handle,
2704 : struct dom_sid *domain_sid,
2705 : uint8_t *buffer)
2706 : {
2707 0 : struct USER_MODALS_INFO_0 *info0;
2708 0 : struct USER_MODALS_INFO_3 *info3;
2709 0 : struct USER_MODALS_INFO_1001 *info1001;
2710 0 : struct USER_MODALS_INFO_1002 *info1002;
2711 0 : struct USER_MODALS_INFO_1003 *info1003;
2712 0 : struct USER_MODALS_INFO_1004 *info1004;
2713 0 : struct USER_MODALS_INFO_1005 *info1005;
2714 :
2715 1 : if (!buffer) {
2716 0 : return ERROR_INSUFFICIENT_BUFFER;
2717 : }
2718 :
2719 1 : switch (level) {
2720 1 : case 0:
2721 1 : info0 = (struct USER_MODALS_INFO_0 *)buffer;
2722 1 : return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2723 : pipe_cli,
2724 : domain_handle,
2725 : info0);
2726 0 : case 3:
2727 0 : info3 = (struct USER_MODALS_INFO_3 *)buffer;
2728 0 : return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2729 : pipe_cli,
2730 : domain_handle,
2731 : info3);
2732 0 : case 1001:
2733 0 : info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2734 0 : return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2735 : pipe_cli,
2736 : domain_handle,
2737 : info1001);
2738 0 : case 1002:
2739 0 : info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2740 0 : return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2741 : pipe_cli,
2742 : domain_handle,
2743 : info1002);
2744 0 : case 1003:
2745 0 : info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2746 0 : return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2747 : pipe_cli,
2748 : domain_handle,
2749 : info1003);
2750 0 : case 1004:
2751 0 : info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2752 0 : return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2753 : pipe_cli,
2754 : domain_handle,
2755 : info1004);
2756 0 : case 1005:
2757 0 : info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2758 0 : return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2759 : pipe_cli,
2760 : domain_handle,
2761 : info1005);
2762 :
2763 0 : default:
2764 0 : break;
2765 : }
2766 :
2767 0 : return NT_STATUS_OK;
2768 : }
2769 :
2770 : /****************************************************************
2771 : ****************************************************************/
2772 :
2773 1 : WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2774 : struct NetUserModalsSet *r)
2775 : {
2776 1 : struct rpc_pipe_client *pipe_cli = NULL;
2777 0 : NTSTATUS status;
2778 0 : WERROR werr;
2779 :
2780 0 : struct policy_handle connect_handle, domain_handle;
2781 1 : struct dom_sid2 *domain_sid = NULL;
2782 1 : uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2783 :
2784 1 : ZERO_STRUCT(connect_handle);
2785 1 : ZERO_STRUCT(domain_handle);
2786 :
2787 1 : if (!r->in.buffer) {
2788 0 : return WERR_INVALID_PARAMETER;
2789 : }
2790 :
2791 1 : switch (r->in.level) {
2792 1 : case 0:
2793 1 : access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2794 : SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2795 : SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2796 : SAMR_DOMAIN_ACCESS_SET_INFO_2;
2797 1 : break;
2798 0 : case 3:
2799 : case 1001:
2800 : case 1002:
2801 : case 1003:
2802 : case 1005:
2803 0 : access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2804 : SAMR_DOMAIN_ACCESS_SET_INFO_1;
2805 0 : break;
2806 0 : case 1004:
2807 0 : access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2808 : SAMR_DOMAIN_ACCESS_SET_INFO_2;
2809 0 : break;
2810 0 : case 1:
2811 : case 2:
2812 : case 1006:
2813 : case 1007:
2814 0 : werr = WERR_NOT_SUPPORTED;
2815 0 : break;
2816 0 : default:
2817 0 : werr = WERR_INVALID_LEVEL;
2818 0 : goto done;
2819 : }
2820 :
2821 1 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
2822 : &ndr_table_samr,
2823 : &pipe_cli);
2824 1 : if (!W_ERROR_IS_OK(werr)) {
2825 0 : goto done;
2826 : }
2827 :
2828 1 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2829 : SAMR_ACCESS_ENUM_DOMAINS |
2830 : SAMR_ACCESS_LOOKUP_DOMAIN,
2831 : access_mask,
2832 : &connect_handle,
2833 : &domain_handle,
2834 : &domain_sid);
2835 1 : if (!W_ERROR_IS_OK(werr)) {
2836 0 : goto done;
2837 : }
2838 :
2839 1 : status = set_USER_MODALS_INFO_buffer(ctx,
2840 : pipe_cli,
2841 : r->in.level,
2842 : &domain_handle,
2843 : domain_sid,
2844 : r->in.buffer);
2845 1 : if (!NT_STATUS_IS_OK(status)) {
2846 0 : werr = ntstatus_to_werror(status);
2847 0 : goto done;
2848 : }
2849 :
2850 1 : done:
2851 1 : if (ctx->disable_policy_handle_cache) {
2852 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2853 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2854 : }
2855 :
2856 1 : return werr;
2857 : }
2858 :
2859 : /****************************************************************
2860 : ****************************************************************/
2861 :
2862 0 : WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2863 : struct NetUserModalsSet *r)
2864 : {
2865 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2866 : }
2867 :
2868 : /****************************************************************
2869 : ****************************************************************/
2870 :
2871 5 : NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2872 : uint32_t level,
2873 : const char *group_name,
2874 : uint32_t attributes,
2875 : uint8_t **buffer,
2876 : uint32_t *num_entries)
2877 : {
2878 0 : struct GROUP_USERS_INFO_0 u0;
2879 0 : struct GROUP_USERS_INFO_1 u1;
2880 :
2881 5 : switch (level) {
2882 3 : case 0:
2883 3 : if (group_name) {
2884 3 : u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2885 3 : NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2886 : } else {
2887 0 : u0.grui0_name = NULL;
2888 : }
2889 :
2890 3 : ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2891 : (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2892 3 : break;
2893 2 : case 1:
2894 2 : if (group_name) {
2895 2 : u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2896 2 : NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2897 : } else {
2898 0 : u1.grui1_name = NULL;
2899 : }
2900 :
2901 2 : u1.grui1_attributes = attributes;
2902 :
2903 2 : ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2904 : (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2905 2 : break;
2906 0 : default:
2907 0 : return NT_STATUS_INVALID_INFO_CLASS;
2908 : }
2909 :
2910 5 : return NT_STATUS_OK;
2911 : }
2912 :
2913 : /****************************************************************
2914 : ****************************************************************/
2915 :
2916 2 : WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2917 : struct NetUserGetGroups *r)
2918 : {
2919 2 : struct rpc_pipe_client *pipe_cli = NULL;
2920 0 : struct policy_handle connect_handle, domain_handle, user_handle;
2921 0 : struct lsa_String lsa_account_name;
2922 2 : struct dom_sid2 *domain_sid = NULL;
2923 0 : struct samr_Ids user_rids, name_types;
2924 2 : struct samr_RidWithAttributeArray *rid_array = NULL;
2925 0 : struct lsa_Strings names;
2926 0 : struct samr_Ids types;
2927 2 : uint32_t *rids = NULL;
2928 :
2929 0 : int i;
2930 2 : uint32_t entries_read = 0;
2931 :
2932 0 : NTSTATUS status;
2933 2 : NTSTATUS result = NT_STATUS_OK;
2934 0 : WERROR werr;
2935 2 : struct dcerpc_binding_handle *b = NULL;
2936 :
2937 2 : ZERO_STRUCT(connect_handle);
2938 2 : ZERO_STRUCT(domain_handle);
2939 :
2940 2 : if (!r->out.buffer) {
2941 0 : return WERR_INVALID_PARAMETER;
2942 : }
2943 :
2944 2 : *r->out.buffer = NULL;
2945 2 : *r->out.entries_read = 0;
2946 2 : *r->out.total_entries = 0;
2947 :
2948 2 : switch (r->in.level) {
2949 2 : case 0:
2950 : case 1:
2951 2 : break;
2952 0 : default:
2953 0 : return WERR_INVALID_LEVEL;
2954 : }
2955 :
2956 2 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
2957 : &ndr_table_samr,
2958 : &pipe_cli);
2959 2 : if (!W_ERROR_IS_OK(werr)) {
2960 0 : goto done;
2961 : }
2962 :
2963 2 : b = pipe_cli->binding_handle;
2964 :
2965 2 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2966 : SAMR_ACCESS_ENUM_DOMAINS |
2967 : SAMR_ACCESS_LOOKUP_DOMAIN,
2968 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2969 : &connect_handle,
2970 : &domain_handle,
2971 : &domain_sid);
2972 2 : if (!W_ERROR_IS_OK(werr)) {
2973 0 : goto done;
2974 : }
2975 :
2976 2 : init_lsa_String(&lsa_account_name, r->in.user_name);
2977 :
2978 2 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
2979 : &domain_handle,
2980 : 1,
2981 : &lsa_account_name,
2982 : &user_rids,
2983 : &name_types,
2984 : &result);
2985 2 : if (any_nt_status_not_ok(status, result, &status)) {
2986 0 : werr = ntstatus_to_werror(status);
2987 0 : goto done;
2988 : }
2989 2 : if (user_rids.count != 1) {
2990 0 : werr = WERR_BAD_NET_RESP;
2991 0 : goto done;
2992 : }
2993 2 : if (name_types.count != 1) {
2994 0 : werr = WERR_BAD_NET_RESP;
2995 0 : goto done;
2996 : }
2997 :
2998 2 : status = dcerpc_samr_OpenUser(b, talloc_tos(),
2999 : &domain_handle,
3000 : SAMR_USER_ACCESS_GET_GROUPS,
3001 2 : user_rids.ids[0],
3002 : &user_handle,
3003 : &result);
3004 2 : if (any_nt_status_not_ok(status, result, &status)) {
3005 0 : werr = ntstatus_to_werror(status);
3006 0 : goto done;
3007 : }
3008 :
3009 2 : status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3010 : &user_handle,
3011 : &rid_array,
3012 : &result);
3013 2 : if (any_nt_status_not_ok(status, result, &status)) {
3014 0 : werr = ntstatus_to_werror(status);
3015 0 : goto done;
3016 : }
3017 :
3018 2 : rids = talloc_array(ctx, uint32_t, rid_array->count);
3019 2 : if (!rids) {
3020 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3021 0 : goto done;
3022 : }
3023 :
3024 4 : for (i=0; i < rid_array->count; i++) {
3025 2 : rids[i] = rid_array->rids[i].rid;
3026 : }
3027 :
3028 2 : status = dcerpc_samr_LookupRids(b, talloc_tos(),
3029 : &domain_handle,
3030 2 : rid_array->count,
3031 : rids,
3032 : &names,
3033 : &types,
3034 : &result);
3035 2 : if (!NT_STATUS_IS_OK(status)) {
3036 0 : werr = ntstatus_to_werror(status);
3037 0 : goto done;
3038 : }
3039 2 : if (!NT_STATUS_IS_OK(result) &&
3040 0 : !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
3041 0 : werr = ntstatus_to_werror(result);
3042 0 : goto done;
3043 : }
3044 2 : if (names.count != rid_array->count) {
3045 0 : werr = WERR_BAD_NET_RESP;
3046 0 : goto done;
3047 : }
3048 2 : if (types.count != rid_array->count) {
3049 0 : werr = WERR_BAD_NET_RESP;
3050 0 : goto done;
3051 : }
3052 :
3053 4 : for (i=0; i < names.count; i++) {
3054 2 : status = add_GROUP_USERS_INFO_X_buffer(ctx,
3055 : r->in.level,
3056 2 : names.names[i].string,
3057 2 : rid_array->rids[i].attributes,
3058 : r->out.buffer,
3059 : &entries_read);
3060 2 : if (!NT_STATUS_IS_OK(status)) {
3061 0 : werr = ntstatus_to_werror(status);
3062 0 : goto done;
3063 : }
3064 : }
3065 :
3066 2 : *r->out.entries_read = entries_read;
3067 2 : *r->out.total_entries = entries_read;
3068 :
3069 2 : done:
3070 2 : if (ctx->disable_policy_handle_cache) {
3071 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3072 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3073 : }
3074 :
3075 2 : return werr;
3076 : }
3077 :
3078 : /****************************************************************
3079 : ****************************************************************/
3080 :
3081 0 : WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
3082 : struct NetUserGetGroups *r)
3083 : {
3084 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
3085 : }
3086 :
3087 : /****************************************************************
3088 : ****************************************************************/
3089 :
3090 0 : WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
3091 : struct NetUserSetGroups *r)
3092 : {
3093 0 : struct rpc_pipe_client *pipe_cli = NULL;
3094 0 : struct policy_handle connect_handle, domain_handle, user_handle, group_handle;
3095 0 : struct lsa_String lsa_account_name;
3096 0 : struct dom_sid2 *domain_sid = NULL;
3097 0 : struct samr_Ids user_rids, name_types;
3098 0 : struct samr_Ids group_rids;
3099 0 : struct samr_RidWithAttributeArray *rid_array = NULL;
3100 0 : struct lsa_String *lsa_names = NULL;
3101 :
3102 0 : uint32_t *add_rids = NULL;
3103 0 : uint32_t *del_rids = NULL;
3104 0 : size_t num_add_rids = 0;
3105 0 : size_t num_del_rids = 0;
3106 :
3107 0 : uint32_t *member_rids = NULL;
3108 :
3109 0 : struct GROUP_USERS_INFO_0 *i0 = NULL;
3110 0 : struct GROUP_USERS_INFO_1 *i1 = NULL;
3111 :
3112 0 : int i, k;
3113 :
3114 0 : NTSTATUS status;
3115 0 : NTSTATUS result = NT_STATUS_OK;
3116 0 : WERROR werr;
3117 0 : struct dcerpc_binding_handle *b = NULL;
3118 :
3119 0 : ZERO_STRUCT(connect_handle);
3120 0 : ZERO_STRUCT(domain_handle);
3121 0 : ZERO_STRUCT(group_handle);
3122 :
3123 0 : if (!r->in.buffer) {
3124 0 : return WERR_INVALID_PARAMETER;
3125 : }
3126 :
3127 0 : switch (r->in.level) {
3128 0 : case 0:
3129 : case 1:
3130 0 : break;
3131 0 : default:
3132 0 : return WERR_INVALID_LEVEL;
3133 : }
3134 :
3135 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
3136 : &ndr_table_samr,
3137 : &pipe_cli);
3138 0 : if (!W_ERROR_IS_OK(werr)) {
3139 0 : goto done;
3140 : }
3141 :
3142 0 : b = pipe_cli->binding_handle;
3143 :
3144 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3145 : SAMR_ACCESS_ENUM_DOMAINS |
3146 : SAMR_ACCESS_LOOKUP_DOMAIN,
3147 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
3148 : &connect_handle,
3149 : &domain_handle,
3150 : &domain_sid);
3151 0 : if (!W_ERROR_IS_OK(werr)) {
3152 0 : goto done;
3153 : }
3154 :
3155 0 : init_lsa_String(&lsa_account_name, r->in.user_name);
3156 :
3157 0 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
3158 : &domain_handle,
3159 : 1,
3160 : &lsa_account_name,
3161 : &user_rids,
3162 : &name_types,
3163 : &result);
3164 0 : if (any_nt_status_not_ok(status, result, &status)) {
3165 0 : werr = ntstatus_to_werror(status);
3166 0 : goto done;
3167 : }
3168 0 : if (user_rids.count != 1) {
3169 0 : werr = WERR_BAD_NET_RESP;
3170 0 : goto done;
3171 : }
3172 0 : if (name_types.count != 1) {
3173 0 : werr = WERR_BAD_NET_RESP;
3174 0 : goto done;
3175 : }
3176 :
3177 0 : status = dcerpc_samr_OpenUser(b, talloc_tos(),
3178 : &domain_handle,
3179 : SAMR_USER_ACCESS_GET_GROUPS,
3180 0 : user_rids.ids[0],
3181 : &user_handle,
3182 : &result);
3183 0 : if (any_nt_status_not_ok(status, result, &status)) {
3184 0 : werr = ntstatus_to_werror(status);
3185 0 : goto done;
3186 : }
3187 :
3188 0 : switch (r->in.level) {
3189 0 : case 0:
3190 0 : i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
3191 0 : break;
3192 0 : case 1:
3193 0 : i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
3194 0 : break;
3195 : }
3196 :
3197 0 : lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
3198 0 : if (!lsa_names) {
3199 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3200 0 : goto done;
3201 : }
3202 :
3203 0 : for (i=0; i < r->in.num_entries; i++) {
3204 :
3205 0 : switch (r->in.level) {
3206 0 : case 0:
3207 0 : init_lsa_String(&lsa_names[i], i0->grui0_name);
3208 0 : i0++;
3209 0 : break;
3210 0 : case 1:
3211 0 : init_lsa_String(&lsa_names[i], i1->grui1_name);
3212 0 : i1++;
3213 0 : break;
3214 : }
3215 : }
3216 :
3217 0 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
3218 : &domain_handle,
3219 : r->in.num_entries,
3220 : lsa_names,
3221 : &group_rids,
3222 : &name_types,
3223 : &result);
3224 0 : if (any_nt_status_not_ok(status, result, &status)) {
3225 0 : werr = ntstatus_to_werror(status);
3226 0 : goto done;
3227 : }
3228 0 : if (group_rids.count != r->in.num_entries) {
3229 0 : werr = WERR_BAD_NET_RESP;
3230 0 : goto done;
3231 : }
3232 0 : if (name_types.count != r->in.num_entries) {
3233 0 : werr = WERR_BAD_NET_RESP;
3234 0 : goto done;
3235 : }
3236 :
3237 0 : member_rids = group_rids.ids;
3238 :
3239 0 : status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3240 : &user_handle,
3241 : &rid_array,
3242 : &result);
3243 0 : if (any_nt_status_not_ok(status, result, &status)) {
3244 0 : werr = ntstatus_to_werror(status);
3245 0 : goto done;
3246 : }
3247 :
3248 : /* add list */
3249 :
3250 0 : for (i=0; i < r->in.num_entries; i++) {
3251 0 : bool already_member = false;
3252 0 : for (k=0; k < rid_array->count; k++) {
3253 0 : if (member_rids[i] == rid_array->rids[k].rid) {
3254 0 : already_member = true;
3255 0 : break;
3256 : }
3257 : }
3258 0 : if (!already_member) {
3259 0 : if (!add_rid_to_array_unique(ctx,
3260 0 : member_rids[i],
3261 : &add_rids, &num_add_rids)) {
3262 0 : werr = WERR_GEN_FAILURE;
3263 0 : goto done;
3264 : }
3265 : }
3266 : }
3267 :
3268 : /* del list */
3269 :
3270 0 : for (k=0; k < rid_array->count; k++) {
3271 0 : bool keep_member = false;
3272 0 : for (i=0; i < r->in.num_entries; i++) {
3273 0 : if (member_rids[i] == rid_array->rids[k].rid) {
3274 0 : keep_member = true;
3275 0 : break;
3276 : }
3277 : }
3278 0 : if (!keep_member) {
3279 0 : if (!add_rid_to_array_unique(ctx,
3280 0 : rid_array->rids[k].rid,
3281 : &del_rids, &num_del_rids)) {
3282 0 : werr = WERR_GEN_FAILURE;
3283 0 : goto done;
3284 : }
3285 : }
3286 : }
3287 :
3288 : /* add list */
3289 :
3290 0 : for (i=0; i < num_add_rids; i++) {
3291 0 : status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3292 : &domain_handle,
3293 : SAMR_GROUP_ACCESS_ADD_MEMBER,
3294 0 : add_rids[i],
3295 : &group_handle,
3296 : &result);
3297 0 : if (any_nt_status_not_ok(status, result, &status)) {
3298 0 : werr = ntstatus_to_werror(status);
3299 0 : goto done;
3300 : }
3301 :
3302 0 : status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
3303 : &group_handle,
3304 0 : user_rids.ids[0],
3305 : 7 /* ? */,
3306 : &result);
3307 0 : if (any_nt_status_not_ok(status, result, &status)) {
3308 0 : werr = ntstatus_to_werror(status);
3309 0 : goto done;
3310 : }
3311 :
3312 0 : if (is_valid_policy_hnd(&group_handle)) {
3313 0 : dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3314 : }
3315 : }
3316 :
3317 : /* del list */
3318 :
3319 0 : for (i=0; i < num_del_rids; i++) {
3320 0 : status = dcerpc_samr_OpenGroup(b, talloc_tos(),
3321 : &domain_handle,
3322 : SAMR_GROUP_ACCESS_REMOVE_MEMBER,
3323 0 : del_rids[i],
3324 : &group_handle,
3325 : &result);
3326 0 : if (any_nt_status_not_ok(status, result, &status)) {
3327 0 : werr = ntstatus_to_werror(status);
3328 0 : goto done;
3329 : }
3330 :
3331 0 : status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
3332 : &group_handle,
3333 0 : user_rids.ids[0],
3334 : &result);
3335 0 : if (any_nt_status_not_ok(status, result, &status)) {
3336 0 : werr = ntstatus_to_werror(status);
3337 0 : goto done;
3338 : }
3339 :
3340 0 : if (is_valid_policy_hnd(&group_handle)) {
3341 0 : dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3342 : }
3343 : }
3344 :
3345 0 : werr = WERR_OK;
3346 :
3347 0 : done:
3348 0 : if (is_valid_policy_hnd(&group_handle)) {
3349 0 : dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
3350 : }
3351 :
3352 0 : if (ctx->disable_policy_handle_cache) {
3353 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3354 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3355 : }
3356 :
3357 0 : return werr;
3358 : }
3359 :
3360 : /****************************************************************
3361 : ****************************************************************/
3362 :
3363 0 : WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx,
3364 : struct NetUserSetGroups *r)
3365 : {
3366 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups);
3367 : }
3368 :
3369 : /****************************************************************
3370 : ****************************************************************/
3371 :
3372 0 : static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
3373 : uint32_t level,
3374 : const char *group_name,
3375 : uint8_t **buffer,
3376 : uint32_t *num_entries)
3377 : {
3378 0 : struct LOCALGROUP_USERS_INFO_0 u0;
3379 :
3380 0 : switch (level) {
3381 0 : case 0:
3382 0 : u0.lgrui0_name = talloc_strdup(mem_ctx, group_name);
3383 0 : NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name);
3384 :
3385 0 : ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0,
3386 : (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries);
3387 0 : break;
3388 0 : default:
3389 0 : return NT_STATUS_INVALID_INFO_CLASS;
3390 : }
3391 :
3392 0 : return NT_STATUS_OK;
3393 : }
3394 :
3395 : /****************************************************************
3396 : ****************************************************************/
3397 :
3398 0 : WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
3399 : struct NetUserGetLocalGroups *r)
3400 : {
3401 0 : struct rpc_pipe_client *pipe_cli = NULL;
3402 0 : struct policy_handle connect_handle, domain_handle, user_handle,
3403 : builtin_handle;
3404 0 : struct lsa_String lsa_account_name;
3405 0 : struct dom_sid2 *domain_sid = NULL;
3406 0 : struct samr_Ids user_rids, name_types;
3407 0 : struct samr_RidWithAttributeArray *rid_array = NULL;
3408 0 : struct lsa_Strings names;
3409 0 : struct samr_Ids types;
3410 0 : uint32_t *rids = NULL;
3411 0 : size_t num_rids = 0;
3412 0 : struct dom_sid user_sid;
3413 0 : struct lsa_SidArray sid_array;
3414 0 : struct samr_Ids domain_rids;
3415 0 : struct samr_Ids builtin_rids;
3416 :
3417 0 : int i;
3418 0 : uint32_t entries_read = 0;
3419 :
3420 0 : NTSTATUS status;
3421 0 : NTSTATUS result = NT_STATUS_OK;
3422 0 : WERROR werr;
3423 0 : struct dcerpc_binding_handle *b = NULL;
3424 :
3425 0 : ZERO_STRUCT(connect_handle);
3426 0 : ZERO_STRUCT(domain_handle);
3427 :
3428 0 : if (!r->out.buffer) {
3429 0 : return WERR_INVALID_PARAMETER;
3430 : }
3431 :
3432 0 : *r->out.buffer = NULL;
3433 0 : *r->out.entries_read = 0;
3434 0 : *r->out.total_entries = 0;
3435 :
3436 0 : switch (r->in.level) {
3437 0 : case 0:
3438 : case 1:
3439 0 : break;
3440 0 : default:
3441 0 : return WERR_INVALID_LEVEL;
3442 : }
3443 :
3444 0 : werr = libnetapi_open_pipe(ctx, r->in.server_name,
3445 : &ndr_table_samr,
3446 : &pipe_cli);
3447 0 : if (!W_ERROR_IS_OK(werr)) {
3448 0 : goto done;
3449 : }
3450 :
3451 0 : b = pipe_cli->binding_handle;
3452 :
3453 0 : werr = libnetapi_samr_open_domain(ctx, pipe_cli,
3454 : SAMR_ACCESS_ENUM_DOMAINS |
3455 : SAMR_ACCESS_LOOKUP_DOMAIN,
3456 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3457 : SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3458 : &connect_handle,
3459 : &domain_handle,
3460 : &domain_sid);
3461 0 : if (!W_ERROR_IS_OK(werr)) {
3462 0 : goto done;
3463 : }
3464 :
3465 0 : werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
3466 : SAMR_ACCESS_ENUM_DOMAINS |
3467 : SAMR_ACCESS_LOOKUP_DOMAIN,
3468 : SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
3469 : SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
3470 : &connect_handle,
3471 : &builtin_handle);
3472 0 : if (!W_ERROR_IS_OK(werr)) {
3473 0 : goto done;
3474 : }
3475 :
3476 0 : init_lsa_String(&lsa_account_name, r->in.user_name);
3477 :
3478 0 : status = dcerpc_samr_LookupNames(b, talloc_tos(),
3479 : &domain_handle,
3480 : 1,
3481 : &lsa_account_name,
3482 : &user_rids,
3483 : &name_types,
3484 : &result);
3485 0 : if (any_nt_status_not_ok(status, result, &status)) {
3486 0 : werr = ntstatus_to_werror(status);
3487 0 : goto done;
3488 : }
3489 0 : if (user_rids.count != 1) {
3490 0 : werr = WERR_BAD_NET_RESP;
3491 0 : goto done;
3492 : }
3493 0 : if (name_types.count != 1) {
3494 0 : werr = WERR_BAD_NET_RESP;
3495 0 : goto done;
3496 : }
3497 :
3498 0 : status = dcerpc_samr_OpenUser(b, talloc_tos(),
3499 : &domain_handle,
3500 : SAMR_USER_ACCESS_GET_GROUPS,
3501 0 : user_rids.ids[0],
3502 : &user_handle,
3503 : &result);
3504 0 : if (any_nt_status_not_ok(status, result, &status)) {
3505 0 : werr = ntstatus_to_werror(status);
3506 0 : goto done;
3507 : }
3508 :
3509 0 : status = dcerpc_samr_GetGroupsForUser(b, talloc_tos(),
3510 : &user_handle,
3511 : &rid_array,
3512 : &result);
3513 0 : if (any_nt_status_not_ok(status, result, &status)) {
3514 0 : werr = ntstatus_to_werror(status);
3515 0 : goto done;
3516 : }
3517 :
3518 0 : if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) {
3519 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3520 0 : goto done;
3521 : }
3522 :
3523 0 : sid_array.num_sids = rid_array->count + 1;
3524 0 : sid_array.sids = talloc_array(ctx, struct lsa_SidPtr, sid_array.num_sids);
3525 0 : if (!sid_array.sids) {
3526 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3527 0 : goto done;
3528 : }
3529 :
3530 0 : sid_array.sids[0].sid = dom_sid_dup(ctx, &user_sid);
3531 0 : if (!sid_array.sids[0].sid) {
3532 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3533 0 : goto done;
3534 : }
3535 :
3536 0 : for (i=0; i < rid_array->count; i++) {
3537 0 : struct dom_sid sid;
3538 :
3539 0 : if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) {
3540 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3541 0 : goto done;
3542 : }
3543 :
3544 0 : sid_array.sids[i+1].sid = dom_sid_dup(ctx, &sid);
3545 0 : if (!sid_array.sids[i+1].sid) {
3546 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3547 0 : goto done;
3548 : }
3549 : }
3550 :
3551 0 : status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3552 : &domain_handle,
3553 : &sid_array,
3554 : &domain_rids,
3555 : &result);
3556 0 : if (any_nt_status_not_ok(status, result, &status)) {
3557 0 : werr = ntstatus_to_werror(status);
3558 0 : goto done;
3559 : }
3560 :
3561 0 : for (i=0; i < domain_rids.count; i++) {
3562 0 : if (!add_rid_to_array_unique(ctx, domain_rids.ids[i],
3563 : &rids, &num_rids)) {
3564 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3565 0 : goto done;
3566 : }
3567 : }
3568 :
3569 0 : status = dcerpc_samr_GetAliasMembership(b, talloc_tos(),
3570 : &builtin_handle,
3571 : &sid_array,
3572 : &builtin_rids,
3573 : &result);
3574 0 : if (any_nt_status_not_ok(status, result, &status)) {
3575 0 : werr = ntstatus_to_werror(status);
3576 0 : goto done;
3577 : }
3578 :
3579 0 : for (i=0; i < builtin_rids.count; i++) {
3580 0 : if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i],
3581 : &rids, &num_rids)) {
3582 0 : werr = WERR_NOT_ENOUGH_MEMORY;
3583 0 : goto done;
3584 : }
3585 : }
3586 :
3587 0 : status = dcerpc_samr_LookupRids(b, talloc_tos(),
3588 : &builtin_handle,
3589 : num_rids,
3590 : rids,
3591 : &names,
3592 : &types,
3593 : &result);
3594 0 : if (any_nt_status_not_ok(status, result, &status)) {
3595 0 : werr = ntstatus_to_werror(status);
3596 0 : goto done;
3597 : }
3598 0 : if (names.count != num_rids) {
3599 0 : werr = WERR_BAD_NET_RESP;
3600 0 : goto done;
3601 : }
3602 0 : if (types.count != num_rids) {
3603 0 : werr = WERR_BAD_NET_RESP;
3604 0 : goto done;
3605 : }
3606 :
3607 0 : for (i=0; i < names.count; i++) {
3608 0 : status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
3609 : r->in.level,
3610 0 : names.names[i].string,
3611 : r->out.buffer,
3612 : &entries_read);
3613 0 : if (!NT_STATUS_IS_OK(status)) {
3614 0 : werr = ntstatus_to_werror(status);
3615 0 : goto done;
3616 : }
3617 : }
3618 :
3619 0 : *r->out.entries_read = entries_read;
3620 0 : *r->out.total_entries = entries_read;
3621 :
3622 0 : done:
3623 0 : if (ctx->disable_policy_handle_cache) {
3624 0 : libnetapi_samr_close_domain_handle(ctx, &domain_handle);
3625 0 : libnetapi_samr_close_connect_handle(ctx, &connect_handle);
3626 : }
3627 :
3628 0 : return werr;
3629 : }
3630 :
3631 : /****************************************************************
3632 : ****************************************************************/
3633 :
3634 0 : WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx,
3635 : struct NetUserGetLocalGroups *r)
3636 : {
3637 0 : LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups);
3638 : }
|