Exemple #1
0
static bool print_printjob(struct torture_context *tctx,
			   struct smbcli_tree *tree)
{
	int fnum;
	DATA_BLOB data;
	ssize_t size_written;
	const char *str;

	torture_comment(tctx, "creating printjob %s\n", TORTURE_PRINT_FILE);

	fnum = smbcli_open(tree, TORTURE_PRINT_FILE, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
	if (fnum == -1) {
		torture_fail(tctx, "failed to open file");
	}

	str = talloc_asprintf(tctx, "TortureTestPage: %d\nData\n",0);

	data = data_blob_string_const(str);

	size_written = smbcli_write(tree, fnum, 0, data.data, 0, data.length);
	if (size_written != data.length) {
		torture_fail(tctx, "failed to write file");
	}

	torture_assert_ntstatus_ok(tctx,
		smbcli_close(tree, fnum),
		"failed to close file");

	return true;
}
Exemple #2
0
static int				/* O - 0 = success, non-0 = failure */
smb_print(struct smbcli_state *cli,	/* I - SMB connection */
          char             *title,	/* I - Title/job name */
          FILE             *fp)		/* I - File to print */
{
  int	fnum;		/* File number */
  int	nbytes,		/* Number of bytes read */
	tbytes;		/* Total bytes read */
  char	buffer[8192],	/* Buffer for copy */
	*ptr;		/* Pointer into tile */


 /*
  * Sanitize the title...
  */

  for (ptr = title; *ptr; ptr ++)
    if (!isalnum((int)*ptr) && !isspace((int)*ptr))
      *ptr = '_';

 /*
  * Open the printer device...
  */

  if ((fnum = smbcli_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1)
  {
    fprintf(stderr, "ERROR: %s opening remote file %s\n",
            smbcli_errstr(cli), title);
    return (1);
  }

 /*
  * Copy the file to the printer...
  */

  if (fp != stdin)
    rewind(fp);

  tbytes = 0;

  while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
  {
    if (smbcli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes)
    {
      fprintf(stderr, "ERROR: Error writing file: %s\n", smbcli_errstr(cli));
      break;
    }

    tbytes += nbytes;
  } 

  if (!smbcli_close(cli, fnum))
  {
    fprintf(stderr, "ERROR: %s closing remote file %s\n",
            smbcli_errstr(cli), title);
    return (1);
  }
  else
    return (0);
}
Exemple #3
0
/**
  sometimes we need a fairly complex file to work with, so we can test
  all possible attributes. 
*/
_PUBLIC_ int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *fname)
{
	int fnum;
	char buf[7] = "abc";
	union smb_setfileinfo setfile;
	union smb_fileinfo fileinfo;
	time_t t = (time(NULL) & ~1);
	NTSTATUS status;

	smbcli_unlink(cli->tree, fname);
	fnum = smbcli_nt_create_full(cli->tree, fname, 0, 
				     SEC_RIGHTS_FILE_ALL,
				     FILE_ATTRIBUTE_NORMAL,
				     NTCREATEX_SHARE_ACCESS_DELETE|
				     NTCREATEX_SHARE_ACCESS_READ|
				     NTCREATEX_SHARE_ACCESS_WRITE, 
				     NTCREATEX_DISP_OVERWRITE_IF,
				     0, 0);
	if (fnum == -1) return -1;

	smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));

	if (strchr(fname, ':') == NULL) {
		/* setup some EAs */
		setfile.generic.level = RAW_SFILEINFO_EA_SET;
		setfile.generic.in.file.fnum = fnum;
		setfile.ea_set.in.num_eas = 2;	
		setfile.ea_set.in.eas = talloc_array(mem_ctx, struct ea_struct, 2);
		setfile.ea_set.in.eas[0].flags = 0;
		setfile.ea_set.in.eas[0].name.s = "EAONE";
		setfile.ea_set.in.eas[0].value = data_blob_talloc(mem_ctx, "VALUE1", 6);
		setfile.ea_set.in.eas[1].flags = 0;
		setfile.ea_set.in.eas[1].name.s = "SECONDEA";
		setfile.ea_set.in.eas[1].value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
		status = smb_raw_setfileinfo(cli->tree, &setfile);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to setup EAs\n");
		}
	}
Exemple #4
0
/*
  test seek ops
*/
static BOOL test_seek(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_seek io;
	union smb_fileinfo finfo;
	union smb_setfileinfo sfinfo;
	NTSTATUS status;
	BOOL ret = True;
	int fnum, fnum2;
	const char *fname = BASEDIR "\\test.txt";
	uint8_t c[2];

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
	if (fnum == -1) {
		printf("Failed to open test.txt - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	
	printf("Trying bad handle\n");
	io.lseek.in.file.fnum = fnum+1;
	io.lseek.in.mode = SEEK_MODE_START;
	io.lseek.in.offset = 0;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("Trying simple seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_START;
	io.lseek.in.offset = 17;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 17);
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);
	
	printf("Trying relative seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_CURRENT;
	io.lseek.in.offset = -3;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 14);

	printf("Trying end seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_END;
	io.lseek.in.offset = 0;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	finfo.generic.level = RAW_FILEINFO_ALL_INFO;
	finfo.all_info.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, finfo.all_info.out.size);

	printf("Trying max seek\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_START;
	io.lseek.in.offset = -1;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 0xffffffff);

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);

	printf("Trying max overflow\n");
	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_CURRENT;
	io.lseek.in.offset = 1000;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 999);

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);

	printf("trying write to update offset\n");
	ZERO_STRUCT(c);
	if (smbcli_write(cli->tree, fnum, 0, c, 0, 2) != 2) {
		printf("Write failed - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;		
	}

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);

	io.lseek.in.file.fnum = fnum;
	io.lseek.in.mode = SEEK_MODE_CURRENT;
	io.lseek.in.offset = 0;
	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 2);
	
	if (smbcli_read(cli->tree, fnum, c, 0, 1) != 1) {
		printf("Read failed - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;		
	}

	printf("Testing position information change\n");
	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 1);

	status = smb_raw_seek(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.lseek.out.offset, 1);

	printf("Testing position information\n");
	fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
	if (fnum2 == -1) {
		printf("2nd open failed - %s\n", smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}
	sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
	sfinfo.position_information.in.file.fnum = fnum2;
	sfinfo.position_information.in.position = 25;
	status = smb_raw_setfileinfo(cli->tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum2;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 25);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 1);

	printf("position_information via paths\n");

	sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
	sfinfo.position_information.in.file.path = fname;
	sfinfo.position_information.in.position = 32;
	status = smb_raw_setpathinfo(cli->tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.fnum = fnum2;
	status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 25);

	finfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
	finfo.position_information.in.file.path = fname;
	status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(finfo.position_information.out.position, 0);
	

done:
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemple #5
0
/*
  test SMBntrename ops
*/
static bool test_ntrename(struct torture_context *tctx,
                          struct smbcli_state *cli)
{
    union smb_rename io;
    NTSTATUS status;
    bool ret = true;
    int fnum, i;
    const char *fname1 = BASEDIR "\\test1.txt";
    const char *fname2 = BASEDIR "\\test2.txt";
    union smb_fileinfo finfo;

    torture_comment(tctx, "Testing SMBntrename\n");

    if (!torture_setup_dir(cli, BASEDIR)) {
        return false;
    }

    torture_comment(tctx, "Trying simple rename\n");

    fnum = create_complex_file(cli, tctx, fname1);

    io.generic.level = RAW_RENAME_NTRENAME;
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.cluster_size = 0;
    io.ntrename.in.flags = RENAME_FLAG_RENAME;

    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);

    smbcli_close(cli->tree, fnum);
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying self rename\n");
    io.ntrename.in.old_name = fname2;
    io.ntrename.in.new_name = fname2;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

    torture_comment(tctx, "trying wildcard rename\n");
    io.ntrename.in.old_name = BASEDIR "\\*.txt";
    io.ntrename.in.new_name = fname1;

    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);

    torture_comment(tctx, "Checking attrib handling\n");
    torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN);
    io.ntrename.in.old_name = fname2;
    io.ntrename.in.new_name = fname1;
    io.ntrename.in.attrib = 0;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE);

    io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);

    torture_comment(tctx, "Checking hard link\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_HARD_LINK;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname2;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 2);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 2);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);

    smbcli_unlink(cli->tree, fname2);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    torture_comment(tctx, "Checking copy\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_COPY;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname2;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM);

    finfo.generic.level = RAW_FILEINFO_ALL_INFO;
    finfo.generic.in.file.path = fname2;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);
    CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM);

    torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL);

    smbcli_unlink(cli->tree, fname2);

    finfo.generic.in.file.path = fname1;
    status = smb_raw_pathinfo(cli->tree, tctx, &finfo);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_VALUE(finfo.all_info.out.nlink, 1);

    torture_comment(tctx, "Checking invalid flags\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = 0;
    status = smb_raw_rename(cli->tree, &io);
    if (TARGET_IS_WIN7(tctx)) {
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    io.ntrename.in.flags = 300;
    status = smb_raw_rename(cli->tree, &io);
    if (TARGET_IS_WIN7(tctx)) {
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    io.ntrename.in.flags = 0x106;
    status = smb_raw_rename(cli->tree, &io);
    if (TARGET_IS_WIN7(tctx)) {
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    torture_comment(tctx, "Checking unknown field\n");
    io.ntrename.in.old_name = fname1;
    io.ntrename.in.new_name = fname2;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_RENAME;
    io.ntrename.in.cluster_size = 0xff;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n");

    io.ntrename.in.old_name = fname2;
    io.ntrename.in.new_name = fname1;
    io.ntrename.in.attrib = 0;
    io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
    io.ntrename.in.cluster_size = 1;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    io.ntrename.in.flags = RENAME_FLAG_COPY;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

#if 0
    {
        char buf[16384];
        fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE);
        memset(buf, 1, sizeof(buf));
        smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
        smbcli_close(cli->tree, fnum);

        fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE);
        memset(buf, 1, sizeof(buf));
        smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1);
        smbcli_close(cli->tree, fnum);

        torture_all_info(cli->tree, fname1);
        torture_all_info(cli->tree, fname2);
    }


    io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION;
    status = smb_raw_rename(cli->tree, &io);
    CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

    for (i=0; i<20000; i++) {
        io.ntrename.in.cluster_size = i;
        status = smb_raw_rename(cli->tree, &io);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
            torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status));
        }
    }
#endif

    torture_comment(tctx, "Checking other flags\n");

    for (i=0; i<0xFFF; i++) {
        if (i == RENAME_FLAG_RENAME ||
                i == RENAME_FLAG_HARD_LINK ||
                i == RENAME_FLAG_COPY) {
            continue;
        }

        io.ntrename.in.old_name = fname2;
        io.ntrename.in.new_name = fname1;
        io.ntrename.in.flags = i;
        io.ntrename.in.attrib = 0;
        io.ntrename.in.cluster_size = 0;
        status = smb_raw_rename(cli->tree, &io);
        if (TARGET_IS_WIN7(tctx)) {
            if (!NT_STATUS_EQUAL(status,
                                 NT_STATUS_INVALID_PARAMETER)) {
                torture_warning(tctx, "flags=0x%x status=%s\n",
                                i, nt_errstr(status));
            }
        } else {
            if (!NT_STATUS_EQUAL(status,
                                 NT_STATUS_ACCESS_DENIED)) {
                torture_warning(tctx, "flags=0x%x status=%s\n",
                                i, nt_errstr(status));
            }
        }
    }

done:
    smb_raw_exit(cli->session);
    smbcli_deltree(cli->tree, BASEDIR);
    return ret;
}
Exemple #6
0
/* 
   test offline file handling
*/
bool torture_test_offline(struct torture_context *torture)
{
	bool ret = true;
	TALLOC_CTX *mem_ctx = talloc_new(torture);
	int i;
	int timelimit = torture_setting_int(torture, "timelimit", 10);
	struct timeval tv;
	struct offline_state *state;
	struct smbcli_state *cli;
	bool progress;
	progress = torture_setting_bool(torture, "progress", true);

	nconnections = torture_setting_int(torture, "nprocs", 4);
	numstates = nconnections * torture_entries;

	state = talloc_zero_array(mem_ctx, struct offline_state, numstates);

	printf("Opening %d connections with %d simultaneous operations and %u files\n", nconnections, numstates, torture_numops);
	for (i=0;i<nconnections;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].ev = torture->ev;
		if (!torture_open_connection_ev(&cli, i, torture, torture->ev)) {
			return false;
		}
		state[i].tree = cli->tree;
		state[i].client = i;
		/* allow more time for offline files */
		state[i].tree->session->transport->options.request_timeout = 200;
	}

	/* the others are repeats on the earlier connections */
	for (i=nconnections;i<numstates;i++) {
		state[i].tctx = torture;
		state[i].mem_ctx = talloc_new(state);
		state[i].ev = torture->ev;
		state[i].tree = state[i % nconnections].tree;
		state[i].client = i;
	}

	num_connected = i;

	if (!torture_setup_dir(cli, BASEDIR)) {
		goto failed;
	}

	/* pre-create files */
	printf("Pre-creating %u files ....\n", torture_numops);
	for (i=0;i<torture_numops;i++) {
		int fnum;
		char *fname = filename(mem_ctx, i);
		char buf[FILE_SIZE];
		NTSTATUS status;

		memset(buf, 1+(i % 255), sizeof(buf));

		fnum = smbcli_open(state[0].tree, fname, O_RDWR|O_CREAT, DENY_NONE);
		if (fnum == -1) {
			printf("Failed to open %s on connection %d\n", fname, i);
			goto failed;
		}

		if (smbcli_write(state[0].tree, fnum, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
			printf("Failed to write file of size %u\n", FILE_SIZE);
			goto failed;
		}

		status = smbcli_close(state[0].tree, fnum);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Close failed - %s\n", nt_errstr(status));
			goto failed;
		}

		talloc_free(fname);
	}

	/* start the async ops */
	for (i=0;i<numstates;i++) {
		state[i].tv_start = timeval_current();
		test_offline(&state[i]);
	}

	tv = timeval_current();	

	if (progress) {
		event_add_timed(torture->ev, state, timeval_current_ofs(1, 0), report_rate, state);
	}

	printf("Running for %d seconds\n", timelimit);
	while (timeval_elapsed(&tv) < timelimit) {
		event_loop_once(torture->ev);

		if (test_failed) {
			DEBUG(0,("test failed\n"));
			goto failed;
		}
	}

	printf("\nWaiting for completion\n");
	test_finished = true;
	for (i=0;i<numstates;i++) {
		while (state[i].loadfile || 
		       state[i].savefile ||
		       state[i].req) {
			event_loop_once(torture->ev);
		}
	}	

	printf("worst latencies: set_lat=%.1f get_lat=%.1f save_lat=%.1f load_lat=%.1f\n",
	       worst_latencies[OP_SETOFFLINE],
	       worst_latencies[OP_GETOFFLINE],
	       worst_latencies[OP_SAVEFILE],
	       worst_latencies[OP_LOADFILE]);

	smbcli_deltree(state[0].tree, BASEDIR);
	talloc_free(mem_ctx);
	printf("\n");
	return ret;

failed:
	talloc_free(mem_ctx);
	return false;
}
Exemple #7
0
bool torture_casetable(struct torture_context *tctx, 
					   struct smbcli_state *cli)
{
	char *fname;
	int fnum;
	int c, i;
#define MAX_EQUIVALENCE 8
	codepoint_t equiv[0x10000][MAX_EQUIVALENCE];

	torture_comment(tctx, "Determining upper/lower case table\n");

	memset(equiv, 0, sizeof(equiv));

	torture_assert(tctx, torture_setup_dir(cli, "\\utable"),
				   "Error setting up dir \\utable");

	for (c=1; c < 0x10000; c++) {
		size_t size;

		if (c == '.' || c == '\\') continue;

		torture_comment(tctx, "%04x (%c)\n", c, isprint(c)?c:'.');

		fname = form_name(lp_iconv_convenience(tctx->lp_ctx), c);
		fnum = smbcli_nt_create_full(cli->tree, fname, 0,
#if 0
					     SEC_RIGHT_MAXIMUM_ALLOWED, 
#else
					     SEC_RIGHTS_FILE_ALL,
#endif
					     FILE_ATTRIBUTE_NORMAL,
					     NTCREATEX_SHARE_ACCESS_NONE,
					     NTCREATEX_DISP_OPEN_IF, 0, 0);

		torture_assert(tctx, fnum != -1, 
					   talloc_asprintf(tctx, 
			"Failed to create file with char %04x\n", c));

		size = 0;

		if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, 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) {
				torture_comment(tctx, "too many chars match?? size=%d c=0x%04x\n",
				       (int)size, c);
				smbcli_close(cli->tree, fnum);
				return false;
			}

			smbcli_read(cli->tree, fnum, c2, 0, size);
			torture_comment(tctx, "%04x: ", c);
			equiv[c][0] = c;
			for (i=0; i<size/sizeof(int); i++) {
				torture_comment(tctx, "%04x ", c2[i]);
				equiv[c][i+1] = c2[i];
			}
			torture_comment(tctx, "\n");
		}

		smbcli_write(cli->tree, fnum, 0, &c, size, sizeof(c));
		smbcli_close(cli->tree, fnum);
	}

	smbcli_unlink(cli->tree, "\\utable\\*");
	smbcli_rmdir(cli->tree, "\\utable");

	return true;
}
Exemple #8
0
static bool rw_torture(struct torture_context *tctx, struct smbcli_state *c)
{
	const char *lockfname = "\\torture.lck";
	char *fname;
	int fnum;
	int fnum2;
	pid_t pid2, pid = getpid();
	int i, j;
	uint8_t buf[1024];
	bool correct = true;

	fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL, 
			 DENY_NONE);
	if (fnum2 == -1)
		fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
	if (fnum2 == -1) {
		torture_comment(tctx, "open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
		return false;
	}

	generate_random_buffer(buf, sizeof(buf));

	for (i=0;i<torture_numops;i++) {
		uint_t n = (uint_t)random()%10;
		if (i % 10 == 0) {
			if (torture_setting_bool(tctx, "progress", true)) {
				torture_comment(tctx, "%d\r", i);
				fflush(stdout);
			}
		}
		asprintf(&fname, "\\torture.%u", n);

		if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
			return false;
		}

		fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
		if (fnum == -1) {
			torture_comment(tctx, "open failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
			break;
		}

		if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
			torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		for (j=0;j<50;j++) {
			if (smbcli_write(c->tree, fnum, 0, buf, 
				      sizeof(pid)+(j*sizeof(buf)), 
				      sizeof(buf)) != sizeof(buf)) {
				torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));
				correct = false;
			}
		}

		pid2 = 0;

		if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
			torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		if (pid2 != pid) {
			torture_comment(tctx, "data corruption!\n");
			correct = false;
		}

		if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
			torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
			torture_comment(tctx, "unlink failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}

		if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
			torture_comment(tctx, "unlock failed (%s)\n", smbcli_errstr(c->tree));
			correct = false;
		}
		free(fname);
	}

	smbcli_close(c->tree, fnum2);
	smbcli_unlink(c->tree, lockfname);

	torture_comment(tctx, "%d\n", i);

	return correct;
}
Exemple #9
0
/*
  test read ops
*/
static BOOL test_read(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_read io;
	NTSTATUS status;
	BOOL ret = True;
	int fnum;
	uint8_t *buf;
	const int maxsize = 90000;
	const char *fname = BASEDIR "\\test.txt";
	const char *test_data = "TEST DATA";
	uint_t seed = time(NULL);

	buf = talloc_zero_size(mem_ctx, maxsize);

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	printf("Testing RAW_READ_READ\n");
	io.generic.level = RAW_READ_READ;
	
	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
	if (fnum == -1) {
		printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}

	printf("Trying empty file read\n");
	io.read.in.file.fnum = fnum;
	io.read.in.count = 1;
	io.read.in.offset = 0;
	io.read.in.remaining = 0;
	io.read.out.data = buf;
	status = smb_raw_read(cli->tree, &io);

	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, 0);

	printf("Trying zero file read\n");
	io.read.in.count = 0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, 0);

	printf("Trying bad fnum\n");
	io.read.in.file.fnum = fnum+1;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
	io.read.in.file.fnum = fnum;

	smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));

	printf("Trying small read\n");
	io.read.in.file.fnum = fnum;
	io.read.in.offset = 0;
	io.read.in.remaining = 0;
	io.read.in.count = strlen(test_data);
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, strlen(test_data));
	if (memcmp(buf, test_data, strlen(test_data)) != 0) {
		ret = False;
		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
		goto done;
	}

	printf("Trying short read\n");
	io.read.in.offset = 1;
	io.read.in.count = strlen(test_data);
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
	if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
		ret = False;
		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
		goto done;
	}

	if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
		printf("Trying max offset\n");
		io.read.in.offset = ~0;
		io.read.in.count = strlen(test_data);
		status = smb_raw_read(cli->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OK);
		CHECK_VALUE(io.read.out.nread, 0);
	}

	setup_buffer(buf, seed, maxsize);
	smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
	memset(buf, 0, maxsize);

	printf("Trying large read\n");
	io.read.in.offset = 0;
	io.read.in.count = ~0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_BUFFER(buf, seed, io.read.out.nread);


	printf("Trying locked region\n");
	cli->session->pid++;
	if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
		printf("Failed to lock file at %d\n", __LINE__);
		ret = False;
		goto done;
	}
	cli->session->pid--;
	memset(buf, 0, maxsize);
	io.read.in.offset = 0;
	io.read.in.count = ~0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
	

done:
	smbcli_close(cli->tree, fnum);
	smb_raw_exit(cli->session);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemple #10
0
/*
  test readx ops
*/
static BOOL test_readx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	union smb_read io;
	NTSTATUS status;
	BOOL ret = True;
	int fnum;
	uint8_t *buf;
	const int maxsize = 90000;
	const char *fname = BASEDIR "\\test.txt";
	const char *test_data = "TEST DATA";
	uint_t seed = time(NULL);

	buf = talloc_zero_size(mem_ctx, maxsize);

	if (!torture_setup_dir(cli, BASEDIR)) {
		return False;
	}

	printf("Testing RAW_READ_READX\n");
	
	fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
	if (fnum == -1) {
		printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
		ret = False;
		goto done;
	}

	printf("Trying empty file read\n");
	io.generic.level = RAW_READ_READX;
	io.readx.in.file.fnum = fnum;
	io.readx.in.mincnt = 1;
	io.readx.in.maxcnt = 1;
	io.readx.in.offset = 0;
	io.readx.in.remaining = 0;
	io.readx.in.read_for_execute = False;
	io.readx.out.data = buf;
	status = smb_raw_read(cli->tree, &io);

	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.nread, 0);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);

	printf("Trying zero file read\n");
	io.readx.in.mincnt = 0;
	io.readx.in.maxcnt = 0;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.nread, 0);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);

	printf("Trying bad fnum\n");
	io.readx.in.file.fnum = fnum+1;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
	io.readx.in.file.fnum = fnum;

	smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));

	printf("Trying small read\n");
	io.readx.in.file.fnum = fnum;
	io.readx.in.offset = 0;
	io.readx.in.remaining = 0;
	io.readx.in.read_for_execute = False;
	io.readx.in.mincnt = strlen(test_data);
	io.readx.in.maxcnt = strlen(test_data);
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.nread, strlen(test_data));
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);
	if (memcmp(buf, test_data, strlen(test_data)) != 0) {
		ret = False;
		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
		goto done;
	}

	printf("Trying short read\n");
	io.readx.in.offset = 1;
	io.readx.in.mincnt = strlen(test_data);
	io.readx.in.maxcnt = strlen(test_data);
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);
	if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
		ret = False;
		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
		goto done;
	}

	if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
		printf("Trying max offset\n");
		io.readx.in.offset = 0xffffffff;
		io.readx.in.mincnt = strlen(test_data);
		io.readx.in.maxcnt = strlen(test_data);
		status = smb_raw_read(cli->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OK);
		CHECK_VALUE(io.readx.out.nread, 0);
		CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
		CHECK_VALUE(io.readx.out.compaction_mode, 0);
	}

	setup_buffer(buf, seed, maxsize);
	smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
	memset(buf, 0, maxsize);

	printf("Trying large read\n");
	io.readx.in.offset = 0;
	io.readx.in.mincnt = 0xFFFF;
	io.readx.in.maxcnt = 0xFFFF;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);
	CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
	CHECK_BUFFER(buf, seed, io.readx.out.nread);

	printf("Trying extra large read\n");
	io.readx.in.offset = 0;
	io.readx.in.mincnt = 100;
	io.readx.in.maxcnt = 80000;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);
	if (lp_parm_bool(-1, "torture", "samba3", False)) {
		printf("SAMBA3: large read extension\n");
		CHECK_VALUE(io.readx.out.nread, 80000);
	} else {
		CHECK_VALUE(io.readx.out.nread, 0);
	}
	CHECK_BUFFER(buf, seed, io.readx.out.nread);

	printf("Trying mincnt > maxcnt\n");
	memset(buf, 0, maxsize);
	io.readx.in.offset = 0;
	io.readx.in.mincnt = 30000;
	io.readx.in.maxcnt = 20000;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);
	CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
	CHECK_BUFFER(buf, seed, io.readx.out.nread);

	printf("Trying mincnt < maxcnt\n");
	memset(buf, 0, maxsize);
	io.readx.in.offset = 0;
	io.readx.in.mincnt = 20000;
	io.readx.in.maxcnt = 30000;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
	CHECK_VALUE(io.readx.out.compaction_mode, 0);
	CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
	CHECK_BUFFER(buf, seed, io.readx.out.nread);

	if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
		printf("Trying large readx\n");
		io.readx.in.offset = 0;
		io.readx.in.mincnt = 0;
		io.readx.in.maxcnt = 0x10000 - 1;
		status = smb_raw_read(cli->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OK);
		CHECK_VALUE(io.readx.out.nread, 0xFFFF);

		io.readx.in.maxcnt = 0x10000;
		status = smb_raw_read(cli->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OK);
		if (lp_parm_bool(-1, "torture", "samba3", False)) {
			printf("SAMBA3: large read extension\n");
			CHECK_VALUE(io.readx.out.nread, 0x10000);
		} else {
			CHECK_VALUE(io.readx.out.nread, 0);
		}

		io.readx.in.maxcnt = 0x10001;
		status = smb_raw_read(cli->tree, &io);
		CHECK_STATUS(status, NT_STATUS_OK);
		if (lp_parm_bool(-1, "torture", "samba3", False)) {
			printf("SAMBA3: large read extension\n");
			CHECK_VALUE(io.readx.out.nread, 0x10001);
		} else {
			CHECK_VALUE(io.readx.out.nread, 0);
		}
	}

	printf("Trying locked region\n");
	cli->session->pid++;
	if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
		printf("Failed to lock file at %d\n", __LINE__);
		ret = False;
		goto done;
	}
	cli->session->pid--;
	memset(buf, 0, maxsize);
	io.readx.in.offset = 0;
	io.readx.in.mincnt = 100;
	io.readx.in.maxcnt = 200;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);	

	if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
		printf("skipping large file tests - CAP_LARGE_FILES not set\n");
		goto done;
	}

	printf("Trying large offset read\n");
	io.readx.in.offset = ((uint64_t)0x2) << 32;
	io.readx.in.mincnt = 10;
	io.readx.in.maxcnt = 10;
	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.nread, 0);

	if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
		printf("Failed to lock file at %d\n", __LINE__);
		ret = False;
		goto done;
	}

	status = smb_raw_read(cli->tree, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(io.readx.out.nread, 0);

done:
	smbcli_close(cli->tree, fnum);
	smbcli_deltree(cli->tree, BASEDIR);
	return ret;
}
Exemple #11
0
static bool torture_locktest7(struct torture_context *tctx, 
			      struct smbcli_state *cli1)
{
	const char *fname = BASEDIR "\\lockt7.lck";
	int fnum1;
	int fnum2 = -1;
	size_t size;
	uint8_t buf[200];
	bool correct = false;

	torture_assert(tctx, torture_setup_dir(cli1, BASEDIR),
				   talloc_asprintf(tctx, "Unable to set up %s", BASEDIR));

	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);

	memset(buf, 0, sizeof(buf));

	torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) == sizeof(buf),
		"Failed to create file");

	cli1->session->pid = 1;

	torture_assert_ntstatus_ok(tctx, smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK),
		talloc_asprintf(tctx, "Unable to apply read lock on range 130:4, error was %s", 
		       smbcli_errstr(cli1->tree)));

	torture_comment(tctx, "pid1 successfully locked range 130:4 for READ\n");

	torture_assert(tctx, smbcli_read(cli1->tree, fnum1, buf, 130, 4) == 4, 
		 	talloc_asprintf(tctx, "pid1 unable to read the range 130:4, error was %s)", 
		       smbcli_errstr(cli1->tree)));

	torture_comment(tctx, "pid1 successfully read the range 130:4\n");

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
		torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT,
			"Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
	} else {
		torture_fail(tctx, "pid1 successfully wrote to the range 130:4 (should be denied)");
	}

	cli1->session->pid = 2;

	if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
	} else {
		torture_comment(tctx, "pid2 successfully read the range 130:4\n");
	}

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
		torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT, 
			"Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
	} else {
		torture_fail(tctx, "pid2 successfully wrote to the range 130:4 (should be denied)"); 
	}

	cli1->session->pid = 1;
	smbcli_unlock(cli1->tree, fnum1, 130, 4);

	torture_assert_ntstatus_ok(tctx, smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK),
		talloc_asprintf(tctx, "Unable to apply write lock on range 130:4, error was %s", 
		       smbcli_errstr(cli1->tree)));
	torture_comment(tctx, "pid1 successfully locked range 130:4 for WRITE\n");

	torture_assert(tctx, smbcli_read(cli1->tree, fnum1, buf, 130, 4) == 4, 
		talloc_asprintf(tctx, "pid1 unable to read the range 130:4, error was %s", 
		       smbcli_errstr(cli1->tree)));
	torture_comment(tctx, "pid1 successfully read the range 130:4\n");

	torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) == 4, 
		talloc_asprintf(tctx, "pid1 unable to write to the range 130:4, error was %s",
		       smbcli_errstr(cli1->tree)));
	torture_comment(tctx, "pid1 successfully wrote to the range 130:4\n");

	cli1->session->pid = 2;

	if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to read the range 130:4, error was %s\n", 
		       smbcli_errstr(cli1->tree));
		torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT, 
			"Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
	} else {
		torture_fail(tctx, "pid2 successfully read the range 130:4 (should be denied)");
	}

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
		torture_comment(tctx, "pid2 unable to write to the range 130:4, error was %s\n", 
		       smbcli_errstr(cli1->tree));
		if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT)) {
			torture_comment(tctx, "Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
			       __location__);
			goto fail;
		}
	} else {
		torture_comment(tctx, "pid2 successfully wrote to the range 130:4 (should be denied) (%s)\n", 
		       __location__);
		goto fail;
	}

	torture_comment(tctx, "Testing truncate of locked file.\n");

	fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);

	torture_assert(tctx, fnum2 != -1, "Unable to truncate locked file");

	torture_comment(tctx, "Truncated locked file.\n");

	torture_assert_ntstatus_ok(tctx, smbcli_getatr(cli1->tree, fname, NULL, &size, NULL), 
		talloc_asprintf(tctx, "getatr failed (%s)", smbcli_errstr(cli1->tree)));

	torture_assert(tctx, size == 0, talloc_asprintf(tctx, "Unable to truncate locked file. Size was %u", (unsigned)size));

	cli1->session->pid = 1;

	smbcli_unlock(cli1->tree, fnum1, 130, 4);
	correct = true;

fail:
	smbcli_close(cli1->tree, fnum1);
	smbcli_close(cli1->tree, fnum2);
	smbcli_unlink(cli1->tree, fname);

	return correct;
}
Exemple #12
0
/*
  looks at lock upgrade/downgrade.
*/
static bool torture_locktest5(struct torture_context *tctx, struct smbcli_state *cli1, 
			      struct smbcli_state *cli2)
{
	const char *fname = BASEDIR "\\lockt5.lck";
	int fnum1, fnum2, fnum3;
	bool ret;
	uint8_t buf[1000];
	bool correct = true;

	if (!torture_setup_dir(cli1, BASEDIR)) {
		return false;
	}

	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
	fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
	fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);

	memset(buf, 0, sizeof(buf));

	torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) == sizeof(buf),
		"Failed to create file");

	/* Check for NT bug... */
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
		  NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
	smbcli_close(cli1->tree, fnum1);
	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
	smbcli_close(cli1->tree, fnum1);
	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
	smbcli_unlock(cli1->tree, fnum3, 0, 1);

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s overlay a write with a read lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
	EXPECTED(ret, false);

	torture_comment(tctx, "a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");

	/* Unlock the process 2 lock. */
	smbcli_unlock(cli2->tree, fnum2, 0, 4);

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
	EXPECTED(ret, false);

	torture_comment(tctx, "the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");

	/* Unlock the process 1 fnum3 lock. */
	smbcli_unlock(cli1->tree, fnum3, 0, 4);

	/* Stack 2 more locks here. */
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
		  NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));

	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s stack read locks\n", ret?"can":"cannot");

	/* Unlock the first process lock, then check this was the WRITE lock that was
		removed. */

ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
	NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));

	EXPECTED(ret, true);
	torture_comment(tctx, "the first unlock removes the %s lock\n", ret?"WRITE":"READ");

	/* Unlock the process 2 lock. */
	smbcli_unlock(cli2->tree, fnum2, 0, 4);

	/* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */

	ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
		  NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
		  NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));

	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s unlock the stack of 3 locks\n", ret?"can":"cannot");

	/* Ensure the next unlock fails. */
	ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s count the lock stack\n", !ret?"can":"cannot"); 

	/* Ensure connection 2 can get a write lock. */
	ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
	EXPECTED(ret, true);

	torture_comment(tctx, "a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");


	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
		talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),
		talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum3),
		talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));

	torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),
		talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));

	return correct;
}
Exemple #13
0
/*
  looks at overlapping locks
*/
static bool torture_locktest4(struct torture_context *tctx, 
			      struct smbcli_state *cli1,
			      struct smbcli_state *cli2)
{
	const char *fname = BASEDIR "\\lockt4.lck";
	int fnum1, fnum2, f;
	bool ret;
	uint8_t buf[1000];
	bool correct = true;

	if (!torture_setup_dir(cli1, BASEDIR)) {
		return false;
	}

	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
	fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);

	memset(buf, 0, sizeof(buf));

	if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
		torture_comment(tctx, "Failed to create file\n");
		correct = false;
		goto fail;
	}

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s set overlapping write locks\n", ret?"can":"cannot");
	    
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s set overlapping read locks\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "a different connection %s set overlapping write locks\n", ret?"can":"cannot");
	    
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
		NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "a different connection %s set overlapping read locks\n", ret?"can":"cannot");
	
	ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
	      NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
	EXPECTED(ret, false);
	torture_comment(tctx, "a different pid %s set overlapping write locks\n", ret?"can":"cannot");
	    
	ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
	      NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
	EXPECTED(ret, true);
	torture_comment(tctx, "a different pid %s set overlapping read locks\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s set the same read lock twice\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s set the same write lock twice\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
	      NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
	EXPECTED(ret, false);
	torture_comment(tctx, "a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
	EXPECTED(ret, false);
	torture_comment(tctx, "the same process %s coalesce read locks\n", ret?"can":"cannot");


	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
	      (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
	EXPECTED(ret, false);
	torture_comment(tctx, "this server %s strict write locking\n", ret?"doesn't do":"does");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
	      (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
	EXPECTED(ret, false);
	torture_comment(tctx, "this server %s strict read locking\n", ret?"doesn't do":"does");


	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
	EXPECTED(ret, true);
	torture_comment(tctx, "this server %s do recursive read locking\n", ret?"does":"doesn't");


	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
	      (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
	      !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
	EXPECTED(ret, true);
	torture_comment(tctx, "this server %s do recursive lock overlays\n", ret?"does":"doesn't");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
	      (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&		
	      (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);		
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s remove a read lock using write locking\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
	      (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&		
	      (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);		
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s remove a write lock using read locking\n", ret?"can":"cannot");

	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
	      !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&		
	      (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);		
	EXPECTED(ret, true);
	torture_comment(tctx, "the same process %s remove the first lock first\n", ret?"does":"doesn't");

	smbcli_close(cli1->tree, fnum1);
	smbcli_close(cli2->tree, fnum2);
	fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
	f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
	ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
	      NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
	      ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
	      NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
        smbcli_close(cli1->tree, f);
	smbcli_close(cli1->tree, fnum1);
	EXPECTED(ret, true);
	torture_comment(tctx, "the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");

 fail:
	smbcli_close(cli1->tree, fnum1);
	smbcli_close(cli2->tree, fnum2);
	smbcli_unlink(cli1->tree, fname);

	return correct;
}
Exemple #14
0
static bool test_session_reauth2(struct torture_context *tctx,
				 struct smbcli_state *cli)
{
	char *random_string;
	char *fname;
	union smb_open io_open;
	struct smb_composite_sesssetup io_sesssetup;
	union smb_fileinfo io_qsecdesc;
	struct smbcli_request *req;
	struct cli_credentials *anon_creds;
	NTSTATUS status;
	uint16_t fnum;
	ssize_t nwritten;
	uint16_t vuid1 = cli->session->vuid;

	random_string = generate_random_str(tctx, 8);
	torture_assert(tctx, (random_string != NULL),
		       "memory allocation failed");
	fname = talloc_asprintf(tctx, "raw_session_reauth2_%s.dat",
				random_string);
	talloc_free(random_string);
	torture_assert(tctx, (fname != NULL), "memory allocation failed");

	smbcli_unlink(cli->tree, fname);
	smbcli_oplock_handler(cli->transport,
			      test_session_reauth2_oplock_timeout,
			      cli->tree);

	/*
	  base ntcreatex parms
	*/
	ZERO_STRUCT(io_open);
	io_open.generic.level = RAW_OPEN_NTCREATEX;
	io_open.ntcreatex.in.root_fid.fnum = 0;
	io_open.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ |
		SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE;
	io_open.ntcreatex.in.alloc_size = 0;
	io_open.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io_open.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
				       NTCREATEX_SHARE_ACCESS_WRITE;
	io_open.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
	io_open.ntcreatex.in.create_options = 0;
	io_open.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io_open.ntcreatex.in.security_flags = 0;
	io_open.ntcreatex.in.fname = fname;

	torture_comment(tctx, "open with batch oplock\n");
	io_open.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
		NTCREATEX_FLAGS_REQUEST_OPLOCK |
		NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;

	status = smb_raw_open(cli->tree, tctx, &io_open);
	torture_assert_ntstatus_ok(tctx, status, "smb_raw_open failed");

	fnum = io_open.ntcreatex.out.file.fnum;
	torture_assert(
		tctx,
		(io_open.ntcreatex.out.oplock_level == BATCH_OPLOCK_RETURN),
		"did not get batch oplock");

	io_open.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
	req = smb_raw_open_send(cli->tree, &io_open);
	torture_assert(tctx, (req != NULL), "memory allocation failed");

	/*
	 * Make sure the open went through
	 */
	status = smbcli_chkpath(cli->tree, "\\");
	torture_assert_ntstatus_ok(tctx, status, "smb_chkpath failed");

	status = smbcli_nt_delete_on_close(cli->tree, fnum, true);
	torture_assert_ntstatus_ok(tctx, status, "could not set delete on "
				   "close");

	anon_creds = cli_credentials_init_anon(tctx);
	torture_assert(tctx, (anon_creds != NULL), "memory allocation failed");

	ZERO_STRUCT(io_sesssetup);
	io_sesssetup.in.sesskey      = cli->transport->negotiate.sesskey;
	io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
	io_sesssetup.in.credentials  = anon_creds;
	io_sesssetup.in.workgroup    = lpcfg_workgroup(tctx->lp_ctx);
	io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(
		tctx, tctx->lp_ctx);
	status = smb_composite_sesssetup(cli->session, &io_sesssetup);
	torture_assert_ntstatus_ok(tctx, status, "setup2 failed");
	torture_assert_int_equal(tctx, io_sesssetup.out.vuid, vuid1, "setup2");

	status = smbcli_close(cli->tree, fnum);
	torture_assert_ntstatus_ok(tctx, status, "close failed");

	status = smb_raw_open_recv(req, tctx, &io_open);
	torture_assert_ntstatus_ok(tctx, status, "2nd open failed");

	fnum = io_open.ntcreatex.out.file.fnum;

	nwritten = smbcli_write(cli->tree, fnum, 0, fname, 0, strlen(fname));
	torture_assert(tctx, (nwritten == strlen(fname)),
		       "smbcli_write failed");

	ZERO_STRUCT(io_qsecdesc);
	io_qsecdesc.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
	io_qsecdesc.query_secdesc.in.file.fnum = fnum;
	io_qsecdesc.query_secdesc.in.secinfo_flags = SECINFO_OWNER;
	status = smb_raw_fileinfo(cli->tree, tctx, &io_qsecdesc);
	torture_assert_ntstatus_equal(
		tctx, status, NT_STATUS_ACCESS_DENIED,
		"anon qsecdesc did not return ACCESS_DENIED");

	ZERO_STRUCT(io_sesssetup);
	io_sesssetup.in.sesskey      = cli->transport->negotiate.sesskey;
	io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities;
	io_sesssetup.in.credentials  = cmdline_credentials;
	io_sesssetup.in.workgroup    = lpcfg_workgroup(tctx->lp_ctx);
	io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(
		tctx, tctx->lp_ctx);
	status = smb_composite_sesssetup(cli->session, &io_sesssetup);
	torture_assert_ntstatus_ok(tctx, status, "setup3 failed");
	torture_assert_int_equal(tctx, io_sesssetup.out.vuid, vuid1, "setup2");

	status = smb_raw_fileinfo(cli->tree, tctx, &io_qsecdesc);
	torture_assert_ntstatus_ok(tctx, status, "2nd qsecdesc failed");

	status = smbcli_nt_delete_on_close(cli->tree, fnum, true);
	torture_assert_ntstatus_ok(tctx, status, "could not set delete on "
				   "close");

	status = smbcli_close(cli->tree, fnum);
	torture_assert_ntstatus_ok(tctx, status, "close failed");

	return true;
}
Exemple #15
0
static NTSTATUS push_recursive (struct gp_context *gp_ctx, const char *local_path,
                                const char *remote_path, int depth)
{
	DIR *dir;
	struct dirent *dirent;
	char *entry_local_path;
	char *entry_remote_path;
	int local_fd, remote_fd;
	int buf[1024];
	int nread, total_read;
	struct stat s;

	dir = opendir(local_path);
	while ((dirent = readdir(dir)) != NULL) {
		if (strcmp(dirent->d_name, ".") == 0 ||
				strcmp(dirent->d_name, "..") == 0) {
			continue;
		}

		entry_local_path = talloc_asprintf(gp_ctx, "%s/%s", local_path,
		                                   dirent->d_name);
		NT_STATUS_HAVE_NO_MEMORY(entry_local_path);

		entry_remote_path = talloc_asprintf(gp_ctx, "%s\\%s",
		                                    remote_path, dirent->d_name);
		NT_STATUS_HAVE_NO_MEMORY(entry_remote_path);

		if (stat(dirent->d_name, &s) != 0) {
			return NT_STATUS_UNSUCCESSFUL;
		}
		if (s.st_mode & S_IFDIR) {
			DEBUG(6, ("Pushing directory %s to %s on sysvol\n",
			          entry_local_path, entry_remote_path));
			smbcli_mkdir(gp_ctx->cli->tree, entry_remote_path);
			if (depth < GP_MAX_DEPTH) {
				push_recursive(gp_ctx, entry_local_path,
				               entry_remote_path, depth+1);
			}
		} else {
			DEBUG(6, ("Pushing file %s to %s on sysvol\n",
			          entry_local_path, entry_remote_path));
			remote_fd = smbcli_open(gp_ctx->cli->tree,
			                        entry_remote_path,
			                        O_WRONLY | O_CREAT,
			                        0);
			if (remote_fd < 0) {
				talloc_free(entry_local_path);
				talloc_free(entry_remote_path);
				DEBUG(0, ("Failed to create remote file: %s\n",
				          entry_remote_path));
				return NT_STATUS_UNSUCCESSFUL;
			}
			local_fd = open(entry_local_path, O_RDONLY);
			if (local_fd < 0) {
				talloc_free(entry_local_path);
				talloc_free(entry_remote_path);
				DEBUG(0, ("Failed to open local file: %s\n",
				          entry_local_path));
				return NT_STATUS_UNSUCCESSFUL;
			}
			total_read = 0;
			while ((nread = read(local_fd, &buf, sizeof(buf)))) {
				smbcli_write(gp_ctx->cli->tree, remote_fd, 0,
						&buf, total_read, nread);
				total_read += nread;
			}

			close(local_fd);
			smbcli_close(gp_ctx->cli->tree, remote_fd);
		}
		talloc_free(entry_local_path);
		talloc_free(entry_remote_path);
	}
	closedir(dir);

	return NT_STATUS_OK;
}
Exemple #16
0
/*
  test basic io on streams
*/
static BOOL test_stream_io(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	union smb_open io;
	const char *fname = BASEDIR "\\stream.txt";
	const char *sname1, *sname2;
	BOOL ret = True;
	int fnum = -1;
	ssize_t retsize;

	sname1 = talloc_asprintf(mem_ctx, "%s:%s", fname, "Stream One");
	sname2 = talloc_asprintf(mem_ctx, "%s:%s:$DaTa", fname, "Second Stream");

	printf("opening non-existant directory stream\n");
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = 0;
	io.ntcreatex.in.alloc_size = 0;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
	io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
	io.ntcreatex.in.security_flags = 0;
	io.ntcreatex.in.fname = sname1;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);

	printf("creating a stream on a non-existant file\n");
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.fname = sname1;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	ret &= check_stream(cli, mem_ctx, fname, "Stream One", NULL);

	printf("check that open of base file is allowed\n");
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
	io.ntcreatex.in.fname = fname;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);

	printf("writing to stream\n");
	retsize = smbcli_write(cli->tree, fnum, 0, "test data", 0, 9);
	CHECK_VALUE(retsize, 9);

	smbcli_close(cli->tree, fnum);

	ret &= check_stream(cli, mem_ctx, fname, "Stream One", "test data");

	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
	io.ntcreatex.in.fname = sname1;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	printf("modifying stream\n");
	retsize = smbcli_write(cli->tree, fnum, 0, "MORE DATA ", 5, 10);
	CHECK_VALUE(retsize, 10);

	smbcli_close(cli->tree, fnum);

	ret &= check_stream(cli, mem_ctx, fname, "Stream One:$FOO", NULL);

	printf("creating a stream2 on a existing file\n");
	io.ntcreatex.in.fname = sname2;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	printf("modifying stream\n");
	retsize = smbcli_write(cli->tree, fnum, 0, "SECOND STREAM", 0, 13);
	CHECK_VALUE(retsize, 13);

	smbcli_close(cli->tree, fnum);

	ret &= check_stream(cli, mem_ctx, fname, "Stream One", "test MORE DATA ");
	ret &= check_stream(cli, mem_ctx, fname, "Stream One:$DATA", "test MORE DATA ");
	ret &= check_stream(cli, mem_ctx, fname, "Stream One:", NULL);
	ret &= check_stream(cli, mem_ctx, fname, "Second Stream", "SECOND STREAM");
	ret &= check_stream(cli, mem_ctx, fname, "Second Stream:$DATA", "SECOND STREAM");
	ret &= check_stream(cli, mem_ctx, fname, "Second Stream:", NULL);
	ret &= check_stream(cli, mem_ctx, fname, "Second Stream:$FOO", NULL);

	printf("deleting stream\n");
	status = smbcli_unlink(cli->tree, sname1);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("delete a stream via delete-on-close\n");
	io.ntcreatex.in.fname = sname2;
	io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE;
	io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
	status = smb_raw_open(cli->tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;
	
	smbcli_close(cli->tree, fnum);
	status = smbcli_unlink(cli->tree, sname2);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);


	printf("deleting file\n");
	status = smbcli_unlink(cli->tree, fname);
	CHECK_STATUS(status, NT_STATUS_OK);

done:
	smbcli_close(cli->tree, fnum);
	return ret;
}