00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 #define VERBOSE 0
00024 #define OP_MIN 0
00025 #define OP_MAX 20
00026
00027
00028
00029
00030 static void trans2_check_hit(const char *format, int op, int level, NTSTATUS status)
00031 {
00032 if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
00033 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
00034 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
00035 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
00036 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
00037 return;
00038 }
00039 #if VERBOSE
00040 printf("possible %s hit op=%3d level=%5d status=%s\n",
00041 format, op, level, nt_errstr(status));
00042 #endif
00043 }
00044
00045
00046
00047
00048 static NTSTATUS try_trans2(struct cli_state *cli,
00049 int op,
00050 char *param, char *data,
00051 int param_len, int data_len,
00052 unsigned int *rparam_len, unsigned int *rdata_len)
00053 {
00054 uint16 setup = op;
00055 char *rparam=NULL, *rdata=NULL;
00056
00057 if (!cli_send_trans(cli, SMBtrans2,
00058 NULL,
00059 -1, 0,
00060 &setup, 1, 0,
00061 param, param_len, 2,
00062 data, data_len, cli->max_xmit
00063 )) {
00064 return cli_nt_error(cli);
00065 }
00066
00067 cli_receive_trans(cli, SMBtrans2,
00068 &rparam, rparam_len,
00069 &rdata, rdata_len);
00070
00071 SAFE_FREE(rdata);
00072 SAFE_FREE(rparam);
00073
00074 return cli_nt_error(cli);
00075 }
00076
00077
00078 static NTSTATUS try_trans2_len(struct cli_state *cli,
00079 const char *format,
00080 int op, int level,
00081 char *param, char *data,
00082 int param_len, int *data_len,
00083 unsigned int *rparam_len, unsigned int *rdata_len)
00084 {
00085 NTSTATUS ret=NT_STATUS_OK;
00086
00087 ret = try_trans2(cli, op, param, data, param_len,
00088 sizeof(pstring), rparam_len, rdata_len);
00089 #if VERBOSE
00090 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
00091 #endif
00092 if (!NT_STATUS_IS_OK(ret)) return ret;
00093
00094 *data_len = 0;
00095 while (*data_len < sizeof(pstring)) {
00096 ret = try_trans2(cli, op, param, data, param_len,
00097 *data_len, rparam_len, rdata_len);
00098 if (NT_STATUS_IS_OK(ret)) break;
00099 *data_len += 2;
00100 }
00101 if (NT_STATUS_IS_OK(ret)) {
00102 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
00103 format, level, *data_len, *rparam_len, *rdata_len);
00104 } else {
00105 trans2_check_hit(format, op, level, ret);
00106 }
00107 return ret;
00108 }
00109
00110
00111
00112
00113 static BOOL scan_trans2(struct cli_state *cli, int op, int level,
00114 int fnum, int dnum, const char *fname)
00115 {
00116 int data_len = 0;
00117 int param_len = 0;
00118 unsigned int rparam_len, rdata_len;
00119 pstring param, data;
00120 NTSTATUS status;
00121
00122 memset(data, 0, sizeof(data));
00123 data_len = 4;
00124
00125
00126 param_len = 2;
00127 SSVAL(param, 0, level);
00128 status = try_trans2_len(cli, "void", op, level, param, data, param_len, &data_len,
00129 &rparam_len, &rdata_len);
00130 if (NT_STATUS_IS_OK(status)) return True;
00131
00132
00133 param_len = 6;
00134 SSVAL(param, 0, fnum);
00135 SSVAL(param, 2, level);
00136 SSVAL(param, 4, 0);
00137 status = try_trans2_len(cli, "fnum", op, level, param, data, param_len, &data_len,
00138 &rparam_len, &rdata_len);
00139 if (NT_STATUS_IS_OK(status)) return True;
00140
00141
00142
00143 param_len = 6;
00144 SSVAL(param, 0, dnum);
00145 SSVAL(param, 2, dnum);
00146 SSVAL(param, 4, level);
00147 status = try_trans2_len(cli, "notify", op, level, param, data, param_len, &data_len,
00148 &rparam_len, &rdata_len);
00149 if (NT_STATUS_IS_OK(status)) return True;
00150
00151
00152 param_len = 6;
00153 SSVAL(param, 0, level);
00154 SSVAL(param, 2, 0);
00155 SSVAL(param, 4, 0);
00156 param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
00157
00158 status = try_trans2_len(cli, "fname", op, level, param, data, param_len, &data_len,
00159 &rparam_len, &rdata_len);
00160 if (NT_STATUS_IS_OK(status)) return True;
00161
00162
00163 param_len = 6;
00164 SSVAL(param, 0, level);
00165 SSVAL(param, 2, 0);
00166 SSVAL(param, 4, 0);
00167 param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
00168
00169 status = try_trans2_len(cli, "newfile", op, level, param, data, param_len, &data_len,
00170 &rparam_len, &rdata_len);
00171 cli_unlink(cli, "\\newfile.dat");
00172 cli_rmdir(cli, "\\newfile.dat");
00173 if (NT_STATUS_IS_OK(status)) return True;
00174
00175
00176 cli_mkdir(cli, "\\testdir");
00177 param_len = 2;
00178 SSVAL(param, 0, level);
00179 param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
00180
00181 status = try_trans2_len(cli, "dfs", op, level, param, data, param_len, &data_len,
00182 &rparam_len, &rdata_len);
00183 cli_rmdir(cli, "\\testdir");
00184 if (NT_STATUS_IS_OK(status)) return True;
00185
00186 return False;
00187 }
00188
00189
00190 BOOL torture_trans2_scan(int dummy)
00191 {
00192 static struct cli_state *cli;
00193 int op, level;
00194 const char *fname = "\\scanner.dat";
00195 int fnum, dnum;
00196
00197 printf("starting trans2 scan test\n");
00198
00199 if (!torture_open_connection(&cli, 0)) {
00200 return False;
00201 }
00202
00203 fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
00204 DENY_NONE);
00205 dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
00206
00207 for (op=OP_MIN; op<=OP_MAX; op++) {
00208 printf("Scanning op=%d\n", op);
00209 for (level = 0; level <= 50; level++) {
00210 scan_trans2(cli, op, level, fnum, dnum, fname);
00211 }
00212
00213 for (level = 0x100; level <= 0x130; level++) {
00214 scan_trans2(cli, op, level, fnum, dnum, fname);
00215 }
00216
00217 for (level = 1000; level < 1050; level++) {
00218 scan_trans2(cli, op, level, fnum, dnum, fname);
00219 }
00220 }
00221
00222 torture_close_connection(cli);
00223
00224 printf("trans2 scan finished\n");
00225 return True;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234 static void nttrans_check_hit(const char *format, int op, int level, NTSTATUS status)
00235 {
00236 if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_LEVEL) ||
00237 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ||
00238 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED) ||
00239 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) ||
00240 NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INVALID_INFO_CLASS)) {
00241 return;
00242 }
00243 #if VERBOSE
00244 printf("possible %s hit op=%3d level=%5d status=%s\n",
00245 format, op, level, nt_errstr(status));
00246 #endif
00247 }
00248
00249
00250
00251
00252 static NTSTATUS try_nttrans(struct cli_state *cli,
00253 int op,
00254 char *param, char *data,
00255 int param_len, int data_len,
00256 unsigned int *rparam_len, unsigned int *rdata_len)
00257 {
00258 char *rparam=NULL, *rdata=NULL;
00259
00260 if (!cli_send_nt_trans(cli, op,
00261 0,
00262 NULL, 0, 0,
00263 param, param_len, 2,
00264 data, data_len, cli->max_xmit
00265 )) {
00266 return cli_nt_error(cli);
00267 }
00268
00269 cli_receive_nt_trans(cli,
00270 &rparam, rparam_len,
00271 &rdata, rdata_len);
00272
00273 SAFE_FREE(rdata);
00274 SAFE_FREE(rparam);
00275
00276 return cli_nt_error(cli);
00277 }
00278
00279
00280 static NTSTATUS try_nttrans_len(struct cli_state *cli,
00281 const char *format,
00282 int op, int level,
00283 char *param, char *data,
00284 int param_len, int *data_len,
00285 unsigned int *rparam_len, unsigned int *rdata_len)
00286 {
00287 NTSTATUS ret=NT_STATUS_OK;
00288
00289 ret = try_nttrans(cli, op, param, data, param_len,
00290 sizeof(pstring), rparam_len, rdata_len);
00291 #if VERBOSE
00292 printf("op=%d level=%d ret=%s\n", op, level, nt_errstr(ret));
00293 #endif
00294 if (!NT_STATUS_IS_OK(ret)) return ret;
00295
00296 *data_len = 0;
00297 while (*data_len < sizeof(pstring)) {
00298 ret = try_nttrans(cli, op, param, data, param_len,
00299 *data_len, rparam_len, rdata_len);
00300 if (NT_STATUS_IS_OK(ret)) break;
00301 *data_len += 2;
00302 }
00303 if (NT_STATUS_IS_OK(ret)) {
00304 printf("found %s level=%d data_len=%d rparam_len=%d rdata_len=%d\n",
00305 format, level, *data_len, *rparam_len, *rdata_len);
00306 } else {
00307 nttrans_check_hit(format, op, level, ret);
00308 }
00309 return ret;
00310 }
00311
00312
00313
00314
00315 static BOOL scan_nttrans(struct cli_state *cli, int op, int level,
00316 int fnum, int dnum, const char *fname)
00317 {
00318 int data_len = 0;
00319 int param_len = 0;
00320 unsigned int rparam_len, rdata_len;
00321 pstring param, data;
00322 NTSTATUS status;
00323
00324 memset(data, 0, sizeof(data));
00325 data_len = 4;
00326
00327
00328 param_len = 2;
00329 SSVAL(param, 0, level);
00330 status = try_nttrans_len(cli, "void", op, level, param, data, param_len, &data_len,
00331 &rparam_len, &rdata_len);
00332 if (NT_STATUS_IS_OK(status)) return True;
00333
00334
00335 param_len = 6;
00336 SSVAL(param, 0, fnum);
00337 SSVAL(param, 2, level);
00338 SSVAL(param, 4, 0);
00339 status = try_nttrans_len(cli, "fnum", op, level, param, data, param_len, &data_len,
00340 &rparam_len, &rdata_len);
00341 if (NT_STATUS_IS_OK(status)) return True;
00342
00343
00344
00345 param_len = 6;
00346 SSVAL(param, 0, dnum);
00347 SSVAL(param, 2, dnum);
00348 SSVAL(param, 4, level);
00349 status = try_nttrans_len(cli, "notify", op, level, param, data, param_len, &data_len,
00350 &rparam_len, &rdata_len);
00351 if (NT_STATUS_IS_OK(status)) return True;
00352
00353
00354 param_len = 6;
00355 SSVAL(param, 0, level);
00356 SSVAL(param, 2, 0);
00357 SSVAL(param, 4, 0);
00358 param_len += clistr_push(cli, ¶m[6], fname, -1, STR_TERMINATE);
00359
00360 status = try_nttrans_len(cli, "fname", op, level, param, data, param_len, &data_len,
00361 &rparam_len, &rdata_len);
00362 if (NT_STATUS_IS_OK(status)) return True;
00363
00364
00365 param_len = 6;
00366 SSVAL(param, 0, level);
00367 SSVAL(param, 2, 0);
00368 SSVAL(param, 4, 0);
00369 param_len += clistr_push(cli, ¶m[6], "\\newfile.dat", -1, STR_TERMINATE);
00370
00371 status = try_nttrans_len(cli, "newfile", op, level, param, data, param_len, &data_len,
00372 &rparam_len, &rdata_len);
00373 cli_unlink(cli, "\\newfile.dat");
00374 cli_rmdir(cli, "\\newfile.dat");
00375 if (NT_STATUS_IS_OK(status)) return True;
00376
00377
00378 cli_mkdir(cli, "\\testdir");
00379 param_len = 2;
00380 SSVAL(param, 0, level);
00381 param_len += clistr_push(cli, ¶m[2], "\\testdir", -1, STR_TERMINATE);
00382
00383 status = try_nttrans_len(cli, "dfs", op, level, param, data, param_len, &data_len,
00384 &rparam_len, &rdata_len);
00385 cli_rmdir(cli, "\\testdir");
00386 if (NT_STATUS_IS_OK(status)) return True;
00387
00388 return False;
00389 }
00390
00391
00392 BOOL torture_nttrans_scan(int dummy)
00393 {
00394 static struct cli_state *cli;
00395 int op, level;
00396 const char *fname = "\\scanner.dat";
00397 int fnum, dnum;
00398
00399 printf("starting nttrans scan test\n");
00400
00401 if (!torture_open_connection(&cli, 0)) {
00402 return False;
00403 }
00404
00405 fnum = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC,
00406 DENY_NONE);
00407 dnum = cli_open(cli, "\\", O_RDONLY, DENY_NONE);
00408
00409 for (op=OP_MIN; op<=OP_MAX; op++) {
00410 printf("Scanning op=%d\n", op);
00411 for (level = 0; level <= 50; level++) {
00412 scan_nttrans(cli, op, level, fnum, dnum, fname);
00413 }
00414
00415 for (level = 0x100; level <= 0x130; level++) {
00416 scan_nttrans(cli, op, level, fnum, dnum, fname);
00417 }
00418
00419 for (level = 1000; level < 1050; level++) {
00420 scan_nttrans(cli, op, level, fnum, dnum, fname);
00421 }
00422 }
00423
00424 torture_close_connection(cli);
00425
00426 printf("nttrans scan finished\n");
00427 return True;
00428 }