LCOV - code coverage report
Current view: top level - source3/lib/netapi - group.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 501 836 59.9 %
Date: 2024-06-13 04:01:37 Functions: 15 24 62.5 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  NetApi Group 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 "rpc_client/rpc_client.h"
      27             : #include "../librpc/gen_ndr/ndr_samr_c.h"
      28             : #include "rpc_client/init_lsa.h"
      29             : #include "../libcli/security/security.h"
      30             : 
      31             : /****************************************************************
      32             : ****************************************************************/
      33             : 
      34          72 : WERROR NetGroupAdd_r(struct libnetapi_ctx *ctx,
      35             :                      struct NetGroupAdd *r)
      36             : {
      37          72 :         struct rpc_pipe_client *pipe_cli = NULL;
      38             :         NTSTATUS status, result;
      39             :         WERROR werr;
      40             :         struct policy_handle connect_handle, domain_handle, group_handle;
      41             :         struct lsa_String lsa_group_name;
      42          72 :         struct dom_sid2 *domain_sid = NULL;
      43          72 :         uint32_t rid = 0;
      44          72 :         struct dcerpc_binding_handle *b = NULL;
      45             : 
      46          72 :         struct GROUP_INFO_0 *info0 = NULL;
      47          72 :         struct GROUP_INFO_1 *info1 = NULL;
      48          72 :         struct GROUP_INFO_2 *info2 = NULL;
      49          72 :         struct GROUP_INFO_3 *info3 = NULL;
      50             :         union samr_GroupInfo info;
      51             : 
      52          72 :         ZERO_STRUCT(connect_handle);
      53          72 :         ZERO_STRUCT(domain_handle);
      54          72 :         ZERO_STRUCT(group_handle);
      55             : 
      56          72 :         if (!r->in.buffer) {
      57           0 :                 return WERR_INVALID_PARAMETER;
      58             :         }
      59             : 
      60          72 :         switch (r->in.level) {
      61           2 :                 case 0:
      62           2 :                         info0 = (struct GROUP_INFO_0 *)r->in.buffer;
      63           2 :                         break;
      64          70 :                 case 1:
      65          70 :                         info1 = (struct GROUP_INFO_1 *)r->in.buffer;
      66          70 :                         break;
      67           0 :                 case 2:
      68           0 :                         info2 = (struct GROUP_INFO_2 *)r->in.buffer;
      69           0 :                         break;
      70           0 :                 case 3:
      71           0 :                         info3 = (struct GROUP_INFO_3 *)r->in.buffer;
      72           0 :                         break;
      73           0 :                 default:
      74           0 :                         werr = WERR_INVALID_LEVEL;
      75           0 :                         goto done;
      76             :         }
      77             : 
      78          72 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
      79             :                                    &ndr_table_samr,
      80             :                                    &pipe_cli);
      81          72 :         if (!W_ERROR_IS_OK(werr)) {
      82           0 :                 goto done;
      83             :         }
      84             : 
      85          72 :         b = pipe_cli->binding_handle;
      86             : 
      87          72 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
      88             :                                           SAMR_ACCESS_ENUM_DOMAINS |
      89             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
      90             :                                           SAMR_DOMAIN_ACCESS_CREATE_GROUP |
      91             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
      92             :                                           &connect_handle,
      93             :                                           &domain_handle,
      94             :                                           &domain_sid);
      95          72 :         if (!W_ERROR_IS_OK(werr)) {
      96           0 :                 goto done;
      97             :         }
      98             : 
      99          72 :         switch (r->in.level) {
     100           2 :                 case 0:
     101           2 :                         init_lsa_String(&lsa_group_name, info0->grpi0_name);
     102           2 :                         break;
     103          70 :                 case 1:
     104          70 :                         init_lsa_String(&lsa_group_name, info1->grpi1_name);
     105          70 :                         break;
     106           0 :                 case 2:
     107           0 :                         init_lsa_String(&lsa_group_name, info2->grpi2_name);
     108           0 :                         break;
     109           0 :                 case 3:
     110           0 :                         init_lsa_String(&lsa_group_name, info3->grpi3_name);
     111           0 :                         break;
     112             :         }
     113             : 
     114          72 :         status = dcerpc_samr_CreateDomainGroup(b, talloc_tos(),
     115             :                                                &domain_handle,
     116             :                                                &lsa_group_name,
     117             :                                                SEC_STD_DELETE |
     118             :                                                SAMR_GROUP_ACCESS_SET_INFO,
     119             :                                                &group_handle,
     120             :                                                &rid,
     121             :                                                &result);
     122             : 
     123          72 :         if (any_nt_status_not_ok(status, result, &status)) {
     124           1 :                 werr = ntstatus_to_werror(status);
     125           1 :                 goto done;
     126             :         }
     127             : 
     128          71 :         switch (r->in.level) {
     129          70 :                 case 1:
     130          70 :                         if (info1->grpi1_comment) {
     131           0 :                                 init_lsa_String(&info.description,
     132             :                                                 info1->grpi1_comment);
     133             : 
     134           0 :                                 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     135             :                                                                   &group_handle,
     136             :                                                                   GROUPINFODESCRIPTION,
     137             :                                                                   &info,
     138             :                                                                   &result);
     139             :                         }
     140          70 :                         break;
     141           0 :                 case 2:
     142           0 :                         if (info2->grpi2_comment) {
     143           0 :                                 init_lsa_String(&info.description,
     144             :                                                 info2->grpi2_comment);
     145             : 
     146           0 :                                 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     147             :                                                                   &group_handle,
     148             :                                                                   GROUPINFODESCRIPTION,
     149             :                                                                   &info,
     150             :                                                                   &result);
     151           0 :                                 if (any_nt_status_not_ok(
     152             :                                             status, result, &status)) {
     153           0 :                                         werr = ntstatus_to_werror(status);
     154           0 :                                         goto failed;
     155             :                                 }
     156             :                         }
     157             : 
     158           0 :                         if (info2->grpi2_attributes != 0) {
     159           0 :                                 info.attributes.attributes = info2->grpi2_attributes;
     160           0 :                                 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     161             :                                                                   &group_handle,
     162             :                                                                   GROUPINFOATTRIBUTES,
     163             :                                                                   &info,
     164             :                                                                   &result);
     165             : 
     166             :                         }
     167           0 :                         break;
     168           0 :                 case 3:
     169           0 :                         if (info3->grpi3_comment) {
     170           0 :                                 init_lsa_String(&info.description,
     171             :                                                 info3->grpi3_comment);
     172             : 
     173           0 :                                 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     174             :                                                                   &group_handle,
     175             :                                                                   GROUPINFODESCRIPTION,
     176             :                                                                   &info,
     177             :                                                                   &result);
     178           0 :                                 if (any_nt_status_not_ok(
     179             :                                             status, result, &status)) {
     180           0 :                                         werr = ntstatus_to_werror(status);
     181           0 :                                         goto failed;
     182             :                                 }
     183             :                         }
     184             : 
     185           0 :                         if (info3->grpi3_attributes != 0) {
     186           0 :                                 info.attributes.attributes = info3->grpi3_attributes;
     187           0 :                                 status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     188             :                                                                   &group_handle,
     189             :                                                                   GROUPINFOATTRIBUTES,
     190             :                                                                   &info,
     191             :                                                                   &result);
     192             :                         }
     193           0 :                         break;
     194           1 :                 default:
     195           1 :                         break;
     196             :         }
     197             : 
     198          71 :         if (any_nt_status_not_ok(status, result, &status)) {
     199           0 :                 werr = ntstatus_to_werror(status);
     200           0 :                 goto failed;
     201             :         }
     202             : 
     203          71 :         werr = WERR_OK;
     204          71 :         goto done;
     205             : 
     206           0 :  failed:
     207           0 :         dcerpc_samr_DeleteDomainGroup(b, talloc_tos(),
     208             :                                       &group_handle, &result);
     209             : 
     210          72 :  done:
     211          72 :         if (is_valid_policy_hnd(&group_handle)) {
     212          71 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
     213             :         }
     214             : 
     215          72 :         if (ctx->disable_policy_handle_cache) {
     216           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
     217           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
     218             :         }
     219             : 
     220          72 :         return werr;
     221             : }
     222             : 
     223             : /****************************************************************
     224             : ****************************************************************/
     225             : 
     226           0 : WERROR NetGroupAdd_l(struct libnetapi_ctx *ctx,
     227             :                      struct NetGroupAdd *r)
     228             : {
     229           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupAdd);
     230             : }
     231             : 
     232             : /****************************************************************
     233             : ****************************************************************/
     234             : 
     235           4 : WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
     236             :                      struct NetGroupDel *r)
     237             : {
     238           4 :         struct rpc_pipe_client *pipe_cli = NULL;
     239             :         NTSTATUS status, result;
     240             :         WERROR werr;
     241             :         struct policy_handle connect_handle, domain_handle, group_handle;
     242             :         struct lsa_String lsa_group_name;
     243           4 :         struct dom_sid2 *domain_sid = NULL;
     244           4 :         int i = 0;
     245           4 :         struct dcerpc_binding_handle *b = NULL;
     246             : 
     247             :         struct samr_Ids rids;
     248             :         struct samr_Ids types;
     249           4 :         union samr_GroupInfo *info = NULL;
     250           4 :         struct samr_RidAttrArray *rid_array = NULL;
     251             : 
     252           4 :         ZERO_STRUCT(connect_handle);
     253           4 :         ZERO_STRUCT(domain_handle);
     254           4 :         ZERO_STRUCT(group_handle);
     255             : 
     256           4 :         if (!r->in.group_name) {
     257           0 :                 return WERR_INVALID_PARAMETER;
     258             :         }
     259             : 
     260           4 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     261             :                                    &ndr_table_samr,
     262             :                                    &pipe_cli);
     263           4 :         if (!W_ERROR_IS_OK(werr)) {
     264           0 :                 goto done;
     265             :         }
     266             : 
     267           4 :         b = pipe_cli->binding_handle;
     268             : 
     269           4 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
     270             :                                           SAMR_ACCESS_ENUM_DOMAINS |
     271             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
     272             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
     273             :                                           &connect_handle,
     274             :                                           &domain_handle,
     275             :                                           &domain_sid);
     276           4 :         if (!W_ERROR_IS_OK(werr)) {
     277           0 :                 goto done;
     278             :         }
     279             : 
     280           4 :         init_lsa_String(&lsa_group_name, r->in.group_name);
     281             : 
     282           4 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
     283             :                                          &domain_handle,
     284             :                                          1,
     285             :                                          &lsa_group_name,
     286             :                                          &rids,
     287             :                                          &types,
     288             :                                          &result);
     289           4 :         if (any_nt_status_not_ok(status, result, &status)) {
     290           3 :                 werr = ntstatus_to_werror(status);
     291           3 :                 goto done;
     292             :         }
     293             : 
     294           1 :         if (rids.count != 1) {
     295           0 :                 werr = WERR_BAD_NET_RESP;
     296           0 :                 goto done;
     297             :         }
     298           1 :         if (types.count != 1) {
     299           0 :                 werr = WERR_BAD_NET_RESP;
     300           0 :                 goto done;
     301             :         }
     302             : 
     303           1 :         if (types.ids[0] != SID_NAME_DOM_GRP) {
     304           0 :                 werr = WERR_INVALID_DATATYPE;
     305           0 :                 goto done;
     306             :         }
     307             : 
     308           1 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
     309             :                                        &domain_handle,
     310             :                                        SEC_STD_DELETE |
     311             :                                        SAMR_GROUP_ACCESS_GET_MEMBERS |
     312             :                                        SAMR_GROUP_ACCESS_REMOVE_MEMBER |
     313             :                                        SAMR_GROUP_ACCESS_ADD_MEMBER |
     314             :                                        SAMR_GROUP_ACCESS_LOOKUP_INFO,
     315           1 :                                        rids.ids[0],
     316             :                                        &group_handle,
     317             :                                        &result);
     318           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     319           0 :                 werr = ntstatus_to_werror(status);
     320           0 :                 goto done;
     321             :         }
     322             : 
     323           1 :         status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
     324             :                                             &group_handle,
     325             :                                             GROUPINFOATTRIBUTES,
     326             :                                             &info,
     327             :                                             &result);
     328           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     329           0 :                 werr = ntstatus_to_werror(status);
     330           0 :                 goto done;
     331             :         }
     332             : 
     333             : #if 0
     334             :         /* breaks against NT4 */
     335             :         if (!(info->attributes.attributes & SE_GROUP_ENABLED)) {
     336             :                 werr = WERR_ACCESS_DENIED;
     337             :                 goto done;
     338             :         }
     339             : #endif
     340           1 :         status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
     341             :                                               &group_handle,
     342             :                                               &rid_array,
     343             :                                               &result);
     344           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     345           0 :                 werr = ntstatus_to_werror(status);
     346           0 :                 goto done;
     347             :         }
     348             : 
     349             :         {
     350             :         struct lsa_Strings names;
     351             :         struct samr_Ids member_types;
     352             : 
     353           2 :         status = dcerpc_samr_LookupRids(b, talloc_tos(),
     354             :                                         &domain_handle,
     355           1 :                                         rid_array->count,
     356           1 :                                         rid_array->rids,
     357             :                                         &names,
     358             :                                         &member_types,
     359             :                                         &result);
     360           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     361           0 :                 werr = ntstatus_to_werror(status);
     362           0 :                 goto done;
     363             :         }
     364           1 :         if (names.count != rid_array->count) {
     365           0 :                 werr = WERR_BAD_NET_RESP;
     366           0 :                 goto done;
     367             :         }
     368           1 :         if (member_types.count != rid_array->count) {
     369           0 :                 werr = WERR_BAD_NET_RESP;
     370           0 :                 goto done;
     371             :         }
     372             :         }
     373             : 
     374           1 :         for (i=0; i < rid_array->count; i++) {
     375             : 
     376           0 :                 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
     377             :                                                        &group_handle,
     378           0 :                                                        rid_array->rids[i],
     379             :                                                        &result);
     380           0 :                 if (any_nt_status_not_ok(status, result, &status)) {
     381           0 :                         werr = ntstatus_to_werror(status);
     382           0 :                         goto done;
     383             :                 }
     384             :         }
     385             : 
     386           1 :         status = dcerpc_samr_DeleteDomainGroup(b, talloc_tos(),
     387             :                                                &group_handle,
     388             :                                                &result);
     389           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     390           0 :                 werr = ntstatus_to_werror(status);
     391           0 :                 goto done;
     392             :         }
     393             : 
     394           1 :         ZERO_STRUCT(group_handle);
     395             : 
     396           1 :         werr = WERR_OK;
     397             : 
     398           4 :  done:
     399           4 :         if (is_valid_policy_hnd(&group_handle)) {
     400           0 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
     401             :         }
     402             : 
     403           4 :         if (ctx->disable_policy_handle_cache) {
     404           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
     405           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
     406             :         }
     407             : 
     408           4 :         return werr;
     409             : }
     410             : 
     411             : /****************************************************************
     412             : ****************************************************************/
     413             : 
     414           0 : WERROR NetGroupDel_l(struct libnetapi_ctx *ctx,
     415             :                      struct NetGroupDel *r)
     416             : {
     417           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupDel);
     418             : }
     419             : 
     420             : /****************************************************************
     421             : ****************************************************************/
     422             : 
     423           1 : WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx,
     424             :                          struct NetGroupSetInfo *r)
     425             : {
     426           1 :         struct rpc_pipe_client *pipe_cli = NULL;
     427             :         NTSTATUS status, result;
     428             :         WERROR werr;
     429             :         struct policy_handle connect_handle, domain_handle, group_handle;
     430             :         struct lsa_String lsa_group_name;
     431           1 :         struct dom_sid2 *domain_sid = NULL;
     432           1 :         struct dcerpc_binding_handle *b = NULL;
     433             : 
     434             :         struct samr_Ids rids;
     435             :         struct samr_Ids types;
     436             :         union samr_GroupInfo info;
     437             :         struct GROUP_INFO_0 *g0;
     438             :         struct GROUP_INFO_1 *g1;
     439             :         struct GROUP_INFO_2 *g2;
     440             :         struct GROUP_INFO_3 *g3;
     441             :         struct GROUP_INFO_1002 *g1002;
     442             :         struct GROUP_INFO_1005 *g1005;
     443             : 
     444           1 :         ZERO_STRUCT(connect_handle);
     445           1 :         ZERO_STRUCT(domain_handle);
     446           1 :         ZERO_STRUCT(group_handle);
     447             : 
     448           1 :         if (!r->in.group_name) {
     449           0 :                 return WERR_INVALID_PARAMETER;
     450             :         }
     451             : 
     452           1 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     453             :                                    &ndr_table_samr,
     454             :                                    &pipe_cli);
     455           1 :         if (!W_ERROR_IS_OK(werr)) {
     456           0 :                 goto done;
     457             :         }
     458             : 
     459           1 :         b = pipe_cli->binding_handle;
     460             : 
     461           1 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
     462             :                                           SAMR_ACCESS_ENUM_DOMAINS |
     463             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
     464             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
     465             :                                           &connect_handle,
     466             :                                           &domain_handle,
     467             :                                           &domain_sid);
     468           1 :         if (!W_ERROR_IS_OK(werr)) {
     469           0 :                 goto done;
     470             :         }
     471             : 
     472           1 :         init_lsa_String(&lsa_group_name, r->in.group_name);
     473             : 
     474           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
     475             :                                          &domain_handle,
     476             :                                          1,
     477             :                                          &lsa_group_name,
     478             :                                          &rids,
     479             :                                          &types,
     480             :                                          &result);
     481           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     482           0 :                 werr = ntstatus_to_werror(status);
     483           0 :                 goto done;
     484             :         }
     485           1 :         if (rids.count != 1) {
     486           0 :                 werr = WERR_BAD_NET_RESP;
     487           0 :                 goto done;
     488             :         }
     489           1 :         if (types.count != 1) {
     490           0 :                 werr = WERR_BAD_NET_RESP;
     491           0 :                 goto done;
     492             :         }
     493             : 
     494           1 :         if (types.ids[0] != SID_NAME_DOM_GRP) {
     495           0 :                 werr = WERR_INVALID_DATATYPE;
     496           0 :                 goto done;
     497             :         }
     498             : 
     499           1 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
     500             :                                        &domain_handle,
     501             :                                        SAMR_GROUP_ACCESS_SET_INFO |
     502             :                                        SAMR_GROUP_ACCESS_LOOKUP_INFO,
     503           1 :                                        rids.ids[0],
     504             :                                        &group_handle,
     505             :                                        &result);
     506           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     507           0 :                 werr = ntstatus_to_werror(status);
     508           0 :                 goto done;
     509             :         }
     510             : 
     511           1 :         switch (r->in.level) {
     512           1 :                 case 0:
     513           1 :                         g0 = (struct GROUP_INFO_0 *)r->in.buffer;
     514           1 :                         init_lsa_String(&info.name, g0->grpi0_name);
     515           1 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     516             :                                                           &group_handle,
     517             :                                                           GROUPINFONAME,
     518             :                                                           &info,
     519             :                                                           &result);
     520           1 :                         break;
     521           0 :                 case 1:
     522           0 :                         g1 = (struct GROUP_INFO_1 *)r->in.buffer;
     523           0 :                         init_lsa_String(&info.description, g1->grpi1_comment);
     524           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     525             :                                                           &group_handle,
     526             :                                                           GROUPINFODESCRIPTION,
     527             :                                                           &info,
     528             :                                                           &result);
     529           0 :                         break;
     530           0 :                 case 2:
     531           0 :                         g2 = (struct GROUP_INFO_2 *)r->in.buffer;
     532           0 :                         init_lsa_String(&info.description, g2->grpi2_comment);
     533           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     534             :                                                           &group_handle,
     535             :                                                           GROUPINFODESCRIPTION,
     536             :                                                           &info,
     537             :                                                           &result);
     538           0 :                         if (any_nt_status_not_ok(status, result, &status)) {
     539           0 :                                 werr = ntstatus_to_werror(status);
     540           0 :                                 goto done;
     541             :                         }
     542             : 
     543           0 :                         info.attributes.attributes = g2->grpi2_attributes;
     544           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     545             :                                                           &group_handle,
     546             :                                                           GROUPINFOATTRIBUTES,
     547             :                                                           &info,
     548             :                                                           &result);
     549           0 :                         break;
     550           0 :                 case 3:
     551           0 :                         g3 = (struct GROUP_INFO_3 *)r->in.buffer;
     552           0 :                         init_lsa_String(&info.description, g3->grpi3_comment);
     553           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     554             :                                                           &group_handle,
     555             :                                                           GROUPINFODESCRIPTION,
     556             :                                                           &info,
     557             :                                                           &result);
     558           0 :                         if (any_nt_status_not_ok(status, result, &status)) {
     559           0 :                                 werr = ntstatus_to_werror(status);
     560           0 :                                 goto done;
     561             :                         }
     562             : 
     563           0 :                         info.attributes.attributes = g3->grpi3_attributes;
     564           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     565             :                                                           &group_handle,
     566             :                                                           GROUPINFOATTRIBUTES,
     567             :                                                           &info,
     568             :                                                           &result);
     569           0 :                         break;
     570           0 :                 case 1002:
     571           0 :                         g1002 = (struct GROUP_INFO_1002 *)r->in.buffer;
     572           0 :                         init_lsa_String(&info.description, g1002->grpi1002_comment);
     573           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     574             :                                                           &group_handle,
     575             :                                                           GROUPINFODESCRIPTION,
     576             :                                                           &info,
     577             :                                                           &result);
     578           0 :                         break;
     579           0 :                 case 1005:
     580           0 :                         g1005 = (struct GROUP_INFO_1005 *)r->in.buffer;
     581           0 :                         info.attributes.attributes = g1005->grpi1005_attributes;
     582           0 :                         status = dcerpc_samr_SetGroupInfo(b, talloc_tos(),
     583             :                                                           &group_handle,
     584             :                                                           GROUPINFOATTRIBUTES,
     585             :                                                           &info,
     586             :                                                           &result);
     587           0 :                         break;
     588           0 :                 default:
     589           0 :                         status = NT_STATUS_INVALID_LEVEL;
     590           0 :                         break;
     591             :         }
     592             : 
     593           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     594           0 :                 werr = ntstatus_to_werror(status);
     595           0 :                 goto done;
     596             :         }
     597             : 
     598           1 :         werr = WERR_OK;
     599             : 
     600           1 :  done:
     601           1 :         if (is_valid_policy_hnd(&group_handle)) {
     602           1 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
     603             :         }
     604             : 
     605           1 :         if (ctx->disable_policy_handle_cache) {
     606           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
     607           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
     608             :         }
     609             : 
     610           1 :         return werr;
     611             : }
     612             : 
     613             : /****************************************************************
     614             : ****************************************************************/
     615             : 
     616           0 : WERROR NetGroupSetInfo_l(struct libnetapi_ctx *ctx,
     617             :                          struct NetGroupSetInfo *r)
     618             : {
     619           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupSetInfo);
     620             : }
     621             : 
     622             : /****************************************************************
     623             : ****************************************************************/
     624             : 
     625           8 : static WERROR map_group_info_to_buffer(TALLOC_CTX *mem_ctx,
     626             :                                        uint32_t level,
     627             :                                        struct samr_GroupInfoAll *info,
     628             :                                        struct dom_sid2 *domain_sid,
     629             :                                        uint32_t rid,
     630             :                                        uint8_t **buffer)
     631             : {
     632             :         struct GROUP_INFO_0 info0;
     633             :         struct GROUP_INFO_1 info1;
     634             :         struct GROUP_INFO_2 info2;
     635             :         struct GROUP_INFO_3 info3;
     636             :         struct dom_sid sid;
     637             : 
     638           8 :         switch (level) {
     639           2 :                 case 0:
     640           2 :                         info0.grpi0_name        = info->name.string;
     641             : 
     642           2 :                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0, sizeof(info0));
     643             : 
     644           2 :                         break;
     645           2 :                 case 1:
     646           2 :                         info1.grpi1_name        = info->name.string;
     647           2 :                         info1.grpi1_comment     = info->description.string;
     648             : 
     649           2 :                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1, sizeof(info1));
     650             : 
     651           2 :                         break;
     652           2 :                 case 2:
     653           2 :                         info2.grpi2_name        = info->name.string;
     654           2 :                         info2.grpi2_comment     = info->description.string;
     655           2 :                         info2.grpi2_group_id    = rid;
     656           2 :                         info2.grpi2_attributes  = info->attributes;
     657             : 
     658           2 :                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2, sizeof(info2));
     659             : 
     660           2 :                         break;
     661           2 :                 case 3:
     662           2 :                         if (!sid_compose(&sid, domain_sid, rid)) {
     663           0 :                                 return WERR_NOT_ENOUGH_MEMORY;
     664             :                         }
     665             : 
     666           2 :                         info3.grpi3_name        = info->name.string;
     667           2 :                         info3.grpi3_comment     = info->description.string;
     668           2 :                         info3.grpi3_attributes  = info->attributes;
     669           2 :                         info3.grpi3_group_sid   = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
     670             : 
     671           2 :                         *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3, sizeof(info3));
     672             : 
     673           2 :                         break;
     674           0 :                 default:
     675           0 :                         return WERR_INVALID_LEVEL;
     676             :         }
     677             : 
     678           8 :         W_ERROR_HAVE_NO_MEMORY(*buffer);
     679             : 
     680           8 :         return WERR_OK;
     681             : }
     682             : 
     683             : /****************************************************************
     684             : ****************************************************************/
     685             : 
     686           9 : WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx,
     687             :                          struct NetGroupGetInfo *r)
     688             : {
     689           9 :         struct rpc_pipe_client *pipe_cli = NULL;
     690             :         NTSTATUS status, result;
     691             :         WERROR werr;
     692             :         struct policy_handle connect_handle, domain_handle, group_handle;
     693             :         struct lsa_String lsa_group_name;
     694           9 :         struct dom_sid2 *domain_sid = NULL;
     695           9 :         struct dcerpc_binding_handle *b = NULL;
     696             : 
     697             :         struct samr_Ids rids;
     698             :         struct samr_Ids types;
     699           9 :         union samr_GroupInfo *info = NULL;
     700           9 :         bool group_info_all = false;
     701             : 
     702           9 :         ZERO_STRUCT(connect_handle);
     703           9 :         ZERO_STRUCT(domain_handle);
     704           9 :         ZERO_STRUCT(group_handle);
     705             : 
     706           9 :         if (!r->in.group_name) {
     707           0 :                 return WERR_INVALID_PARAMETER;
     708             :         }
     709             : 
     710           9 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     711             :                                    &ndr_table_samr,
     712             :                                    &pipe_cli);
     713           9 :         if (!W_ERROR_IS_OK(werr)) {
     714           0 :                 goto done;
     715             :         }
     716             : 
     717           9 :         b = pipe_cli->binding_handle;
     718             : 
     719           9 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
     720             :                                           SAMR_ACCESS_ENUM_DOMAINS |
     721             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
     722             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
     723             :                                           &connect_handle,
     724             :                                           &domain_handle,
     725             :                                           &domain_sid);
     726           9 :         if (!W_ERROR_IS_OK(werr)) {
     727           0 :                 goto done;
     728             :         }
     729             : 
     730           9 :         init_lsa_String(&lsa_group_name, r->in.group_name);
     731             : 
     732           9 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
     733             :                                          &domain_handle,
     734             :                                          1,
     735             :                                          &lsa_group_name,
     736             :                                          &rids,
     737             :                                          &types,
     738             :                                          &result);
     739           9 :         if (any_nt_status_not_ok(status, result, &status)) {
     740           1 :                 werr = ntstatus_to_werror(status);
     741           1 :                 goto done;
     742             :         }
     743           8 :         if (rids.count != 1) {
     744           0 :                 werr = WERR_BAD_NET_RESP;
     745           0 :                 goto done;
     746             :         }
     747           8 :         if (types.count != 1) {
     748           0 :                 werr = WERR_BAD_NET_RESP;
     749           0 :                 goto done;
     750             :         }
     751             : 
     752           8 :         if (types.ids[0] != SID_NAME_DOM_GRP) {
     753           0 :                 werr = WERR_INVALID_DATATYPE;
     754           0 :                 goto done;
     755             :         }
     756             : 
     757           8 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
     758             :                                        &domain_handle,
     759             :                                        SAMR_GROUP_ACCESS_LOOKUP_INFO,
     760           8 :                                        rids.ids[0],
     761             :                                        &group_handle,
     762             :                                        &result);
     763           8 :         if (any_nt_status_not_ok(status, result, &status)) {
     764           0 :                 werr = ntstatus_to_werror(status);
     765           0 :                 goto done;
     766             :         }
     767             : 
     768           8 :         status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
     769             :                                             &group_handle,
     770             :                                             GROUPINFOALL2,
     771             :                                             &info,
     772             :                                             &result);
     773           8 :         if (!NT_STATUS_IS_OK(status)) {
     774           0 :                 werr = ntstatus_to_werror(status);
     775           0 :                 goto done;
     776             :         }
     777             : 
     778           8 :         if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS)) {
     779           0 :                 status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
     780             :                                                     &group_handle,
     781             :                                                     GROUPINFOALL,
     782             :                                                     &info,
     783             :                                                     &result);
     784           0 :                 group_info_all = true;
     785           0 :                 if (!NT_STATUS_IS_OK(status)) {
     786           0 :                         werr = ntstatus_to_werror(status);
     787           0 :                         goto done;
     788             :                 }
     789             :         }
     790             : 
     791           8 :         if (!NT_STATUS_IS_OK(result)) {
     792           0 :                 werr = ntstatus_to_werror(result);
     793           0 :                 goto done;
     794             :         }
     795             : 
     796          24 :         werr = map_group_info_to_buffer(ctx, r->in.level,
     797           8 :                                         group_info_all ? &info->all : &info->all2,
     798           8 :                                         domain_sid, rids.ids[0],
     799             :                                         r->out.buffer);
     800           8 :         if (!W_ERROR_IS_OK(werr)) {
     801           0 :                 goto done;
     802             :         }
     803          17 :  done:
     804           9 :         if (is_valid_policy_hnd(&group_handle)) {
     805           8 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
     806             :         }
     807             : 
     808           9 :         if (ctx->disable_policy_handle_cache) {
     809           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
     810           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
     811             :         }
     812             : 
     813           9 :         return werr;
     814             : }
     815             : 
     816             : /****************************************************************
     817             : ****************************************************************/
     818             : 
     819           0 : WERROR NetGroupGetInfo_l(struct libnetapi_ctx *ctx,
     820             :                          struct NetGroupGetInfo *r)
     821             : {
     822           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupGetInfo);
     823             : }
     824             : 
     825             : /****************************************************************
     826             : ****************************************************************/
     827             : 
     828           1 : WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
     829             :                          struct NetGroupAddUser *r)
     830             : {
     831           1 :         struct rpc_pipe_client *pipe_cli = NULL;
     832             :         NTSTATUS status, result;
     833             :         WERROR werr;
     834             :         struct policy_handle connect_handle, domain_handle, group_handle;
     835             :         struct lsa_String lsa_group_name, lsa_user_name;
     836           1 :         struct dom_sid2 *domain_sid = NULL;
     837           1 :         struct dcerpc_binding_handle *b = NULL;
     838             : 
     839             :         struct samr_Ids rids;
     840             :         struct samr_Ids types;
     841             : 
     842           1 :         ZERO_STRUCT(connect_handle);
     843           1 :         ZERO_STRUCT(domain_handle);
     844           1 :         ZERO_STRUCT(group_handle);
     845             : 
     846           1 :         if (!r->in.group_name) {
     847           0 :                 return WERR_INVALID_PARAMETER;
     848             :         }
     849             : 
     850           1 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     851             :                                    &ndr_table_samr,
     852             :                                    &pipe_cli);
     853           1 :         if (!W_ERROR_IS_OK(werr)) {
     854           0 :                 goto done;
     855             :         }
     856             : 
     857           1 :         b = pipe_cli->binding_handle;
     858             : 
     859           1 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
     860             :                                           SAMR_ACCESS_ENUM_DOMAINS |
     861             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
     862             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
     863             :                                           &connect_handle,
     864             :                                           &domain_handle,
     865             :                                           &domain_sid);
     866           1 :         if (!W_ERROR_IS_OK(werr)) {
     867           0 :                 goto done;
     868             :         }
     869             : 
     870           1 :         init_lsa_String(&lsa_group_name, r->in.group_name);
     871             : 
     872           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
     873             :                                          &domain_handle,
     874             :                                          1,
     875             :                                          &lsa_group_name,
     876             :                                          &rids,
     877             :                                          &types,
     878             :                                          &result);
     879           1 :         if (!NT_STATUS_IS_OK(status)) {
     880           0 :                 werr = ntstatus_to_werror(status);
     881           0 :                 goto done;
     882             :         }
     883           1 :         if (!NT_STATUS_IS_OK(result)) {
     884           0 :                 werr = WERR_NERR_GROUPNOTFOUND;
     885           0 :                 goto done;
     886             :         }
     887           1 :         if (rids.count != 1) {
     888           0 :                 werr = WERR_BAD_NET_RESP;
     889           0 :                 goto done;
     890             :         }
     891           1 :         if (types.count != 1) {
     892           0 :                 werr = WERR_BAD_NET_RESP;
     893           0 :                 goto done;
     894             :         }
     895             : 
     896           1 :         if (types.ids[0] != SID_NAME_DOM_GRP) {
     897           0 :                 werr = WERR_NERR_GROUPNOTFOUND;
     898           0 :                 goto done;
     899             :         }
     900             : 
     901           1 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
     902             :                                        &domain_handle,
     903             :                                        SAMR_GROUP_ACCESS_ADD_MEMBER,
     904           1 :                                        rids.ids[0],
     905             :                                        &group_handle,
     906             :                                        &result);
     907           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     908           0 :                 werr = ntstatus_to_werror(status);
     909           0 :                 goto done;
     910             :         }
     911             : 
     912           1 :         init_lsa_String(&lsa_user_name, r->in.user_name);
     913             : 
     914           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
     915             :                                          &domain_handle,
     916             :                                          1,
     917             :                                          &lsa_user_name,
     918             :                                          &rids,
     919             :                                          &types,
     920             :                                          &result);
     921           1 :         if (!NT_STATUS_IS_OK(status)) {
     922           0 :                 werr = ntstatus_to_werror(status);
     923           0 :                 goto done;
     924             :         }
     925           1 :         if (!NT_STATUS_IS_OK(result)) {
     926           0 :                 werr = WERR_NERR_USERNOTFOUND;
     927           0 :                 goto done;
     928             :         }
     929           1 :         if (rids.count != 1) {
     930           0 :                 werr = WERR_BAD_NET_RESP;
     931           0 :                 goto done;
     932             :         }
     933           1 :         if (types.count != 1) {
     934           0 :                 werr = WERR_BAD_NET_RESP;
     935           0 :                 goto done;
     936             :         }
     937             : 
     938           1 :         if (types.ids[0] != SID_NAME_USER) {
     939           0 :                 werr = WERR_NERR_USERNOTFOUND;
     940           0 :                 goto done;
     941             :         }
     942             : 
     943           1 :         status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
     944             :                                             &group_handle,
     945           1 :                                             rids.ids[0],
     946             :                                             7, /* why ? */
     947             :                                             &result);
     948           1 :         if (any_nt_status_not_ok(status, result, &status)) {
     949           0 :                 werr = ntstatus_to_werror(status);
     950           0 :                 goto done;
     951             :         }
     952             : 
     953           1 :         werr = WERR_OK;
     954             : 
     955           1 :  done:
     956           1 :         if (is_valid_policy_hnd(&group_handle)) {
     957           1 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
     958             :         }
     959             : 
     960           1 :         if (ctx->disable_policy_handle_cache) {
     961           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
     962           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
     963             :         }
     964             : 
     965           1 :         return werr;
     966             : }
     967             : 
     968             : /****************************************************************
     969             : ****************************************************************/
     970             : 
     971           0 : WERROR NetGroupAddUser_l(struct libnetapi_ctx *ctx,
     972             :                          struct NetGroupAddUser *r)
     973             : {
     974           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupAddUser);
     975             : }
     976             : 
     977             : /****************************************************************
     978             : ****************************************************************/
     979             : 
     980           1 : WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
     981             :                          struct NetGroupDelUser *r)
     982             : {
     983           1 :         struct rpc_pipe_client *pipe_cli = NULL;
     984             :         NTSTATUS status, result;
     985             :         WERROR werr;
     986             :         struct policy_handle connect_handle, domain_handle, group_handle;
     987             :         struct lsa_String lsa_group_name, lsa_user_name;
     988           1 :         struct dom_sid2 *domain_sid = NULL;
     989           1 :         struct dcerpc_binding_handle *b = NULL;
     990             : 
     991             :         struct samr_Ids rids;
     992             :         struct samr_Ids types;
     993             : 
     994           1 :         ZERO_STRUCT(connect_handle);
     995           1 :         ZERO_STRUCT(domain_handle);
     996           1 :         ZERO_STRUCT(group_handle);
     997             : 
     998           1 :         if (!r->in.group_name) {
     999           0 :                 return WERR_INVALID_PARAMETER;
    1000             :         }
    1001             : 
    1002           1 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
    1003             :                                    &ndr_table_samr,
    1004             :                                    &pipe_cli);
    1005           1 :         if (!W_ERROR_IS_OK(werr)) {
    1006           0 :                 goto done;
    1007             :         }
    1008             : 
    1009           1 :         b = pipe_cli->binding_handle;
    1010             : 
    1011           1 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
    1012             :                                           SAMR_ACCESS_ENUM_DOMAINS |
    1013             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
    1014             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    1015             :                                           &connect_handle,
    1016             :                                           &domain_handle,
    1017             :                                           &domain_sid);
    1018           1 :         if (!W_ERROR_IS_OK(werr)) {
    1019           0 :                 goto done;
    1020             :         }
    1021             : 
    1022           1 :         init_lsa_String(&lsa_group_name, r->in.group_name);
    1023             : 
    1024           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
    1025             :                                          &domain_handle,
    1026             :                                          1,
    1027             :                                          &lsa_group_name,
    1028             :                                          &rids,
    1029             :                                          &types,
    1030             :                                          &result);
    1031           1 :         if (!NT_STATUS_IS_OK(status)) {
    1032           0 :                 werr = ntstatus_to_werror(status);
    1033           0 :                 goto done;
    1034             :         }
    1035           1 :         if (!NT_STATUS_IS_OK(result)) {
    1036           0 :                 werr = WERR_NERR_GROUPNOTFOUND;
    1037           0 :                 goto done;
    1038             :         }
    1039           1 :         if (rids.count != 1) {
    1040           0 :                 werr = WERR_BAD_NET_RESP;
    1041           0 :                 goto done;
    1042             :         }
    1043           1 :         if (types.count != 1) {
    1044           0 :                 werr = WERR_BAD_NET_RESP;
    1045           0 :                 goto done;
    1046             :         }
    1047             : 
    1048           1 :         if (types.ids[0] != SID_NAME_DOM_GRP) {
    1049           0 :                 werr = WERR_NERR_GROUPNOTFOUND;
    1050           0 :                 goto done;
    1051             :         }
    1052             : 
    1053           1 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
    1054             :                                        &domain_handle,
    1055             :                                        SAMR_GROUP_ACCESS_REMOVE_MEMBER,
    1056           1 :                                        rids.ids[0],
    1057             :                                        &group_handle,
    1058             :                                        &result);
    1059           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1060           0 :                 werr = ntstatus_to_werror(status);
    1061           0 :                 goto done;
    1062             :         }
    1063             : 
    1064           1 :         init_lsa_String(&lsa_user_name, r->in.user_name);
    1065             : 
    1066           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
    1067             :                                          &domain_handle,
    1068             :                                          1,
    1069             :                                          &lsa_user_name,
    1070             :                                          &rids,
    1071             :                                          &types,
    1072             :                                          &result);
    1073           1 :         if (!NT_STATUS_IS_OK(status)) {
    1074           0 :                 werr = ntstatus_to_werror(status);
    1075           0 :                 goto done;
    1076             :         }
    1077             : 
    1078           1 :         if (!NT_STATUS_IS_OK(result)) {
    1079           0 :                 werr = WERR_NERR_USERNOTFOUND;
    1080           0 :                 goto done;
    1081             :         }
    1082           1 :         if (rids.count != 1) {
    1083           0 :                 werr = WERR_BAD_NET_RESP;
    1084           0 :                 goto done;
    1085             :         }
    1086           1 :         if (types.count != 1) {
    1087           0 :                 werr = WERR_BAD_NET_RESP;
    1088           0 :                 goto done;
    1089             :         }
    1090             : 
    1091           1 :         if (types.ids[0] != SID_NAME_USER) {
    1092           0 :                 werr = WERR_NERR_USERNOTFOUND;
    1093           0 :                 goto done;
    1094             :         }
    1095             : 
    1096           1 :         status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
    1097             :                                                &group_handle,
    1098           1 :                                                rids.ids[0],
    1099             :                                                &result);
    1100           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1101           0 :                 werr = ntstatus_to_werror(status);
    1102           0 :                 goto done;
    1103             :         }
    1104             : 
    1105           1 :         werr = WERR_OK;
    1106             : 
    1107           1 :  done:
    1108           1 :         if (is_valid_policy_hnd(&group_handle)) {
    1109           1 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
    1110             :         }
    1111             : 
    1112           1 :         if (ctx->disable_policy_handle_cache) {
    1113           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
    1114           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
    1115             :         }
    1116             : 
    1117           1 :         return werr;
    1118             : }
    1119             : 
    1120             : /****************************************************************
    1121             : ****************************************************************/
    1122             : 
    1123           0 : WERROR NetGroupDelUser_l(struct libnetapi_ctx *ctx,
    1124             :                          struct NetGroupDelUser *r)
    1125             : {
    1126           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupDelUser);
    1127             : }
    1128             : 
    1129             : /****************************************************************
    1130             : ****************************************************************/
    1131             : 
    1132           1 : static WERROR convert_samr_disp_groups_to_GROUP_INFO_0_buffer(TALLOC_CTX *mem_ctx,
    1133             :                                                               struct samr_DispInfoFullGroups *groups,
    1134             :                                                               uint8_t **buffer)
    1135             : {
    1136             :         struct GROUP_INFO_0 *g0;
    1137             :         int i;
    1138             : 
    1139           1 :         g0 = talloc_zero_array(mem_ctx, struct GROUP_INFO_0, groups->count);
    1140           1 :         W_ERROR_HAVE_NO_MEMORY(g0);
    1141             : 
    1142          15 :         for (i=0; i<groups->count; i++) {
    1143          14 :                 g0[i].grpi0_name = talloc_strdup(mem_ctx,
    1144          14 :                         groups->entries[i].account_name.string);
    1145          14 :                 W_ERROR_HAVE_NO_MEMORY(g0[i].grpi0_name);
    1146             :         }
    1147             : 
    1148           1 :         *buffer = (uint8_t *)talloc_memdup(mem_ctx, g0,
    1149             :                                            sizeof(struct GROUP_INFO_0) * groups->count);
    1150           1 :         W_ERROR_HAVE_NO_MEMORY(*buffer);
    1151             : 
    1152           1 :         return WERR_OK;
    1153             : }
    1154             : 
    1155             : /****************************************************************
    1156             : ****************************************************************/
    1157             : 
    1158           1 : static WERROR convert_samr_disp_groups_to_GROUP_INFO_1_buffer(TALLOC_CTX *mem_ctx,
    1159             :                                                               struct samr_DispInfoFullGroups *groups,
    1160             :                                                               uint8_t **buffer)
    1161             : {
    1162             :         struct GROUP_INFO_1 *g1;
    1163             :         int i;
    1164             : 
    1165           1 :         g1 = talloc_zero_array(mem_ctx, struct GROUP_INFO_1, groups->count);
    1166           1 :         W_ERROR_HAVE_NO_MEMORY(g1);
    1167             : 
    1168          15 :         for (i=0; i<groups->count; i++) {
    1169          14 :                 g1[i].grpi1_name = talloc_strdup(mem_ctx,
    1170          14 :                         groups->entries[i].account_name.string);
    1171          14 :                 g1[i].grpi1_comment = talloc_strdup(mem_ctx,
    1172          14 :                         groups->entries[i].description.string);
    1173          14 :                 W_ERROR_HAVE_NO_MEMORY(g1[i].grpi1_name);
    1174             :         }
    1175             : 
    1176           1 :         *buffer = (uint8_t *)talloc_memdup(mem_ctx, g1,
    1177             :                                            sizeof(struct GROUP_INFO_1) * groups->count);
    1178           1 :         W_ERROR_HAVE_NO_MEMORY(*buffer);
    1179             : 
    1180           1 :         return WERR_OK;
    1181             : }
    1182             : 
    1183             : /****************************************************************
    1184             : ****************************************************************/
    1185             : 
    1186           1 : static WERROR convert_samr_disp_groups_to_GROUP_INFO_2_buffer(TALLOC_CTX *mem_ctx,
    1187             :                                                               struct samr_DispInfoFullGroups *groups,
    1188             :                                                               uint8_t **buffer)
    1189             : {
    1190             :         struct GROUP_INFO_2 *g2;
    1191             :         int i;
    1192             : 
    1193           1 :         g2 = talloc_zero_array(mem_ctx, struct GROUP_INFO_2, groups->count);
    1194           1 :         W_ERROR_HAVE_NO_MEMORY(g2);
    1195             : 
    1196          15 :         for (i=0; i<groups->count; i++) {
    1197          14 :                 g2[i].grpi2_name = talloc_strdup(mem_ctx,
    1198          14 :                         groups->entries[i].account_name.string);
    1199          14 :                 g2[i].grpi2_comment = talloc_strdup(mem_ctx,
    1200          14 :                         groups->entries[i].description.string);
    1201          14 :                 g2[i].grpi2_group_id = groups->entries[i].rid;
    1202          14 :                 g2[i].grpi2_attributes = groups->entries[i].acct_flags;
    1203          14 :                 W_ERROR_HAVE_NO_MEMORY(g2[i].grpi2_name);
    1204             :         }
    1205             : 
    1206           1 :         *buffer = (uint8_t *)talloc_memdup(mem_ctx, g2,
    1207             :                                            sizeof(struct GROUP_INFO_2) * groups->count);
    1208           1 :         W_ERROR_HAVE_NO_MEMORY(*buffer);
    1209             : 
    1210           1 :         return WERR_OK;
    1211             : }
    1212             : 
    1213             : /****************************************************************
    1214             : ****************************************************************/
    1215             : 
    1216           1 : static WERROR convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX *mem_ctx,
    1217             :                                                               struct samr_DispInfoFullGroups *groups,
    1218             :                                                               const struct dom_sid *domain_sid,
    1219             :                                                               uint8_t **buffer)
    1220             : {
    1221             :         struct GROUP_INFO_3 *g3;
    1222             :         int i;
    1223             : 
    1224           1 :         g3 = talloc_zero_array(mem_ctx, struct GROUP_INFO_3, groups->count);
    1225           1 :         W_ERROR_HAVE_NO_MEMORY(g3);
    1226             : 
    1227          30 :         for (i=0; i<groups->count; i++) {
    1228             : 
    1229             :                 struct dom_sid sid;
    1230             : 
    1231          14 :                 if (!sid_compose(&sid, domain_sid, groups->entries[i].rid)) {
    1232           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    1233             :                 }
    1234             : 
    1235          14 :                 g3[i].grpi3_name = talloc_strdup(mem_ctx,
    1236          14 :                         groups->entries[i].account_name.string);
    1237          14 :                 g3[i].grpi3_comment = talloc_strdup(mem_ctx,
    1238          14 :                         groups->entries[i].description.string);
    1239          14 :                 g3[i].grpi3_group_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid);
    1240          14 :                 g3[i].grpi3_attributes = groups->entries[i].acct_flags;
    1241          14 :                 W_ERROR_HAVE_NO_MEMORY(g3[i].grpi3_name);
    1242             :         }
    1243             : 
    1244           1 :         *buffer = (uint8_t *)talloc_memdup(mem_ctx, g3,
    1245             :                                            sizeof(struct GROUP_INFO_3) * groups->count);
    1246           1 :         W_ERROR_HAVE_NO_MEMORY(*buffer);
    1247             : 
    1248           1 :         return WERR_OK;
    1249             : }
    1250             : 
    1251             : /****************************************************************
    1252             : ****************************************************************/
    1253             : 
    1254           4 : static WERROR convert_samr_disp_groups_to_GROUP_INFO_buffer(TALLOC_CTX *mem_ctx,
    1255             :                                                             uint32_t level,
    1256             :                                                             struct samr_DispInfoFullGroups *groups,
    1257             :                                                             const struct dom_sid *domain_sid,
    1258             :                                                             uint32_t *entries_read,
    1259             :                                                             uint8_t **buffer)
    1260             : {
    1261           4 :         if (entries_read) {
    1262           4 :                 *entries_read = groups->count;
    1263             :         }
    1264             : 
    1265           4 :         switch (level) {
    1266           1 :                 case 0:
    1267           1 :                         return convert_samr_disp_groups_to_GROUP_INFO_0_buffer(mem_ctx, groups, buffer);
    1268           1 :                 case 1:
    1269           1 :                         return convert_samr_disp_groups_to_GROUP_INFO_1_buffer(mem_ctx, groups, buffer);
    1270           1 :                 case 2:
    1271           1 :                         return convert_samr_disp_groups_to_GROUP_INFO_2_buffer(mem_ctx, groups, buffer);
    1272           1 :                 case 3:
    1273           1 :                         return convert_samr_disp_groups_to_GROUP_INFO_3_buffer(mem_ctx, groups, domain_sid, buffer);
    1274           0 :                 default:
    1275           0 :                         return WERR_INVALID_LEVEL;
    1276             :         }
    1277             : }
    1278             : 
    1279             : /****************************************************************
    1280             : ****************************************************************/
    1281             : 
    1282           4 : WERROR NetGroupEnum_r(struct libnetapi_ctx *ctx,
    1283             :                       struct NetGroupEnum *r)
    1284             : {
    1285           4 :         struct rpc_pipe_client *pipe_cli = NULL;
    1286             :         struct policy_handle connect_handle;
    1287           4 :         struct dom_sid2 *domain_sid = NULL;
    1288             :         struct policy_handle domain_handle;
    1289             :         union samr_DispInfo info;
    1290           4 :         union samr_DomainInfo *domain_info = NULL;
    1291           4 :         struct dcerpc_binding_handle *b = NULL;
    1292             : 
    1293           4 :         uint32_t total_size = 0;
    1294           4 :         uint32_t returned_size = 0;
    1295             : 
    1296           4 :         NTSTATUS result = NT_STATUS_OK;
    1297             :         NTSTATUS status;
    1298             :         WERROR werr, tmp_werr;
    1299             : 
    1300           4 :         ZERO_STRUCT(connect_handle);
    1301           4 :         ZERO_STRUCT(domain_handle);
    1302             : 
    1303           4 :         switch (r->in.level) {
    1304           4 :                 case 0:
    1305             :                 case 1:
    1306             :                 case 2:
    1307             :                 case 3:
    1308           4 :                         break;
    1309           0 :                 default:
    1310           0 :                         return WERR_INVALID_LEVEL;
    1311             :         }
    1312             : 
    1313           4 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
    1314             :                                    &ndr_table_samr,
    1315             :                                    &pipe_cli);
    1316           4 :         if (!W_ERROR_IS_OK(werr)) {
    1317           0 :                 goto done;
    1318             :         }
    1319             : 
    1320           4 :         b = pipe_cli->binding_handle;
    1321             : 
    1322           4 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
    1323             :                                           SAMR_ACCESS_ENUM_DOMAINS |
    1324             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
    1325             :                                           SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
    1326             :                                           SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
    1327             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    1328             :                                           &connect_handle,
    1329             :                                           &domain_handle,
    1330             :                                           &domain_sid);
    1331           4 :         if (!W_ERROR_IS_OK(werr)) {
    1332           0 :                 goto done;
    1333             :         }
    1334             : 
    1335           4 :         status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(),
    1336             :                                              &domain_handle,
    1337             :                                              2,
    1338             :                                              &domain_info,
    1339             :                                              &result);
    1340           4 :         if (any_nt_status_not_ok(status, result, &status)) {
    1341           0 :                 werr = ntstatus_to_werror(status);
    1342           0 :                 goto done;
    1343             :         }
    1344             : 
    1345           4 :         if (r->out.total_entries) {
    1346           4 :                 *r->out.total_entries = domain_info->general.num_groups;
    1347             :         }
    1348             : 
    1349          12 :         status = dcerpc_samr_QueryDisplayInfo2(b,
    1350             :                                                ctx,
    1351             :                                                &domain_handle,
    1352             :                                                3,
    1353           4 :                                                r->in.resume_handle ?
    1354           4 :                                                *r->in.resume_handle : 0,
    1355             :                                                (uint32_t)-1,
    1356             :                                                r->in.prefmaxlen,
    1357             :                                                &total_size,
    1358             :                                                &returned_size,
    1359             :                                                &info,
    1360             :                                                &result);
    1361           4 :         if (!NT_STATUS_IS_OK(status)) {
    1362           0 :                 werr = ntstatus_to_werror(status);
    1363           0 :                 goto done;
    1364             :         }
    1365             : 
    1366           4 :         werr = ntstatus_to_werror(result);
    1367           4 :         if (NT_STATUS_IS_ERR(result)) {
    1368           0 :                 goto done;
    1369             :         }
    1370             : 
    1371           4 :         if (r->out.resume_handle && info.info3.count > 0) {
    1372           8 :                 *r->out.resume_handle =
    1373           8 :                         info.info3.entries[info.info3.count-1].idx;
    1374             :         }
    1375             : 
    1376           4 :         tmp_werr = convert_samr_disp_groups_to_GROUP_INFO_buffer(ctx,
    1377             :                                                                  r->in.level,
    1378             :                                                                  &info.info3,
    1379             :                                                                  domain_sid,
    1380             :                                                                  r->out.entries_read,
    1381             :                                                                  r->out.buffer);
    1382           4 :         if (!W_ERROR_IS_OK(tmp_werr)) {
    1383           0 :                 werr = tmp_werr;
    1384           0 :                 goto done;
    1385             :         }
    1386             : 
    1387           8 :  done:
    1388             :         /* if last query */
    1389           4 :         if (NT_STATUS_IS_OK(result) ||
    1390           0 :             NT_STATUS_IS_ERR(result)) {
    1391             : 
    1392           4 :                 if (ctx->disable_policy_handle_cache) {
    1393           0 :                         libnetapi_samr_close_domain_handle(ctx, &domain_handle);
    1394           0 :                         libnetapi_samr_close_connect_handle(ctx, &connect_handle);
    1395             :                 }
    1396             :         }
    1397             : 
    1398           4 :         return werr;
    1399             : }
    1400             : 
    1401             : /****************************************************************
    1402             : ****************************************************************/
    1403             : 
    1404           0 : WERROR NetGroupEnum_l(struct libnetapi_ctx *ctx,
    1405             :                       struct NetGroupEnum *r)
    1406             : {
    1407           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupEnum);
    1408             : }
    1409             : 
    1410             : /****************************************************************
    1411             : ****************************************************************/
    1412             : 
    1413           6 : WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
    1414             :                           struct NetGroupGetUsers *r)
    1415             : {
    1416             :         /* FIXME: this call needs to cope with large replies */
    1417             : 
    1418           6 :         struct rpc_pipe_client *pipe_cli = NULL;
    1419             :         struct policy_handle connect_handle, domain_handle, group_handle;
    1420             :         struct lsa_String lsa_account_name;
    1421           6 :         struct dom_sid2 *domain_sid = NULL;
    1422             :         struct samr_Ids group_rids, name_types;
    1423           6 :         struct samr_RidAttrArray *rid_array = NULL;
    1424             :         struct lsa_Strings names;
    1425             :         struct samr_Ids member_types;
    1426           6 :         struct dcerpc_binding_handle *b = NULL;
    1427             : 
    1428             :         int i;
    1429           6 :         uint32_t entries_read = 0;
    1430             : 
    1431             :         NTSTATUS status;
    1432           6 :         NTSTATUS result = NT_STATUS_OK;
    1433             :         WERROR werr;
    1434             : 
    1435           6 :         ZERO_STRUCT(connect_handle);
    1436           6 :         ZERO_STRUCT(domain_handle);
    1437           6 :         ZERO_STRUCT(group_handle);
    1438             : 
    1439           6 :         if (!r->out.buffer) {
    1440           0 :                 return WERR_INVALID_PARAMETER;
    1441             :         }
    1442             : 
    1443           6 :         *r->out.buffer = NULL;
    1444           6 :         *r->out.entries_read = 0;
    1445           6 :         *r->out.total_entries = 0;
    1446             : 
    1447           6 :         switch (r->in.level) {
    1448           6 :                 case 0:
    1449             :                 case 1:
    1450           6 :                         break;
    1451           0 :                 default:
    1452           0 :                         return WERR_INVALID_LEVEL;
    1453             :         }
    1454             : 
    1455             : 
    1456           6 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
    1457             :                                    &ndr_table_samr,
    1458             :                                    &pipe_cli);
    1459           6 :         if (!W_ERROR_IS_OK(werr)) {
    1460           0 :                 goto done;
    1461             :         }
    1462             : 
    1463           6 :         b = pipe_cli->binding_handle;
    1464             : 
    1465           6 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
    1466             :                                           SAMR_ACCESS_ENUM_DOMAINS |
    1467             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
    1468             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    1469             :                                           &connect_handle,
    1470             :                                           &domain_handle,
    1471             :                                           &domain_sid);
    1472           6 :         if (!W_ERROR_IS_OK(werr)) {
    1473           0 :                 goto done;
    1474             :         }
    1475             : 
    1476           6 :         init_lsa_String(&lsa_account_name, r->in.group_name);
    1477             : 
    1478           6 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
    1479             :                                          &domain_handle,
    1480             :                                          1,
    1481             :                                          &lsa_account_name,
    1482             :                                          &group_rids,
    1483             :                                          &name_types,
    1484             :                                          &result);
    1485           6 :         if (any_nt_status_not_ok(status, result, &status)) {
    1486           0 :                 werr = ntstatus_to_werror(status);
    1487           0 :                 goto done;
    1488             :         }
    1489           6 :         if (group_rids.count != 1) {
    1490           0 :                 werr = WERR_BAD_NET_RESP;
    1491           0 :                 goto done;
    1492             :         }
    1493           6 :         if (name_types.count != 1) {
    1494           0 :                 werr = WERR_BAD_NET_RESP;
    1495           0 :                 goto done;
    1496             :         }
    1497             : 
    1498           6 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
    1499             :                                        &domain_handle,
    1500             :                                        SAMR_GROUP_ACCESS_GET_MEMBERS,
    1501           6 :                                        group_rids.ids[0],
    1502             :                                        &group_handle,
    1503             :                                        &result);
    1504           6 :         if (any_nt_status_not_ok(status, result, &status)) {
    1505           0 :                 werr = ntstatus_to_werror(status);
    1506           0 :                 goto done;
    1507             :         }
    1508             : 
    1509           6 :         status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
    1510             :                                               &group_handle,
    1511             :                                               &rid_array,
    1512             :                                               &result);
    1513           6 :         if (any_nt_status_not_ok(status, result, &status)) {
    1514           0 :                 werr = ntstatus_to_werror(status);
    1515           0 :                 goto done;
    1516             :         }
    1517             : 
    1518          12 :         status = dcerpc_samr_LookupRids(b, talloc_tos(),
    1519             :                                         &domain_handle,
    1520           6 :                                         rid_array->count,
    1521           6 :                                         rid_array->rids,
    1522             :                                         &names,
    1523             :                                         &member_types,
    1524             :                                         &result);
    1525           6 :         if (any_nt_status_not_ok(status, result, &status)) {
    1526           0 :                 werr = ntstatus_to_werror(status);
    1527           0 :                 goto done;
    1528             :         }
    1529           6 :         if (names.count != rid_array->count) {
    1530           0 :                 werr = WERR_BAD_NET_RESP;
    1531           0 :                 goto done;
    1532             :         }
    1533           6 :         if (member_types.count != rid_array->count) {
    1534           0 :                 werr = WERR_BAD_NET_RESP;
    1535           0 :                 goto done;
    1536             :         }
    1537             : 
    1538           9 :         for (i=0; i < names.count; i++) {
    1539             : 
    1540           3 :                 if (member_types.ids[i] != SID_NAME_USER) {
    1541           0 :                         continue;
    1542             :                 }
    1543             : 
    1544           6 :                 status = add_GROUP_USERS_INFO_X_buffer(ctx,
    1545             :                                                        r->in.level,
    1546           3 :                                                        names.names[i].string,
    1547             :                                                        7,
    1548             :                                                        r->out.buffer,
    1549             :                                                        &entries_read);
    1550           3 :                 if (!NT_STATUS_IS_OK(status)) {
    1551           0 :                         werr = ntstatus_to_werror(status);
    1552           0 :                         goto done;
    1553             :                 }
    1554             :         }
    1555             : 
    1556           6 :         *r->out.entries_read = entries_read;
    1557           6 :         *r->out.total_entries = entries_read;
    1558             : 
    1559           6 :         werr = WERR_OK;
    1560             : 
    1561           6 :  done:
    1562           6 :         if (is_valid_policy_hnd(&group_handle)) {
    1563           6 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
    1564             :         }
    1565             : 
    1566           6 :         if (ctx->disable_policy_handle_cache) {
    1567           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
    1568           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
    1569             :         }
    1570             : 
    1571           6 :         return werr;
    1572             : }
    1573             : 
    1574             : /****************************************************************
    1575             : ****************************************************************/
    1576             : 
    1577           0 : WERROR NetGroupGetUsers_l(struct libnetapi_ctx *ctx,
    1578             :                           struct NetGroupGetUsers *r)
    1579             : {
    1580           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupGetUsers);
    1581             : }
    1582             : 
    1583             : /****************************************************************
    1584             : ****************************************************************/
    1585             : 
    1586           1 : WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx,
    1587             :                           struct NetGroupSetUsers *r)
    1588             : {
    1589           1 :         struct rpc_pipe_client *pipe_cli = NULL;
    1590             :         struct policy_handle connect_handle, domain_handle, group_handle;
    1591             :         struct lsa_String lsa_account_name;
    1592           1 :         struct dom_sid2 *domain_sid = NULL;
    1593           1 :         union samr_GroupInfo *group_info = NULL;
    1594             :         struct samr_Ids user_rids, name_types;
    1595             :         struct samr_Ids group_rids, group_types;
    1596           1 :         struct samr_RidAttrArray *rid_array = NULL;
    1597           1 :         struct lsa_String *lsa_names = NULL;
    1598           1 :         struct dcerpc_binding_handle *b = NULL;
    1599             : 
    1600           1 :         uint32_t *add_rids = NULL;
    1601           1 :         uint32_t *del_rids = NULL;
    1602           1 :         size_t num_add_rids = 0;
    1603           1 :         size_t num_del_rids = 0;
    1604             : 
    1605           1 :         uint32_t *member_rids = NULL;
    1606             : 
    1607           1 :         struct GROUP_USERS_INFO_0 *i0 = NULL;
    1608           1 :         struct GROUP_USERS_INFO_1 *i1 = NULL;
    1609             : 
    1610             :         int i, k;
    1611             : 
    1612             :         NTSTATUS status;
    1613           1 :         NTSTATUS result = NT_STATUS_OK;
    1614             :         WERROR werr;
    1615             : 
    1616           1 :         ZERO_STRUCT(connect_handle);
    1617           1 :         ZERO_STRUCT(domain_handle);
    1618           1 :         ZERO_STRUCT(group_handle);
    1619             : 
    1620           1 :         if (!r->in.buffer) {
    1621           0 :                 return WERR_INVALID_PARAMETER;
    1622             :         }
    1623             : 
    1624           1 :         switch (r->in.level) {
    1625           1 :                 case 0:
    1626             :                 case 1:
    1627           1 :                         break;
    1628           0 :                 default:
    1629           0 :                         return WERR_INVALID_LEVEL;
    1630             :         }
    1631             : 
    1632           1 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
    1633             :                                    &ndr_table_samr,
    1634             :                                    &pipe_cli);
    1635           1 :         if (!W_ERROR_IS_OK(werr)) {
    1636           0 :                 goto done;
    1637             :         }
    1638             : 
    1639           1 :         b = pipe_cli->binding_handle;
    1640             : 
    1641           1 :         werr = libnetapi_samr_open_domain(ctx, pipe_cli,
    1642             :                                           SAMR_ACCESS_ENUM_DOMAINS |
    1643             :                                           SAMR_ACCESS_LOOKUP_DOMAIN,
    1644             :                                           SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    1645             :                                           &connect_handle,
    1646             :                                           &domain_handle,
    1647             :                                           &domain_sid);
    1648           1 :         if (!W_ERROR_IS_OK(werr)) {
    1649           0 :                 goto done;
    1650             :         }
    1651             : 
    1652           1 :         init_lsa_String(&lsa_account_name, r->in.group_name);
    1653             : 
    1654           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
    1655             :                                          &domain_handle,
    1656             :                                          1,
    1657             :                                          &lsa_account_name,
    1658             :                                          &group_rids,
    1659             :                                          &group_types,
    1660             :                                          &result);
    1661           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1662           0 :                 werr = ntstatus_to_werror(status);
    1663           0 :                 goto done;
    1664             :         }
    1665           1 :         if (group_rids.count != 1) {
    1666           0 :                 werr = WERR_BAD_NET_RESP;
    1667           0 :                 goto done;
    1668             :         }
    1669           1 :         if (group_types.count != 1) {
    1670           0 :                 werr = WERR_BAD_NET_RESP;
    1671           0 :                 goto done;
    1672             :         }
    1673             : 
    1674           1 :         status = dcerpc_samr_OpenGroup(b, talloc_tos(),
    1675             :                                        &domain_handle,
    1676             :                                        SAMR_GROUP_ACCESS_GET_MEMBERS |
    1677             :                                        SAMR_GROUP_ACCESS_ADD_MEMBER |
    1678             :                                        SAMR_GROUP_ACCESS_REMOVE_MEMBER |
    1679             :                                        SAMR_GROUP_ACCESS_LOOKUP_INFO,
    1680           1 :                                        group_rids.ids[0],
    1681             :                                        &group_handle,
    1682             :                                        &result);
    1683           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1684           0 :                 werr = ntstatus_to_werror(status);
    1685           0 :                 goto done;
    1686             :         }
    1687             : 
    1688           1 :         status = dcerpc_samr_QueryGroupInfo(b, talloc_tos(),
    1689             :                                             &group_handle,
    1690             :                                             GROUPINFOATTRIBUTES,
    1691             :                                             &group_info,
    1692             :                                             &result);
    1693           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1694           0 :                 werr = ntstatus_to_werror(status);
    1695           0 :                 goto done;
    1696             :         }
    1697             : 
    1698           1 :         switch (r->in.level) {
    1699           1 :                 case 0:
    1700           1 :                         i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer;
    1701           1 :                         break;
    1702           0 :                 case 1:
    1703           0 :                         i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer;
    1704           0 :                         break;
    1705             :         }
    1706             : 
    1707           1 :         lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries);
    1708           1 :         if (!lsa_names) {
    1709           0 :                 werr = WERR_NOT_ENOUGH_MEMORY;
    1710           0 :                 goto done;
    1711             :         }
    1712             : 
    1713           2 :         for (i=0; i < r->in.num_entries; i++) {
    1714             : 
    1715           1 :                 switch (r->in.level) {
    1716           1 :                         case 0:
    1717           1 :                                 init_lsa_String(&lsa_names[i], i0->grui0_name);
    1718           1 :                                 i0++;
    1719           1 :                                 break;
    1720           0 :                         case 1:
    1721           0 :                                 init_lsa_String(&lsa_names[i], i1->grui1_name);
    1722           0 :                                 i1++;
    1723           0 :                                 break;
    1724             :                 }
    1725             :         }
    1726             : 
    1727           1 :         status = dcerpc_samr_LookupNames(b, talloc_tos(),
    1728             :                                          &domain_handle,
    1729             :                                          r->in.num_entries,
    1730             :                                          lsa_names,
    1731             :                                          &user_rids,
    1732             :                                          &name_types,
    1733             :                                          &result);
    1734           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1735           0 :                 werr = ntstatus_to_werror(status);
    1736           0 :                 goto done;
    1737             :         }
    1738             : 
    1739           1 :         if (r->in.num_entries != user_rids.count) {
    1740           0 :                 werr = WERR_BAD_NET_RESP;
    1741           0 :                 goto done;
    1742             :         }
    1743           1 :         if (r->in.num_entries != name_types.count) {
    1744           0 :                 werr = WERR_BAD_NET_RESP;
    1745           0 :                 goto done;
    1746             :         }
    1747             : 
    1748           1 :         member_rids = user_rids.ids;
    1749             : 
    1750           1 :         status = dcerpc_samr_QueryGroupMember(b, talloc_tos(),
    1751             :                                               &group_handle,
    1752             :                                               &rid_array,
    1753             :                                               &result);
    1754           1 :         if (any_nt_status_not_ok(status, result, &status)) {
    1755           0 :                 werr = ntstatus_to_werror(status);
    1756           0 :                 goto done;
    1757             :         }
    1758             : 
    1759             :         /* add list */
    1760             : 
    1761           2 :         for (i=0; i < r->in.num_entries; i++) {
    1762           1 :                 bool already_member = false;
    1763           1 :                 for (k=0; k < rid_array->count; k++) {
    1764           0 :                         if (member_rids[i] == rid_array->rids[k]) {
    1765           0 :                                 already_member = true;
    1766           0 :                                 break;
    1767             :                         }
    1768             :                 }
    1769           1 :                 if (!already_member) {
    1770           1 :                         if (!add_rid_to_array_unique(ctx,
    1771           1 :                                                      member_rids[i],
    1772             :                                                      &add_rids, &num_add_rids)) {
    1773           0 :                                 werr = WERR_GEN_FAILURE;
    1774           0 :                                 goto done;
    1775             :                         }
    1776             :                 }
    1777             :         }
    1778             : 
    1779             :         /* del list */
    1780             : 
    1781           1 :         for (k=0; k < rid_array->count; k++) {
    1782           0 :                 bool keep_member = false;
    1783           0 :                 for (i=0; i < r->in.num_entries; i++) {
    1784           0 :                         if (member_rids[i] == rid_array->rids[k]) {
    1785           0 :                                 keep_member = true;
    1786           0 :                                 break;
    1787             :                         }
    1788             :                 }
    1789           0 :                 if (!keep_member) {
    1790           0 :                         if (!add_rid_to_array_unique(ctx,
    1791           0 :                                                      rid_array->rids[k],
    1792             :                                                      &del_rids, &num_del_rids)) {
    1793           0 :                                 werr = WERR_GEN_FAILURE;
    1794           0 :                                 goto done;
    1795             :                         }
    1796             :                 }
    1797             :         }
    1798             : 
    1799             :         /* add list */
    1800             : 
    1801           2 :         for (i=0; i < num_add_rids; i++) {
    1802           1 :                 status = dcerpc_samr_AddGroupMember(b, talloc_tos(),
    1803             :                                                     &group_handle,
    1804           1 :                                                     add_rids[i],
    1805             :                                                     7 /* ? */,
    1806             :                                                     &result);
    1807           1 :                 if (any_nt_status_not_ok(status, result, &status)) {
    1808           0 :                         werr = ntstatus_to_werror(status);
    1809           0 :                         goto done;
    1810             :                 }
    1811             :         }
    1812             : 
    1813             :         /* del list */
    1814             : 
    1815           1 :         for (i=0; i < num_del_rids; i++) {
    1816           0 :                 status = dcerpc_samr_DeleteGroupMember(b, talloc_tos(),
    1817             :                                                        &group_handle,
    1818           0 :                                                        del_rids[i],
    1819             :                                                        &result);
    1820           0 :                 if (any_nt_status_not_ok(status, result, &status)) {
    1821           0 :                         werr = ntstatus_to_werror(status);
    1822           0 :                         goto done;
    1823             :                 }
    1824             :         }
    1825             : 
    1826           1 :         werr = WERR_OK;
    1827             : 
    1828           1 :  done:
    1829           1 :         if (is_valid_policy_hnd(&group_handle)) {
    1830           1 :                 dcerpc_samr_Close(b, talloc_tos(), &group_handle, &result);
    1831             :         }
    1832             : 
    1833           1 :         if (ctx->disable_policy_handle_cache) {
    1834           0 :                 libnetapi_samr_close_domain_handle(ctx, &domain_handle);
    1835           0 :                 libnetapi_samr_close_connect_handle(ctx, &connect_handle);
    1836             :         }
    1837             : 
    1838           1 :         return werr;
    1839             : }
    1840             : 
    1841             : /****************************************************************
    1842             : ****************************************************************/
    1843             : 
    1844           0 : WERROR NetGroupSetUsers_l(struct libnetapi_ctx *ctx,
    1845             :                           struct NetGroupSetUsers *r)
    1846             : {
    1847           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetGroupSetUsers);
    1848             : }

Generated by: LCOV version 1.13