LCOV - code coverage report
Current view: top level - source4/torture/libnetapi - libnetapi_group.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 197 282 69.9 %
Date: 2024-04-21 15:09:00 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester
       4             :    Copyright (C) Guenther Deschner 2009
       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             : #include "torture/smbtorture.h"
      22             : #include <netapi.h>
      23             : #include "torture/libnetapi/proto.h"
      24             : 
      25             : #undef strcasecmp
      26             : 
      27             : #define TORTURE_TEST_USER "testuser"
      28             : 
      29             : #define NETAPI_STATUS(tctx, x,y,fn) \
      30             :         torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \
      31             :                 __LINE__, fn, libnetapi_get_error_string(x,y), y);
      32             : 
      33             : #define NETAPI_STATUS_MSG(tctx, x,y,fn,z) \
      34             :         torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d), %s\n", \
      35             :                 __LINE__, fn, libnetapi_get_error_string(x,y), y, z);
      36             : 
      37           4 : static NET_API_STATUS test_netgroupenum(struct torture_context *tctx,
      38             :                                         const char *hostname,
      39             :                                         uint32_t level,
      40             :                                         const char *groupname)
      41             : {
      42           0 :         NET_API_STATUS status;
      43           4 :         uint32_t entries_read = 0;
      44           4 :         uint32_t total_entries = 0;
      45           4 :         uint32_t resume_handle = 0;
      46           4 :         int found_group = 0;
      47           4 :         const char *current_name = NULL;
      48           4 :         uint8_t *buffer = NULL;
      49           0 :         int i;
      50             : 
      51           4 :         struct GROUP_INFO_0 *info0 = NULL;
      52           4 :         struct GROUP_INFO_1 *info1 = NULL;
      53           4 :         struct GROUP_INFO_2 *info2 = NULL;
      54           4 :         struct GROUP_INFO_3 *info3 = NULL;
      55             : 
      56           4 :         torture_comment(tctx, "Testing NetGroupEnum level %d\n", level);
      57             : 
      58           0 :         do {
      59           4 :                 status = NetGroupEnum(hostname,
      60             :                                       level,
      61             :                                       &buffer,
      62             :                                       (uint32_t)-1,
      63             :                                       &entries_read,
      64             :                                       &total_entries,
      65             :                                       &resume_handle);
      66           4 :                 if (status == 0 || status == ERROR_MORE_DATA) {
      67           4 :                         switch (level) {
      68           1 :                                 case 0:
      69           1 :                                         info0 = (struct GROUP_INFO_0 *)buffer;
      70           1 :                                         break;
      71           1 :                                 case 1:
      72           1 :                                         info1 = (struct GROUP_INFO_1 *)buffer;
      73           1 :                                         break;
      74           1 :                                 case 2:
      75           1 :                                         info2 = (struct GROUP_INFO_2 *)buffer;
      76           1 :                                         break;
      77           1 :                                 case 3:
      78           1 :                                         info3 = (struct GROUP_INFO_3 *)buffer;
      79           1 :                                         break;
      80           0 :                                 default:
      81           0 :                                         return -1;
      82             :                         }
      83             : 
      84          60 :                         for (i=0; i<entries_read; i++) {
      85             : 
      86          56 :                                 switch (level) {
      87          14 :                                         case 0:
      88          14 :                                                 current_name =  info0->grpi0_name;
      89          14 :                                                 break;
      90          14 :                                         case 1:
      91          14 :                                                 current_name =  info1->grpi1_name;
      92          14 :                                                 break;
      93          14 :                                         case 2:
      94          14 :                                                 current_name =  info2->grpi2_name;
      95          14 :                                                 break;
      96          14 :                                         case 3:
      97          14 :                                                 current_name =  info3->grpi3_name;
      98          14 :                                                 break;
      99           0 :                                         default:
     100           0 :                                                 break;
     101             :                                 }
     102             : 
     103          56 :                                 if (strcasecmp(current_name, groupname) == 0) {
     104           4 :                                         found_group = 1;
     105             :                                 }
     106             : 
     107          56 :                                 switch (level) {
     108          14 :                                         case 0:
     109          14 :                                                 info0++;
     110          14 :                                                 break;
     111          14 :                                         case 1:
     112          14 :                                                 info1++;
     113          14 :                                                 break;
     114          14 :                                         case 2:
     115          14 :                                                 info2++;
     116          14 :                                                 break;
     117          14 :                                         case 3:
     118          14 :                                                 info3++;
     119          14 :                                                 break;
     120             :                                 }
     121             :                         }
     122           4 :                         NetApiBufferFree(buffer);
     123             :                 }
     124           4 :         } while (status == ERROR_MORE_DATA);
     125             : 
     126           4 :         if (status) {
     127           0 :                 return status;
     128             :         }
     129             : 
     130           4 :         if (!found_group) {
     131           0 :                 torture_comment(tctx, "failed to get group\n");
     132           0 :                 return -1;
     133             :         }
     134             : 
     135           4 :         return 0;
     136             : }
     137             : 
     138           6 : static NET_API_STATUS test_netgroupgetusers(struct torture_context *tctx,
     139             :                                             const char *hostname,
     140             :                                             uint32_t level,
     141             :                                             const char *groupname,
     142             :                                             const char *username)
     143             : {
     144           0 :         NET_API_STATUS status;
     145           6 :         uint32_t entries_read = 0;
     146           6 :         uint32_t total_entries = 0;
     147           6 :         uint32_t resume_handle = 0;
     148           6 :         int found_user = 0;
     149           6 :         const char *current_name = NULL;
     150           6 :         uint8_t *buffer = NULL;
     151           0 :         int i;
     152             : 
     153           6 :         struct GROUP_USERS_INFO_0 *info0 = NULL;
     154           6 :         struct GROUP_USERS_INFO_1 *info1 = NULL;
     155             : 
     156           6 :         torture_comment(tctx, "Testing NetGroupGetUsers level %d\n", level);
     157             : 
     158           0 :         do {
     159           6 :                 status = NetGroupGetUsers(hostname,
     160             :                                           groupname,
     161             :                                           level,
     162             :                                           &buffer,
     163             :                                           (uint32_t)-1,
     164             :                                           &entries_read,
     165             :                                           &total_entries,
     166             :                                           &resume_handle);
     167           6 :                 if (status == 0 || status == ERROR_MORE_DATA) {
     168             : 
     169           6 :                         switch (level) {
     170           4 :                                 case 0:
     171           4 :                                         info0 = (struct GROUP_USERS_INFO_0 *)buffer;
     172           4 :                                         break;
     173           2 :                                 case 1:
     174           2 :                                         info1 = (struct GROUP_USERS_INFO_1 *)buffer;
     175           2 :                                         break;
     176           0 :                                 default:
     177           0 :                                         break;
     178             :                         }
     179           9 :                         for (i=0; i<entries_read; i++) {
     180           3 :                                 switch (level) {
     181           2 :                                         case 0:
     182           2 :                                                 current_name = info0->grui0_name;
     183           2 :                                                 break;
     184           1 :                                         case 1:
     185           1 :                                                 current_name = info1->grui1_name;
     186           1 :                                                 break;
     187           0 :                                         default:
     188           0 :                                                 break;
     189             :                                 }
     190             : 
     191           3 :                                 if (username && strcasecmp(current_name, username) == 0) {
     192           3 :                                         found_user = 1;
     193             :                                 }
     194             : 
     195           3 :                                 switch (level) {
     196           2 :                                         case 0:
     197           2 :                                                 info0++;
     198           2 :                                                 break;
     199           1 :                                         case 1:
     200           1 :                                                 info1++;
     201           1 :                                                 break;
     202             :                                 }
     203             :                         }
     204           6 :                         NetApiBufferFree(buffer);
     205             :                 }
     206           6 :         } while (status == ERROR_MORE_DATA);
     207             : 
     208           6 :         if (status) {
     209           0 :                 return status;
     210             :         }
     211             : 
     212           6 :         if (username && !found_user) {
     213           0 :                 torture_comment(tctx, "failed to get user\n");
     214           0 :                 return -1;
     215             :         }
     216             : 
     217           6 :         return 0;
     218             : }
     219             : 
     220           1 : static NET_API_STATUS test_netgroupsetusers(struct torture_context *tctx,
     221             :                                             const char *hostname,
     222             :                                             const char *groupname,
     223             :                                             uint32_t level,
     224             :                                             size_t num_entries,
     225             :                                             const char **names)
     226             : {
     227           0 :         NET_API_STATUS status;
     228           1 :         uint8_t *buffer = NULL;
     229           1 :         int i = 0;
     230           1 :         size_t buf_size = 0;
     231             : 
     232           1 :         struct GROUP_USERS_INFO_0 *g0 = NULL;
     233           1 :         struct GROUP_USERS_INFO_1 *g1 = NULL;
     234             : 
     235           1 :         torture_comment(tctx, "Testing NetGroupSetUsers level %d\n", level);
     236             : 
     237           1 :         switch (level) {
     238           1 :                 case 0:
     239           1 :                         buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries;
     240             : 
     241           1 :                         status = NetApiBufferAllocate(buf_size, (void **)&g0);
     242           1 :                         if (status) {
     243           0 :                                 goto out;
     244             :                         }
     245             : 
     246           2 :                         for (i=0; i<num_entries; i++) {
     247           1 :                                 g0[i].grui0_name = names[i];
     248             :                         }
     249             : 
     250           1 :                         buffer = (uint8_t *)g0;
     251           1 :                         break;
     252           0 :                 case 1:
     253           0 :                         buf_size = sizeof(struct GROUP_USERS_INFO_1) * num_entries;
     254             : 
     255           0 :                         status = NetApiBufferAllocate(buf_size, (void **)&g1);
     256           0 :                         if (status) {
     257           0 :                                 goto out;
     258             :                         }
     259             : 
     260           0 :                         for (i=0; i<num_entries; i++) {
     261           0 :                                 g1[i].grui1_name = names[i];
     262             :                         }
     263             : 
     264           0 :                         buffer = (uint8_t *)g1;
     265           0 :                         break;
     266           0 :                 default:
     267           0 :                         break;
     268             :         }
     269             : 
     270             :         /* NetGroupSetUsers */
     271             : 
     272           1 :         status = NetGroupSetUsers(hostname,
     273             :                                   groupname,
     274             :                                   level,
     275             :                                   buffer,
     276             :                                   num_entries);
     277           1 :         if (status) {
     278           0 :                 goto out;
     279             :         }
     280             : 
     281           1 :  out:
     282           1 :         NetApiBufferFree(buffer);
     283           1 :         return status;
     284             : }
     285             : 
     286           1 : bool torture_libnetapi_group(struct torture_context *tctx)
     287             : {
     288           1 :         NET_API_STATUS status = 0;
     289           0 :         const char *username, *groupname, *groupname2;
     290           1 :         uint8_t *buffer = NULL;
     291           0 :         struct GROUP_INFO_0 g0;
     292           1 :         uint32_t parm_err = 0;
     293           1 :         uint32_t levels[] = { 0, 1, 2, 3};
     294           1 :         uint32_t enum_levels[] = { 0, 1, 2, 3};
     295           1 :         uint32_t getmem_levels[] = { 0, 1};
     296           0 :         int i;
     297           1 :         const char *hostname = torture_setting_string(tctx, "host", NULL);
     298           0 :         struct libnetapi_ctx *ctx;
     299             : 
     300           1 :         torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx),
     301             :                        "failed to initialize libnetapi");
     302             : 
     303           1 :         torture_comment(tctx, "NetGroup tests\n");
     304             : 
     305           1 :         username = "torture_test_user";
     306           1 :         groupname = "torture_test_group";
     307           1 :         groupname2 = "torture_test_group2";
     308             : 
     309             :         /* cleanup */
     310           1 :         NetGroupDel(hostname, groupname);
     311           1 :         NetGroupDel(hostname, groupname2);
     312           1 :         NetUserDel(hostname, username);
     313             : 
     314             :         /* add a group */
     315             : 
     316           1 :         g0.grpi0_name = groupname;
     317             : 
     318           1 :         torture_comment(tctx, "Testing NetGroupAdd\n");
     319             : 
     320           1 :         status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err);
     321           1 :         if (status) {
     322           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd");
     323           0 :                 goto out;
     324             :         }
     325             : 
     326             :         /* 2nd add must fail */
     327             : 
     328           1 :         status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err);
     329           1 :         if (status == 0) {
     330           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd");
     331           0 :                 status = -1;
     332           0 :                 goto out;
     333             :         }
     334             : 
     335             :         /* test enum */
     336             : 
     337           5 :         for (i=0; i<ARRAY_SIZE(enum_levels); i++) {
     338             : 
     339           4 :                 status = test_netgroupenum(tctx, hostname, enum_levels[i], groupname);
     340           4 :                 if (status) {
     341           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetGroupEnum");
     342           0 :                         goto out;
     343             :                 }
     344             :         }
     345             : 
     346             :         /* basic queries */
     347             : 
     348           5 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     349             : 
     350           4 :                 torture_comment(tctx, "Testing NetGroupGetInfo level %d\n", levels[i]);
     351             : 
     352           4 :                 status = NetGroupGetInfo(hostname, groupname, levels[i], &buffer);
     353           4 :                 if (status && status != 124) {
     354           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo");
     355           0 :                         goto out;
     356             :                 }
     357             :         }
     358             : 
     359             :         /* group rename */
     360             : 
     361           1 :         g0.grpi0_name = groupname2;
     362             : 
     363           1 :         torture_comment(tctx, "Testing NetGroupSetInfo level 0\n");
     364             : 
     365           1 :         status = NetGroupSetInfo(hostname, groupname, 0, (uint8_t *)&g0, &parm_err);
     366           1 :         switch ((uint32_t)status) {
     367           1 :                 case 0:
     368           1 :                         break;
     369           0 :                 case 50: /* not supported */
     370             :                 case 124: /* not implemented */
     371           0 :                         groupname2 = groupname;
     372           0 :                         goto skip_rename;
     373           0 :                 default:
     374           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetGroupSetInfo");
     375           0 :                         goto out;
     376             :         }
     377             : 
     378             :         /* should not exist anymore */
     379             : 
     380           1 :         status = NetGroupDel(hostname, groupname);
     381           1 :         if (status == 0) {
     382           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupDel");
     383           0 :                 goto out;
     384             :         }
     385             : 
     386           1 :  skip_rename:
     387             :         /* query info */
     388             : 
     389           5 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     390             : 
     391           4 :                 status = NetGroupGetInfo(hostname, groupname2, levels[i], &buffer);
     392           4 :                 if (status && status != 124) {
     393           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo");
     394           0 :                         goto out;
     395             :                 }
     396             :         }
     397             : 
     398             :         /* add user to group */
     399             : 
     400           1 :         status = test_netuseradd(tctx, hostname, username);
     401           1 :         if (status) {
     402           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserAdd");
     403           0 :                 goto out;
     404             :         }
     405             : 
     406             :         /* should not be member */
     407             : 
     408           3 :         for (i=0; i<ARRAY_SIZE(getmem_levels); i++) {
     409             : 
     410           2 :                 status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, NULL);
     411           2 :                 if (status) {
     412           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
     413           0 :                         goto out;
     414             :                 }
     415             :         }
     416             : 
     417           1 :         torture_comment(tctx, "Testing NetGroupAddUser\n");
     418             : 
     419           1 :         status = NetGroupAddUser(hostname, groupname2, username);
     420           1 :         if (status) {
     421           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupAddUser");
     422           0 :                 goto out;
     423             :         }
     424             : 
     425             :         /* should be member */
     426             : 
     427           3 :         for (i=0; i<ARRAY_SIZE(getmem_levels); i++) {
     428             : 
     429           2 :                 status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, username);
     430           2 :                 if (status) {
     431           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
     432           0 :                         goto out;
     433             :                 }
     434             :         }
     435             : 
     436           1 :         torture_comment(tctx, "Testing NetGroupDelUser\n");
     437             : 
     438           1 :         status = NetGroupDelUser(hostname, groupname2, username);
     439           1 :         if (status) {
     440           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupDelUser");
     441           0 :                 goto out;
     442             :         }
     443             : 
     444             :         /* should not be member */
     445             : 
     446           1 :         status = test_netgroupgetusers(tctx, hostname, 0, groupname2, NULL);
     447           1 :         if (status) {
     448           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
     449           0 :                 goto out;
     450             :         }
     451             : 
     452             :         /* set it again via explicit member set */
     453             : 
     454           1 :         status = test_netgroupsetusers(tctx, hostname, groupname2, 0, 1, &username);
     455           1 :         if (status) {
     456           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers");
     457           0 :                 goto out;
     458             :         }
     459             : 
     460             :         /* should be member */
     461             : 
     462           1 :         status = test_netgroupgetusers(tctx, hostname, 0, groupname2, username);
     463           1 :         if (status) {
     464           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
     465           0 :                 goto out;
     466             :         }
     467             : #if 0
     468             :         /* wipe out member list */
     469             : 
     470             :         status = test_netgroupsetusers(hostname, groupname2, 0, 0, NULL);
     471             :         if (status) {
     472             :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers");
     473             :                 goto out;
     474             :         }
     475             : 
     476             :         /* should not be member */
     477             : 
     478             :         status = test_netgroupgetusers(hostname, 0, groupname2, NULL);
     479             :         if (status) {
     480             :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
     481             :                 goto out;
     482             :         }
     483             : #endif
     484           1 :         status = NetUserDel(hostname, username);
     485           1 :         if (status) {
     486           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserDel");
     487           0 :                 goto out;
     488             :         }
     489             : 
     490             :         /* delete */
     491             : 
     492           1 :         torture_comment(tctx, "Testing NetGroupDel\n");
     493             : 
     494           1 :         status = NetGroupDel(hostname, groupname2);
     495           1 :         if (status) {
     496           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetGroupDel");
     497           0 :                 goto out;
     498           0 :         };
     499             : 
     500             :         /* should not exist anymore */
     501             : 
     502           1 :         status = NetGroupGetInfo(hostname, groupname2, 0, &buffer);
     503           1 :         if (status == 0) {
     504           0 :                 NETAPI_STATUS_MSG(tctx, ctx, status, "NetGroupGetInfo", "expected failure and error code");
     505           0 :                 status = -1;
     506           0 :                 goto out;
     507           0 :         };
     508             : 
     509           1 :         status = 0;
     510             : 
     511           1 :         torture_comment(tctx, "NetGroup tests succeeded\n");
     512           1 :  out:
     513           1 :         if (status != 0) {
     514           0 :                 torture_comment(tctx, "NetGroup testsuite failed with: %s\n",
     515             :                         libnetapi_get_error_string(ctx, status));
     516           0 :                 libnetapi_free(ctx);
     517           0 :                 return false;
     518             :         }
     519             : 
     520           1 :         libnetapi_free(ctx);
     521           1 :         return true;
     522             : }

Generated by: LCOV version 1.14