Esempio n. 1
0
/*
 * Takes a DFS path in UNC format (dfs_path) and parse it into a dfs_path_t
 * structure.
 *
 * dfs_path_free() MUST be called to free the allocated memory in this
 * function.
 *
 * Returns:
 *
 * ERROR_INVALID_PARAMETER	path is not a valid UNC or not valid for the
 * 				specified object type
 * ERROR_NOT_ENOUGH_MEMORY	not enough memory to peform the parse
 * ERROR_NOT_FOUND		namespace specified does not exist
 */
uint32_t
dfs_path_parse(dfs_path_t *path, const char *dfs_path, uint32_t path_type)
{
	char rootdir[DFS_PATH_MAX];
	smb_unc_t *unc;
	uint32_t status = ERROR_SUCCESS;
	int rc;

	bzero(path, sizeof (dfs_path_t));
	unc = &path->p_unc;

	rc = smb_unc_init(dfs_path, unc);
	switch (rc) {
	case EINVAL:
		return (ERROR_INVALID_PARAMETER);
	case ENOMEM:
		return (ERROR_NOT_ENOUGH_MEMORY);
	default:
		break;
	}

	if (dfs_namespace_path(unc->unc_share, rootdir, DFS_PATH_MAX)
	    != ERROR_SUCCESS) {
		smb_unc_free(unc);
		return (ERROR_NOT_FOUND);
	}

	if (path_type == DFS_OBJECT_ANY)
		path->p_type = (unc->unc_path != NULL)
		    ? DFS_OBJECT_LINK : DFS_OBJECT_ROOT;
	else
		path->p_type = path_type;

	switch (path->p_type) {
	case DFS_OBJECT_LINK:
		if ((unc->unc_path == NULL) || (*unc->unc_path == '\0'))
			status = ERROR_NOT_FOUND;
		else
			(void) snprintf(path->p_fspath, sizeof (path->p_fspath),
			    "%s/%s", rootdir, unc->unc_path);
		break;

	case DFS_OBJECT_ROOT:
		if (unc->unc_path == NULL)
			(void) strlcpy(path->p_fspath, rootdir,
			    sizeof (path->p_fspath));
		else
			status = ERROR_INVALID_PARAMETER;
		break;

	default:
		status = ERROR_INVALID_PARAMETER;
	}

	if (status != ERROR_SUCCESS)
		smb_unc_free(unc);

	return (status);
}
Esempio n. 2
0
/*
 * [MS-DFSC]: REQ_GET_DFS_REFERRAL
 *
 * Determines the referral type based on the specified path:
 *
 * Domain referral:
 *    ""
 *
 * DC referral:
 *    \<domain>
 *
 * Sysvol referral:
 *    \<domain>\SYSVOL
 *    \<domain>\NETLOGON
 *
 * Root referral:
 *    \<domain>\<dfsname>
 *    \<server>\<dfsname>
 *
 * Link referral:
 *    \<domain>\<dfsname>\<linkpath>
 *    \<server>\<dfsname>\<linkpath>
 */
static dfs_reftype_t
smb_dfs_get_reftype(const char *path)
{
	smb_unc_t unc;
	dfs_reftype_t reftype = 0;

	if (*path == '\0')
		return (DFS_REFERRAL_DOMAIN);

	if (smb_unc_init(path, &unc) != 0)
		return (DFS_REFERRAL_INVALID);

	if (unc.unc_path != NULL) {
		reftype = DFS_REFERRAL_LINK;
	} else if (unc.unc_share != NULL) {
		if ((smb_strcasecmp(unc.unc_share, "SYSVOL", 0) == 0) ||
		    (smb_strcasecmp(unc.unc_share, "NETLOGON", 0) == 0)) {
			reftype = DFS_REFERRAL_SYSVOL;
		} else {
			reftype = DFS_REFERRAL_ROOT;
		}
	} else if (unc.unc_server != NULL) {
		reftype = DFS_REFERRAL_DC;
	}

	smb_unc_free(&unc);
	return (reftype);
}
Esempio n. 3
0
/*
 * valid DFS I/O path:
 *
 * \server-or-domain\share
 * \server-or-domain\share\path
 *
 * All the returned errors by this function needs to be
 * checked against Windows.
 */
static int
smb_pathname_dfs_preprocess(smb_request_t *sr, char *path, size_t pathsz)
{
	smb_unc_t unc;
	char *linkpath;
	int rc;

	if (sr->tid_tree == NULL)
		return (0);

	if ((rc = smb_unc_init(path, &unc)) != 0)
		return (rc);

	if (smb_strcasecmp(unc.unc_share, sr->tid_tree->t_sharename, 0)) {
		smb_unc_free(&unc);
		return (EINVAL);
	}

	linkpath = unc.unc_path;
	(void) snprintf(path, pathsz, "/%s", (linkpath) ? linkpath : "");

	smb_unc_free(&unc);
	return (0);
}
Esempio n. 4
0
/*
 * Frees the allocated memory for p_unc field of the passed path
 */
void
dfs_path_free(dfs_path_t *path)
{
	if (path != NULL)
		smb_unc_free(&path->p_unc);
}