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