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