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