root/source4/torture/basic/aliases.c

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

DEFINITIONS

This source file includes following definitions.
  1. gen_aliases
  2. qfsinfo_aliases
  3. qfileinfo_aliases
  4. qpathinfo_aliases
  5. findfirst_aliases
  6. gen_set_aliases
  7. setfileinfo_aliases
  8. setpathinfo_aliases
  9. torture_trans2_aliases

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    SMB trans2 alias scanner
   4    Copyright (C) Andrew Tridgell 2003
   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 "../lib/util/dlinklist.h"
  22 #include "libcli/raw/libcliraw.h"
  23 #include "libcli/raw/raw_proto.h"
  24 #include "torture/torture.h"
  25 #include "libcli/libcli.h"
  26 #include "torture/util.h"
  27 
  28 int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *fname);
  29 
  30 struct trans2_blobs {
  31         struct trans2_blobs *next, *prev;
  32         uint16_t level;
  33         DATA_BLOB params, data;
  34 };
  35 
  36 /* look for aliases for a query */
  37 static bool gen_aliases(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
  38                                                 struct smbcli_state *cli, struct smb_trans2 *t2, 
  39                                                 int level_offset)
  40 {
  41         uint16_t level;
  42         struct trans2_blobs *alias_blobs = NULL;
  43         struct trans2_blobs *t2b, *t2b2;
  44         int count=0, alias_count=0;
  45 
  46         for (level=0;level<2000;level++) {
  47                 NTSTATUS status;
  48 
  49                 SSVAL(t2->in.params.data, level_offset, level);
  50                 
  51                 status = smb_raw_trans2(cli->tree, tctx, t2);
  52                 if (!NT_STATUS_IS_OK(status)) continue;
  53 
  54                 t2b = talloc(tctx, struct trans2_blobs);
  55                 t2b->level = level;
  56                 t2b->params = t2->out.params;
  57                 t2b->data = t2->out.data;
  58                 DLIST_ADD(alias_blobs, t2b);
  59                 torture_comment(tctx, 
  60                                                 "\tFound level %4u (0x%03x) of size %3d (0x%02x)\n", 
  61                          level, level,
  62                          (int)t2b->data.length, (int)t2b->data.length);
  63                 count++;
  64         }
  65 
  66         torture_comment(tctx, "Found %d levels with success status\n", count);
  67 
  68         for (t2b=alias_blobs; t2b; t2b=t2b->next) {
  69                 for (t2b2=alias_blobs; t2b2; t2b2=t2b2->next) {
  70                         if (t2b->level >= t2b2->level) continue;
  71                         if (data_blob_cmp(&t2b->params, &t2b2->params) == 0 &&
  72                             data_blob_cmp(&t2b->data, &t2b2->data) == 0) {
  73                                 torture_comment(tctx, 
  74                                 "\tLevel %u (0x%x) and level %u (0x%x) are possible aliases\n", 
  75                                        t2b->level, t2b->level, t2b2->level, t2b2->level);
  76                                 alias_count++;
  77                         }
  78                 }
  79         }
  80 
  81         torture_comment(tctx, "Found %d aliased levels\n", alias_count);
  82 
  83         return true;
  84 }
  85 
  86 /* look for qfsinfo aliases */
  87 static bool qfsinfo_aliases(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
  88 {
  89         struct smb_trans2 t2;
  90         uint16_t setup = TRANSACT2_QFSINFO;
  91 
  92         t2.in.max_param = 0;
  93         t2.in.max_data = UINT16_MAX;
  94         t2.in.max_setup = 0;
  95         t2.in.flags = 0;
  96         t2.in.timeout = 0;
  97         t2.in.setup_count = 1;
  98         t2.in.setup = &setup;
  99         t2.in.params = data_blob_talloc_zero(tctx, 2);
 100         t2.in.data = data_blob(NULL, 0);
 101         ZERO_STRUCT(t2.out);
 102 
 103         return gen_aliases(tctx, cli, &t2, 0);
 104 }
 105 
 106 /* look for qfileinfo aliases */
 107 static bool qfileinfo_aliases(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 108 {
 109         struct smb_trans2 t2;
 110         uint16_t setup = TRANSACT2_QFILEINFO;
 111         const char *fname = "\\qfileinfo_aliases.txt";
 112         int fnum;
 113 
 114         t2.in.max_param = 2;
 115         t2.in.max_data = UINT16_MAX;
 116         t2.in.max_setup = 0;
 117         t2.in.flags = 0;
 118         t2.in.timeout = 0;
 119         t2.in.setup_count = 1;
 120         t2.in.setup = &setup;
 121         t2.in.params = data_blob_talloc_zero(tctx, 4);
 122         t2.in.data = data_blob(NULL, 0);
 123         ZERO_STRUCT(t2.out);
 124 
 125         smbcli_unlink(cli->tree, fname);
 126         fnum = create_complex_file(cli, cli, fname);
 127         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, 
 128                                         "open of %s failed (%s)", fname, 
 129                                    smbcli_errstr(cli->tree)));
 130 
 131         smbcli_write(cli->tree, fnum, 0, &t2, 0, sizeof(t2));
 132 
 133         SSVAL(t2.in.params.data, 0, fnum);
 134 
 135         if (!gen_aliases(tctx, cli, &t2, 2))
 136                 return false;
 137 
 138         smbcli_close(cli->tree, fnum);
 139         smbcli_unlink(cli->tree, fname);
 140 
 141         return true;
 142 }
 143 
 144 
 145 /* look for qpathinfo aliases */
 146 static bool qpathinfo_aliases(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 147 {
 148         struct smb_trans2 t2;
 149         uint16_t setup = TRANSACT2_QPATHINFO;
 150         const char *fname = "\\qpathinfo_aliases.txt";
 151         int fnum;
 152 
 153         t2.in.max_param = 2;
 154         t2.in.max_data = UINT16_MAX;
 155         t2.in.max_setup = 0;
 156         t2.in.flags = 0;
 157         t2.in.timeout = 0;
 158         t2.in.setup_count = 1;
 159         t2.in.setup = &setup;
 160         t2.in.params = data_blob_talloc_zero(tctx, 6);
 161         t2.in.data = data_blob(NULL, 0);
 162         ZERO_STRUCT(t2.out);
 163 
 164         smbcli_unlink(cli->tree, fname);
 165         fnum = create_complex_file(cli, cli, fname);
 166         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, 
 167                                         "open of %s failed (%s)", fname, 
 168                                    smbcli_errstr(cli->tree)));
 169 
 170         smbcli_write(cli->tree, fnum, 0, &t2, 0, sizeof(t2));
 171         smbcli_close(cli->tree, fnum);
 172 
 173         SIVAL(t2.in.params.data, 2, 0);
 174 
 175         smbcli_blob_append_string(cli->session, tctx, &t2.in.params, 
 176                                fname, STR_TERMINATE);
 177 
 178         if (!gen_aliases(tctx, cli, &t2, 0))
 179                 return false;
 180 
 181         smbcli_unlink(cli->tree, fname);
 182 
 183         return true;
 184 }
 185 
 186 
 187 /* look for trans2 findfirst aliases */
 188 static bool findfirst_aliases(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 189 {
 190         struct smb_trans2 t2;
 191         uint16_t setup = TRANSACT2_FINDFIRST;
 192         const char *fname = "\\findfirst_aliases.txt";
 193         int fnum;
 194 
 195         t2.in.max_param = 16;
 196         t2.in.max_data = UINT16_MAX;
 197         t2.in.max_setup = 0;
 198         t2.in.flags = 0;
 199         t2.in.timeout = 0;
 200         t2.in.setup_count = 1;
 201         t2.in.setup = &setup;
 202         t2.in.params = data_blob_talloc_zero(tctx, 12);
 203         t2.in.data = data_blob(NULL, 0);
 204         ZERO_STRUCT(t2.out);
 205 
 206         smbcli_unlink(cli->tree, fname);
 207         fnum = create_complex_file(cli, cli, fname);
 208         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, 
 209                                         "open of %s failed (%s)", fname, 
 210                                    smbcli_errstr(cli->tree)));
 211 
 212         smbcli_write(cli->tree, fnum, 0, &t2, 0, sizeof(t2));
 213         smbcli_close(cli->tree, fnum);
 214 
 215         SSVAL(t2.in.params.data, 0, 0);
 216         SSVAL(t2.in.params.data, 2, 1);
 217         SSVAL(t2.in.params.data, 4, FLAG_TRANS2_FIND_CLOSE);
 218         SSVAL(t2.in.params.data, 6, 0);
 219         SIVAL(t2.in.params.data, 8, 0);
 220 
 221         smbcli_blob_append_string(cli->session, tctx, &t2.in.params, 
 222                                fname, STR_TERMINATE);
 223 
 224         if (!gen_aliases(tctx, cli, &t2, 6))
 225                 return false;
 226 
 227         smbcli_unlink(cli->tree, fname);
 228 
 229         return true;
 230 }
 231 
 232 
 233 
 234 /* look for aliases for a set function */
 235 static bool gen_set_aliases(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 236                                                         struct smbcli_state *cli, 
 237                                                         struct smb_trans2 *t2, int level_offset)
 238 {
 239         uint16_t level;
 240         struct trans2_blobs *alias_blobs = NULL;
 241         struct trans2_blobs *t2b;
 242         int count=0, dsize;
 243 
 244         for (level=1;level<1100;level++) {
 245                 NTSTATUS status, status1;
 246                 SSVAL(t2->in.params.data, level_offset, level);
 247 
 248                 status1 = NT_STATUS_OK;
 249 
 250                 for (dsize=2; dsize<1024; dsize += 2) {
 251                         data_blob_free(&t2->in.data);
 252                         t2->in.data = data_blob(NULL, dsize);
 253                         data_blob_clear(&t2->in.data);
 254                         status = smb_raw_trans2(cli->tree, tctx, t2);
 255                         /* some error codes mean that this whole level doesn't exist */
 256                         if (NT_STATUS_EQUAL(NT_STATUS_INVALID_LEVEL, status) ||
 257                             NT_STATUS_EQUAL(NT_STATUS_INVALID_INFO_CLASS, status) ||
 258                             NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED, status)) {
 259                                 break;
 260                         }
 261                         if (NT_STATUS_IS_OK(status)) break;
 262 
 263                         /* invalid parameter means that the level exists at this 
 264                            size, but the contents are wrong (not surprising with
 265                            all zeros!) */
 266                         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) break;
 267 
 268                         /* this is the usual code for 'wrong size' */
 269                         if (NT_STATUS_EQUAL(status, NT_STATUS_INFO_LENGTH_MISMATCH)) {
 270                                 continue;
 271                         }
 272 
 273                         if (!NT_STATUS_EQUAL(status, status1)) {
 274                                 torture_comment(tctx, "level=%d size=%d %s\n", level, dsize, nt_errstr(status));
 275                         }
 276                         status1 = status;
 277                 }
 278 
 279                 if (!NT_STATUS_IS_OK(status) &&
 280                     !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) continue;
 281 
 282                 t2b = talloc(tctx, struct trans2_blobs);
 283                 t2b->level = level;
 284                 t2b->params = t2->out.params;
 285                 t2b->data = t2->out.data;
 286                 DLIST_ADD(alias_blobs, t2b);
 287                 torture_comment(tctx, 
 288                                         "\tFound level %4u (0x%03x) of size %3d (0x%02x)\n", 
 289                          level, level,
 290                          (int)t2->in.data.length, (int)t2->in.data.length);
 291                 count++;
 292         }
 293 
 294         torture_comment(tctx, "Found %d valid levels\n", count);
 295 
 296         return true;
 297 }
 298 
 299 
 300 
 301 /* look for setfileinfo aliases */
 302 static bool setfileinfo_aliases(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 303 {
 304         struct smb_trans2 t2;
 305         uint16_t setup = TRANSACT2_SETFILEINFO;
 306         const char *fname = "\\setfileinfo_aliases.txt";
 307         int fnum;
 308 
 309         t2.in.max_param = 2;
 310         t2.in.max_data = 0;
 311         t2.in.max_setup = 0;
 312         t2.in.flags = 0;
 313         t2.in.timeout = 0;
 314         t2.in.setup_count = 1;
 315         t2.in.setup = &setup;
 316         t2.in.params = data_blob_talloc_zero(tctx, 6);
 317         t2.in.data = data_blob(NULL, 0);
 318         ZERO_STRUCT(t2.out);
 319 
 320         smbcli_unlink(cli->tree, fname);
 321         fnum = create_complex_file(cli, cli, fname);
 322         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, 
 323                                    "open of %s failed (%s)", fname, 
 324                                    smbcli_errstr(cli->tree)));
 325 
 326         smbcli_write(cli->tree, fnum, 0, &t2, 0, sizeof(t2));
 327 
 328         SSVAL(t2.in.params.data, 0, fnum);
 329         SSVAL(t2.in.params.data, 4, 0);
 330 
 331         gen_set_aliases(tctx, cli, &t2, 2);
 332 
 333         smbcli_close(cli->tree, fnum);
 334         smbcli_unlink(cli->tree, fname);
 335 
 336         return true;
 337 }
 338 
 339 /* look for setpathinfo aliases */
 340 static bool setpathinfo_aliases(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 341                                                                 struct smbcli_state *cli)
 342 {
 343         struct smb_trans2 t2;
 344         uint16_t setup = TRANSACT2_SETPATHINFO;
 345         const char *fname = "\\setpathinfo_aliases.txt";
 346         int fnum;
 347 
 348         t2.in.max_param = 32;
 349         t2.in.max_data = UINT16_MAX;
 350         t2.in.max_setup = 0;
 351         t2.in.flags = 0;
 352         t2.in.timeout = 0;
 353         t2.in.setup_count = 1;
 354         t2.in.setup = &setup;
 355         t2.in.params = data_blob_talloc_zero(tctx, 4);
 356         t2.in.data = data_blob(NULL, 0);
 357         ZERO_STRUCT(t2.out);
 358 
 359         smbcli_unlink(cli->tree, fname);
 360 
 361         fnum = create_complex_file(cli, cli, fname);
 362         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, 
 363                                         "open of %s failed (%s)", fname, 
 364                                    smbcli_errstr(cli->tree)));
 365 
 366         smbcli_write(cli->tree, fnum, 0, &t2, 0, sizeof(t2));
 367         smbcli_close(cli->tree, fnum);
 368 
 369         SSVAL(t2.in.params.data, 2, 0);
 370 
 371         smbcli_blob_append_string(cli->session, tctx, &t2.in.params, 
 372                                fname, STR_TERMINATE);
 373 
 374         if (!gen_set_aliases(tctx, cli, &t2, 0))
 375                 return false;
 376 
 377         torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli->tree, fname),
 378                 talloc_asprintf(tctx, "unlink: %s", smbcli_errstr(cli->tree)));
 379 
 380         return true;
 381 }
 382 
 383 
 384 /* look for aliased info levels in trans2 calls */
 385 struct torture_suite *torture_trans2_aliases(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 386 {
 387         struct torture_suite *suite = torture_suite_create(mem_ctx, "ALIASES");
 388 
 389         torture_suite_add_1smb_test(suite, "QFILEINFO aliases", qfsinfo_aliases);
 390         torture_suite_add_1smb_test(suite, "QFSINFO aliases", qfileinfo_aliases);
 391         torture_suite_add_1smb_test(suite, "QPATHINFO aliases", qpathinfo_aliases);
 392         torture_suite_add_1smb_test(suite, "FINDFIRST aliases", findfirst_aliases);
 393         torture_suite_add_1smb_test(suite, "setfileinfo_aliases", setfileinfo_aliases);
 394         torture_suite_add_1smb_test(suite, "setpathinfo_aliases", setpathinfo_aliases);
 395 
 396         return suite;
 397 }

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