Example #1
0
/* Perform a tree disconnect
   
     tree_disconnect(tree);

 */
static int ejs_cli_tree_disconnect(MprVarHandle eid, int argc, MprVar **argv)
{
	struct smbcli_tree *tree;
	NTSTATUS status;

	/* Argument parsing */

	if (argc != 1) {
		ejsSetErrorMsg(eid, "tree_disconnect invalid arguments");
		return -1;
	}

	if (!mprVarIsPtr(argv[0]->type)) {
		ejsSetErrorMsg(eid, "first arg is not a tree handle");
		return -1;
	}	

	tree = argv[0]->ptr;

	status = smb_tree_disconnect(tree);

	if (!NT_STATUS_IS_OK(status)) {
		ejsSetErrorMsg(eid, "tree_disconnect: %s", nt_errstr(status));
		return -1;
	}

	talloc_free(tree);

	return 0;
}
Example #2
0
int main()
{
  struct in_addr  addr;
  smb_session   *session;
  smb_tid     tid;
  smb_fd      fd;

  session = smb_session_new();
  if (session == NULL)
    exit(1);

  inet_aton("127.0.0.1", &addr.sin_addr);

  if (smb_session_connect(session, "MYNAME", 
      addr.sin_addr.s_addr, SMB_TRANSPORT_TCP))
  {
    printf("Unable to connect to host\n");
    exit(2);
  }

  smb_session_set_creds(session, "MYNAME", "login", 
              "password");
  if (smb_session_login(session))
  {
    if (session->guest)
      printf("Logged in as GUEST \n");
    else
      printf("Successfully logged in\n");
  }
  else
  {
    printf("Auth failed\n");
    exit(3);
  }

  tid = smb_tree_connect(session, "MyShare");
  if (!tid)
  {
    printf("Unable to connect to share\n");
    exit(4);
  }

  fd = smb_fopen(session, tid, "\\My\\File");
  if (!fd)
  {
    printf("Unable to open file\n");
    exit(5);
  }

  char buffer[512];
  smb_fread(session, fd, buffer, 512);

  /* Use data */

  smb_fclose(session, fd);
  smb_tree_disconnect(session, tid);
  smb_session_destroy(session);

  return(0);
}
Example #3
0
static int ejs_tree_disconnect(MprVarHandle eid, int argc, MprVar **argv)
{
	struct smbcli_tree *tree;
	NTSTATUS result;

	if (argc != 1) {
		ejsSetErrorMsg(eid, 
			       "tree_disconnect(): invalid number of args");
		return -1;
	}

	if (!IS_TREE_HANDLE(argv[0])) {
		ejsSetErrorMsg(eid, "first arg is not a tree handle");
		return -1;
	}

	tree = talloc_check_name(argv[0]->ptr, "struct smbcli_tree");

	result = smb_tree_disconnect(tree);

	mpr_Return(eid, mprNTSTATUS(result));

	return 0;
}
Example #4
0
/*
  test tree with ulogoff
  this demonstrates that a tcon isn't autoclosed by a ulogoff
  the tcon can be reused using any other valid session later
*/
static BOOL test_tree_ulogoff(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	BOOL ret = True;
	const char *share, *host;
	struct smbcli_session *session1;
	struct smbcli_session *session2;
	struct smb_composite_sesssetup setup;
	struct smbcli_tree *tree;
	union smb_tcon tcon;
	union smb_open io;
	union smb_write wr;
	int fnum1, fnum2;
	const char *fname1 = BASEDIR "\\test1.txt";
	const char *fname2 = BASEDIR "\\test2.txt";
	uint8_t c = 1;

	printf("TESTING TREE with ulogoff\n");

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

	share = lp_parm_string(-1, "torture", "share");
	host  = lp_parm_string(-1, "torture", "host");

	printf("create the first new sessions\n");
	session1 = smbcli_session_init(cli->transport, mem_ctx, False);
	setup.in.sesskey = cli->transport->negotiate.sesskey;
	setup.in.capabilities = cli->transport->negotiate.capabilities;
	setup.in.workgroup = lp_workgroup();
	setup.in.credentials = cmdline_credentials;
	status = smb_composite_sesssetup(session1, &setup);
	CHECK_STATUS(status, NT_STATUS_OK);
	session1->vuid = setup.out.vuid;
	printf("vuid1=%d\n", session1->vuid);

	printf("create a tree context on the with vuid1\n");
	tree = smbcli_tree_init(session1, mem_ctx, False);
	tcon.generic.level = RAW_TCON_TCONX;
	tcon.tconx.in.flags = 0;
	tcon.tconx.in.password = data_blob(NULL, 0);
	tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
	tcon.tconx.in.device = "A:";
	status = smb_raw_tcon(tree, mem_ctx, &tcon);
	CHECK_STATUS(status, NT_STATUS_OK);
	tree->tid = tcon.tconx.out.tid;
	printf("tid=%d\n", tree->tid);

	printf("create a file using vuid1\n");
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	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 = fname1;
	status = smb_raw_open(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum1 = io.ntcreatex.out.file.fnum;

	printf("write using vuid1\n");
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum1;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;
	status = smb_raw_write(tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("ulogoff the vuid1\n");
	status = smb_raw_ulogoff(session1);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("create the second new sessions\n");
	session2 = smbcli_session_init(cli->transport, mem_ctx, False);
	setup.in.sesskey = cli->transport->negotiate.sesskey;
	setup.in.capabilities = cli->transport->negotiate.capabilities;
	setup.in.workgroup = lp_workgroup();
	setup.in.credentials = cmdline_credentials;
	status = smb_composite_sesssetup(session2, &setup);
	CHECK_STATUS(status, NT_STATUS_OK);
	session2->vuid = setup.out.vuid;
	printf("vuid2=%d\n", session2->vuid);

	printf("use the existing tree with vuid2\n");
	tree->session = session2;

	printf("create a file using vuid2\n");
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	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 = fname2;
	status = smb_raw_open(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum2 = io.ntcreatex.out.file.fnum;

	printf("write using vuid2\n");
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum2;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;
	status = smb_raw_write(tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("ulogoff the vuid2\n");
	status = smb_raw_ulogoff(session2);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* this also demonstrates that SMBtdis doesn't need a valid vuid */
	printf("disconnect the existing tree connection\n");
	status = smb_tree_disconnect(tree);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("disconnect the existing tree connection\n");
	status = smb_tree_disconnect(tree);
	CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));

	/* close down the new tree */
	talloc_free(tree);
	
done:
	return ret;
}
Example #5
0
/*
  test tree ops
*/
static BOOL test_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
{
	NTSTATUS status;
	BOOL ret = True;
	const char *share, *host;
	struct smbcli_tree *tree;
	union smb_tcon tcon;
	union smb_open io;
	union smb_write wr;
	union smb_close cl;
	int fnum;
	const char *fname = BASEDIR "\\test.txt";
	uint8_t c = 1;

	printf("TESTING TREE HANDLING\n");

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

	share = lp_parm_string(-1, "torture", "share");
	host  = lp_parm_string(-1, "torture", "host");
	
	printf("create a second tree context on the same session\n");
	tree = smbcli_tree_init(cli->session, mem_ctx, False);

	tcon.generic.level = RAW_TCON_TCONX;
	tcon.tconx.in.flags = 0;
	tcon.tconx.in.password = data_blob(NULL, 0);
	tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
	tcon.tconx.in.device = "A:";	
	status = smb_raw_tcon(tree, mem_ctx, &tcon);
	CHECK_STATUS(status, NT_STATUS_OK);
	

	tree->tid = tcon.tconx.out.tid;
	printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);

	printf("try a tconx with a bad device type\n");
	tcon.tconx.in.device = "FOO";	
	status = smb_raw_tcon(tree, mem_ctx, &tcon);
	CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);


	printf("create a file using the new tid\n");
	io.generic.level = RAW_OPEN_NTCREATEX;
	io.ntcreatex.in.root_fid = 0;
	io.ntcreatex.in.flags = 0;
	io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	io.ntcreatex.in.create_options = 0;
	io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
	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 = fname;
	status = smb_raw_open(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	fnum = io.ntcreatex.out.file.fnum;

	printf("write using the old tid\n");
	wr.generic.level = RAW_WRITE_WRITEX;
	wr.writex.in.file.fnum = fnum;
	wr.writex.in.offset = 0;
	wr.writex.in.wmode = 0;
	wr.writex.in.remaining = 0;
	wr.writex.in.count = 1;
	wr.writex.in.data = &c;

	status = smb_raw_write(cli->tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("write with the new tid\n");
	status = smb_raw_write(tree, &wr);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VALUE(wr.writex.out.nwritten, 1);

	printf("disconnect the new tid\n");
	status = smb_tree_disconnect(tree);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("the new tid should not now be accessible\n");
	status = smb_raw_write(tree, &wr);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	printf("the fnum should have been auto-closed\n");
	cl.close.level = RAW_CLOSE_CLOSE;
	cl.close.in.file.fnum = fnum;
	cl.close.in.write_time = 0;
	status = smb_raw_close(cli->tree, &cl);
	CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);

	/* close down the new tree */
	talloc_free(tree);
	
done:
	return ret;
}
Example #6
0
/*
  disconnect the tree
*/
NTSTATUS smbcli_tdis(struct smbcli_state *cli)
{
	return smb_tree_disconnect(cli->tree);
}
static smb_tree_t *
smb_tree_connect_disk(smb_request_t *sr, const char *sharename)
{
	smb_user_t		*user = sr->uid_user;
	smb_node_t		*dnode = NULL;
	smb_node_t		*snode = NULL;
	char			last_component[MAXNAMELEN];
	smb_tree_t		*tree;
	smb_share_t 		*si;
	cred_t			*u_cred;
	int			rc;
	uint32_t		access = 0; /* read/write is assumed */
	uint32_t		hostaccess = ACE_ALL_PERMS;
	uint32_t		aclaccess;
	smb_execsub_info_t	subs;

	ASSERT(user);
	u_cred = user->u_cred;
	ASSERT(u_cred);

	if (user->u_flags & SMB_USER_FLAG_IPC) {
		smb_tree_log(sr, sharename, "access denied: IPC only");
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
		return (NULL);
	}

	si = kmem_zalloc(sizeof (smb_share_t), KM_SLEEP);

	if (smb_kshare_getinfo(sr->sr_server->sv_lmshrd, (char *)sharename, si,
	    &sr->session->ipaddr) != NERR_Success) {
		smb_tree_log(sr, sharename, "share not found");
		smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
		kmem_free(si, sizeof (smb_share_t));
		return (NULL);
	}

	if (user->u_flags & SMB_USER_FLAG_GUEST) {
		if ((si->shr_flags & SMB_SHRF_GUEST_OK) == 0) {
			smb_tree_log(sr, sharename,
			    "access denied: guest disabled");
			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV,
			    ERRaccess);
			kmem_free(si, sizeof (smb_share_t));
			return (NULL);
		}
	}

	/*
	 * Handle the default administration shares: C$, D$ etc.
	 * Only a user with admin rights is allowed to map these
	 * shares.
	 */
	if (si->shr_flags & SMB_SHRF_ADMIN) {
		if (!smb_user_is_admin(user)) {
			smb_tree_log(sr, sharename, "access denied: not admin");
			smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
			    ERRSRV, ERRaccess);
			kmem_free(si, sizeof (smb_share_t));
			return (NULL);
		}
	}

	/*
	 * Set up the OptionalSupport for this share.
	 */
	sr->arg.tcon.optional_support = SMB_SUPPORT_SEARCH_BITS;

	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
	case SMB_SHRF_CSC_DISABLED:
		sr->arg.tcon.optional_support |= SMB_CSC_CACHE_NONE;
		break;
	case SMB_SHRF_CSC_AUTO:
		sr->arg.tcon.optional_support |= SMB_CSC_CACHE_AUTO_REINT;
		break;
	case SMB_SHRF_CSC_VDO:
		sr->arg.tcon.optional_support |= SMB_CSC_CACHE_VDO;
		break;
	case SMB_SHRF_CSC_MANUAL:
	default:
		/*
		 * Default to SMB_CSC_CACHE_MANUAL_REINT.
		 */
		break;
	}

	/* ABE support */
	if (si->shr_flags & SMB_SHRF_ABE)
		sr->arg.tcon.optional_support |=
		    SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM;

	access = si->shr_access_value & SMB_SHRF_ACC_ALL;

	if (access == SMB_SHRF_ACC_RO) {
		hostaccess &= ~ACE_ALL_WRITE_PERMS;
	} else if (access == SMB_SHRF_ACC_NONE) {
		kmem_free(si, sizeof (smb_share_t));
		smb_tree_log(sr, sharename, "access denied: host access");
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
		return (NULL);
	}

	/*
	 * Check that the shared directory exists.
	 */
	rc = smb_pathname_reduce(sr, u_cred, si->shr_path, 0, 0, &dnode,
	    last_component);

	if (rc == 0) {
		rc = smb_fsop_lookup(sr, u_cred, SMB_FOLLOW_LINKS,
		    sr->sr_server->si_root_smb_node, dnode, last_component,
		    &snode);

		smb_node_release(dnode);
	}

	if (rc) {
		if (snode)
			smb_node_release(snode);

		smb_tree_log(sr, sharename, "bad path: %s", si->shr_path);
		smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
		kmem_free(si, sizeof (smb_share_t));
		return (NULL);
	}

	/*
	 * Find share level ACL if it exists in the designated
	 * location. Needs to be done after finding a valid path but
	 * before the tree is allocated.
	 */
	smb_tree_acl_access(u_cred, sharename, snode->vp, &aclaccess);
	if ((aclaccess & ACE_ALL_PERMS) == 0) {
		smb_tree_log(sr, sharename, "access denied: share ACL");
		smbsr_error(sr, 0, ERRSRV, ERRaccess);
		kmem_free(si, sizeof (smb_share_t));
		smb_node_release(snode);
		return (NULL);
	}

	/*
	 * Set tree ACL access to the minimum ACL permissions based on
	 * hostaccess (those allowed by host based access) and
	 * aclaccess (those from the ACL object for the share). This
	 * is done during the alloc.
	 */

	(void) strlcpy(si->shr_name, sharename, MAXNAMELEN);
	tree = smb_tree_alloc(user, si, STYPE_DISKTREE, snode,
	    hostaccess & aclaccess);

	smb_node_release(snode);

	if (tree == NULL)
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
	else {

		tree->t_shr_flags = si->shr_flags;

		if (tree->t_shr_flags & SMB_SHRF_MAP) {
			(void) smb_tree_set_execsub_info(tree, &subs);

			rc = smb_kshare_exec(sr->sr_server->sv_lmshrd,
			    (char *)sharename, &subs, SMB_SHR_MAP);

			if (rc != 0 && tree->t_shr_flags & SMB_SHRF_DISP_TERM) {
				smb_tree_disconnect(tree, B_FALSE);
				smb_tree_release(tree);
				smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV,
				    ERRaccess);
				kmem_free(si, sizeof (smb_share_t));
				return (NULL);
			}
		}
	}

	kmem_free(si, sizeof (smb_share_t));

	return (tree);
}