Example #1
0
static int atalk_unlink(struct vfs_handle_struct *handle,
			const struct smb_filename *smb_fname)
{
	int ret = 0, i;
	char *path = NULL;
	char *adbl_path = NULL;
	char *orig_path = NULL;
	SMB_STRUCT_STAT adbl_info;
	SMB_STRUCT_STAT orig_info;
	NTSTATUS status;

	ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);

	status = get_full_smb_filename(talloc_tos(), smb_fname, &path);
	if (!NT_STATUS_IS_OK(status)) {
		return ret;
	}

	/* no .AppleDouble sync if veto or hide list is empty,
	 * otherwise "Cannot find the specified file" error will be caused
	 */

	if (!handle->conn->veto_list) return ret;
	if (!handle->conn->hide_list) return ret;

	for (i = 0; handle->conn->veto_list[i].name; i ++) {
		if (strstr_m(handle->conn->veto_list[i].name, APPLEDOUBLE))
			break;
	}

	if (!handle->conn->veto_list[i].name) {
		for (i = 0; handle->conn->hide_list[i].name; i ++) {
			if (strstr_m(handle->conn->hide_list[i].name, APPLEDOUBLE))
				break;
			else {
				DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
				  APPLEDOUBLE));		
				goto exit_unlink;
			}
		}
	}

	if (atalk_build_paths(talloc_tos(), handle->conn->cwd, path,
			      &adbl_path, &orig_path,
			      &adbl_info, &orig_info) != 0)
		goto exit_unlink;

	if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) {
		DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
		goto exit_unlink;
	}

	atalk_unlink_file(adbl_path);

exit_unlink:
	TALLOC_FREE(path);
	TALLOC_FREE(adbl_path);
	TALLOC_FREE(orig_path);
	return ret;
}
Example #2
0
static int tsmsm_set_offline(struct vfs_handle_struct *handle, 
                             const struct smb_filename *fname)
{
	struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
	int result = 0;
	char *command;
	NTSTATUS status;
	char *path;

	if (tsmd->hsmscript == NULL) {
		/* no script enabled */
		DEBUG(1, ("tsmsm_set_offline: No 'tsmsm:hsm script' configured\n"));
		return 0;
	}

        status = get_full_smb_filename(talloc_tos(), fname, &path);
        if (!NT_STATUS_IS_OK(status)) {
                errno = map_errno_from_nt_status(status);
                return false;
        }

	/* Now, call the script */
	command = talloc_asprintf(tsmd, "%s offline \"%s\"", tsmd->hsmscript, path);
	if(!command) {
		DEBUG(1, ("tsmsm_set_offline: can't allocate memory to run hsm script"));
		return -1;
	}
	DEBUG(10, ("tsmsm_set_offline: Running [%s]\n", command));
	if((result = smbrun(command, NULL)) != 0) {
		DEBUG(1,("tsmsm_set_offline: Running [%s] returned %d\n", command, result));
	}
	TALLOC_FREE(command);
	return result;
}
/**
 * Return a string using the talloc_tos()
 */
const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
{
	char *fname = NULL;
	NTSTATUS status;

	if (smb_fname == NULL) {
		return "";
	}
	status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
	if (!NT_STATUS_IS_OK(status)) {
		return "";
	}
	return fname;
}
static int fake_acls_stat(vfs_handle_struct *handle,
			   struct smb_filename *smb_fname)
{
	int ret = -1;

	ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
	if (ret == 0) {
		TALLOC_CTX *frame = talloc_stackframe();
		char *path;
		struct smb_filename smb_fname_base = {
			.base_name = smb_fname->base_name
		};
		NTSTATUS status;
		/*
		 * As we're calling getxattr directly here
		 * we need to use only the base_name, not
		 * the full name containing any stream name.
		 */
		status = get_full_smb_filename(frame, &smb_fname_base, &path);
		if (!NT_STATUS_IS_OK(status)) {
			errno = map_errno_from_nt_status(status);
			TALLOC_FREE(frame);
			return -1;
		}
		
		ret = fake_acls_uid(handle, path, &smb_fname->st.st_ex_uid);
		if (ret != 0) {
			TALLOC_FREE(frame);
			return ret;
		}
		ret = fake_acls_gid(handle, path, &smb_fname->st.st_ex_gid);
		if (ret != 0) {
			TALLOC_FREE(frame);
			return ret;
		}
		TALLOC_FREE(frame);
	}

	return ret;
}
static int fake_acls_lstat(vfs_handle_struct *handle,
			   struct smb_filename *smb_fname)
{
	int ret = -1;

	ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
	if (ret == 0) {
		TALLOC_CTX *frame = talloc_stackframe();
		char *path;
		struct smb_filename smb_fname_base = {
			.base_name = smb_fname->base_name
		};
		NTSTATUS status;
		/*
		 * As we're calling getxattr directly here
		 * we need to use only the base_name, not
		 * the full name containing any stream name.
		 */
		status = get_full_smb_filename(frame, &smb_fname_base, &path);
		if (!NT_STATUS_IS_OK(status)) {
			errno = map_errno_from_nt_status(status);
			TALLOC_FREE(frame);
			return -1;
		}

		/* This isn't quite right (calling getxattr not
		 * lgetxattr), but for the test purposes of this
		 * module (fake NT ACLs from windows clients), it is
		 * close enough.  We removed the l*xattr functions
		 * because linux doesn't support using them, but we
		 * could fake them in xattr_tdb if we really wanted
		 * to.  We ignore errors because the link might not point anywhere */
		fake_acls_uid(handle, path, &smb_fname->st.st_ex_uid);
		fake_acls_gid(handle, path, &smb_fname->st.st_ex_gid);
		TALLOC_FREE(frame);
	}

	return ret;
}
Example #6
0
static int atalk_rename(struct vfs_handle_struct *handle,
			const struct smb_filename *smb_fname_src,
			const struct smb_filename *smb_fname_dst)
{
	int ret = 0;
	char *oldname = NULL;
	char *adbl_path = NULL;
	char *orig_path = NULL;
	SMB_STRUCT_STAT adbl_info;
	SMB_STRUCT_STAT orig_info;
	NTSTATUS status;

	ret = SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);

	status = get_full_smb_filename(talloc_tos(), smb_fname_src, &oldname);
	if (!NT_STATUS_IS_OK(status)) {
		return ret;
	}

	if (atalk_build_paths(talloc_tos(), handle->conn->cwd, oldname,
			      &adbl_path, &orig_path, &adbl_info,
			      &orig_info) != 0)
		goto exit_rename;

	if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) {
		DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));		
		goto exit_rename;
	}

	atalk_unlink_file(adbl_path);

exit_rename:
	TALLOC_FREE(oldname);
	TALLOC_FREE(adbl_path);
	TALLOC_FREE(orig_path);
	return ret;
}
Example #7
0
static bool tsmsm_is_offline(struct vfs_handle_struct *handle, 
			     const struct smb_filename *fname,
			     SMB_STRUCT_STAT *stbuf)
{
	struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
	const dm_sessid_t *dmsession_id;
	void *dmhandle = NULL;
	size_t dmhandle_len = 0;
	size_t rlen;
	dm_attrname_t dmname;
	int ret, lerrno;
	bool offline;
	char *buf = NULL;
	size_t buflen;
	NTSTATUS status;
	char *path;

        status = get_full_smb_filename(talloc_tos(), fname, &path);
        if (!NT_STATUS_IS_OK(status)) {
                errno = map_errno_from_nt_status(status);
                return false;
        }

        /* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
	   then assume it is not offline (it may not be 100%, as it could be sparse) */
	if (512 * stbuf->st_ex_blocks >=
	    stbuf->st_ex_size * tsmd->online_ratio) {
		DEBUG(10,("%s not offline: st_blocks=%llu st_size=%llu "
			  "online_ratio=%.2f\n", path,
			  (unsigned long long)stbuf->st_ex_blocks,
			  (unsigned long long)stbuf->st_ex_size, tsmd->online_ratio));
		return false;
	}

	dmsession_id = dmapi_get_current_session();
	if (dmsession_id == NULL) {
		DEBUG(2, ("tsmsm_is_offline: no DMAPI session available? "
			  "Assume file is online.\n"));
		return false;
	}

        /* using POSIX capabilities does not work here. It's a slow path, so 
	 * become_root() is just as good anyway (tridge) 
	 */

	/* Also, AIX has DMAPI but no POSIX capablities support. In this case,
	 * we need to be root to do DMAPI manipulations.
	 */
	become_root();

	/* go the slow DMAPI route */
	if (dm_path_to_handle((char*)path, &dmhandle, &dmhandle_len) != 0) {
		DEBUG(2,("dm_path_to_handle failed - assuming offline (%s) - %s\n", 
			 path, strerror(errno)));
		offline = true;
		goto done;
	}

	memset(&dmname, 0, sizeof(dmname));
	strlcpy((char *)&dmname.an_chars[0], tsmd->attrib_name, sizeof(dmname.an_chars));

	if (tsmd->attrib_value != NULL) {
		buflen = strlen(tsmd->attrib_value);
	} else {
		buflen = 1;
	}
	buf = talloc_zero_size(tsmd, buflen);
	if (buf == NULL) {
		DEBUG(0,("out of memory in tsmsm_is_offline -- assuming online (%s)\n", path));
		errno = ENOMEM;
		offline = false;
		goto done;
	}

	do {
		lerrno = 0;

		ret = dm_get_dmattr(*dmsession_id, dmhandle, dmhandle_len, 
				    DM_NO_TOKEN, &dmname, buflen, buf, &rlen);
		if (ret == -1 && errno == EINVAL) {
			DEBUG(0, ("Stale DMAPI session, re-creating it.\n"));
			lerrno = EINVAL;
			if (dmapi_new_session()) {
				dmsession_id = dmapi_get_current_session();
			} else {
				DEBUG(0, 
				      ("Unable to re-create DMAPI session, assuming offline (%s) - %s\n", 
				       path, strerror(errno)));
				offline = true;
				dm_handle_free(dmhandle, dmhandle_len);
				goto done;
			}
		}
	} while (ret == -1 && lerrno == EINVAL);

	/* check if we need a specific attribute value */
	if (tsmd->attrib_value != NULL) {
		offline = (ret == 0 && rlen == buflen && 
			    memcmp(buf, tsmd->attrib_value, buflen) == 0);
	} else {
		/* its offline if the specified DMAPI attribute exists */
		offline = (ret == 0 || (ret == -1 && errno == E2BIG));
	}

	DEBUG(10,("dm_get_dmattr %s ret=%d (%s)\n", path, ret, strerror(errno)));

	ret = 0;

	dm_handle_free(dmhandle, dmhandle_len);	

done:
	talloc_free(buf);
	unbecome_root();
	return offline;
}
Example #8
0
static int open_acl_common(vfs_handle_struct *handle,
			struct smb_filename *smb_fname,
			files_struct *fsp,
			int flags,
			mode_t mode)
{
	uint32_t access_granted = 0;
	struct security_descriptor *pdesc = NULL;
	struct security_descriptor *parent_desc = NULL;
	bool file_existed = true;
	char *fname = NULL;
	NTSTATUS status;

	if (fsp->base_fsp) {
		/* Stream open. Base filename open already did the ACL check. */
		DEBUG(10,("open_acl_common: stream open on %s\n",
			fsp_str_dbg(fsp) ));
		return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
	}

	status = get_full_smb_filename(talloc_tos(), smb_fname,
				       &fname);
	if (!NT_STATUS_IS_OK(status)) {
		goto err;
	}

	status = get_nt_acl_internal(handle,
				NULL,
				fname,
				(OWNER_SECURITY_INFORMATION |
				 GROUP_SECURITY_INFORMATION |
				 DACL_SECURITY_INFORMATION),
				&pdesc);
        if (NT_STATUS_IS_OK(status)) {
		/* See if we can access it. */
		status = smb1_file_se_access_check(handle->conn,
					pdesc,
					handle->conn->server_info->ptok,
					fsp->access_mask,
					&access_granted);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(10,("open_acl_xattr: %s open "
				"refused with error %s\n",
				fsp_str_dbg(fsp),
				nt_errstr(status) ));
			goto err;
		}
        } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
		file_existed = false;
		/*
		 * If O_CREAT is true then we're trying to create a file.
		 * Check the parent directory ACL will allow this.
		 */
		if (flags & O_CREAT) {
			struct security_descriptor *psd = NULL;

			status = check_parent_acl_common(handle, fname,
					SEC_DIR_ADD_FILE, &parent_desc);
			if (!NT_STATUS_IS_OK(status)) {
				goto err;
			}
			/* Cache the parent security descriptor for
			 * later use. We do have an fsp here, but to
			 * keep the code consistent with the directory
			 * case which doesn't, use the handle. */

			/* Attach this to the conn, move from talloc_tos(). */
			psd = (struct security_descriptor *)talloc_move(handle->conn,
				&parent_desc);

			if (!psd) {
				status = NT_STATUS_NO_MEMORY;
				goto err;
			}
			status = NT_STATUS_NO_MEMORY;
			SMB_VFS_HANDLE_SET_DATA(handle, psd, free_sd_common,
				struct security_descriptor *, goto err);
			status = NT_STATUS_OK;
		}
	}

	DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for "
		"%s returned %s\n",
		fsp_str_dbg(fsp),
		nt_errstr(status) ));

	fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
	return fsp->fh->fd;

  err:

	errno = map_errno_from_nt_status(status);
	return -1;
}