NTSTATUS cli_get_quota_handle(struct cli_state *cli, uint16_t *quota_fnum) { return cli_ntcreate(cli, FAKE_FILE_NAME_QUOTA_WIN32, 0x00000016, DESIRED_ACCESS_PIPE, 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x00000000, 0x03, quota_fnum); }
bool run_cleanup1(int dummy) { struct cli_state *cli; const char *fname = "\\cleanup1"; uint16_t fnum; NTSTATUS status; printf("CLEANUP1: Checking that a conflicting share mode is cleaned " "up\n"); if (!torture_open_connection(&cli, 0)) { return false; } status = cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_ALL, &fnum); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } status = smbXcli_conn_samba_suicide(cli->conn, 1); if (!NT_STATUS_IS_OK(status)) { printf("smbXcli_conn_samba_suicide failed: %s\n", nt_errstr(status)); return false; } if (!torture_open_connection(&cli, 1)) { return false; } status = cli_ntcreate( cli, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, FILE_DELETE_ON_CLOSE, 0, &fnum, NULL); if (!NT_STATUS_IS_OK(status)) { printf("2nd open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } cli_close(cli, fnum); torture_close_connection(cli); return NT_STATUS_IS_OK(status); }
void nb_createx(const char *fname, unsigned create_options, unsigned create_disposition, int handle) { uint16_t fd = (uint16_t)-1; int i; NTSTATUS status; uint32 desired_access; if (create_options & FILE_DIRECTORY_FILE) { desired_access = FILE_READ_DATA; } else { desired_access = FILE_READ_DATA | FILE_WRITE_DATA; } status = cli_ntcreate(c, fname, 0, desired_access, 0x0, FILE_SHARE_READ|FILE_SHARE_WRITE, create_disposition, create_options, 0, &fd, NULL); if (!NT_STATUS_IS_OK(status) && handle != -1) { printf("ERROR: cli_ntcreate failed for %s - %s\n", fname, nt_errstr(status)); exit(1); } if (NT_STATUS_IS_OK(status) && handle == -1) { printf("ERROR: cli_ntcreate succeeded for %s\n", fname); exit(1); } if (fd == (uint16_t)-1) return; for (i=0;i<MAX_FILES;i++) { if (ftable[i].handle == 0) break; } if (i == MAX_FILES) { printf("(%d) file table full for %s\n", line_count, fname); exit(1); } ftable[i].handle = handle; ftable[i].fd = fd; }
bool run_posix_append(int dummy) { struct cli_state *cli; const char *fname = "append"; NTSTATUS status; uint16_t fnum; SMB_OFF_T size; uint8_t c = '\0'; bool ret = false; printf("Starting POSIX_APPEND\n"); if (!torture_open_connection(&cli, 0)) { return false; } status = torture_setup_unix_extensions(cli); if (!NT_STATUS_IS_OK(status)) { printf("torture_setup_unix_extensions failed: %s\n", nt_errstr(status)); goto fail; } status = cli_ntcreate( cli, fname, 0, GENERIC_WRITE_ACCESS|GENERIC_READ_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_POSIX_SEMANTICS, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE|FILE_DELETE_ON_CLOSE, 0, &fnum); if (!NT_STATUS_IS_OK(status)) { printf("cli_ntcreate failed: %s\n", nt_errstr(status)); goto fail; } /* * Write two bytes at offset 0. With bug 6898 we would end up * with a file of 2 byte length. */ status = cli_writeall(cli, fnum, 0, &c, 0, sizeof(c), NULL); if (!NT_STATUS_IS_OK(status)) { printf("cli_write failed: %s\n", nt_errstr(status)); goto fail; } status = cli_writeall(cli, fnum, 0, &c, 0, sizeof(c), NULL); if (!NT_STATUS_IS_OK(status)) { printf("cli_write failed: %s\n", nt_errstr(status)); goto fail; } status = cli_getattrE(cli, fnum, NULL, &size, NULL, NULL, NULL); if (!NT_STATUS_IS_OK(status)) { printf("cli_getatrE failed: %s\n", nt_errstr(status)); goto fail; } if (size != sizeof(c)) { printf("BUG: Writing with O_APPEND!!\n"); goto fail; } ret = true; fail: torture_close_connection(cli); return ret; }
bool torture_casetable(int dummy) { static struct cli_state *cli; char *fname; uint16_t fnum; int c, i; #define MAX_EQUIVALENCE 8 smb_ucs2_t equiv[0x10000][MAX_EQUIVALENCE]; printf("starting casetable\n"); if (!torture_open_connection(&cli, 0)) { return False; } memset(equiv, 0, sizeof(equiv)); cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); cli_rmdir(cli, "\\utable"); if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\utable"))) { printf("Failed to create utable directory!\n"); return False; } for (c=1; c < 0x10000; c++) { SMB_OFF_T size; if (c == '.' || c == '\\') continue; printf("%04x (%c)\n", c, isprint(c)?c:'.'); fname = form_name(c); if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum))) { printf("Failed to create file with char %04x\n", c); continue; } size = 0; if (!NT_STATUS_IS_OK(cli_qfileinfo_basic( cli, fnum, NULL, &size, NULL, NULL, NULL, NULL, NULL))) { continue; } if (size > 0) { /* found a character equivalence! */ int c2[MAX_EQUIVALENCE]; if (size/sizeof(int) >= MAX_EQUIVALENCE) { printf("too many chars match?? size=%ld c=0x%04x\n", (unsigned long)size, c); cli_close(cli, fnum); return False; } cli_read(cli, fnum, (char *)c2, 0, size); printf("%04x: ", c); equiv[c][0] = c; for (i=0; i<size/sizeof(int); i++) { printf("%04x ", c2[i]); equiv[c][i+1] = c2[i]; } printf("\n"); fflush(stdout); } cli_writeall(cli, fnum, 0, (uint8_t *)&c, size, sizeof(c), NULL); cli_close(cli, fnum); } cli_unlink(cli, "\\utable\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); cli_rmdir(cli, "\\utable"); return True; }
bool run_cleanup2(int dummy) { struct cli_state *cli1, *cli2, *cli3; const char *fname = "\\cleanup2"; uint16_t fnum1, fnum2, fnum3; NTSTATUS status; char buf; printf("CLEANUP2: Checking that a conflicting brlock is cleaned up\n"); if (!torture_open_connection(&cli1, 0)) { return false; } status = cli_ntcreate( cli1, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } status = cli_lock32(cli1, fnum1, 0, 1, 0, WRITE_LOCK); if (!NT_STATUS_IS_OK(status)) { printf("lock failed (%s)\n", nt_errstr(status)); return false; } if (!torture_open_connection(&cli3, 1)) { return false; } status = cli_ntcreate( cli3, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum3, NULL); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } status = cli_lock32(cli3, fnum3, 1, 1, 0, WRITE_LOCK); if (!NT_STATUS_IS_OK(status)) { printf("lock failed (%s)\n", nt_errstr(status)); return false; } status = cli_lock32(cli1, fnum1, 2, 1, 0, WRITE_LOCK); if (!NT_STATUS_IS_OK(status)) { printf("lock failed (%s)\n", nt_errstr(status)); return false; } /* * Check the file is indeed locked */ if (!torture_open_connection(&cli2, 1)) { return false; } status = cli_ntcreate( cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2, NULL); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } buf = 'x'; status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL); if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { printf("write succeeded\n"); return false; } /* * Kill the lock holder */ status = smbXcli_conn_samba_suicide(cli1->conn, 1); if (!NT_STATUS_IS_OK(status)) { printf("smbXcli_conn_samba_suicide failed: %s\n", nt_errstr(status)); return false; } /* * Give the suicidal smbd a bit of time to really pass away */ smb_msleep(1000); status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL); if (!NT_STATUS_IS_OK(status)) { printf("write failed: %s\n", nt_errstr(status)); return false; } return true; }
bool run_cleanup4(int dummy) { struct cli_state *cli1, *cli2; const char *fname = "\\cleanup4"; uint16_t fnum1, fnum2; NTSTATUS status; printf("CLEANUP4: Checking that a conflicting share mode is cleaned " "up\n"); if (!torture_open_connection(&cli1, 0)) { return false; } if (!torture_open_connection(&cli2, 0)) { return false; } status = cli_ntcreate( cli1, fname, 0, FILE_GENERIC_READ|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL); if (!NT_STATUS_IS_OK(status)) { printf("creating file failed: %s\n", nt_errstr(status)); return false; } status = cli_ntcreate( cli2, fname, 0, FILE_GENERIC_READ|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2, NULL); if (!NT_STATUS_IS_OK(status)) { printf("opening file 1st time failed: %s\n", nt_errstr(status)); return false; } status = smbXcli_conn_samba_suicide(cli1->conn, 1); if (!NT_STATUS_IS_OK(status)) { printf("smbXcli_conn_samba_suicide failed: %s\n", nt_errstr(status)); return false; } /* * The next open will conflict with both opens above. The first open * above will be correctly cleaned up. A bug in smbd iterating over * the share mode array made it skip the share conflict check for the * second open. Trigger this bug. */ status = cli_ntcreate( cli2, fname, 0, FILE_GENERIC_WRITE|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2, NULL); if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { printf("opening file 2nd time returned: %s\n", nt_errstr(status)); return false; } return true; }