netapi: always return correct account name in NetUserGetInfo/NetUserEnum.
[kai/samba-autobuild/.git] / source3 / lib / netapi / user.c
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,
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_PASSWORD;
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         init_samr_user_info21(info21,
95                               0,
96                               0,
97                               0,
98                               0,
99                               0,
100                               password_age,
101                               infoX->usriX_name,
102                               infoX->usriX_full_name,
103                               infoX->usriX_home_dir,
104                               infoX->usriX_home_dir_drive,
105                               infoX->usriX_script_path,
106                               infoX->usriX_profile,
107                               infoX->usriX_comment,
108                               infoX->usriX_workstations,
109                               infoX->usriX_usr_comment,
110                               &zero_parameters,
111                               0,
112                               infoX->usriX_primary_group_id,
113                               infoX->usriX_flags,
114                               fields_present,
115                               zero_logon_hours,
116                               0,
117                               0,
118                               infoX->usriX_country_code,
119                               0,
120                               0,
121                               0,
122                               0);
123 }
124
125 /****************************************************************
126 ****************************************************************/
127
128 static NTSTATUS construct_USER_INFO_X(uint32_t level,
129                                       uint8_t *buffer,
130                                       struct USER_INFO_X *uX)
131 {
132         struct USER_INFO_0 *u0 = NULL;
133         struct USER_INFO_1 *u1 = NULL;
134         struct USER_INFO_2 *u2 = NULL;
135         struct USER_INFO_1003 *u1003 = NULL;
136         struct USER_INFO_1006 *u1006 = NULL;
137         struct USER_INFO_1007 *u1007 = NULL;
138         struct USER_INFO_1009 *u1009 = NULL;
139         struct USER_INFO_1011 *u1011 = NULL;
140         struct USER_INFO_1012 *u1012 = NULL;
141         struct USER_INFO_1014 *u1014 = NULL;
142         struct USER_INFO_1024 *u1024 = NULL;
143         struct USER_INFO_1051 *u1051 = NULL;
144         struct USER_INFO_1052 *u1052 = NULL;
145         struct USER_INFO_1053 *u1053 = NULL;
146
147         if (!buffer || !uX) {
148                 return NT_STATUS_INVALID_PARAMETER;
149         }
150
151         ZERO_STRUCTP(uX);
152
153         switch (level) {
154                 case 0:
155                         u0 = (struct USER_INFO_0 *)buffer;
156                         uX->usriX_name          = u0->usri0_name;
157                         break;
158                 case 1:
159                         u1 = (struct USER_INFO_1 *)buffer;
160                         uX->usriX_name          = u1->usri1_name;
161                         uX->usriX_password      = u1->usri1_password;
162                         uX->usriX_password_age  = u1->usri1_password_age;
163                         uX->usriX_priv          = u1->usri1_priv;
164                         uX->usriX_home_dir      = u1->usri1_home_dir;
165                         uX->usriX_comment       = u1->usri1_comment;
166                         uX->usriX_flags         = u1->usri1_flags;
167                         uX->usriX_script_path   = u1->usri1_script_path;
168                         break;
169                 case 2:
170                         u2 = (struct USER_INFO_2 *)buffer;
171                         uX->usriX_name          = u2->usri2_name;
172                         uX->usriX_password      = u2->usri2_password;
173                         uX->usriX_password_age  = u2->usri2_password_age;
174                         uX->usriX_priv          = u2->usri2_priv;
175                         uX->usriX_home_dir      = u2->usri2_home_dir;
176                         uX->usriX_comment       = u2->usri2_comment;
177                         uX->usriX_flags         = u2->usri2_flags;
178                         uX->usriX_script_path   = u2->usri2_script_path;
179                         uX->usriX_auth_flags    = u2->usri2_auth_flags;
180                         uX->usriX_full_name     = u2->usri2_full_name;
181                         uX->usriX_usr_comment   = u2->usri2_usr_comment;
182                         uX->usriX_parms         = u2->usri2_parms;
183                         uX->usriX_workstations  = u2->usri2_workstations;
184                         uX->usriX_last_logon    = u2->usri2_last_logon;
185                         uX->usriX_last_logoff   = u2->usri2_last_logoff;
186                         uX->usriX_acct_expires  = u2->usri2_acct_expires;
187                         uX->usriX_max_storage   = u2->usri2_max_storage;
188                         uX->usriX_units_per_week= u2->usri2_units_per_week;
189                         uX->usriX_logon_hours   = u2->usri2_logon_hours;
190                         uX->usriX_bad_pw_count  = u2->usri2_bad_pw_count;
191                         uX->usriX_num_logons    = u2->usri2_num_logons;
192                         uX->usriX_logon_server  = u2->usri2_logon_server;
193                         uX->usriX_country_code  = u2->usri2_country_code;
194                         uX->usriX_code_page     = u2->usri2_code_page;
195                         break;
196                 case 1003:
197                         u1003 = (struct USER_INFO_1003 *)buffer;
198                         uX->usriX_password      = u1003->usri1003_password;
199                         break;
200                 case 1006:
201                         u1006 = (struct USER_INFO_1006 *)buffer;
202                         uX->usriX_home_dir      = u1006->usri1006_home_dir;
203                         break;
204                 case 1007:
205                         u1007 = (struct USER_INFO_1007 *)buffer;
206                         uX->usriX_comment       = u1007->usri1007_comment;
207                         break;
208                 case 1009:
209                         u1009 = (struct USER_INFO_1009 *)buffer;
210                         uX->usriX_script_path   = u1009->usri1009_script_path;
211                         break;
212                 case 1011:
213                         u1011 = (struct USER_INFO_1011 *)buffer;
214                         uX->usriX_full_name     = u1011->usri1011_full_name;
215                         break;
216                 case 1012:
217                         u1012 = (struct USER_INFO_1012 *)buffer;
218                         uX->usriX_usr_comment   = u1012->usri1012_usr_comment;
219                         break;
220                 case 1014:
221                         u1014 = (struct USER_INFO_1014 *)buffer;
222                         uX->usriX_workstations  = u1014->usri1014_workstations;
223                         break;
224                 case 1024:
225                         u1024 = (struct USER_INFO_1024 *)buffer;
226                         uX->usriX_country_code  = u1024->usri1024_country_code;
227                         break;
228                 case 1051:
229                         u1051 = (struct USER_INFO_1051 *)buffer;
230                         uX->usriX_primary_group_id = u1051->usri1051_primary_group_id;
231                         break;
232                 case 1052:
233                         u1052 = (struct USER_INFO_1052 *)buffer;
234                         uX->usriX_profile       = u1052->usri1052_profile;
235                         break;
236                 case 1053:
237                         u1053 = (struct USER_INFO_1053 *)buffer;
238                         uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive;
239                         break;
240                 case 3:
241                 case 4:
242                 default:
243                         return NT_STATUS_INVALID_INFO_CLASS;
244         }
245
246         return NT_STATUS_OK;
247 }
248
249 /****************************************************************
250 ****************************************************************/
251
252 static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx,
253                                           struct rpc_pipe_client *pipe_cli,
254                                           DATA_BLOB *session_key,
255                                           struct policy_handle *user_handle,
256                                           struct USER_INFO_X *uX)
257 {
258         union samr_UserInfo user_info;
259         struct samr_UserInfo21 info21;
260         NTSTATUS status;
261
262         if (!uX) {
263                 return NT_STATUS_INVALID_PARAMETER;
264         }
265
266         convert_USER_INFO_X_to_samr_user_info21(uX, &info21);
267
268         ZERO_STRUCT(user_info);
269
270         if (uX->usriX_password) {
271
272                 user_info.info25.info = info21;
273
274                 init_samr_CryptPasswordEx(uX->usriX_password,
275                                           session_key,
276                                           &user_info.info25.password);
277
278                 status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
279                                                   user_handle,
280                                                   25,
281                                                   &user_info);
282
283                 if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
284
285                         user_info.info23.info = info21;
286
287                         init_samr_CryptPassword(uX->usriX_password,
288                                                 session_key,
289                                                 &user_info.info23.password);
290
291                         status = rpccli_samr_SetUserInfo2(pipe_cli, ctx,
292                                                           user_handle,
293                                                           23,
294                                                           &user_info);
295                 }
296         } else {
297
298                 user_info.info21 = info21;
299
300                 status = rpccli_samr_SetUserInfo(pipe_cli, ctx,
301                                                  user_handle,
302                                                  21,
303                                                  &user_info);
304         }
305
306         return status;
307 }
308
309 /****************************************************************
310 ****************************************************************/
311
312 WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
313                     struct NetUserAdd *r)
314 {
315         struct cli_state *cli = NULL;
316         struct rpc_pipe_client *pipe_cli = NULL;
317         NTSTATUS status;
318         WERROR werr;
319         POLICY_HND connect_handle, domain_handle, user_handle;
320         struct lsa_String lsa_account_name;
321         struct dom_sid2 *domain_sid = NULL;
322         union samr_UserInfo *user_info = NULL;
323         struct samr_PwInfo pw_info;
324         uint32_t access_granted = 0;
325         uint32_t rid = 0;
326         struct USER_INFO_X uX;
327
328         ZERO_STRUCT(connect_handle);
329         ZERO_STRUCT(domain_handle);
330         ZERO_STRUCT(user_handle);
331
332         if (!r->in.buffer) {
333                 return WERR_INVALID_PARAM;
334         }
335
336         switch (r->in.level) {
337                 case 1:
338                         break;
339                 case 2:
340                 case 3:
341                 case 4:
342                 default:
343                         werr = WERR_NOT_SUPPORTED;
344                         goto done;
345         }
346
347         werr = libnetapi_open_pipe(ctx, r->in.server_name,
348                                    &ndr_table_samr.syntax_id,
349                                    &cli,
350                                    &pipe_cli);
351         if (!W_ERROR_IS_OK(werr)) {
352                 goto done;
353         }
354
355         status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
356         if (!NT_STATUS_IS_OK(status)) {
357                 werr = ntstatus_to_werror(status);
358                 goto done;
359         }
360
361         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
362                                           SAMR_ACCESS_ENUM_DOMAINS |
363                                           SAMR_ACCESS_OPEN_DOMAIN,
364                                           SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
365                                           SAMR_DOMAIN_ACCESS_CREATE_USER |
366                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
367                                           &connect_handle,
368                                           &domain_handle,
369                                           &domain_sid);
370         if (!W_ERROR_IS_OK(werr)) {
371                 goto done;
372         }
373
374         init_lsa_String(&lsa_account_name, uX.usriX_name);
375
376         status = rpccli_samr_CreateUser2(pipe_cli, ctx,
377                                          &domain_handle,
378                                          &lsa_account_name,
379                                          ACB_NORMAL,
380                                          SEC_STD_WRITE_DAC |
381                                          SEC_STD_DELETE |
382                                          SAMR_USER_ACCESS_SET_PASSWORD |
383                                          SAMR_USER_ACCESS_SET_ATTRIBUTES |
384                                          SAMR_USER_ACCESS_GET_ATTRIBUTES,
385                                          &user_handle,
386                                          &access_granted,
387                                          &rid);
388         if (!NT_STATUS_IS_OK(status)) {
389                 werr = ntstatus_to_werror(status);
390                 goto done;
391         }
392
393         status = rpccli_samr_QueryUserInfo(pipe_cli, ctx,
394                                            &user_handle,
395                                            16,
396                                            &user_info);
397         if (!NT_STATUS_IS_OK(status)) {
398                 werr = ntstatus_to_werror(status);
399                 goto done;
400         }
401
402         if (!(user_info->info16.acct_flags & ACB_NORMAL)) {
403                 werr = WERR_INVALID_PARAM;
404                 goto done;
405         }
406
407         status = rpccli_samr_GetUserPwInfo(pipe_cli, ctx,
408                                            &user_handle,
409                                            &pw_info);
410         if (!NT_STATUS_IS_OK(status)) {
411                 werr = ntstatus_to_werror(status);
412                 goto done;
413         }
414
415         uX.usriX_flags |= ACB_NORMAL;
416
417         status = set_user_info_USER_INFO_X(ctx, pipe_cli,
418                                            &cli->user_session_key,
419                                            &user_handle,
420                                            &uX);
421         if (!NT_STATUS_IS_OK(status)) {
422                 werr = ntstatus_to_werror(status);
423                 goto failed;
424         }
425
426         werr = WERR_OK;
427         goto done;
428
429  failed:
430         rpccli_samr_DeleteUser(pipe_cli, ctx,
431                                &user_handle);
432
433  done:
434         if (!cli) {
435                 return werr;
436         }
437
438         if (is_valid_policy_hnd(&user_handle)) {
439                 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
440         }
441
442         if (ctx->disable_policy_handle_cache) {
443                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
444                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
445         }
446
447         return werr;
448 }
449
450 /****************************************************************
451 ****************************************************************/
452
453 WERROR NetUserAdd_l(struct libnetapi_ctx *ctx,
454                     struct NetUserAdd *r)
455 {
456         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd);
457 }
458
459 /****************************************************************
460 ****************************************************************/
461
462 WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
463                     struct NetUserDel *r)
464 {
465         struct cli_state *cli = NULL;
466         struct rpc_pipe_client *pipe_cli = NULL;
467         NTSTATUS status;
468         WERROR werr;
469         POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle;
470         struct lsa_String lsa_account_name;
471         struct samr_Ids user_rids, name_types;
472         struct dom_sid2 *domain_sid = NULL;
473         struct dom_sid2 user_sid;
474
475         ZERO_STRUCT(connect_handle);
476         ZERO_STRUCT(builtin_handle);
477         ZERO_STRUCT(domain_handle);
478         ZERO_STRUCT(user_handle);
479
480         werr = libnetapi_open_pipe(ctx, r->in.server_name,
481                                    &ndr_table_samr.syntax_id,
482                                    &cli,
483                                    &pipe_cli);
484
485         if (!W_ERROR_IS_OK(werr)) {
486                 goto done;
487         }
488
489         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
490                                           SAMR_ACCESS_ENUM_DOMAINS |
491                                           SAMR_ACCESS_OPEN_DOMAIN,
492                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
493                                           &connect_handle,
494                                           &domain_handle,
495                                           &domain_sid);
496         if (!W_ERROR_IS_OK(werr)) {
497                 goto done;
498         }
499
500         status = rpccli_samr_OpenDomain(pipe_cli, ctx,
501                                         &connect_handle,
502                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
503                                         CONST_DISCARD(DOM_SID *, &global_sid_Builtin),
504                                         &builtin_handle);
505         if (!NT_STATUS_IS_OK(status)) {
506                 werr = ntstatus_to_werror(status);
507                 goto done;
508         }
509
510         init_lsa_String(&lsa_account_name, r->in.user_name);
511
512         status = rpccli_samr_LookupNames(pipe_cli, ctx,
513                                          &domain_handle,
514                                          1,
515                                          &lsa_account_name,
516                                          &user_rids,
517                                          &name_types);
518         if (!NT_STATUS_IS_OK(status)) {
519                 werr = ntstatus_to_werror(status);
520                 goto done;
521         }
522
523         status = rpccli_samr_OpenUser(pipe_cli, ctx,
524                                       &domain_handle,
525                                       STD_RIGHT_DELETE_ACCESS,
526                                       user_rids.ids[0],
527                                       &user_handle);
528         if (!NT_STATUS_IS_OK(status)) {
529                 werr = ntstatus_to_werror(status);
530                 goto done;
531         }
532
533         sid_compose(&user_sid, domain_sid, user_rids.ids[0]);
534
535         status = rpccli_samr_RemoveMemberFromForeignDomain(pipe_cli, ctx,
536                                                            &builtin_handle,
537                                                            &user_sid);
538         if (!NT_STATUS_IS_OK(status)) {
539                 werr = ntstatus_to_werror(status);
540                 goto done;
541         }
542
543         status = rpccli_samr_DeleteUser(pipe_cli, ctx,
544                                         &user_handle);
545         if (!NT_STATUS_IS_OK(status)) {
546                 werr = ntstatus_to_werror(status);
547                 goto done;
548         }
549
550         werr = WERR_OK;
551
552  done:
553         if (!cli) {
554                 return werr;
555         }
556
557         if (is_valid_policy_hnd(&user_handle)) {
558                 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
559         }
560
561         if (ctx->disable_policy_handle_cache) {
562                 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
563                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
564                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
565         }
566
567         return werr;
568 }
569
570 /****************************************************************
571 ****************************************************************/
572
573 WERROR NetUserDel_l(struct libnetapi_ctx *ctx,
574                     struct NetUserDel *r)
575 {
576         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel);
577 }
578
579 /****************************************************************
580 ****************************************************************/
581
582 static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx,
583                                            struct rpc_pipe_client *pipe_cli,
584                                            struct policy_handle *domain_handle,
585                                            struct policy_handle *builtin_handle,
586                                            const char *user_name,
587                                            uint32_t rid,
588                                            uint32_t level,
589                                            struct samr_UserInfo21 **info21,
590                                            struct sec_desc_buf **sec_desc)
591 {
592         NTSTATUS status;
593
594         struct policy_handle user_handle;
595         union samr_UserInfo *user_info = NULL;
596         struct samr_RidWithAttributeArray *rid_array = NULL;
597         uint32_t access_mask = SEC_STD_READ_CONTROL |
598                                SAMR_USER_ACCESS_GET_ATTRIBUTES |
599                                SAMR_USER_ACCESS_GET_NAME_ETC;
600
601         ZERO_STRUCT(user_handle);
602
603         switch (level) {
604                 case 0:
605                 case 1:
606                 case 2:
607                 case 3:
608                 case 10:
609                 case 11:
610                 case 20:
611                 case 23:
612                         break;
613                 default:
614                         return NT_STATUS_INVALID_LEVEL;
615         }
616
617         if (level == 0) {
618                 return NT_STATUS_OK;
619         }
620
621         status = rpccli_samr_OpenUser(pipe_cli, mem_ctx,
622                                       domain_handle,
623                                       access_mask,
624                                       rid,
625                                       &user_handle);
626         if (!NT_STATUS_IS_OK(status)) {
627                 goto done;
628         }
629
630         status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx,
631                                            &user_handle,
632                                            21,
633                                            &user_info);
634         if (!NT_STATUS_IS_OK(status)) {
635                 goto done;
636         }
637
638         status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx,
639                                            &user_handle,
640                                            SECINFO_DACL,
641                                            sec_desc);
642         if (!NT_STATUS_IS_OK(status)) {
643                 goto done;
644         }
645
646         if (level == 1) {
647                 status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx,
648                                                       &user_handle,
649                                                       &rid_array);
650                 if (!NT_STATUS_IS_OK(status)) {
651                         goto done;
652                 }
653
654 #if 0
655                 status = rpccli_samr_GetAliasMembership(pipe_cli, ctx,
656                                                         &builtin_handle,
657                                                         &sids,
658                                                         &rids);
659                 if (!NT_STATUS_IS_OK(status)) {
660                         goto done;
661                 }
662 #endif
663         }
664
665         *info21 = &user_info->info21;
666
667  done:
668         if (is_valid_policy_hnd(&user_handle)) {
669                 rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle);
670         }
671
672         return status;
673 }
674
675 /****************************************************************
676 ****************************************************************/
677
678 static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
679 {
680         uint32_t fl = UF_SCRIPT; /* god knows why */
681
682         fl |= ads_acb2uf(acb);
683
684         return fl;
685 }
686
687 /****************************************************************
688 ****************************************************************/
689
690 static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx,
691                                                          struct rpc_pipe_client *pipe_cli,
692                                                          struct dom_sid *domain_sid,
693                                                          struct policy_handle *domain_handle,
694                                                          struct policy_handle *builtin_handle,
695                                                          const char *user_name,
696                                                          uint32_t rid,
697                                                          uint32_t level,
698                                                          uint8_t **buffer,
699                                                          uint32_t *num_entries)
700 {
701         NTSTATUS status;
702
703         struct samr_UserInfo21 *info21 = NULL;
704         struct sec_desc_buf *sec_desc = NULL;
705         struct dom_sid sid;
706
707         struct USER_INFO_0 info0;
708         struct USER_INFO_10 info10;
709         struct USER_INFO_20 info20;
710         struct USER_INFO_23 info23;
711
712         switch (level) {
713                 case 0:
714                 case 1:
715                 case 2:
716                 case 3:
717                 case 10:
718                 case 11:
719                 case 20:
720                 case 23:
721                         break;
722                 default:
723                         return NT_STATUS_INVALID_LEVEL;
724         }
725
726         if (level == 0) {
727                 info0.usri0_name = talloc_strdup(mem_ctx, user_name);
728                 NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name);
729
730                 ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0,
731                              (struct USER_INFO_0 **)buffer, num_entries);
732
733                 return NT_STATUS_OK;
734         }
735
736         status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli,
737                                             domain_handle,
738                                             builtin_handle,
739                                             user_name,
740                                             rid,
741                                             level,
742                                             &info21,
743                                             &sec_desc);
744
745         if (!NT_STATUS_IS_OK(status)) {
746                 goto done;
747         }
748
749         switch (level) {
750                 case 10:
751                         info10.usri10_name = talloc_strdup(mem_ctx,
752                                 info21->account_name.string);
753                         NT_STATUS_HAVE_NO_MEMORY(info10.usri10_name);
754
755                         info10.usri10_comment = talloc_strdup(mem_ctx,
756                                 info21->description.string);
757
758                         info10.usri10_full_name = talloc_strdup(mem_ctx,
759                                 info21->full_name.string);
760
761                         info10.usri10_usr_comment = talloc_strdup(mem_ctx,
762                                 info21->comment.string);
763
764                         ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10,
765                                      (struct USER_INFO_10 **)buffer, num_entries);
766
767                         break;
768
769                 case 20:
770                         info20.usri20_name = talloc_strdup(mem_ctx,
771                                 info21->account_name.string);
772                         NT_STATUS_HAVE_NO_MEMORY(info20.usri20_name);
773
774                         info20.usri20_comment = talloc_strdup(mem_ctx,
775                                 info21->description.string);
776
777                         info20.usri20_full_name = talloc_strdup(mem_ctx,
778                                 info21->full_name.string);
779
780                         info20.usri20_flags =
781                                 samr_acb_flags_to_netapi_flags(info21->acct_flags);
782                         info20.usri20_user_id = rid;
783
784                         ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20,
785                                      (struct USER_INFO_20 **)buffer, num_entries);
786
787                         break;
788                 case 23:
789                         info23.usri23_name = talloc_strdup(mem_ctx,
790                                 info21->account_name.string);
791                         NT_STATUS_HAVE_NO_MEMORY(info23.usri23_name);
792
793                         info23.usri23_comment = talloc_strdup(mem_ctx,
794                                 info21->description.string);
795
796                         info23.usri23_full_name = talloc_strdup(mem_ctx,
797                                 info21->full_name.string);
798
799                         info23.usri23_flags =
800                                 samr_acb_flags_to_netapi_flags(info21->acct_flags);
801
802                         if (!sid_compose(&sid, domain_sid, rid)) {
803                                 return NT_STATUS_NO_MEMORY;
804                         }
805
806                         info23.usri23_user_sid =
807                                 (struct domsid *)sid_dup_talloc(mem_ctx, &sid);
808
809                         ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23,
810                                      (struct USER_INFO_23 **)buffer, num_entries);
811                         break;
812         }
813
814  done:
815         return status;
816 }
817
818 /****************************************************************
819 ****************************************************************/
820
821 WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
822                      struct NetUserEnum *r)
823 {
824         struct cli_state *cli = NULL;
825         struct rpc_pipe_client *pipe_cli = NULL;
826         struct policy_handle connect_handle;
827         struct dom_sid2 *domain_sid = NULL;
828         struct policy_handle domain_handle;
829         struct samr_SamArray *sam = NULL;
830         uint32_t filter = ACB_NORMAL;
831         int i;
832         uint32_t entries_read = 0;
833
834         NTSTATUS status = NT_STATUS_OK;
835         WERROR werr;
836
837         ZERO_STRUCT(connect_handle);
838         ZERO_STRUCT(domain_handle);
839
840         if (!r->out.buffer) {
841                 return WERR_INVALID_PARAM;
842         }
843
844         *r->out.buffer = NULL;
845         *r->out.entries_read = 0;
846
847         switch (r->in.level) {
848                 case 0:
849                 case 10:
850                 case 20:
851                 case 23:
852                         break;
853                 case 1:
854                 case 2:
855                 case 3:
856                 case 11:
857                 default:
858                         return WERR_NOT_SUPPORTED;
859         }
860
861         werr = libnetapi_open_pipe(ctx, r->in.server_name,
862                                    &ndr_table_samr.syntax_id,
863                                    &cli,
864                                    &pipe_cli);
865         if (!W_ERROR_IS_OK(werr)) {
866                 goto done;
867         }
868
869         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
870                                           SAMR_ACCESS_ENUM_DOMAINS |
871                                           SAMR_ACCESS_OPEN_DOMAIN,
872                                           SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
873                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
874                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
875                                           &connect_handle,
876                                           &domain_handle,
877                                           &domain_sid);
878         if (!W_ERROR_IS_OK(werr)) {
879                 goto done;
880         }
881
882         switch (r->in.filter) {
883                 case FILTER_NORMAL_ACCOUNT:
884                         filter = ACB_NORMAL;
885                         break;
886                 case FILTER_TEMP_DUPLICATE_ACCOUNT:
887                         filter = ACB_TEMPDUP;
888                         break;
889                 case FILTER_INTERDOMAIN_TRUST_ACCOUNT:
890                         filter = ACB_DOMTRUST;
891                         break;
892                 case FILTER_WORKSTATION_TRUST_ACCOUNT:
893                         filter = ACB_WSTRUST;
894                         break;
895                 case FILTER_SERVER_TRUST_ACCOUNT:
896                         filter = ACB_SVRTRUST;
897                         break;
898                 default:
899                         break;
900         }
901
902         status = rpccli_samr_EnumDomainUsers(pipe_cli,
903                                              ctx,
904                                              &domain_handle,
905                                              r->in.resume_handle,
906                                              filter,
907                                              &sam,
908                                              r->in.prefmaxlen,
909                                              &entries_read);
910         werr = ntstatus_to_werror(status);
911         if (NT_STATUS_IS_ERR(status)) {
912                 goto done;
913         }
914
915         for (i=0; i < sam->count; i++) {
916
917                 status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
918                                                                   domain_sid,
919                                                                   &domain_handle,
920                                                                   NULL, /*&builtin_handle, */
921                                                                   sam->entries[i].name.string,
922                                                                   sam->entries[i].idx,
923                                                                   r->in.level,
924                                                                   r->out.buffer,
925                                                                   r->out.entries_read);
926                 if (!NT_STATUS_IS_OK(status)) {
927                         werr = ntstatus_to_werror(status);
928                         goto done;
929                 }
930         }
931
932  done:
933         if (!cli) {
934                 return werr;
935         }
936
937         /* if last query */
938         if (NT_STATUS_IS_OK(status) ||
939             NT_STATUS_IS_ERR(status)) {
940
941                 if (ctx->disable_policy_handle_cache) {
942                         libnetapi_samr_close_domain_handle(ctx, &domain_handle);
943                         libnetapi_samr_close_connect_handle(ctx, &connect_handle);
944                 }
945         }
946
947         return werr;
948 }
949
950 /****************************************************************
951 ****************************************************************/
952
953 WERROR NetUserEnum_l(struct libnetapi_ctx *ctx,
954                      struct NetUserEnum *r)
955 {
956         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum);
957 }
958
959 /****************************************************************
960 ****************************************************************/
961
962 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER(TALLOC_CTX *mem_ctx,
963                                                         struct samr_DispInfoGeneral *info,
964                                                         uint32_t *entries_read,
965                                                         void **buffer)
966 {
967         struct NET_DISPLAY_USER *user = NULL;
968         int i;
969
970         user = TALLOC_ZERO_ARRAY(mem_ctx,
971                                  struct NET_DISPLAY_USER,
972                                  info->count);
973         W_ERROR_HAVE_NO_MEMORY(user);
974
975         for (i = 0; i < info->count; i++) {
976                 user[i].usri1_name = talloc_strdup(mem_ctx,
977                         info->entries[i].account_name.string);
978                 user[i].usri1_comment = talloc_strdup(mem_ctx,
979                         info->entries[i].description.string);
980                 user[i].usri1_flags =
981                         info->entries[i].acct_flags;
982                 user[i].usri1_full_name = talloc_strdup(mem_ctx,
983                         info->entries[i].full_name.string);
984                 user[i].usri1_user_id =
985                         info->entries[i].rid;
986                 user[i].usri1_next_index =
987                         info->entries[i].idx;
988
989                 if (!user[i].usri1_name) {
990                         return WERR_NOMEM;
991                 }
992         }
993
994         *buffer = talloc_memdup(mem_ctx, user,
995                 sizeof(struct NET_DISPLAY_USER) * info->count);
996         W_ERROR_HAVE_NO_MEMORY(*buffer);
997
998         *entries_read = info->count;
999
1000         return WERR_OK;
1001 }
1002
1003 /****************************************************************
1004 ****************************************************************/
1005
1006 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(TALLOC_CTX *mem_ctx,
1007                                                            struct samr_DispInfoFull *info,
1008                                                            uint32_t *entries_read,
1009                                                            void **buffer)
1010 {
1011         struct NET_DISPLAY_MACHINE *machine = NULL;
1012         int i;
1013
1014         machine = TALLOC_ZERO_ARRAY(mem_ctx,
1015                                     struct NET_DISPLAY_MACHINE,
1016                                     info->count);
1017         W_ERROR_HAVE_NO_MEMORY(machine);
1018
1019         for (i = 0; i < info->count; i++) {
1020                 machine[i].usri2_name = talloc_strdup(mem_ctx,
1021                         info->entries[i].account_name.string);
1022                 machine[i].usri2_comment = talloc_strdup(mem_ctx,
1023                         info->entries[i].description.string);
1024                 machine[i].usri2_flags =
1025                         info->entries[i].acct_flags;
1026                 machine[i].usri2_user_id =
1027                         info->entries[i].rid;
1028                 machine[i].usri2_next_index =
1029                         info->entries[i].idx;
1030
1031                 if (!machine[i].usri2_name) {
1032                         return WERR_NOMEM;
1033                 }
1034         }
1035
1036         *buffer = talloc_memdup(mem_ctx, machine,
1037                 sizeof(struct NET_DISPLAY_MACHINE) * info->count);
1038         W_ERROR_HAVE_NO_MEMORY(*buffer);
1039
1040         *entries_read = info->count;
1041
1042         return WERR_OK;
1043 }
1044
1045 /****************************************************************
1046 ****************************************************************/
1047
1048 static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx,
1049                                                          struct samr_DispInfoFullGroups *info,
1050                                                          uint32_t *entries_read,
1051                                                          void **buffer)
1052 {
1053         struct NET_DISPLAY_GROUP *group = NULL;
1054         int i;
1055
1056         group = TALLOC_ZERO_ARRAY(mem_ctx,
1057                                   struct NET_DISPLAY_GROUP,
1058                                   info->count);
1059         W_ERROR_HAVE_NO_MEMORY(group);
1060
1061         for (i = 0; i < info->count; i++) {
1062                 group[i].grpi3_name = talloc_strdup(mem_ctx,
1063                         info->entries[i].account_name.string);
1064                 group[i].grpi3_comment = talloc_strdup(mem_ctx,
1065                         info->entries[i].description.string);
1066                 group[i].grpi3_group_id =
1067                         info->entries[i].rid;
1068                 group[i].grpi3_attributes =
1069                         info->entries[i].acct_flags;
1070                 group[i].grpi3_next_index =
1071                         info->entries[i].idx;
1072
1073                 if (!group[i].grpi3_name) {
1074                         return WERR_NOMEM;
1075                 }
1076         }
1077
1078         *buffer = talloc_memdup(mem_ctx, group,
1079                 sizeof(struct NET_DISPLAY_GROUP) * info->count);
1080         W_ERROR_HAVE_NO_MEMORY(*buffer);
1081
1082         *entries_read = info->count;
1083
1084         return WERR_OK;
1085
1086 }
1087
1088 /****************************************************************
1089 ****************************************************************/
1090
1091 static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx,
1092                                                    union samr_DispInfo *info,
1093                                                    uint32_t level,
1094                                                    uint32_t *entries_read,
1095                                                    void **buffer)
1096 {
1097         switch (level) {
1098                 case 1:
1099                         return convert_samr_dispinfo_to_NET_DISPLAY_USER(mem_ctx,
1100                                                                          &info->info1,
1101                                                                          entries_read,
1102                                                                          buffer);
1103                 case 2:
1104                         return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE(mem_ctx,
1105                                                                             &info->info2,
1106                                                                             entries_read,
1107                                                                             buffer);
1108                 case 3:
1109                         return convert_samr_dispinfo_to_NET_DISPLAY_GROUP(mem_ctx,
1110                                                                           &info->info3,
1111                                                                           entries_read,
1112                                                                           buffer);
1113                 default:
1114                         return WERR_UNKNOWN_LEVEL;
1115         }
1116
1117         return WERR_OK;
1118 }
1119
1120 /****************************************************************
1121 ****************************************************************/
1122
1123 WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
1124                                     struct NetQueryDisplayInformation *r)
1125 {
1126         struct cli_state *cli = NULL;
1127         struct rpc_pipe_client *pipe_cli = NULL;
1128         struct policy_handle connect_handle;
1129         struct dom_sid2 *domain_sid = NULL;
1130         struct policy_handle domain_handle;
1131         union samr_DispInfo info;
1132
1133         uint32_t total_size = 0;
1134         uint32_t returned_size = 0;
1135
1136         NTSTATUS status = NT_STATUS_OK;
1137         WERROR werr;
1138
1139         ZERO_STRUCT(connect_handle);
1140         ZERO_STRUCT(domain_handle);
1141
1142         switch (r->in.level) {
1143                 case 1:
1144                 case 2:
1145                 case 3:
1146                         break;
1147                 default:
1148                         return WERR_UNKNOWN_LEVEL;
1149         }
1150
1151         werr = libnetapi_open_pipe(ctx, r->in.server_name,
1152                                    &ndr_table_samr.syntax_id,
1153                                    &cli,
1154                                    &pipe_cli);
1155         if (!W_ERROR_IS_OK(werr)) {
1156                 goto done;
1157         }
1158
1159         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1160                                           SAMR_ACCESS_ENUM_DOMAINS |
1161                                           SAMR_ACCESS_OPEN_DOMAIN,
1162                                           SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
1163                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
1164                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1165                                           &connect_handle,
1166                                           &domain_handle,
1167                                           &domain_sid);
1168         if (!W_ERROR_IS_OK(werr)) {
1169                 goto done;
1170         }
1171
1172         status = rpccli_samr_QueryDisplayInfo2(pipe_cli,
1173                                                ctx,
1174                                                &domain_handle,
1175                                                r->in.level,
1176                                                r->in.idx,
1177                                                r->in.entries_requested,
1178                                                r->in.prefmaxlen,
1179                                                &total_size,
1180                                                &returned_size,
1181                                                &info);
1182         if (!NT_STATUS_IS_OK(status)) {
1183                 werr = ntstatus_to_werror(status);
1184                 goto done;
1185         }
1186
1187         werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info,
1188                                                     r->in.level,
1189                                                     r->out.entries_read,
1190                                                     r->out.buffer);
1191  done:
1192         if (!cli) {
1193                 return werr;
1194         }
1195
1196         /* if last query */
1197         if (NT_STATUS_IS_OK(status) ||
1198             NT_STATUS_IS_ERR(status)) {
1199
1200                 if (ctx->disable_policy_handle_cache) {
1201                         libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1202                         libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1203                 }
1204         }
1205
1206         return werr;
1207
1208 }
1209
1210 /****************************************************************
1211 ****************************************************************/
1212
1213
1214 WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx,
1215                                     struct NetQueryDisplayInformation *r)
1216 {
1217         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation);
1218 }
1219
1220 /****************************************************************
1221 ****************************************************************/
1222
1223 WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx,
1224                                struct NetUserChangePassword *r)
1225 {
1226         return WERR_NOT_SUPPORTED;
1227 }
1228
1229 /****************************************************************
1230 ****************************************************************/
1231
1232 WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx,
1233                                struct NetUserChangePassword *r)
1234 {
1235         return WERR_NOT_SUPPORTED;
1236 }
1237
1238 /****************************************************************
1239 ****************************************************************/
1240
1241 WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
1242                         struct NetUserGetInfo *r)
1243 {
1244         struct cli_state *cli = NULL;
1245         struct rpc_pipe_client *pipe_cli = NULL;
1246         NTSTATUS status;
1247         WERROR werr;
1248
1249         struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1250         struct lsa_String lsa_account_name;
1251         struct dom_sid2 *domain_sid = NULL;
1252         struct samr_Ids user_rids, name_types;
1253         uint32_t num_entries = 0;
1254
1255         ZERO_STRUCT(connect_handle);
1256         ZERO_STRUCT(domain_handle);
1257         ZERO_STRUCT(builtin_handle);
1258         ZERO_STRUCT(user_handle);
1259
1260         if (!r->out.buffer) {
1261                 return WERR_INVALID_PARAM;
1262         }
1263
1264         switch (r->in.level) {
1265                 case 0:
1266                 /* case 1: */
1267                 case 10:
1268                 case 20:
1269                 case 23:
1270                         break;
1271                 default:
1272                         werr = WERR_NOT_SUPPORTED;
1273                         goto done;
1274         }
1275
1276         werr = libnetapi_open_pipe(ctx, r->in.server_name,
1277                                    &ndr_table_samr.syntax_id,
1278                                    &cli,
1279                                    &pipe_cli);
1280         if (!W_ERROR_IS_OK(werr)) {
1281                 goto done;
1282         }
1283
1284         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1285                                           SAMR_ACCESS_ENUM_DOMAINS |
1286                                           SAMR_ACCESS_OPEN_DOMAIN,
1287                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1288                                           &connect_handle,
1289                                           &domain_handle,
1290                                           &domain_sid);
1291         if (!W_ERROR_IS_OK(werr)) {
1292                 goto done;
1293         }
1294
1295         werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1296                                                   SAMR_ACCESS_ENUM_DOMAINS |
1297                                                   SAMR_ACCESS_OPEN_DOMAIN,
1298                                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1299                                                   SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1300                                                   &connect_handle,
1301                                                   &builtin_handle);
1302         if (!W_ERROR_IS_OK(werr)) {
1303                 goto done;
1304         }
1305
1306         init_lsa_String(&lsa_account_name, r->in.user_name);
1307
1308         status = rpccli_samr_LookupNames(pipe_cli, ctx,
1309                                          &domain_handle,
1310                                          1,
1311                                          &lsa_account_name,
1312                                          &user_rids,
1313                                          &name_types);
1314         if (!NT_STATUS_IS_OK(status)) {
1315                 werr = ntstatus_to_werror(status);
1316                 goto done;
1317         }
1318
1319         status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli,
1320                                                           domain_sid,
1321                                                           &domain_handle,
1322                                                           &builtin_handle,
1323                                                           r->in.user_name,
1324                                                           user_rids.ids[0],
1325                                                           r->in.level,
1326                                                           r->out.buffer,
1327                                                           &num_entries);
1328         if (!NT_STATUS_IS_OK(status)) {
1329                 werr = ntstatus_to_werror(status);
1330                 goto done;
1331         }
1332
1333  done:
1334         if (!cli) {
1335                 return werr;
1336         }
1337
1338         if (is_valid_policy_hnd(&user_handle)) {
1339                 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1340         }
1341
1342         if (ctx->disable_policy_handle_cache) {
1343                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1344                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1345         }
1346
1347         return werr;
1348 }
1349
1350 /****************************************************************
1351 ****************************************************************/
1352
1353 WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx,
1354                         struct NetUserGetInfo *r)
1355 {
1356         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo);
1357 }
1358
1359 /****************************************************************
1360 ****************************************************************/
1361
1362 WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
1363                         struct NetUserSetInfo *r)
1364 {
1365         struct cli_state *cli = NULL;
1366         struct rpc_pipe_client *pipe_cli = NULL;
1367         NTSTATUS status;
1368         WERROR werr;
1369
1370         struct policy_handle connect_handle, domain_handle, builtin_handle, user_handle;
1371         struct lsa_String lsa_account_name;
1372         struct dom_sid2 *domain_sid = NULL;
1373         struct samr_Ids user_rids, name_types;
1374         uint32_t user_mask = 0;
1375
1376         struct USER_INFO_X uX;
1377
1378         ZERO_STRUCT(connect_handle);
1379         ZERO_STRUCT(domain_handle);
1380         ZERO_STRUCT(builtin_handle);
1381         ZERO_STRUCT(user_handle);
1382
1383         if (!r->in.buffer) {
1384                 return WERR_INVALID_PARAM;
1385         }
1386
1387         switch (r->in.level) {
1388                 case 0:
1389                 case 1003:
1390                         user_mask = SAMR_USER_ACCESS_SET_PASSWORD;
1391                         break;
1392                 case 1006:
1393                 case 1007:
1394                 case 1009:
1395                 case 1011:
1396                 case 1014:
1397                 case 1052:
1398                 case 1053:
1399                         user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES;
1400                         break;
1401                 case 1012:
1402                 case 1024:
1403                         user_mask = SAMR_USER_ACCESS_SET_LOC_COM;
1404                 case 1051:
1405                         user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
1406                                     SAMR_USER_ACCESS_GET_GROUPS;
1407                         break;
1408                 case 1:
1409                 case 2:
1410                 case 3:
1411                 case 4:
1412                 case 21:
1413                 case 22:
1414                 case 1005:
1415                 case 1008:
1416                 case 1010:
1417                 case 1017:
1418                 case 1020:
1419                         werr = WERR_NOT_SUPPORTED;
1420                         goto done;
1421                 default:
1422                         werr = WERR_UNKNOWN_LEVEL;
1423                         goto done;
1424         }
1425
1426         werr = libnetapi_open_pipe(ctx, r->in.server_name,
1427                                    &ndr_table_samr.syntax_id,
1428                                    &cli,
1429                                    &pipe_cli);
1430         if (!W_ERROR_IS_OK(werr)) {
1431                 goto done;
1432         }
1433
1434         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1435                                           SAMR_ACCESS_ENUM_DOMAINS |
1436                                           SAMR_ACCESS_OPEN_DOMAIN,
1437                                           SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1438                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
1439                                           &connect_handle,
1440                                           &domain_handle,
1441                                           &domain_sid);
1442         if (!W_ERROR_IS_OK(werr)) {
1443                 goto done;
1444         }
1445
1446         werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
1447                                                   SAMR_ACCESS_ENUM_DOMAINS |
1448                                                   SAMR_ACCESS_OPEN_DOMAIN,
1449                                                   SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
1450                                                   SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
1451                                                   &connect_handle,
1452                                                   &builtin_handle);
1453         if (!W_ERROR_IS_OK(werr)) {
1454                 goto done;
1455         }
1456
1457         init_lsa_String(&lsa_account_name, r->in.user_name);
1458
1459         status = rpccli_samr_LookupNames(pipe_cli, ctx,
1460                                          &domain_handle,
1461                                          1,
1462                                          &lsa_account_name,
1463                                          &user_rids,
1464                                          &name_types);
1465         if (!NT_STATUS_IS_OK(status)) {
1466                 werr = ntstatus_to_werror(status);
1467                 goto done;
1468         }
1469
1470         status = rpccli_samr_OpenUser(pipe_cli, ctx,
1471                                       &domain_handle,
1472                                       user_mask,
1473                                       user_rids.ids[0],
1474                                       &user_handle);
1475         if (!NT_STATUS_IS_OK(status)) {
1476                 werr = ntstatus_to_werror(status);
1477                 goto done;
1478         }
1479
1480         status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX);
1481         if (!NT_STATUS_IS_OK(status)) {
1482                 werr = ntstatus_to_werror(status);
1483                 goto done;
1484         }
1485
1486         status = set_user_info_USER_INFO_X(ctx, pipe_cli,
1487                                            &cli->user_session_key,
1488                                            &user_handle,
1489                                            &uX);
1490         if (!NT_STATUS_IS_OK(status)) {
1491                 werr = ntstatus_to_werror(status);
1492                 goto done;
1493         }
1494
1495         werr = WERR_OK;
1496
1497  done:
1498         if (!cli) {
1499                 return werr;
1500         }
1501
1502         if (is_valid_policy_hnd(&user_handle)) {
1503                 rpccli_samr_Close(pipe_cli, ctx, &user_handle);
1504         }
1505
1506         if (ctx->disable_policy_handle_cache) {
1507                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1508                 libnetapi_samr_close_builtin_handle(ctx, &builtin_handle);
1509                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1510         }
1511
1512         return werr;
1513 }
1514
1515 /****************************************************************
1516 ****************************************************************/
1517
1518 WERROR NetUserSetInfo_l(struct libnetapi_ctx *ctx,
1519                         struct NetUserSetInfo *r)
1520 {
1521         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo);
1522 }
1523
1524 /****************************************************************
1525 ****************************************************************/
1526
1527 static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1528                                            struct rpc_pipe_client *pipe_cli,
1529                                            struct policy_handle *domain_handle,
1530                                            struct samr_DomInfo1 *info1,
1531                                            struct samr_DomInfo3 *info3,
1532                                            struct samr_DomInfo5 *info5,
1533                                            struct samr_DomInfo6 *info6,
1534                                            struct samr_DomInfo7 *info7,
1535                                            struct samr_DomInfo12 *info12)
1536 {
1537         NTSTATUS status;
1538         union samr_DomainInfo *dom_info = NULL;
1539
1540         if (info1) {
1541                 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1542                                                      domain_handle,
1543                                                      1,
1544                                                      &dom_info);
1545                 NT_STATUS_NOT_OK_RETURN(status);
1546
1547                 *info1 = dom_info->info1;
1548         }
1549
1550         if (info3) {
1551                 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1552                                                      domain_handle,
1553                                                      3,
1554                                                      &dom_info);
1555                 NT_STATUS_NOT_OK_RETURN(status);
1556
1557                 *info3 = dom_info->info3;
1558         }
1559
1560         if (info5) {
1561                 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1562                                                      domain_handle,
1563                                                      5,
1564                                                      &dom_info);
1565                 NT_STATUS_NOT_OK_RETURN(status);
1566
1567                 *info5 = dom_info->info5;
1568         }
1569
1570         if (info6) {
1571                 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1572                                                      domain_handle,
1573                                                      6,
1574                                                      &dom_info);
1575                 NT_STATUS_NOT_OK_RETURN(status);
1576
1577                 *info6 = dom_info->info6;
1578         }
1579
1580         if (info7) {
1581                 status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx,
1582                                                      domain_handle,
1583                                                      7,
1584                                                      &dom_info);
1585                 NT_STATUS_NOT_OK_RETURN(status);
1586
1587                 *info7 = dom_info->info7;
1588         }
1589
1590         if (info12) {
1591                 status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx,
1592                                                       domain_handle,
1593                                                       12,
1594                                                       &dom_info);
1595                 NT_STATUS_NOT_OK_RETURN(status);
1596
1597                 *info12 = dom_info->info12;
1598         }
1599
1600         return NT_STATUS_OK;
1601 }
1602
1603 /****************************************************************
1604 ****************************************************************/
1605
1606 static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx,
1607                                          struct rpc_pipe_client *pipe_cli,
1608                                          struct policy_handle *domain_handle,
1609                                          struct USER_MODALS_INFO_0 *info0)
1610 {
1611         NTSTATUS status;
1612         struct samr_DomInfo1 dom_info1;
1613         struct samr_DomInfo3 dom_info3;
1614
1615         ZERO_STRUCTP(info0);
1616
1617         status = query_USER_MODALS_INFO_rpc(mem_ctx,
1618                                             pipe_cli,
1619                                             domain_handle,
1620                                             &dom_info1,
1621                                             &dom_info3,
1622                                             NULL,
1623                                             NULL,
1624                                             NULL,
1625                                             NULL);
1626         NT_STATUS_NOT_OK_RETURN(status);
1627
1628         info0->usrmod0_min_passwd_len =
1629                 dom_info1.min_password_length;
1630         info0->usrmod0_max_passwd_age =
1631                 nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age);
1632         info0->usrmod0_min_passwd_age =
1633                 nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age);
1634         info0->usrmod0_password_hist_len =
1635                 dom_info1.password_history_length;
1636
1637         info0->usrmod0_force_logoff =
1638                 nt_time_to_unix_abs(&dom_info3.force_logoff_time);
1639
1640         return NT_STATUS_OK;
1641 }
1642
1643 /****************************************************************
1644 ****************************************************************/
1645
1646 static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx,
1647                                          struct rpc_pipe_client *pipe_cli,
1648                                          struct policy_handle *domain_handle,
1649                                          struct USER_MODALS_INFO_1 *info1)
1650 {
1651         NTSTATUS status;
1652         struct samr_DomInfo6 dom_info6;
1653         struct samr_DomInfo7 dom_info7;
1654
1655         status = query_USER_MODALS_INFO_rpc(mem_ctx,
1656                                             pipe_cli,
1657                                             domain_handle,
1658                                             NULL,
1659                                             NULL,
1660                                             NULL,
1661                                             &dom_info6,
1662                                             &dom_info7,
1663                                             NULL);
1664         NT_STATUS_NOT_OK_RETURN(status);
1665
1666         info1->usrmod1_primary =
1667                 talloc_strdup(mem_ctx, dom_info6.primary.string);
1668
1669         info1->usrmod1_role = dom_info7.role;
1670
1671         return NT_STATUS_OK;
1672 }
1673
1674 /****************************************************************
1675 ****************************************************************/
1676
1677 static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx,
1678                                          struct rpc_pipe_client *pipe_cli,
1679                                          struct policy_handle *domain_handle,
1680                                          struct dom_sid *domain_sid,
1681                                          struct USER_MODALS_INFO_2 *info2)
1682 {
1683         NTSTATUS status;
1684         struct samr_DomInfo5 dom_info5;
1685
1686         status = query_USER_MODALS_INFO_rpc(mem_ctx,
1687                                             pipe_cli,
1688                                             domain_handle,
1689                                             NULL,
1690                                             NULL,
1691                                             &dom_info5,
1692                                             NULL,
1693                                             NULL,
1694                                             NULL);
1695         NT_STATUS_NOT_OK_RETURN(status);
1696
1697         info2->usrmod2_domain_name =
1698                 talloc_strdup(mem_ctx, dom_info5.domain_name.string);
1699         info2->usrmod2_domain_id =
1700                 (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid);
1701
1702         NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name);
1703         NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id);
1704
1705         return NT_STATUS_OK;
1706 }
1707
1708 /****************************************************************
1709 ****************************************************************/
1710
1711 static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx,
1712                                          struct rpc_pipe_client *pipe_cli,
1713                                          struct policy_handle *domain_handle,
1714                                          struct USER_MODALS_INFO_3 *info3)
1715 {
1716         NTSTATUS status;
1717         struct samr_DomInfo12 dom_info12;
1718
1719         status = query_USER_MODALS_INFO_rpc(mem_ctx,
1720                                             pipe_cli,
1721                                             domain_handle,
1722                                             NULL,
1723                                             NULL,
1724                                             NULL,
1725                                             NULL,
1726                                             NULL,
1727                                             &dom_info12);
1728         NT_STATUS_NOT_OK_RETURN(status);
1729
1730         info3->usrmod3_lockout_duration =
1731                 nt_time_to_unix_abs(&dom_info12.lockout_duration);
1732         info3->usrmod3_lockout_observation_window =
1733                 nt_time_to_unix_abs(&dom_info12.lockout_window);
1734         info3->usrmod3_lockout_threshold =
1735                 dom_info12.lockout_threshold;
1736
1737         return NT_STATUS_OK;
1738 }
1739
1740 /****************************************************************
1741 ****************************************************************/
1742
1743 static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx,
1744                                                  struct rpc_pipe_client *pipe_cli,
1745                                                  uint32_t level,
1746                                                  struct policy_handle *domain_handle,
1747                                                  struct dom_sid *domain_sid,
1748                                                  uint8_t **buffer)
1749 {
1750         NTSTATUS status;
1751
1752         struct USER_MODALS_INFO_0 info0;
1753         struct USER_MODALS_INFO_1 info1;
1754         struct USER_MODALS_INFO_2 info2;
1755         struct USER_MODALS_INFO_3 info3;
1756
1757         if (!buffer) {
1758                 return ERROR_INSUFFICIENT_BUFFER;
1759         }
1760
1761         switch (level) {
1762                 case 0:
1763                         status = query_USER_MODALS_INFO_0(mem_ctx,
1764                                                           pipe_cli,
1765                                                           domain_handle,
1766                                                           &info0);
1767                         NT_STATUS_NOT_OK_RETURN(status);
1768
1769                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0,
1770                                                            sizeof(info0));
1771                         break;
1772
1773                 case 1:
1774                         status = query_USER_MODALS_INFO_1(mem_ctx,
1775                                                           pipe_cli,
1776                                                           domain_handle,
1777                                                           &info1);
1778                         NT_STATUS_NOT_OK_RETURN(status);
1779
1780                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1,
1781                                                            sizeof(info1));
1782                         break;
1783                 case 2:
1784                         status = query_USER_MODALS_INFO_2(mem_ctx,
1785                                                           pipe_cli,
1786                                                           domain_handle,
1787                                                           domain_sid,
1788                                                           &info2);
1789                         NT_STATUS_NOT_OK_RETURN(status);
1790
1791                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2,
1792                                                            sizeof(info2));
1793                         break;
1794                 case 3:
1795                         status = query_USER_MODALS_INFO_3(mem_ctx,
1796                                                           pipe_cli,
1797                                                           domain_handle,
1798                                                           &info3);
1799                         NT_STATUS_NOT_OK_RETURN(status);
1800
1801                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3,
1802                                                            sizeof(info3));
1803                         break;
1804                 default:
1805                         break;
1806         }
1807
1808         NT_STATUS_HAVE_NO_MEMORY(*buffer);
1809
1810         return NT_STATUS_OK;
1811 }
1812
1813 /****************************************************************
1814 ****************************************************************/
1815
1816 WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
1817                           struct NetUserModalsGet *r)
1818 {
1819         struct cli_state *cli = NULL;
1820         struct rpc_pipe_client *pipe_cli = NULL;
1821         NTSTATUS status;
1822         WERROR werr;
1823
1824         struct policy_handle connect_handle, domain_handle;
1825         struct dom_sid2 *domain_sid = NULL;
1826         uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
1827
1828         ZERO_STRUCT(connect_handle);
1829         ZERO_STRUCT(domain_handle);
1830
1831         if (!r->out.buffer) {
1832                 return WERR_INVALID_PARAM;
1833         }
1834
1835         switch (r->in.level) {
1836                 case 0:
1837                         access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
1838                                        SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1839                         break;
1840                 case 1:
1841                 case 2:
1842                         access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2;
1843                         break;
1844                 case 3:
1845                         access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1;
1846                         break;
1847                 default:
1848                         werr = WERR_UNKNOWN_LEVEL;
1849                         goto done;
1850         }
1851
1852         werr = libnetapi_open_pipe(ctx, r->in.server_name,
1853                                    &ndr_table_samr.syntax_id,
1854                                    &cli,
1855                                    &pipe_cli);
1856         if (!W_ERROR_IS_OK(werr)) {
1857                 goto done;
1858         }
1859
1860         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
1861                                           SAMR_ACCESS_ENUM_DOMAINS |
1862                                           SAMR_ACCESS_OPEN_DOMAIN,
1863                                           access_mask,
1864                                           &connect_handle,
1865                                           &domain_handle,
1866                                           &domain_sid);
1867         if (!W_ERROR_IS_OK(werr)) {
1868                 goto done;
1869         }
1870
1871         /* 0:  1 + 3 */
1872         /* 1:  6 + 7 */
1873         /* 2:  5 */
1874         /* 3: 12 (DomainInfo2) */
1875
1876         status = query_USER_MODALS_INFO_to_buffer(ctx,
1877                                                   pipe_cli,
1878                                                   r->in.level,
1879                                                   &domain_handle,
1880                                                   domain_sid,
1881                                                   r->out.buffer);
1882         if (!NT_STATUS_IS_OK(status)) {
1883                 werr = ntstatus_to_werror(status);
1884                 goto done;
1885         }
1886
1887  done:
1888         if (!cli) {
1889                 return werr;
1890         }
1891
1892         if (ctx->disable_policy_handle_cache) {
1893                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
1894                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
1895         }
1896
1897         return werr;
1898 }
1899
1900 /****************************************************************
1901 ****************************************************************/
1902
1903 WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx,
1904                           struct NetUserModalsGet *r)
1905 {
1906         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet);
1907 }
1908
1909 /****************************************************************
1910 ****************************************************************/
1911
1912 static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx,
1913                                          struct rpc_pipe_client *pipe_cli,
1914                                          struct policy_handle *domain_handle,
1915                                          struct samr_DomInfo1 *info1,
1916                                          struct samr_DomInfo3 *info3,
1917                                          struct samr_DomInfo12 *info12)
1918 {
1919         NTSTATUS status;
1920         union samr_DomainInfo dom_info;
1921
1922         if (info1) {
1923
1924                 ZERO_STRUCT(dom_info);
1925
1926                 dom_info.info1 = *info1;
1927
1928                 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1929                                                    domain_handle,
1930                                                    1,
1931                                                    &dom_info);
1932                 NT_STATUS_NOT_OK_RETURN(status);
1933         }
1934
1935         if (info3) {
1936
1937                 ZERO_STRUCT(dom_info);
1938
1939                 dom_info.info3 = *info3;
1940
1941                 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1942                                                    domain_handle,
1943                                                    3,
1944                                                    &dom_info);
1945
1946                 NT_STATUS_NOT_OK_RETURN(status);
1947         }
1948
1949         if (info12) {
1950
1951                 ZERO_STRUCT(dom_info);
1952
1953                 dom_info.info12 = *info12;
1954
1955                 status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx,
1956                                                    domain_handle,
1957                                                    12,
1958                                                    &dom_info);
1959
1960                 NT_STATUS_NOT_OK_RETURN(status);
1961         }
1962
1963         return NT_STATUS_OK;
1964 }
1965
1966 /****************************************************************
1967 ****************************************************************/
1968
1969 static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx,
1970                                               struct rpc_pipe_client *pipe_cli,
1971                                               struct policy_handle *domain_handle,
1972                                               struct USER_MODALS_INFO_0 *info0)
1973 {
1974         NTSTATUS status;
1975         struct samr_DomInfo1 dom_info_1;
1976         struct samr_DomInfo3 dom_info_3;
1977
1978         status = query_USER_MODALS_INFO_rpc(mem_ctx,
1979                                             pipe_cli,
1980                                             domain_handle,
1981                                             &dom_info_1,
1982                                             &dom_info_3,
1983                                             NULL,
1984                                             NULL,
1985                                             NULL,
1986                                             NULL);
1987         NT_STATUS_NOT_OK_RETURN(status);
1988
1989         dom_info_1.min_password_length =
1990                 info0->usrmod0_min_passwd_len;
1991         dom_info_1.password_history_length =
1992                 info0->usrmod0_password_hist_len;
1993
1994         unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
1995                 info0->usrmod0_max_passwd_age);
1996         unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
1997                 info0->usrmod0_min_passwd_age);
1998
1999         unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2000                 info0->usrmod0_force_logoff);
2001
2002         return set_USER_MODALS_INFO_rpc(mem_ctx,
2003                                         pipe_cli,
2004                                         domain_handle,
2005                                         &dom_info_1,
2006                                         &dom_info_3,
2007                                         NULL);
2008 }
2009
2010 /****************************************************************
2011 ****************************************************************/
2012
2013 static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx,
2014                                               struct rpc_pipe_client *pipe_cli,
2015                                               struct policy_handle *domain_handle,
2016                                               struct USER_MODALS_INFO_3 *info3)
2017 {
2018         NTSTATUS status;
2019         struct samr_DomInfo12 dom_info_12;
2020
2021         status = query_USER_MODALS_INFO_rpc(mem_ctx,
2022                                             pipe_cli,
2023                                             domain_handle,
2024                                             NULL,
2025                                             NULL,
2026                                             NULL,
2027                                             NULL,
2028                                             NULL,
2029                                             &dom_info_12);
2030         NT_STATUS_NOT_OK_RETURN(status);
2031
2032         unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration,
2033                 info3->usrmod3_lockout_duration);
2034         unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window,
2035                 info3->usrmod3_lockout_observation_window);
2036         dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold;
2037
2038         return set_USER_MODALS_INFO_rpc(mem_ctx,
2039                                         pipe_cli,
2040                                         domain_handle,
2041                                         NULL,
2042                                         NULL,
2043                                         &dom_info_12);
2044 }
2045
2046 /****************************************************************
2047 ****************************************************************/
2048
2049 static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx,
2050                                                  struct rpc_pipe_client *pipe_cli,
2051                                                  struct policy_handle *domain_handle,
2052                                                  struct USER_MODALS_INFO_1001 *info1001)
2053 {
2054         NTSTATUS status;
2055         struct samr_DomInfo1 dom_info_1;
2056
2057         status = query_USER_MODALS_INFO_rpc(mem_ctx,
2058                                             pipe_cli,
2059                                             domain_handle,
2060                                             &dom_info_1,
2061                                             NULL,
2062                                             NULL,
2063                                             NULL,
2064                                             NULL,
2065                                             NULL);
2066         NT_STATUS_NOT_OK_RETURN(status);
2067
2068         dom_info_1.min_password_length =
2069                 info1001->usrmod1001_min_passwd_len;
2070
2071         return set_USER_MODALS_INFO_rpc(mem_ctx,
2072                                         pipe_cli,
2073                                         domain_handle,
2074                                         &dom_info_1,
2075                                         NULL,
2076                                         NULL);
2077 }
2078
2079 /****************************************************************
2080 ****************************************************************/
2081
2082 static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx,
2083                                                  struct rpc_pipe_client *pipe_cli,
2084                                                  struct policy_handle *domain_handle,
2085                                                  struct USER_MODALS_INFO_1002 *info1002)
2086 {
2087         NTSTATUS status;
2088         struct samr_DomInfo1 dom_info_1;
2089
2090         status = query_USER_MODALS_INFO_rpc(mem_ctx,
2091                                             pipe_cli,
2092                                             domain_handle,
2093                                             &dom_info_1,
2094                                             NULL,
2095                                             NULL,
2096                                             NULL,
2097                                             NULL,
2098                                             NULL);
2099         NT_STATUS_NOT_OK_RETURN(status);
2100
2101         unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age,
2102                 info1002->usrmod1002_max_passwd_age);
2103
2104         return set_USER_MODALS_INFO_rpc(mem_ctx,
2105                                         pipe_cli,
2106                                         domain_handle,
2107                                         &dom_info_1,
2108                                         NULL,
2109                                         NULL);
2110 }
2111
2112 /****************************************************************
2113 ****************************************************************/
2114
2115 static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx,
2116                                                  struct rpc_pipe_client *pipe_cli,
2117                                                  struct policy_handle *domain_handle,
2118                                                  struct USER_MODALS_INFO_1003 *info1003)
2119 {
2120         NTSTATUS status;
2121         struct samr_DomInfo1 dom_info_1;
2122
2123         status = query_USER_MODALS_INFO_rpc(mem_ctx,
2124                                             pipe_cli,
2125                                             domain_handle,
2126                                             &dom_info_1,
2127                                             NULL,
2128                                             NULL,
2129                                             NULL,
2130                                             NULL,
2131                                             NULL);
2132         NT_STATUS_NOT_OK_RETURN(status);
2133
2134         unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age,
2135                 info1003->usrmod1003_min_passwd_age);
2136
2137         return set_USER_MODALS_INFO_rpc(mem_ctx,
2138                                         pipe_cli,
2139                                         domain_handle,
2140                                         &dom_info_1,
2141                                         NULL,
2142                                         NULL);
2143 }
2144
2145 /****************************************************************
2146 ****************************************************************/
2147
2148 static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx,
2149                                                  struct rpc_pipe_client *pipe_cli,
2150                                                  struct policy_handle *domain_handle,
2151                                                  struct USER_MODALS_INFO_1004 *info1004)
2152 {
2153         NTSTATUS status;
2154         struct samr_DomInfo3 dom_info_3;
2155
2156         status = query_USER_MODALS_INFO_rpc(mem_ctx,
2157                                             pipe_cli,
2158                                             domain_handle,
2159                                             NULL,
2160                                             &dom_info_3,
2161                                             NULL,
2162                                             NULL,
2163                                             NULL,
2164                                             NULL);
2165         NT_STATUS_NOT_OK_RETURN(status);
2166
2167         unix_to_nt_time_abs(&dom_info_3.force_logoff_time,
2168                 info1004->usrmod1004_force_logoff);
2169
2170         return set_USER_MODALS_INFO_rpc(mem_ctx,
2171                                         pipe_cli,
2172                                         domain_handle,
2173                                         NULL,
2174                                         &dom_info_3,
2175                                         NULL);
2176 }
2177
2178 /****************************************************************
2179 ****************************************************************/
2180
2181 static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx,
2182                                                  struct rpc_pipe_client *pipe_cli,
2183                                                  struct policy_handle *domain_handle,
2184                                                  struct USER_MODALS_INFO_1005 *info1005)
2185 {
2186         NTSTATUS status;
2187         struct samr_DomInfo1 dom_info_1;
2188
2189         status = query_USER_MODALS_INFO_rpc(mem_ctx,
2190                                             pipe_cli,
2191                                             domain_handle,
2192                                             &dom_info_1,
2193                                             NULL,
2194                                             NULL,
2195                                             NULL,
2196                                             NULL,
2197                                             NULL);
2198         NT_STATUS_NOT_OK_RETURN(status);
2199
2200         dom_info_1.password_history_length =
2201                 info1005->usrmod1005_password_hist_len;
2202
2203         return set_USER_MODALS_INFO_rpc(mem_ctx,
2204                                         pipe_cli,
2205                                         domain_handle,
2206                                         &dom_info_1,
2207                                         NULL,
2208                                         NULL);
2209 }
2210
2211 /****************************************************************
2212 ****************************************************************/
2213
2214 static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx,
2215                                             struct rpc_pipe_client *pipe_cli,
2216                                             uint32_t level,
2217                                             struct policy_handle *domain_handle,
2218                                             struct dom_sid *domain_sid,
2219                                             uint8_t *buffer)
2220 {
2221         struct USER_MODALS_INFO_0 *info0;
2222         struct USER_MODALS_INFO_3 *info3;
2223         struct USER_MODALS_INFO_1001 *info1001;
2224         struct USER_MODALS_INFO_1002 *info1002;
2225         struct USER_MODALS_INFO_1003 *info1003;
2226         struct USER_MODALS_INFO_1004 *info1004;
2227         struct USER_MODALS_INFO_1005 *info1005;
2228
2229         if (!buffer) {
2230                 return ERROR_INSUFFICIENT_BUFFER;
2231         }
2232
2233         switch (level) {
2234                 case 0:
2235                         info0 = (struct USER_MODALS_INFO_0 *)buffer;
2236                         return set_USER_MODALS_INFO_0_buffer(mem_ctx,
2237                                                              pipe_cli,
2238                                                              domain_handle,
2239                                                              info0);
2240                 case 3:
2241                         info3 = (struct USER_MODALS_INFO_3 *)buffer;
2242                         return set_USER_MODALS_INFO_3_buffer(mem_ctx,
2243                                                              pipe_cli,
2244                                                              domain_handle,
2245                                                              info3);
2246                 case 1001:
2247                         info1001 = (struct USER_MODALS_INFO_1001 *)buffer;
2248                         return set_USER_MODALS_INFO_1001_buffer(mem_ctx,
2249                                                                 pipe_cli,
2250                                                                 domain_handle,
2251                                                                 info1001);
2252                 case 1002:
2253                         info1002 = (struct USER_MODALS_INFO_1002 *)buffer;
2254                         return set_USER_MODALS_INFO_1002_buffer(mem_ctx,
2255                                                                 pipe_cli,
2256                                                                 domain_handle,
2257                                                                 info1002);
2258                 case 1003:
2259                         info1003 = (struct USER_MODALS_INFO_1003 *)buffer;
2260                         return set_USER_MODALS_INFO_1003_buffer(mem_ctx,
2261                                                                 pipe_cli,
2262                                                                 domain_handle,
2263                                                                 info1003);
2264                 case 1004:
2265                         info1004 = (struct USER_MODALS_INFO_1004 *)buffer;
2266                         return set_USER_MODALS_INFO_1004_buffer(mem_ctx,
2267                                                                 pipe_cli,
2268                                                                 domain_handle,
2269                                                                 info1004);
2270                 case 1005:
2271                         info1005 = (struct USER_MODALS_INFO_1005 *)buffer;
2272                         return set_USER_MODALS_INFO_1005_buffer(mem_ctx,
2273                                                                 pipe_cli,
2274                                                                 domain_handle,
2275                                                                 info1005);
2276
2277                 default:
2278                         break;
2279         }
2280
2281         return NT_STATUS_OK;
2282 }
2283
2284 /****************************************************************
2285 ****************************************************************/
2286
2287 WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
2288                           struct NetUserModalsSet *r)
2289 {
2290         struct cli_state *cli = NULL;
2291         struct rpc_pipe_client *pipe_cli = NULL;
2292         NTSTATUS status;
2293         WERROR werr;
2294
2295         struct policy_handle connect_handle, domain_handle;
2296         struct dom_sid2 *domain_sid = NULL;
2297         uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT;
2298
2299         ZERO_STRUCT(connect_handle);
2300         ZERO_STRUCT(domain_handle);
2301
2302         if (!r->in.buffer) {
2303                 return WERR_INVALID_PARAM;
2304         }
2305
2306         switch (r->in.level) {
2307                 case 0:
2308                         access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2309                                        SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2310                                        SAMR_DOMAIN_ACCESS_SET_INFO_1 |
2311                                        SAMR_DOMAIN_ACCESS_SET_INFO_2;
2312                         break;
2313                 case 3:
2314                 case 1001:
2315                 case 1002:
2316                 case 1003:
2317                 case 1005:
2318                         access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
2319                                        SAMR_DOMAIN_ACCESS_SET_INFO_1;
2320                         break;
2321                 case 1004:
2322                         access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
2323                                        SAMR_DOMAIN_ACCESS_SET_INFO_2;
2324                         break;
2325                 case 1:
2326                 case 2:
2327                 case 1006:
2328                 case 1007:
2329                         werr = WERR_NOT_SUPPORTED;
2330                         break;
2331                 default:
2332                         werr = WERR_UNKNOWN_LEVEL;
2333                         goto done;
2334         }
2335
2336         werr = libnetapi_open_pipe(ctx, r->in.server_name,
2337                                    &ndr_table_samr.syntax_id,
2338                                    &cli,
2339                                    &pipe_cli);
2340         if (!W_ERROR_IS_OK(werr)) {
2341                 goto done;
2342         }
2343
2344         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2345                                           SAMR_ACCESS_ENUM_DOMAINS |
2346                                           SAMR_ACCESS_OPEN_DOMAIN,
2347                                           access_mask,
2348                                           &connect_handle,
2349                                           &domain_handle,
2350                                           &domain_sid);
2351         if (!W_ERROR_IS_OK(werr)) {
2352                 goto done;
2353         }
2354
2355         status = set_USER_MODALS_INFO_buffer(ctx,
2356                                              pipe_cli,
2357                                              r->in.level,
2358                                              &domain_handle,
2359                                              domain_sid,
2360                                              r->in.buffer);
2361         if (!NT_STATUS_IS_OK(status)) {
2362                 werr = ntstatus_to_werror(status);
2363                 goto done;
2364         }
2365
2366  done:
2367         if (!cli) {
2368                 return werr;
2369         }
2370
2371         if (ctx->disable_policy_handle_cache) {
2372                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2373                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2374         }
2375
2376         return werr;
2377 }
2378
2379 /****************************************************************
2380 ****************************************************************/
2381
2382 WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx,
2383                           struct NetUserModalsSet *r)
2384 {
2385         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet);
2386 }
2387
2388 /****************************************************************
2389 ****************************************************************/
2390
2391 static NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx,
2392                                               uint32_t level,
2393                                               const char *group_name,
2394                                               uint32_t attributes,
2395                                               uint8_t **buffer,
2396                                               uint32_t *num_entries)
2397 {
2398         struct GROUP_USERS_INFO_0 u0;
2399         struct GROUP_USERS_INFO_1 u1;
2400
2401         switch (level) {
2402                 case 0:
2403                         u0.grui0_name = talloc_strdup(mem_ctx, group_name);
2404                         NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name);
2405
2406                         ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0,
2407                                      (struct GROUP_USERS_INFO_0 **)buffer, num_entries);
2408                         break;
2409                 case 1:
2410                         u1.grui1_name = talloc_strdup(mem_ctx, group_name);
2411                         NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name);
2412
2413                         u1.grui1_attributes = attributes;
2414
2415                         ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1,
2416                                      (struct GROUP_USERS_INFO_1 **)buffer, num_entries);
2417                         break;
2418                 default:
2419                         return NT_STATUS_INVALID_INFO_CLASS;
2420         }
2421
2422         return NT_STATUS_OK;
2423 }
2424
2425 /****************************************************************
2426 ****************************************************************/
2427
2428 WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
2429                           struct NetUserGetGroups *r)
2430 {
2431         struct cli_state *cli = NULL;
2432         struct rpc_pipe_client *pipe_cli = NULL;
2433         struct policy_handle connect_handle, domain_handle, user_handle;
2434         struct lsa_String lsa_account_name;
2435         struct dom_sid2 *domain_sid = NULL;
2436         struct samr_Ids user_rids, name_types;
2437         struct samr_RidWithAttributeArray *rid_array = NULL;
2438         struct lsa_Strings names;
2439         struct samr_Ids types;
2440         uint32_t *rids = NULL;
2441
2442         int i;
2443         uint32_t entries_read = 0;
2444
2445         NTSTATUS status = NT_STATUS_OK;
2446         WERROR werr;
2447
2448         ZERO_STRUCT(connect_handle);
2449         ZERO_STRUCT(domain_handle);
2450
2451         if (!r->out.buffer) {
2452                 return WERR_INVALID_PARAM;
2453         }
2454
2455         *r->out.buffer = NULL;
2456         *r->out.entries_read = 0;
2457
2458         switch (r->in.level) {
2459                 case 0:
2460                 case 1:
2461                         break;
2462                 default:
2463                         return WERR_UNKNOWN_LEVEL;
2464         }
2465
2466         werr = libnetapi_open_pipe(ctx, r->in.server_name,
2467                                    &ndr_table_samr.syntax_id,
2468                                    &cli,
2469                                    &pipe_cli);
2470         if (!W_ERROR_IS_OK(werr)) {
2471                 goto done;
2472         }
2473
2474         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
2475                                           SAMR_ACCESS_ENUM_DOMAINS |
2476                                           SAMR_ACCESS_OPEN_DOMAIN,
2477                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
2478                                           &connect_handle,
2479                                           &domain_handle,
2480                                           &domain_sid);
2481         if (!W_ERROR_IS_OK(werr)) {
2482                 goto done;
2483         }
2484
2485         init_lsa_String(&lsa_account_name, r->in.user_name);
2486
2487         status = rpccli_samr_LookupNames(pipe_cli, ctx,
2488                                          &domain_handle,
2489                                          1,
2490                                          &lsa_account_name,
2491                                          &user_rids,
2492                                          &name_types);
2493         if (!NT_STATUS_IS_OK(status)) {
2494                 werr = ntstatus_to_werror(status);
2495                 goto done;
2496         }
2497
2498         status = rpccli_samr_OpenUser(pipe_cli, ctx,
2499                                       &domain_handle,
2500                                       SAMR_USER_ACCESS_GET_GROUPS,
2501                                       user_rids.ids[0],
2502                                       &user_handle);
2503         if (!NT_STATUS_IS_OK(status)) {
2504                 werr = ntstatus_to_werror(status);
2505                 goto done;
2506         }
2507
2508         status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx,
2509                                               &user_handle,
2510                                               &rid_array);
2511         if (!NT_STATUS_IS_OK(status)) {
2512                 werr = ntstatus_to_werror(status);
2513                 goto done;
2514         }
2515
2516         rids = talloc_array(ctx, uint32_t, rid_array->count);
2517         if (!rids) {
2518                 werr = WERR_NOMEM;
2519                 goto done;
2520         }
2521
2522         for (i=0; i < rid_array->count; i++) {
2523                 rids[i] = rid_array->rids[i].rid;
2524         }
2525
2526         status = rpccli_samr_LookupRids(pipe_cli, ctx,
2527                                         &domain_handle,
2528                                         rid_array->count,
2529                                         rids,
2530                                         &names,
2531                                         &types);
2532         if (!NT_STATUS_IS_OK(status)) {
2533                 werr = ntstatus_to_werror(status);
2534                 goto done;
2535         }
2536
2537         for (i=0; i < rid_array->count; i++) {
2538                 status = add_GROUP_USERS_INFO_X_buffer(ctx,
2539                                                        r->in.level,
2540                                                        names.names[i].string,
2541                                                        rid_array->rids[i].attributes,
2542                                                        r->out.buffer,
2543                                                        &entries_read);
2544                 if (!NT_STATUS_IS_OK(status)) {
2545                         werr = ntstatus_to_werror(status);
2546                         goto done;
2547                 }
2548         }
2549
2550         if (r->out.entries_read) {
2551                 *r->out.entries_read = entries_read;
2552         }
2553         if (r->out.total_entries) {
2554                 *r->out.total_entries = entries_read;
2555         }
2556
2557  done:
2558         if (!cli) {
2559                 return werr;
2560         }
2561
2562         if (ctx->disable_policy_handle_cache) {
2563                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
2564                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
2565         }
2566
2567         return werr;
2568 }
2569
2570 /****************************************************************
2571 ****************************************************************/
2572
2573 WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx,
2574                           struct NetUserGetGroups *r)
2575 {
2576         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups);
2577 }