LCOV - code coverage report
Current view: top level - source3/torture - mangle_test.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 107 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester - mangling test
       4             :    Copyright (C) Andrew Tridgell 2002
       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 "system/filesys.h"
      22             : #include "torture/proto.h"
      23             : #include "libsmb/libsmb.h"
      24             : #include "libsmb/clirap.h"
      25             : #include "util_tdb.h"
      26             : #include "lib/util/string_wrappers.h"
      27             : 
      28             : extern int torture_numops;
      29             : 
      30             : static TDB_CONTEXT *tdb;
      31             : 
      32             : #define NAME_LENGTH 20
      33             : 
      34             : static unsigned total, collisions, failures;
      35             : 
      36           0 : static bool test_one(struct cli_state *cli, const char *name)
      37             : {
      38           0 :         uint16_t fnum;
      39           0 :         fstring shortname;
      40           0 :         fstring name2;
      41           0 :         NTSTATUS status;
      42           0 :         TDB_DATA data;
      43             : 
      44           0 :         total++;
      45             : 
      46           0 :         status = cli_openx(cli, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
      47           0 :         if (!NT_STATUS_IS_OK(status)) {
      48           0 :                 printf("open of %s failed (%s)\n", name, nt_errstr(status));
      49           0 :                 return False;
      50             :         }
      51             : 
      52           0 :         status = cli_close(cli, fnum);
      53           0 :         if (!NT_STATUS_IS_OK(status)) {
      54           0 :                 printf("close of %s failed (%s)\n", name, nt_errstr(status));
      55           0 :                 return False;
      56             :         }
      57             : 
      58             :         /* get the short name */
      59           0 :         status = cli_qpathinfo_alt_name(cli, name, shortname);
      60           0 :         if (!NT_STATUS_IS_OK(status)) {
      61           0 :                 printf("query altname of %s failed (%s)\n", name, nt_errstr(status));
      62           0 :                 return False;
      63             :         }
      64             : 
      65           0 :         fstr_sprintf(name2, "\\mangle_test\\%s", shortname);
      66           0 :         status = cli_unlink(cli, name2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
      67           0 :         if (!NT_STATUS_IS_OK(status)) {
      68           0 :                 printf("unlink of %s  (%s) failed (%s)\n", 
      69             :                        name2, name, nt_errstr(status));
      70           0 :                 return False;
      71             :         }
      72             : 
      73             :         /* recreate by short name */
      74           0 :         status = cli_openx(cli, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
      75           0 :         if (!NT_STATUS_IS_OK(status)) {
      76           0 :                 printf("open2 of %s failed (%s)\n", name2, nt_errstr(status));
      77           0 :                 return False;
      78             :         }
      79             : 
      80           0 :         status = cli_close(cli, fnum);
      81           0 :         if (!NT_STATUS_IS_OK(status)) {
      82           0 :                 printf("close of %s failed (%s)\n", name, nt_errstr(status));
      83           0 :                 return False;
      84             :         }
      85             : 
      86             :         /* and unlink by long name */
      87           0 :         status = cli_unlink(cli, name, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
      88           0 :         if (!NT_STATUS_IS_OK(status)) {
      89           0 :                 printf("unlink2 of %s  (%s) failed (%s)\n", 
      90             :                        name, name2, nt_errstr(status));
      91           0 :                 failures++;
      92           0 :                 cli_unlink(cli, name2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
      93           0 :                 return True;
      94             :         }
      95             : 
      96             :         /* see if the short name is already in the tdb */
      97           0 :         data = tdb_fetch_bystring(tdb, shortname);
      98           0 :         if (data.dptr) {
      99             :                 /* maybe its a duplicate long name? */
     100           0 :                 if (!strequal(name, (const char *)data.dptr)) {
     101             :                         /* we have a collision */
     102           0 :                         collisions++;
     103           0 :                         printf("Collision between %s and %s   ->  %s "
     104             :                                 " (coll/tot: %u/%u)\n", 
     105             :                                 name, data.dptr, shortname, collisions, total);
     106             :                 }
     107           0 :                 free(data.dptr);
     108             :         } else {
     109           0 :                 TDB_DATA namedata;
     110             :                 /* store it for later */
     111           0 :                 namedata.dptr = discard_const_p(uint8_t, name);
     112           0 :                 namedata.dsize = strlen(name)+1;
     113           0 :                 tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE);
     114             :         }
     115             : 
     116           0 :         return True;
     117             : }
     118             : 
     119             : 
     120           0 : static void gen_name(char *name)
     121             : {
     122           0 :         const char *chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz._-$~... ";
     123           0 :         unsigned max_idx = strlen(chars);
     124           0 :         unsigned len;
     125           0 :         int i;
     126           0 :         char *p;
     127             : 
     128           0 :         fstrcpy(name, "\\mangle_test\\");
     129           0 :         p = name + strlen(name);
     130             : 
     131           0 :         len = 1 + random() % NAME_LENGTH;
     132             :         
     133           0 :         for (i=0;i<len;i++) {
     134           0 :                 p[i] = chars[random() % max_idx];
     135             :         }
     136             : 
     137           0 :         p[i] = 0;
     138             : 
     139           0 :         if (strcmp(p, ".") == 0 || strcmp(p, "..") == 0) {
     140           0 :                 p[0] = '_';
     141             :         }
     142             : 
     143             :         /* have a high probability of a common lead char */
     144           0 :         if (random() % 2 == 0) {
     145           0 :                 p[0] = 'A';
     146             :         }
     147             : 
     148             :         /* and a medium probability of a common lead string */
     149           0 :         if (random() % 10 == 0) {
     150           0 :                 if (strlen(p) <= 5) {
     151           0 :                         fstrcpy(p, "ABCDE");
     152             :                 } else {
     153             :                         /* try not to kill off the null termination */
     154           0 :                         memcpy(p, "ABCDE", 5);
     155             :                 }
     156             :         }
     157             : 
     158             :         /* and a high probability of a good extension length */
     159           0 :         if (random() % 2 == 0) {
     160           0 :                 char *s = strrchr(p, '.');
     161           0 :                 if (s) {
     162           0 :                         s[4] = 0;
     163             :                 }
     164             :         }
     165             : 
     166             :         /* ..... and a 100% proability of a file not ending in "." */
     167           0 :         if (p[strlen(p)-1] == '.')
     168           0 :                 p[strlen(p)-1] = '_';
     169           0 : }
     170             : 
     171             : 
     172           0 : bool torture_mangle(int dummy)
     173             : {
     174           0 :         static struct cli_state *cli;
     175           0 :         int i;
     176           0 :         bool ret = True;
     177             : 
     178           0 :         printf("starting mangle test\n");
     179             : 
     180           0 :         if (!torture_open_connection(&cli, 0)) {
     181           0 :                 return False;
     182             :         }
     183             : 
     184             :         /* we will use an internal tdb to store the names we have used */
     185           0 :         tdb = tdb_open(NULL, 100000, TDB_INTERNAL, 0, 0);
     186           0 :         if (!tdb) {
     187           0 :                 printf("ERROR: Failed to open tdb\n");
     188           0 :                 return False;
     189             :         }
     190             : 
     191           0 :         torture_deltree(cli, "\\mangle_test");
     192             : 
     193           0 :         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\mangle_test"))) {
     194           0 :                 printf("ERROR: Failed to make directory\n");
     195           0 :                 return False;
     196             :         }
     197             : 
     198           0 :         for (i=0;i<torture_numops;i++) {
     199           0 :                 fstring name;
     200           0 :                 ZERO_STRUCT(name);
     201             : 
     202           0 :                 gen_name(name);
     203             :                 
     204           0 :                 if (!test_one(cli, name)) {
     205           0 :                         ret = False;
     206           0 :                         break;
     207             :                 }
     208           0 :                 if (total && total % 100 == 0) {
     209           0 :                         printf("collisions %u/%u  - %.2f%%   (%u failures)\r",
     210           0 :                                collisions, total, (100.0*collisions) / total, failures);
     211             :                 }
     212             :         }
     213             : 
     214           0 :         torture_deltree(cli, "\\mangle_test");
     215             : 
     216           0 :         printf("\nTotal collisions %u/%u  - %.2f%%   (%u failures)\n",
     217           0 :                collisions, total, (100.0*collisions) / total, failures);
     218             : 
     219           0 :         torture_close_connection(cli);
     220             : 
     221           0 :         printf("mangle test finished\n");
     222           0 :         return (ret && (failures == 0));
     223             : }

Generated by: LCOV version 1.14