root/source3/torture/scanner.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. trans2_check_hit
  2. try_trans2
  3. try_trans2_len
  4. scan_trans2
  5. torture_trans2_scan
  6. nttrans_check_hit
  7. try_nttrans
  8. try_nttrans_len
  9. scan_nttrans
  10. torture_nttrans_scan

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    SMB torture tester - scanning functions
   4    Copyright (C) Andrew Tridgell 2001
   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 #define VERBOSE 0
  23 #define OP_MIN 0
  24 #define OP_MAX 20
  25 
  26 #define DATA_SIZE 1024
  27 #define PARAM_SIZE 1024
  28 
  29 /****************************************************************************
  30 look for a partial hit
  31 ****************************************************************************/
  32 static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
     /* [<][>][^][v][top][bottom][index][help] */
  33 {
  34         if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
  35             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
  36             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
  37             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
  38             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
  39                 return;
  40         }
  41 #if VERBOSE
  42         printf("possible %s hit op=%3d level=%5d status=%s\n",
  43                format, op, level, nt_errstr(status));
  44 #endif
  45 }
  46 
  47 /****************************************************************************
  48 check for existance of a trans2 call
  49 ****************************************************************************/
  50 static NTSTATUS try_trans2(struct cli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
  51                          int op,
  52                          char *param, char *data,
  53                          int param_len, int data_len,
  54                          unsigned int *rparam_len, unsigned int *rdata_len)
  55 {
  56         uint16 setup = op;
  57         char *rparam=NULL, *rdata=NULL;
  58 
  59         if (!cli_send_trans(cli, SMBtrans2, 
  60                             NULL,                           /* name */
  61                             -1, 0,                          /* fid, flags */
  62                             &setup, 1, 0,                   /* setup, length, max */
  63                             param, param_len, 2,            /* param, length, max */
  64                             data, data_len, cli->max_xmit   /* data, length, max */
  65                            )) {
  66                 return cli_nt_error(cli);
  67         }
  68 
  69         cli_receive_trans(cli, SMBtrans2,
  70                            &rparam, rparam_len,
  71                            &rdata, rdata_len);
  72 
  73         SAFE_FREE(rdata);
  74         SAFE_FREE(rparam);
  75 
  76         return cli_nt_error(cli);
  77 }
  78 
  79 
  80 static NTSTATUS try_trans2_len(struct cli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
  81                              const char *format,
  82                              int op, int level,
  83                              char *param, char *data,
  84                              int param_len, int *data_len,
  85                              unsigned int *rparam_len, unsigned int *rdata_len)
  86 {
  87         NTSTATUS ret=NT_STATUS_OK;
  88 
  89         ret = try_trans2(cli, op, param, data, param_len,
  90                          DATA_SIZE, rparam_len, rdata_len);
  91 #if VERBOSE 
  92         printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
  93 #endif
  94         if (!NT_STATUS_IS_OK(ret)) return ret;
  95 
  96         *data_len = 0;
  97         while (*data_len < DATA_SIZE) {
  98                 ret = try_trans2(cli, op, param, data, param_len,
  99                                  *data_len, rparam_len, rdata_len);
 100                 if (NT_STATUS_IS_OK(ret)) break;
 101                 *data_len += 2;
 102         }
 103         if (NT_STATUS_IS_OK(ret)) {
 104                 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
 105                        format, level, *data_len, *rparam_len, *rdata_len);
 106         } else {
 107                 trans2_check_hit(format, op, level, ret);
 108         }
 109         return ret;
 110 }
 111 
 112 /****************************************************************************
 113 check for existance of a trans2 call
 114 ****************************************************************************/
 115 static bool scan_trans2(struct cli_state *cli, int op, int level, 
     /* [<][>][^][v][top][bottom][index][help] */
 116                         int fnum, int dnum, const char *fname)
 117 {
 118         int data_len = 0;
 119         int param_len = 0;
 120         unsigned int rparam_len, rdata_len;
 121         char param[PARAM_SIZE], data[DATA_SIZE];
 122         NTSTATUS status;
 123 
 124         memset(data, 0, sizeof(data));
 125         data_len = 4;
 126 
 127         /* try with a info level only */
 128         param_len = 2;
 129         SSVAL(param, 0, level);
 130         status = try_trans2_len(cli, "void", op, level, param, data, param_len, &data_len, 
 131                             &rparam_len, &rdata_len);
 132         if (NT_STATUS_IS_OK(status)) return True;
 133 
 134         /* try with a file descriptor */
 135         param_len = 6;
 136         SSVAL(param, 0, fnum);
 137         SSVAL(param, 2, level);
 138         SSVAL(param, 4, 0);
 139         status = try_trans2_len(cli, "fnum", op, level, param, data, param_len, &data_len, 
 140                                 &rparam_len, &rdata_len);
 141         if (NT_STATUS_IS_OK(status)) return True;
 142 
 143 
 144         /* try with a notify style */
 145         param_len = 6;
 146         SSVAL(param, 0, dnum);
 147         SSVAL(param, 2, dnum);
 148         SSVAL(param, 4, level);
 149         status = try_trans2_len(cli, "notify", op, level, param, data, param_len, &data_len, 
 150                                 &rparam_len, &rdata_len);
 151         if (NT_STATUS_IS_OK(status)) return True;
 152 
 153         /* try with a file name */
 154         param_len = 6;
 155         SSVAL(param, 0, level);
 156         SSVAL(param, 2, 0);
 157         SSVAL(param, 4, 0);
 158         param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
 159 
 160         status = try_trans2_len(cli, "fname", op, level, param, data, param_len, &data_len, 
 161                                 &rparam_len, &rdata_len);
 162         if (NT_STATUS_IS_OK(status)) return True;
 163 
 164         /* try with a new file name */
 165         param_len = 6;
 166         SSVAL(param, 0, level);
 167         SSVAL(param, 2, 0);
 168         SSVAL(param, 4, 0);
 169         param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
 170 
 171         status = try_trans2_len(cli, "newfile", op, level, param, data, param_len, &data_len, 
 172                                 &rparam_len, &rdata_len);
 173         cli_unlink(cli, "\\newfile.dat");
 174         cli_rmdir(cli, "\\newfile.dat");
 175         if (NT_STATUS_IS_OK(status)) return True;
 176 
 177         /* try dfs style  */
 178         cli_mkdir(cli, "\\testdir");
 179         param_len = 2;
 180         SSVAL(param, 0, level);
 181         param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
 182 
 183         status = try_trans2_len(cli, "dfs", op, level, param, data, param_len, &data_len, 
 184                                 &rparam_len, &rdata_len);
 185         cli_rmdir(cli, "\\testdir");
 186         if (NT_STATUS_IS_OK(status)) return True;
 187 
 188         return False;
 189 }
 190 
 191 
 192 bool torture_trans2_scan(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 193 {
 194         static struct cli_state *cli;
 195         int op, level;
 196         const char *fname = "\\scanner.dat";
 197         int fnum, dnum;
 198 
 199         printf("starting trans2 scan test\n");
 200 
 201         if (!torture_open_connection(&cli, 0)) {
 202                 return False;
 203         }
 204 
 205         fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, 
 206                          DENY_NONE);
 207         dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
 208 
 209         for (op=OP_MIN; op<=OP_MAX; op++) {
 210                 printf("Scanning op=%d\n", op);
 211                 for (level = 0; level <= 50; level++) {
 212                         scan_trans2(cli, op, level, fnum, dnum, fname);
 213                 }
 214 
 215                 for (level = 0x100; level <= 0x130; level++) {
 216                         scan_trans2(cli, op, level, fnum, dnum, fname);
 217                 }
 218 
 219                 for (level = 1000; level < 1050; level++) {
 220                         scan_trans2(cli, op, level, fnum, dnum, fname);
 221                 }
 222         }
 223 
 224         torture_close_connection(cli);
 225 
 226         printf("trans2 scan finished\n");
 227         return True;
 228 }
 229 
 230 
 231 
 232 
 233 /****************************************************************************
 234 look for a partial hit
 235 ****************************************************************************/
 236 static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
     /* [<][>][^][v][top][bottom][index][help] */
 237 {
 238         if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
 239             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
 240             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
 241             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
 242             NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
 243                 return;
 244         }
 245 #if VERBOSE
 246                 printf("possible %s hit op=%3d level=%5d status=%s\n",
 247                        format, op, level, nt_errstr(status));
 248 #endif
 249 }
 250 
 251 /****************************************************************************
 252 check for existance of a nttrans call
 253 ****************************************************************************/
 254 static NTSTATUS try_nttrans(struct cli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
 255                          int op,
 256                          char *param, char *data,
 257                          int param_len, int data_len,
 258                          unsigned int *rparam_len, unsigned int *rdata_len)
 259 {
 260         char *rparam=NULL, *rdata=NULL;
 261 
 262         if (!cli_send_nt_trans(cli, op, 
 263                                0,   
 264                                NULL, 0, 0,
 265                                param, param_len, 2,            /* param, length, max */
 266                                data, data_len, cli->max_xmit   /* data, length, max */
 267                            )) {
 268                 return cli_nt_error(cli);
 269         }
 270 
 271         cli_receive_nt_trans(cli,
 272                              &rparam, rparam_len,
 273                              &rdata, rdata_len);
 274 
 275         SAFE_FREE(rdata);
 276         SAFE_FREE(rparam);
 277 
 278         return cli_nt_error(cli);
 279 }
 280 
 281 
 282 static NTSTATUS try_nttrans_len(struct cli_state *cli, 
     /* [<][>][^][v][top][bottom][index][help] */
 283                              const char *format,
 284                              int op, int level,
 285                              char *param, char *data,
 286                              int param_len, int *data_len,
 287                              unsigned int *rparam_len, unsigned int *rdata_len)
 288 {
 289         NTSTATUS ret=NT_STATUS_OK;
 290 
 291         ret = try_nttrans(cli, op, param, data, param_len,
 292                          DATA_SIZE, rparam_len, rdata_len);
 293 #if VERBOSE 
 294         printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
 295 #endif
 296         if (!NT_STATUS_IS_OK(ret)) return ret;
 297 
 298         *data_len = 0;
 299         while (*data_len < DATA_SIZE) {
 300                 ret = try_nttrans(cli, op, param, data, param_len,
 301                                  *data_len, rparam_len, rdata_len);
 302                 if (NT_STATUS_IS_OK(ret)) break;
 303                 *data_len += 2;
 304         }
 305         if (NT_STATUS_IS_OK(ret)) {
 306                 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
 307                        format, level, *data_len, *rparam_len, *rdata_len);
 308         } else {
 309                 nttrans_check_hit(format, op, level, ret);
 310         }
 311         return ret;
 312 }
 313 
 314 /****************************************************************************
 315 check for existance of a nttrans call
 316 ****************************************************************************/
 317 static bool scan_nttrans(struct cli_state *cli, int op, int level, 
     /* [<][>][^][v][top][bottom][index][help] */
 318                         int fnum, int dnum, const char *fname)
 319 {
 320         int data_len = 0;
 321         int param_len = 0;
 322         unsigned int rparam_len, rdata_len;
 323         char param[PARAM_SIZE], data[DATA_SIZE];
 324         NTSTATUS status;
 325 
 326         memset(data, 0, sizeof(data));
 327         data_len = 4;
 328 
 329         /* try with a info level only */
 330         param_len = 2;
 331         SSVAL(param, 0, level);
 332         status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len, 
 333                             &rparam_len, &rdata_len);
 334         if (NT_STATUS_IS_OK(status)) return True;
 335 
 336         /* try with a file descriptor */
 337         param_len = 6;
 338         SSVAL(param, 0, fnum);
 339         SSVAL(param, 2, level);
 340         SSVAL(param, 4, 0);
 341         status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len, 
 342                                 &rparam_len, &rdata_len);
 343         if (NT_STATUS_IS_OK(status)) return True;
 344 
 345 
 346         /* try with a notify style */
 347         param_len = 6;
 348         SSVAL(param, 0, dnum);
 349         SSVAL(param, 2, dnum);
 350         SSVAL(param, 4, level);
 351         status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len, 
 352                                 &rparam_len, &rdata_len);
 353         if (NT_STATUS_IS_OK(status)) return True;
 354 
 355         /* try with a file name */
 356         param_len = 6;
 357         SSVAL(param, 0, level);
 358         SSVAL(param, 2, 0);
 359         SSVAL(param, 4, 0);
 360         param_len += clistr_push(cli, &param[6], fname, -1, STR_TERMINATE);
 361 
 362         status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len, 
 363                                 &rparam_len, &rdata_len);
 364         if (NT_STATUS_IS_OK(status)) return True;
 365 
 366         /* try with a new file name */
 367         param_len = 6;
 368         SSVAL(param, 0, level);
 369         SSVAL(param, 2, 0);
 370         SSVAL(param, 4, 0);
 371         param_len += clistr_push(cli, &param[6], "\\newfile.dat", -1, STR_TERMINATE);
 372 
 373         status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len, 
 374                                 &rparam_len, &rdata_len);
 375         cli_unlink(cli, "\\newfile.dat");
 376         cli_rmdir(cli, "\\newfile.dat");
 377         if (NT_STATUS_IS_OK(status)) return True;
 378 
 379         /* try dfs style  */
 380         cli_mkdir(cli, "\\testdir");
 381         param_len = 2;
 382         SSVAL(param, 0, level);
 383         param_len += clistr_push(cli, &param[2], "\\testdir", -1, STR_TERMINATE);
 384 
 385         status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len, 
 386                                 &rparam_len, &rdata_len);
 387         cli_rmdir(cli, "\\testdir");
 388         if (NT_STATUS_IS_OK(status)) return True;
 389 
 390         return False;
 391 }
 392 
 393 
 394 bool torture_nttrans_scan(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 395 {
 396         static struct cli_state *cli;
 397         int op, level;
 398         const char *fname = "\\scanner.dat";
 399         int fnum, dnum;
 400 
 401         printf("starting nttrans scan test\n");
 402 
 403         if (!torture_open_connection(&cli, 0)) {
 404                 return False;
 405         }
 406 
 407         fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, 
 408                          DENY_NONE);
 409         dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
 410 
 411         for (op=OP_MIN; op<=OP_MAX; op++) {
 412                 printf("Scanning op=%d\n", op);
 413                 for (level = 0; level <= 50; level++) {
 414                         scan_nttrans(cli, op, level, fnum, dnum, fname);
 415                 }
 416 
 417                 for (level = 0x100; level <= 0x130; level++) {
 418                         scan_nttrans(cli, op, level, fnum, dnum, fname);
 419                 }
 420 
 421                 for (level = 1000; level < 1050; level++) {
 422                         scan_nttrans(cli, op, level, fnum, dnum, fname);
 423                 }
 424         }
 425 
 426         torture_close_connection(cli);
 427 
 428         printf("nttrans scan finished\n");
 429         return True;
 430 }

/* [<][>][^][v][top][bottom][index][help] */