bool torture_utable(struct torture_context *tctx, struct smbcli_state *cli) { char fname[256]; const char *alt_name; int fnum; uint8_t c2[4]; int c, fd; size_t len; int chars_allowed=0, alt_allowed=0; uint8_t valid[0x10000]; torture_comment(tctx, "Generating valid character table\n"); memset(valid, 0, sizeof(valid)); torture_assert(tctx, torture_setup_dir(cli, "\\utable"), "Setting up dir \\utable failed"); for (c=1; c < 0x10000; c++) { char *p; SSVAL(c2, 0, c); strncpy(fname, "\\utable\\x", sizeof(fname)-1); p = fname+strlen(fname); convert_string_convenience(lp_iconv_convenience(tctx->lp_ctx), CH_UTF16, CH_UNIX, c2, 2, p, sizeof(fname)-strlen(fname), &len, false); p[len] = 0; strncat(fname,"_a_long_extension",sizeof(fname)-1); fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); if (fnum == -1) continue; chars_allowed++; smbcli_qpathinfo_alt_name(cli->tree, fname, &alt_name); if (strncmp(alt_name, "X_A_L", 5) != 0) { alt_allowed++; valid[c] = 1; torture_comment(tctx, "fname=[%s] alt_name=[%s]\n", fname, alt_name); } smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); if (c % 100 == 0) { if (torture_setting_bool(tctx, "progress", true)) { torture_comment(tctx, "%d (%d/%d)\r", c, chars_allowed, alt_allowed); fflush(stdout); } } } torture_comment(tctx, "%d (%d/%d)\n", c, chars_allowed, alt_allowed); smbcli_rmdir(cli->tree, "\\utable"); torture_comment(tctx, "%d chars allowed %d alt chars allowed\n", chars_allowed, alt_allowed); fd = open("valid.dat", O_WRONLY|O_CREAT|O_TRUNC, 0644); torture_assert(tctx, fd != -1, talloc_asprintf(tctx, "Failed to create valid.dat - %s", strerror(errno))); write(fd, valid, 0x10000); close(fd); torture_comment(tctx, "wrote valid.dat\n"); return true; }
static BOOL test_one(struct smbcli_state *cli, const char *name) { int fnum; const char *shortname; fstring name2; NTSTATUS status; TDB_DATA data; total++; fnum = smbcli_open(cli->tree, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum == -1) { printf("open of %s failed (%s)\n", name, smbcli_errstr(cli->tree)); return False; } if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) { printf("close of %s failed (%s)\n", name, smbcli_errstr(cli->tree)); return False; } /* get the short name */ status = smbcli_qpathinfo_alt_name(cli->tree, name, &shortname); if (!NT_STATUS_IS_OK(status)) { printf("query altname of %s failed (%s)\n", name, smbcli_errstr(cli->tree)); return False; } snprintf(name2, sizeof(name2), "\\mangle_test\\%s", shortname); if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, name2))) { printf("unlink of %s (%s) failed (%s)\n", name2, name, smbcli_errstr(cli->tree)); return False; } /* recreate by short name */ fnum = smbcli_open(cli->tree, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum == -1) { printf("open2 of %s failed (%s)\n", name2, smbcli_errstr(cli->tree)); return False; } if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) { printf("close of %s failed (%s)\n", name, smbcli_errstr(cli->tree)); return False; } /* and unlink by long name */ if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, name))) { printf("unlink2 of %s (%s) failed (%s)\n", name, name2, smbcli_errstr(cli->tree)); failures++; smbcli_unlink(cli->tree, name2); return True; } /* see if the short name is already in the tdb */ data = tdb_fetch_bystring(tdb, shortname); if (data.dptr) { /* maybe its a duplicate long name? */ if (strcasecmp(name, (const char *)data.dptr) != 0) { /* we have a collision */ collisions++; printf("Collision between %s and %s -> %s " " (coll/tot: %u/%u)\n", name, data.dptr, shortname, collisions, total); } free(data.dptr); } else { TDB_DATA namedata; /* store it for later */ namedata.dptr = discard_const_p(uint8_t, name); namedata.dsize = strlen(name)+1; tdb_store_bystring(tdb, shortname, namedata, TDB_REPLACE); } return True; }