LCOV - code coverage report
Current view: top level - source4/torture/libnetapi - libnetapi_user.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 232 297 78.1 %
Date: 2024-04-21 15:09:00 Functions: 5 5 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 "torture_testuser"
      28             : #define TORTURE_TEST_USER2 "torture_testuser2"
      29             : 
      30             : #define NETAPI_STATUS(tctx, x,y,fn) \
      31             :         torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \
      32             :                 __LINE__, fn, libnetapi_get_error_string(x,y), y);
      33             : 
      34           9 : static NET_API_STATUS test_netuserenum(struct torture_context *tctx,
      35             :                                        const char *hostname,
      36             :                                        uint32_t level,
      37             :                                        const char *username)
      38             : {
      39           0 :         NET_API_STATUS status;
      40           9 :         uint32_t entries_read = 0;
      41           9 :         uint32_t total_entries = 0;
      42           9 :         uint32_t resume_handle = 0;
      43           9 :         const char *current_name = NULL;
      44           9 :         int found_user = 0;
      45           9 :         uint8_t *buffer = NULL;
      46           0 :         int i;
      47             : 
      48           9 :         struct USER_INFO_0 *info0 = NULL;
      49           9 :         struct USER_INFO_1 *info1 = NULL;
      50           9 :         struct USER_INFO_2 *info2 = NULL;
      51           9 :         struct USER_INFO_3 *info3 = NULL;
      52           9 :         struct USER_INFO_4 *info4 = NULL;
      53           9 :         struct USER_INFO_10 *info10 = NULL;
      54           9 :         struct USER_INFO_11 *info11 = NULL;
      55           9 :         struct USER_INFO_20 *info20 = NULL;
      56           9 :         struct USER_INFO_23 *info23 = NULL;
      57             : 
      58           9 :         torture_comment(tctx, "Testing NetUserEnum level %d\n", level);
      59             : 
      60           0 :         do {
      61           9 :                 status = NetUserEnum(hostname,
      62             :                                      level,
      63             :                                      FILTER_NORMAL_ACCOUNT,
      64             :                                      &buffer,
      65             :                                      (uint32_t)-1,
      66             :                                      &entries_read,
      67             :                                      &total_entries,
      68             :                                      &resume_handle);
      69           9 :                 if (status == 0 || status == ERROR_MORE_DATA) {
      70           9 :                         switch (level) {
      71           1 :                                 case 0:
      72           1 :                                         info0 = (struct USER_INFO_0 *)buffer;
      73           1 :                                         break;
      74           1 :                                 case 1:
      75           1 :                                         info1 = (struct USER_INFO_1 *)buffer;
      76           1 :                                         break;
      77           1 :                                 case 2:
      78           1 :                                         info2 = (struct USER_INFO_2 *)buffer;
      79           1 :                                         break;
      80           1 :                                 case 3:
      81           1 :                                         info3 = (struct USER_INFO_3 *)buffer;
      82           1 :                                         break;
      83           1 :                                 case 4:
      84           1 :                                         info4 = (struct USER_INFO_4 *)buffer;
      85           1 :                                         break;
      86           1 :                                 case 10:
      87           1 :                                         info10 = (struct USER_INFO_10 *)buffer;
      88           1 :                                         break;
      89           1 :                                 case 11:
      90           1 :                                         info11 = (struct USER_INFO_11 *)buffer;
      91           1 :                                         break;
      92           1 :                                 case 20:
      93           1 :                                         info20 = (struct USER_INFO_20 *)buffer;
      94           1 :                                         break;
      95           1 :                                 case 23:
      96           1 :                                         info23 = (struct USER_INFO_23 *)buffer;
      97           1 :                                         break;
      98           0 :                                 default:
      99           0 :                                         return -1;
     100             :                         }
     101             : 
     102         144 :                         for (i=0; i<entries_read; i++) {
     103             : 
     104         135 :                                 switch (level) {
     105          15 :                                         case 0:
     106          15 :                                                 current_name = info0->usri0_name;
     107          15 :                                                 break;
     108          15 :                                         case 1:
     109          15 :                                                 current_name = info1->usri1_name;
     110          15 :                                                 break;
     111          15 :                                         case 2:
     112          15 :                                                 current_name = info2->usri2_name;
     113          15 :                                                 break;
     114          15 :                                         case 3:
     115          15 :                                                 current_name = info3->usri3_name;
     116          15 :                                                 break;
     117          15 :                                         case 4:
     118          15 :                                                 current_name = info4->usri4_name;
     119          15 :                                                 break;
     120          15 :                                         case 10:
     121          15 :                                                 current_name = info10->usri10_name;
     122          15 :                                                 break;
     123          15 :                                         case 11:
     124          15 :                                                 current_name = info11->usri11_name;
     125          15 :                                                 break;
     126          15 :                                         case 20:
     127          15 :                                                 current_name = info20->usri20_name;
     128          15 :                                                 break;
     129          15 :                                         case 23:
     130          15 :                                                 current_name = info23->usri23_name;
     131          15 :                                                 break;
     132           0 :                                         default:
     133           0 :                                                 return -1;
     134             :                                 }
     135             : 
     136         135 :                                 if (strcasecmp(current_name, username) == 0) {
     137           9 :                                         found_user = 1;
     138             :                                 }
     139             : 
     140         135 :                                 switch (level) {
     141          15 :                                         case 0:
     142          15 :                                                 info0++;
     143          15 :                                                 break;
     144          15 :                                         case 1:
     145          15 :                                                 info1++;
     146          15 :                                                 break;
     147          15 :                                         case 2:
     148          15 :                                                 info2++;
     149          15 :                                                 break;
     150          15 :                                         case 3:
     151          15 :                                                 info3++;
     152          15 :                                                 break;
     153          15 :                                         case 4:
     154          15 :                                                 info4++;
     155          15 :                                                 break;
     156          15 :                                         case 10:
     157          15 :                                                 info10++;
     158          15 :                                                 break;
     159          15 :                                         case 11:
     160          15 :                                                 info11++;
     161          15 :                                                 break;
     162          15 :                                         case 20:
     163          15 :                                                 info20++;
     164          15 :                                                 break;
     165          15 :                                         case 23:
     166          15 :                                                 info23++;
     167          15 :                                                 break;
     168           0 :                                         default:
     169           0 :                                                 break;
     170             :                                 }
     171             :                         }
     172           9 :                         NetApiBufferFree(buffer);
     173             :                 }
     174           9 :         } while (status == ERROR_MORE_DATA);
     175             : 
     176           9 :         if (status) {
     177           0 :                 return status;
     178             :         }
     179             : 
     180           9 :         if (!found_user) {
     181           0 :                 torture_comment(tctx, "failed to get user\n");
     182           0 :                 return -1;
     183             :         }
     184             : 
     185           9 :         return 0;
     186             : }
     187             : 
     188           2 : NET_API_STATUS test_netuseradd(struct torture_context *tctx,
     189             :                                const char *hostname,
     190             :                                const char *username)
     191             : {
     192           0 :         struct USER_INFO_1 u1;
     193           2 :         uint32_t parm_err = 0;
     194             : 
     195           2 :         ZERO_STRUCT(u1);
     196             : 
     197           2 :         torture_comment(tctx, "Testing NetUserAdd\n");
     198             : 
     199           2 :         u1.usri1_name = username;
     200           2 :         u1.usri1_password = "W297!832jD8J";
     201           2 :         u1.usri1_password_age = 0;
     202           2 :         u1.usri1_priv = 0;
     203           2 :         u1.usri1_home_dir = NULL;
     204           2 :         u1.usri1_comment = "User created using Samba NetApi Example code";
     205           2 :         u1.usri1_flags = 0;
     206           2 :         u1.usri1_script_path = NULL;
     207             : 
     208           2 :         return NetUserAdd(hostname, 1, (uint8_t *)&u1, &parm_err);
     209             : }
     210             : 
     211           1 : static NET_API_STATUS test_netusermodals(struct torture_context *tctx,
     212             :                                          struct libnetapi_ctx *ctx,
     213             :                                          const char *hostname)
     214             : {
     215           0 :         NET_API_STATUS status;
     216           1 :         struct USER_MODALS_INFO_0 *u0 = NULL;
     217           1 :         struct USER_MODALS_INFO_0 *_u0 = NULL;
     218           1 :         uint8_t *buffer = NULL;
     219           1 :         uint32_t parm_err = 0;
     220           1 :         uint32_t levels[] = { 0, 1, 2, 3 };
     221           1 :         int i = 0;
     222             : 
     223           5 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     224             : 
     225           4 :                 torture_comment(tctx, "Testing NetUserModalsGet level %d\n", levels[i]);
     226             : 
     227           4 :                 status = NetUserModalsGet(hostname, levels[i], &buffer);
     228           4 :                 if (status) {
     229           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet");
     230           0 :                         return status;
     231             :                 }
     232             :         }
     233             : 
     234           1 :         status = NetUserModalsGet(hostname, 0, (uint8_t **)&u0);
     235           1 :         if (status) {
     236           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet");
     237           0 :                 return status;
     238             :         }
     239             : 
     240           1 :         torture_comment(tctx, "Testing NetUserModalsSet\n");
     241             : 
     242           1 :         status = NetUserModalsSet(hostname, 0, (uint8_t *)u0, &parm_err);
     243           1 :         if (status) {
     244           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserModalsSet");
     245           0 :                 return status;
     246             :         }
     247             : 
     248           1 :         status = NetUserModalsGet(hostname, 0, (uint8_t **)&_u0);
     249           1 :         if (status) {
     250           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet");
     251           0 :                 return status;
     252             :         }
     253             : 
     254           1 :         if (memcmp(u0, _u0, sizeof(*u0)) != 0) {
     255           0 :                 torture_comment(tctx, "USER_MODALS_INFO_0 struct has changed!!!!\n");
     256           0 :                 return -1;
     257             :         }
     258             : 
     259           1 :         return 0;
     260             : }
     261             : 
     262           2 : static NET_API_STATUS test_netusergetgroups(struct torture_context *tctx,
     263             :                                             const char *hostname,
     264             :                                             uint32_t level,
     265             :                                             const char *username,
     266             :                                             const char *groupname)
     267             : {
     268           0 :         NET_API_STATUS status;
     269           2 :         uint32_t entries_read = 0;
     270           2 :         uint32_t total_entries = 0;
     271           0 :         const char *current_name;
     272           2 :         int found_group = 0;
     273           2 :         uint8_t *buffer = NULL;
     274           0 :         int i;
     275             : 
     276           2 :         struct GROUP_USERS_INFO_0 *i0 = NULL;
     277           2 :         struct GROUP_USERS_INFO_1 *i1 = NULL;
     278             : 
     279           2 :         torture_comment(tctx, "Testing NetUserGetGroups level %d\n", level);
     280             : 
     281           0 :         do {
     282           2 :                 status = NetUserGetGroups(hostname,
     283             :                                           username,
     284             :                                           level,
     285             :                                           &buffer,
     286             :                                           (uint32_t)-1,
     287             :                                           &entries_read,
     288             :                                           &total_entries);
     289           2 :                 if (status == 0 || status == ERROR_MORE_DATA) {
     290           2 :                         switch (level) {
     291           1 :                                 case 0:
     292           1 :                                         i0 = (struct GROUP_USERS_INFO_0 *)buffer;
     293           1 :                                         break;
     294           1 :                                 case 1:
     295           1 :                                         i1 = (struct GROUP_USERS_INFO_1 *)buffer;
     296           1 :                                         break;
     297           0 :                                 default:
     298           0 :                                         return -1;
     299             :                         }
     300             : 
     301           4 :                         for (i=0; i<entries_read; i++) {
     302             : 
     303           2 :                                 switch (level) {
     304           1 :                                         case 0:
     305           1 :                                                 current_name = i0->grui0_name;
     306           1 :                                                 break;
     307           1 :                                         case 1:
     308           1 :                                                 current_name = i1->grui1_name;
     309           1 :                                                 break;
     310           0 :                                         default:
     311           0 :                                                 return -1;
     312             :                                 }
     313             : 
     314           2 :                                 if (groupname && strcasecmp(current_name, groupname) == 0) {
     315           0 :                                         found_group = 1;
     316             :                                 }
     317             : 
     318           2 :                                 switch (level) {
     319           1 :                                         case 0:
     320           1 :                                                 i0++;
     321           1 :                                                 break;
     322           1 :                                         case 1:
     323           1 :                                                 i1++;
     324           1 :                                                 break;
     325           0 :                                         default:
     326           0 :                                                 break;
     327             :                                 }
     328             :                         }
     329           2 :                         NetApiBufferFree(buffer);
     330             :                 }
     331           2 :         } while (status == ERROR_MORE_DATA);
     332             : 
     333           2 :         if (status) {
     334           0 :                 return status;
     335             :         }
     336             : 
     337           2 :         if (groupname && !found_group) {
     338           0 :                 torture_comment(tctx, "failed to get membership\n");
     339           0 :                 return -1;
     340             :         }
     341             : 
     342           2 :         return 0;
     343             : }
     344             : 
     345           1 : bool torture_libnetapi_user(struct torture_context *tctx)
     346             : {
     347           1 :         NET_API_STATUS status = 0;
     348           1 :         uint8_t *buffer = NULL;
     349           1 :         uint32_t levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 };
     350           1 :         uint32_t enum_levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 };
     351           1 :         uint32_t getgr_levels[] = { 0, 1 };
     352           0 :         int i;
     353             : 
     354           0 :         struct USER_INFO_0 u0;
     355           0 :         struct USER_INFO_1007 u1007;
     356           1 :         uint32_t parm_err = 0;
     357             : 
     358           1 :         const char *hostname = torture_setting_string(tctx, "host", NULL);
     359           0 :         struct libnetapi_ctx *ctx;
     360             : 
     361           1 :         torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx),
     362             :                        "failed to initialize libnetapi");
     363             : 
     364           1 :         torture_comment(tctx, "NetUser tests\n");
     365             : 
     366             :         /* cleanup */
     367             : 
     368           1 :         NetUserDel(hostname, TORTURE_TEST_USER);
     369           1 :         NetUserDel(hostname, TORTURE_TEST_USER2);
     370             : 
     371             :         /* add a user */
     372             : 
     373           1 :         status = test_netuseradd(tctx, hostname, TORTURE_TEST_USER);
     374           1 :         if (status) {
     375           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserAdd");
     376           0 :                 goto out;
     377             :         }
     378             : 
     379             :         /* enum the new user */
     380             : 
     381          10 :         for (i=0; i<ARRAY_SIZE(enum_levels); i++) {
     382             : 
     383           9 :                 status = test_netuserenum(tctx, hostname, enum_levels[i], TORTURE_TEST_USER);
     384           9 :                 if (status) {
     385           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetUserEnum");
     386           0 :                         goto out;
     387             :                 }
     388             :         }
     389             : 
     390             :         /* basic queries */
     391             : 
     392          10 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     393             : 
     394           9 :                 torture_comment(tctx, "Testing NetUserGetInfo level %d\n", levels[i]);
     395             : 
     396           9 :                 status = NetUserGetInfo(hostname, TORTURE_TEST_USER, levels[i], &buffer);
     397           9 :                 if (status && status != 124) {
     398           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo");
     399           0 :                         goto out;
     400             :                 }
     401             :         }
     402             : 
     403             :         /* testing getgroups */
     404             : 
     405           3 :         for (i=0; i<ARRAY_SIZE(getgr_levels); i++) {
     406             : 
     407           2 :                 status = test_netusergetgroups(tctx, hostname, getgr_levels[i], TORTURE_TEST_USER, NULL);
     408           2 :                 if (status) {
     409           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetUserGetGroups");
     410           0 :                         goto out;
     411             :                 }
     412             :         }
     413             : 
     414             :         /* modify description */
     415             : 
     416           1 :         torture_comment(tctx, "Testing NetUserSetInfo level %d\n", 1007);
     417             : 
     418           1 :         u1007.usri1007_comment = "NetApi modified user";
     419             : 
     420           1 :         status = NetUserSetInfo(hostname, TORTURE_TEST_USER, 1007, (uint8_t *)&u1007, &parm_err);
     421           1 :         if (status) {
     422           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserSetInfo");
     423           0 :                 goto out;
     424             :         }
     425             : 
     426             :         /* query info */
     427             : 
     428          10 :         for (i=0; i<ARRAY_SIZE(levels); i++) {
     429           9 :                 status = NetUserGetInfo(hostname, TORTURE_TEST_USER, levels[i], &buffer);
     430           9 :                 if (status && status != 124) {
     431           0 :                         NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo");
     432           0 :                         goto out;
     433             :                 }
     434             :         }
     435             : 
     436           1 :         torture_comment(tctx, "Testing NetUserSetInfo level 0\n");
     437             : 
     438           1 :         u0.usri0_name = TORTURE_TEST_USER2;
     439             : 
     440           1 :         status = NetUserSetInfo(hostname, TORTURE_TEST_USER, 0, (uint8_t *)&u0, &parm_err);
     441           1 :         if (status) {
     442           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserSetInfo");
     443           0 :                 goto out;
     444             :         }
     445             : 
     446             :         /* delete */
     447             : 
     448           1 :         torture_comment(tctx, "Testing NetUserDel\n");
     449             : 
     450           1 :         status = NetUserDel(hostname, TORTURE_TEST_USER2);
     451           1 :         if (status) {
     452           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserDel");
     453           0 :                 goto out;
     454             :         }
     455             : 
     456             :         /* should not exist anymore */
     457             : 
     458           1 :         status = NetUserGetInfo(hostname, TORTURE_TEST_USER2, 0, &buffer);
     459           1 :         if (status == 0) {
     460           0 :                 NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo");
     461           0 :                 status = -1;
     462           0 :                 goto out;
     463             :         }
     464             : 
     465           1 :         status = test_netusermodals(tctx, ctx, hostname);
     466           1 :         if (status) {
     467           0 :                 goto out;
     468             :         }
     469             : 
     470           1 :         status = 0;
     471             : 
     472           1 :         torture_comment(tctx, "NetUser tests succeeded\n");
     473           1 :  out:
     474             :         /* cleanup */
     475           1 :         NetUserDel(hostname, TORTURE_TEST_USER);
     476           1 :         NetUserDel(hostname, TORTURE_TEST_USER2);
     477             : 
     478           1 :         if (status != 0) {
     479           0 :                 torture_comment(tctx, "NetUser testsuite failed with: %s\n",
     480             :                         libnetapi_get_error_string(ctx, status));
     481           0 :                 libnetapi_free(ctx);
     482           0 :                 return false;
     483             :         }
     484             : 
     485           1 :         libnetapi_free(ctx);
     486           1 :         return true;
     487             : }

Generated by: LCOV version 1.14