LCOV - code coverage report
Current view: top level - source3/lib/netapi - user.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 844 1784 47.3 %
Date: 2024-04-21 15:09:00 Functions: 33 60 55.0 %

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

Generated by: LCOV version 1.14