static bool test_one(struct cli_state *cli, const char *name) { uint16_t fnum; fstring shortname; fstring name2; NTSTATUS status; TDB_DATA data; total++; status = cli_openx(cli, name, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", name, nt_errstr(status)); return False; } status = cli_close(cli, fnum); if (!NT_STATUS_IS_OK(status)) { printf("close of %s failed (%s)\n", name, nt_errstr(status)); return False; } /* get the short name */ status = cli_qpathinfo_alt_name(cli, name, shortname); if (!NT_STATUS_IS_OK(status)) { printf("query altname of %s failed (%s)\n", name, nt_errstr(status)); return False; } fstr_sprintf(name2, "\\mangle_test\\%s", shortname); status = cli_unlink(cli, name2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); if (!NT_STATUS_IS_OK(status)) { printf("unlink of %s (%s) failed (%s)\n", name2, name, nt_errstr(status)); return False; } /* recreate by short name */ status = cli_openx(cli, name2, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum); if (!NT_STATUS_IS_OK(status)) { printf("open2 of %s failed (%s)\n", name2, nt_errstr(status)); return False; } status = cli_close(cli, fnum); if (!NT_STATUS_IS_OK(status)) { printf("close of %s failed (%s)\n", name, nt_errstr(status)); return False; } /* and unlink by long name */ status = cli_unlink(cli, name, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); if (!NT_STATUS_IS_OK(status)) { printf("unlink2 of %s (%s) failed (%s)\n", name, name2, nt_errstr(status)); failures++; cli_unlink(cli, name2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); 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 (!strequal(name, (const char *)data.dptr)) { /* 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; }
bool torture_utable(int dummy) { struct cli_state *cli; fstring fname, alt_name; uint16_t fnum; smb_ucs2_t c2; int c, len, fd; int chars_allowed=0, alt_allowed=0; uint8 valid[0x10000]; printf("starting utable\n"); if (!torture_open_connection(&cli, 0)) { return False; } memset(valid, 0, sizeof(valid)); cli_mkdir(cli, "\\utable"); cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); for (c=1; c < 0x10000; c++) { size_t size = 0; char *p; SSVAL(&c2, 0, c); fstrcpy(fname, "\\utable\\x"); p = fname+strlen(fname); if (!convert_string(CH_UTF16LE, CH_UNIX, &c2, 2, p, sizeof(fname)-strlen(fname),&size)) { d_printf("convert_string %s failed !\n", fname); continue; } len = size; p[len] = 0; fstrcat(fname,"_a_long_extension"); if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) { continue; } chars_allowed++; cli_qpathinfo_alt_name(cli, fname, alt_name); if (strncmp(alt_name, "X_A_L", 5) != 0) { alt_allowed++; valid[c] = 1; d_printf("fname=[%s] alt_name=[%s]\n", fname, alt_name); } cli_close(cli, fnum); cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); if (c % 100 == 0) { printf("%d (%d/%d)\r", c, chars_allowed, alt_allowed); } } printf("%d (%d/%d)\n", c, chars_allowed, alt_allowed); cli_rmdir(cli, "\\utable"); d_printf("%d chars allowed %d alt chars allowed\n", chars_allowed, alt_allowed); fd = open("valid.dat", O_WRONLY|O_CREAT|O_TRUNC, 0644); if (fd == -1) { d_printf("Failed to create valid.dat - %s", strerror(errno)); return False; } if (write(fd, valid, 0x10000) != 0x10000) { d_printf("Failed to create valid.dat - %s", strerror(errno)); close(fd); return false; } close(fd); d_printf("wrote valid.dat\n"); return True; }