Exemplo n.º 1
0
/*
 * Here we expect something like "[proto:]//[user@]host[:psmb[:pnb]][/share][/path]"
 */
int
smb_ctx_parseunc(struct smb_ctx *ctx, const char *unc, int sharetype,
	const char **next)
{
	const char *p = unc;
	char *p1, *psmb, *pnb;
	char tmp[1024];
	int error ;

	ctx->ct_parsedlevel = SMBL_NONE;
	if (*p++ != '/' || *p++ != '/') {
		smb_error("UNC should start with '//'", 0);
		return EINVAL;
	}
	p1 = tmp;
	error = getsubstring(p, '@', p1, sizeof(tmp), &p);
	if (!error) {
		if (ctx->ct_maxlevel < SMBL_VC) {
			smb_error("no user name required", 0);
			return EINVAL;
		}
		if (*p1 == 0) {
			smb_error("empty user name", 0);
			return EINVAL;
		}
		error = smb_ctx_setuser(ctx, tmp);
		if (error)
			return error;
		ctx->ct_parsedlevel = SMBL_VC;
	}
	error = getsubstring(p, '/', p1, sizeof(tmp), &p);
	if (error) {
		error = getsubstring(p, '\0', p1, sizeof(tmp), &p);
		if (error) {
			smb_error("no server name found", 0);
			return error;
		}
	}
	if (*p1 == 0) {
		smb_error("empty server name", 0);
		return EINVAL;
	}
	/*
	 * Check for port number specification.
	 */
	psmb = strchr(tmp, ':');
	if (psmb) {
		*psmb++ = '\0';
		pnb = strchr(psmb, ':');
		if (pnb) {
			*pnb++ = '\0';
			error = smb_ctx_setnbport(ctx, atoi(pnb));
			if (error) {
				smb_error("Invalid NetBIOS port number", 0);
				return error;
			}
		}
		error = smb_ctx_setsmbport(ctx, atoi(psmb));
		if (error) {
			smb_error("Invalid SMB port number", 0);
			return error;
		}
	}
	error = smb_ctx_setserver(ctx, tmp);
	if (error)
		return error;
	if (sharetype == SMB_ST_NONE) {
		*next = p;
		return 0;
	}
	if (*p != 0 && ctx->ct_maxlevel < SMBL_SHARE) {
		smb_error("no share name required", 0);
		return EINVAL;
	}
	error = getsubstring(p, '/', p1, sizeof(tmp), &p);
	if (error) {
		error = getsubstring(p, '\0', p1, sizeof(tmp), &p);
		if (error) {
			smb_error("unexpected end of line", 0);
			return error;
		}
	}
	if (*p1 == 0 && ctx->ct_minlevel >= SMBL_SHARE) {
		smb_error("empty share name", 0);
		return EINVAL;
	}
	*next = p;
	if (*p1 == 0)
		return 0;
	error = smb_ctx_setshare(ctx, p1, sharetype);
	return error;
}
Exemplo n.º 2
0
/*
 * Here we expect something like "[proto:]//[user@]host[/share][/path]"
 */
int
smb_ctx_parseunc(struct smb_ctx *ctx, const char *unc, int sharetype,
	const char **next)
{
	const char *p = unc;
	char *p1;
	char tmp[1024];
	int error ;

	ctx->ct_parsedlevel = SMBL_NONE;
	if (*p++ != '/' || *p++ != '/') {
		smb_error("UNC should start with '//'", 0);
		return EINVAL;
	}
	p1 = tmp;
	error = getsubstring(p, '@', p1, sizeof(tmp), &p);
	if (!error) {
		if (ctx->ct_maxlevel < SMBL_VC) {
			smb_error("no user name required", 0);
			return EINVAL;
		}
		if (*p1 == 0) {
			smb_error("empty user name", 0);
			return EINVAL;
		}
		error = smb_ctx_setuser(ctx, tmp);
		if (error)
			return error;
		ctx->ct_parsedlevel = SMBL_VC;
	}
	error = getsubstring(p, '/', p1, sizeof(tmp), &p);
	if (error) {
		error = getsubstring(p, '\0', p1, sizeof(tmp), &p);
		if (error) {
			smb_error("no server name found", 0);
			return error;
		}
	}
	if (*p1 == 0) {
		smb_error("empty server name", 0);
		return EINVAL;
	}
	error = smb_ctx_setserver(ctx, tmp);
	if (error)
		return error;
	if (sharetype == SMB_ST_NONE) {
		*next = p;
		return 0;
	}
	if (*p != 0 && ctx->ct_maxlevel < SMBL_SHARE) {
		smb_error("no share name required", 0);
		return EINVAL;
	}
	error = getsubstring(p, '/', p1, sizeof(tmp), &p);
	if (error) {
		error = getsubstring(p, '\0', p1, sizeof(tmp), &p);
		if (error) {
			smb_error("unexpected end of line", 0);
			return error;
		}
	}
	if (*p1 == 0 && ctx->ct_minlevel >= SMBL_SHARE) {
		smb_error("empty share name", 0);
		return EINVAL;
	}
	*next = p;
	if (*p1 == 0)
		return 0;
	error = smb_ctx_setshare(ctx, p1, sharetype);
	return error;
}
Exemplo n.º 3
0
Arquivo: ctx.c Projeto: execunix/vinos
int
smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags)
{
	struct smbioc_lookup rq;
	int error;

	if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) {
		smb_error("smb_ctx_lookup() data is not resolved", 0);
		return EINVAL;
	}
	if (ctx->ct_fd != -1) {
		smb_kops.ko_close(ctx->ct_fd);
		ctx->ct_fd = -1;
	}
	error = smb_ctx_gethandle(ctx);
	if (error) {
		smb_error("can't get handle to requester (no /dev/"NSMB_NAME"* device available)", 0);
		return EINVAL;
	}
	bzero(&rq, sizeof(rq));
	bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof(struct smbioc_ossn));
	bcopy(&ctx->ct_sh, &rq.ioc_sh, sizeof(struct smbioc_oshare));
	rq.ioc_flags = flags;
	rq.ioc_level = level;
	if (smb_kops.ko_ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) == -1) {
		error = errno;

		smb_kops.ko_close(ctx->ct_fd);
		ctx->ct_fd = -1;

		/*
		 * Fallback to *SMBSERVER as NetBIOS name. At least
		 * Windows NT and Windows XP require this (or valid
		 * NetBIOS server name), otherwise they refuse connection.
		 */
		if (smb_ctx_setserver(ctx, "*SMBSERVER") != 0)
			goto fail;

		error = smb_ctx_resolve(ctx);
		if (error)
			goto fail;

		error = smb_ctx_gethandle(ctx);
		if (error)
			goto fail;

		bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof(struct smbioc_ossn));

		if (smb_kops.ko_ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) != -1)
			goto success;
		error = errno;

	    fail:
		if (flags & SMBLK_CREATE)
			smb_error("unable to open connection", error);
		return error;
	}

    success:
	return 0;
}