Ejemplo n.º 1
0
int
xauth_write(Spfid *fid, u64 offset, u32 count, u8 *data)
{
	Xauth *auth;

	auth = fid->aux;
	if (!auth) {
		sp_werror("authentication failed", EIO);
		return -1;
	}

	if (offset+count > sizeof(auth->response)) {
		sp_werror("invalid size", EIO);
		return -1;
	}

	if (count <= 0)
		return 0;

	memmove(auth->response + offset, data, count);
	if (offset+count > auth->resplen)
		auth->resplen = offset + count;

	return count;
}
Ejemplo n.º 2
0
int
ukey_del_group(Spuserpool *up, char *uname, char *gname)
{
	Spuser *user;
	Spgroup *group;

	user = up->uname2user(up, uname);
	if (!user) {
		sp_werror("%s: no such user in userpool", EIO, uname);
		return -1;
	}

	group = up->gname2group(up, gname);
	if (!group) {
		sp_werror("%s: no such group in userpool", EIO, gname);
		return -1;
	}

	if (!user->upool->ismember(user->upool, user, group)) {
		sp_werror("user %s not a member of group %s", EIO,
			  uname, gname);
		return -1;
	}		
	return sp_priv_group_deluser(group, user);
}
Ejemplo n.º 3
0
void
spc_request_flushed(Spcreq *r)
{
	int ecode;
	char *ename;
	Spcreq *req, *preq;
	Spcfsys *fs;

	fs = r->fs;
	for(preq=NULL, req = fs->sent_reqs; req != NULL; preq=req, req = req->next)
		if (r == req)
			break;

	if (req) {
		if (preq)
			preq->next = req->next;
		else
			fs->sent_reqs = req->next;

		sp_rerror(&ename, &ecode);
		if (ename)
			ename = strdup(ename);

		sp_werror(Eflush, EIO);
		(*req->cb)(req->cba, NULL);
		sp_werror(ename, ecode);
		free(ename);
	}

	/* if req->flushed is set, the request is not freed if response arrives */
	spc_put_id(fs->tagpool, r->tag);
	free(r);
}
Ejemplo n.º 4
0
Spfcall *
sp_open(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->omode != (u16)~0) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (fid->type&Qtdir && tc->mode != Oread) {
		sp_werror(Eperm, EISDIR);
		goto done;
	}

	rc = (*conn->srv->open)(fid, tc->mode);
	fid->omode = tc->mode;
done:
//	sp_fid_decref(fid);
	return rc;
}
Ejemplo n.º 5
0
int
spc_rpcnb(Spcfsys *fs, Spfcall *tc, void (*cb)(void *, Spfcall *), void *cba)
{
	Spcreq *req;

	if (!fs->spfd) {
		sp_werror("disconnected", ECONNRESET);
		goto error;
	}

	if (fs->ename) {
		sp_werror(fs->ename, fs->ecode);
		goto error;
	}

	req = sp_malloc(sizeof(*req));
	if (!req)
		goto error;

	if (tc->type != Tversion) {
		tc->tag = spc_get_id(fs->tagpool);
		if (tc->tag == NOTAG) {
			free(req);
			sp_werror("tag pool full", EIO);
			goto error;
		}

		sp_set_tag(tc, tc->tag);
	}

	req->tag = tc->tag;
	req->tc = tc;
	req->rc = NULL;
	req->cb = cb;
	req->cba = cba;
	req->fs = fs;
	req->flushed = 0;
	req->next = NULL;

	if (fs->pend_last)
		fs->pend_last->next = req;
	else
		fs->pend_first = req;

	fs->pend_last = req;
	if (!fs->pend_first->next && spfd_can_write(fs->spfd)) 
		spc_fd_write(fs);

	return 0;

error:
	(*cb)(cba, NULL);
	return -1;
}
Ejemplo n.º 6
0
Spcfsys *
spc_netmount(char *address, char *uname, int dfltport)
{
	int fd, port;
	char *addr, *name, *p, *s;
	struct sockaddr_in saddr;
	struct hostent *hostinfo;

	addr = strdup(address);
	if (strncmp(addr, "tcp!", 4) == 0)
		name = addr + 4;
	else
		name = addr;

	port = dfltport;
	p = strrchr(name, '!');
	if (p) {
		*p = '\0';
		p++;
		port = strtol(p, &s, 10);
		if (*s != '\0') {
			sp_werror("invalid port format", EIO);
			goto error;
		}
	}

	fd = socket(PF_INET, SOCK_STREAM, 0);
	if (fd < 0) {
		sp_uerror(errno);
		goto error;
	}

	hostinfo = gethostbyname(name);
	if (!hostinfo) {
		sp_werror("cannot resolve name: %s", EIO, name);
		goto error;
	}

	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr = *(struct in_addr *) hostinfo->h_addr;

	if (connect(fd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
		sp_uerror(errno);
		goto error;
	}

	free(addr);
	return spc_mount(fd, NULL, uname, 0);

error:
	free(addr);
	return NULL;
}
Ejemplo n.º 7
0
void
spc_flush_requests(Spcfsys *fs, Spcfid *fid)
{
	int ecode;
	char *ename;
	Spcreq *preq, *req, *req1;

	if (fs->fd < 0)
		return;

	// check the unsent requests
	sp_rerror(&ename, &ecode);
	if (ename)
		ename = strdup(ename);

	sp_werror(Eflush, EIO);
	preq = NULL;
	req = fs->pend_first;
	while (req != NULL) {
		if (req->tc->fid == fid->fid) {
			if (preq)
				preq->next = req->next;
			else
				fs->pend_first = req->next;

			if (req == fs->pend_last)
				fs->pend_last = preq;

			(*req->cb)(req->cba, NULL);
			req1 = req->next;
			free(req);
			req = req1;
		} else {
			preq = req;
			req = req->next;
		}
	}

	// check the sent ones
	req = fs->sent_reqs;
	while (req != NULL) {
		if (req->tc->fid == fid->fid && !req->flushed) {
			spc_flush_request(req);
			req = fs->sent_reqs;
		} else {
			req = req->next;
		}
	}
	sp_werror(ename, ecode);
	free(ename);
}
Ejemplo n.º 8
0
int
spc_rpc(Spcfsys *fs, Spfcall *tc, Spfcall **rc)
{
	char *ename;
	Spcrpc r;

	if (fs->fd < 0)
		return -1;

	if (rc)
		*rc = NULL;

	r.fs = fs;
	r.tc = tc;
	r.rc = NULL;
	r.ename = NULL;
	r.ecode = 0;
	
	spc_rpcnb(fs, tc, spc_rpc_cb, &r);
	while (!r.ename && !r.rc)
		sp_poll_once();

	if (r.ename) {
		sp_werror(r.ename, r.ecode);
		goto error;
	}

	if (r.rc && r.rc->type == Rerror) {
		ename = sp_strdup(&r.rc->ename);
		if (ename)
			sp_werror(ename, r.rc->ecode);

		free(ename);
		goto error;
	}

	free(r.ename);
	if (rc)
		*rc = r.rc;
	else
		free(r.rc);

	return 0;

error:
	if (r.ename != Enomem)
		free(r.ename);
	free(r.rc);
	return -1;
}
Ejemplo n.º 9
0
Spfcall *
sp_create(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->omode != (u16)~0) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (!fid->type&Qtdir) {
		sp_werror(Enotdir, ENOTDIR);
		goto done;
	}

	if (tc->perm&Dmdir && tc->mode!=Oread) {
		sp_werror(Eperm, EPERM);
		goto done;
	}

	if (tc->perm&(Dmnamedpipe|Dmsymlink|Dmlink|Dmdevice|Dmsocket)
	&& !fid->conn->dotu) {
		sp_werror(Eperm, ENOTSUP);
		goto done;
	}

	rc = (*conn->srv->create)(fid, &tc->name, tc->perm, tc->mode, 
		&tc->extension);
	if (rc && rc->type == Rcreate) {
		fid->omode = tc->mode;
		fid->type = rc->qid.type;
	}

done:
//	sp_fid_decref(fid);
	return rc;
}
Ejemplo n.º 10
0
static void
spcfd_write_cb(void *cba, Spfcall *rc)
{
	int ecode;
	char *ename;
	Spcfd *spcfd;

	spcfd = cba;

	spcfd_check_error(spcfd, rc);
	sp_rerror(&ename, &ecode);
	if (ecode) {
		spcfd->flags |= Error;
		goto do_notify;
	}

	spcfd->offset += rc->count;
	if (rc->count < spcfd->wpos)
		memmove(spcfd->wbuf, spcfd->wbuf + rc->count, spcfd->wpos - rc->count);

	spcfd->wpos -= rc->count;

do_notify:
	free(spcfd->wtc);
	spcfd->wtc = NULL;
	free(rc);
	if (spcfd->flags & Remove)
		spcfd_remove(spcfd);
	else
		(*spcfd->notify)(spcfd, spcfd->aux);

	sp_werror(NULL, 0);
}
Ejemplo n.º 11
0
int
spcfd_write(Spcfd *spcfd, void *buf, int buflen)
{
	int n;

	if (spcfd->spfd)
		return spfd_write(spcfd->spfd, buf, buflen);

	if (spcfd->wpos == spcfd->iounit) {
		sp_werror("write operation would block", EIO);
		return -1;
	}

	n = spcfd->iounit - spcfd->wpos;
	if (n > buflen)
		n = buflen;

	memmove(spcfd->wbuf + spcfd->wpos, buf, n);
	spcfd->wpos += n;

	if (!spcfd->wtc) {
		spcfd->wtc = sp_create_twrite(spcfd->fid->fid, spcfd->offset, 
			spcfd->wpos, spcfd->wbuf);
		if (spc_rpcnb(spcfd->fid->fsys, spcfd->wtc, spcfd_write_cb, spcfd) < 0) {
			free(spcfd->wtc);
			spcfd->wtc = NULL;
			return -1;
		}
	}

	return n;
}
Ejemplo n.º 12
0
int 
spcfd_read(Spcfd *spcfd, void *buf, int buflen)
{
	int n;

	if (spcfd->spfd)
		return spfd_read(spcfd->spfd, buf, buflen);

	if (spcfd->flags & Reof)
		return 0;

	if (spcfd->rpos == 0) {
		sp_werror("read operation would block", EIO);
		return -1;
	}

	n = buflen;
	if (n > spcfd->rpos)
		n = spcfd->rpos;

	memmove(buf, spcfd->rbuf, n);
	if (n < spcfd->rpos)
		memmove(spcfd->rbuf, spcfd->rbuf + n, spcfd->rpos - n);
	spcfd->rpos -= n;

	spcfd_send_read_request(spcfd);
	return n;
}
Ejemplo n.º 13
0
static void
spcfd_read_cb(void *cba, Spfcall *rc)
{
	int n, ecode;
	char *ename;
	Spcfd *spcfd;

	spcfd = cba;
	spcfd_check_error(spcfd, rc);
	sp_rerror(&ename, &ecode);
	if (ecode) {
		spcfd->flags |= Error;
		goto do_notify;
	}

	n = spcfd->rpos;
	if (rc->count) {
		memmove(spcfd->rbuf + spcfd->rpos, rc->data, rc->count);
		spcfd->rpos += rc->count;
		spcfd->offset += rc->count;
	} else
		spcfd->flags |= Reof;

do_notify:
	free(spcfd->rtc);
	spcfd->rtc = NULL;
	free(rc);

	if (spcfd->flags & Remove)
		spcfd_remove(spcfd);
	else
		(*spcfd->notify)(spcfd, spcfd->aux);

	sp_werror(NULL, 0);
}
Ejemplo n.º 14
0
Spfcall *
sp_write(Spreq *req, Spfcall *tc)
{
	int n;
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->type&Qtauth) {
		if (conn->srv->auth) {
			n = conn->srv->auth->write(fid, tc->offset,
				tc->count, tc->data);
			if (n >= 0)
				rc = sp_create_rwrite(n);

			goto done;
		} else {
			sp_werror(Ebadusefid, EIO);
			goto done;
		}
	}

	if (fid->omode==(u16)~0 || fid->type&Qtdir || (fid->omode&3)==Oread) {
		sp_werror(Ebadusefid, EIO);
		goto done;
	}

	if (tc->count+IOHDRSZ > conn->msize) {
		sp_werror(Etoolarge, EIO);
		goto done;
	}

	rc = (*conn->srv->write)(fid, tc->offset, tc->count, tc->data, req);

done:
	return rc;
}
Ejemplo n.º 15
0
static void
create_rerror(int ecode)
{
	char buf[256];

	strerror_r(ecode, buf, sizeof(buf));
	sp_werror(buf, ecode);
}
Ejemplo n.º 16
0
void
sp_uerror(int ecode)
{
	char *ename;

	ename = strerror(ecode);
	sp_werror(ename, ecode);
}
Ejemplo n.º 17
0
Spfcall *
sp_clunk(Spreq *req, Spfcall *tc)
{
	int n;
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;

	rc = NULL;
	conn = req->conn;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (fid->type&Qtauth) {
		if (conn->srv->auth) {
			n = conn->srv->auth->clunk(fid);
			if (n)
				rc = sp_create_rclunk();
		} else
			sp_werror(Ebadusefid, EIO);

		goto done;
	}

	if (fid->omode!=(u16)~0 && fid->omode==Orclose) {
		rc = (*conn->srv->remove)(fid);
		if (rc->type == Rerror)
			goto done;
		free(rc);
		rc = sp_create_rclunk();
	} else
		rc = (*conn->srv->clunk)(fid);

	if (rc && rc->type == Rclunk)
		sp_fid_decref(fid);

done:
	return rc;
}
Ejemplo n.º 18
0
void
sp_suerror(char *s, int ecode)
{
	char err[1024];
	char buf[1024];

	strerror_r(ecode, err, sizeof(err));
	snprintf(buf, sizeof(buf), "%s: %s", s, err);
	sp_werror(buf, ecode);
}
Ejemplo n.º 19
0
int
ukey_add_group(Spuserpool *up, char *uname, char *gname)
{
	Spuser *user;
	Spgroup *group;

	user = up->uname2user(up, uname);
	if (!user) {
		sp_werror("%s: no such user in userpool", EIO, uname);
		return -1;
	}

	group = up->gname2group(up, gname);
	if (!group) {
		sp_werror("%s: no such group in userpool", EIO, gname);
		return -1;
	}
	return sp_priv_group_adduser(group, user);
}
Ejemplo n.º 20
0
Spfcall *
sp_version(Spreq *req, Spfcall *tc)
{
	if (tc->msize < IOHDRSZ + 1) {
		sp_werror("msize too small", EIO);
		return NULL;
	}

	return (*req->conn->srv->version)(req->conn, tc->msize, &tc->version);
}
Ejemplo n.º 21
0
void *
sp_malloc(int size)
{
	void *ret;

	ret = malloc(size);
	if (!ret)
		sp_werror(Enomem, ENOMEM);

	return ret;
}
Ejemplo n.º 22
0
static void
spc_notify(Spfd *spfd, void *aux)
{
	int ecode;
	char *ename;
	Spcfsys *fs;

	fs = aux;
	fs->in_notify++;
	sp_rerror(&ename, &ecode);
	if (ename)
		ename = strdup(ename);

	sp_werror(NULL, 0);
	if (spfd_can_read(spfd))
		spc_fd_read(fs);

	if (fs->destroyed) {
		free(fs);
		return;
	}

	if (!fs->spfd)
		goto error;

	if (spfd_can_write(spfd))
		spc_fd_write(fs);

	if (spfd_has_error(spfd))
		spc_disconnect_fsys(fs);

error:
	sp_rerror(&ename, &ecode);
	if (ecode) {
		if (spc_chatty)
			fprintf(stderr, "Error: %s: %d\n", ename, ecode);
		sp_werror(NULL, 0);
	}
	fs->in_notify--;
}
Ejemplo n.º 23
0
static void
spcfd_check_error(Spcfd *spcfd, Spfcall *rc)
{
	char *ename;

	if (rc && rc->type == Rerror) {
		ename = sp_strdup(&rc->ename);
		if (ename) {
			sp_werror(ename, rc->ecode);
			free(ename);
		}
	}
}
Ejemplo n.º 24
0
int
group_del(Spuserpool *up, char *groupname)
{
	Spgroup *g;

	g = up->gname2group(up, groupname);
	if (!g) {
		sp_werror("%s: no such group in userpool", EIO, groupname);
		return -1;
	} else {
		sp_priv_group_del(g);
		return 0;
	}
}
Ejemplo n.º 25
0
Spfcall *
sp_wstat(Spreq *req, Spfcall *tc)
{
	Spconn *conn;
	Spfid *fid;
	Spfcall *rc;
	Spstat *stat;

	rc = NULL;
	conn = req->conn;
	stat = &tc->stat;
	fid = sp_fid_find(conn, tc->fid);
	if (!fid) {
		sp_werror(Eunknownfid, EIO);
		goto done;
	} else 
		sp_fid_incref(fid);

	req->fid = fid;
	if (stat->type != (u16)~0 || stat->dev != (u32)~0
	|| stat->qid.version != (u32)~0
	|| stat->qid.path != (u64)~0 ) {
                sp_werror(Eperm, EPERM);
                goto done;
        }

	if ((fid->type&Qtdir && !stat->mode&Dmdir)
	|| (!fid->type&Qtdir&&stat->mode&Dmdir)) {
		sp_werror(Edirchange, EPERM);
		goto done;
	}

	rc = (*conn->srv->wstat)(fid, &tc->stat);
done:
//	sp_fid_decref(fid);
	return rc;
}
Ejemplo n.º 26
0
int
xauth_read(Spfid *fid, u64 offset, u32 count, u8 *data)
{
	int n;
	Xauth *auth;

	n = 0;
	auth = fid->aux;
	if (!auth) {
		sp_werror("authentication failed", EIO);
		return -1;
	}

	n = cutbuf(data, offset, count, auth->authid, 0, sizeof(auth->authid));
	return n;
}
Ejemplo n.º 27
0
int
ukey_del(Spuserpool *up, char *uname)
{
	Spuser *user;
	int i;

	user = up->uname2user(up, uname);
	if (user) {
		for(i=0; i < user->ngroups; i++)
			sp_priv_group_deluser(user->groups[i], user);

		sp_priv_user_del(user);
		sp_user_decref(user);
		return 0;
	} else {
		sp_werror("%s: no such user in userpool", EIO, uname);
		return -1;
	}
}
Ejemplo n.º 28
0
Xpcopy *
xp_file_copy_start(Xpfile *files)
{
	Xpfile *f;
	Xpcopy *c;

	c = malloc(sizeof(*c));
	if (!c) {
		sp_werror(Enomem, ENOMEM);
		return NULL;
	}

	c->files = files;
	c->cfile = files;
	c->finish = NULL;
	c->finishaux = NULL;

	for(f = files; f != NULL; f = f->next) {
		int append = 0;
		if (strstr(f->name, "env"))
			append = Oappend;
		if (f->create) {
			f->fid = spc_create(f->fs, f->name, f->perm, Owrite | append);
			if (!f->fid && f->perm&Dmdir)
				f->fid = spc_open(f->fs, f->name, Oread);
		} else
			if (append)
				f->fid = spc_open(f->fs, f->name, Owrite | append);
			else
				f->fid = spc_open(f->fs, f->name, Owrite | Otrunc);


		if (!f->fid) {
			free(c);
			return NULL;
		}
	}

	xp_file_copy(c);
	return c;
}
Ejemplo n.º 29
0
static Spfcall*
npfs_attach(Spfid *nfid, Spfid *nafid, Spstr *uname, Spstr *aname, u32 n_uname)
{
	int err;
	Spfcall* ret;
	Fid *fid;
	Spqid qid;
	char *user;

	user = NULL;
	ret = NULL;

	if (nafid != NULL) {
		sp_werror(Enoauth, EIO);
		goto done;
	}

	fid = npfs_fidalloc();
	fid->omode = -1;
	npfs_change_user(nfid->user);

	fid->omode = -1;
	if (aname->len==0 || *aname->str!='/')
		fid->path = strdup("/");
	else
		fid->path = sp_strdup(aname);
	
	nfid->aux = fid;
	err = fidstat(fid);
	if (err < 0) {
		create_rerror(err);
		goto done;
	}

	ustat2qid(&fid->stat, &qid);
	ret = sp_create_rattach(&qid);
	sp_fid_incref(nfid);

done:
	return ret;
}
Ejemplo n.º 30
0
int
ukey_add(Spuserpool *up, char *uname, u32 uid, char *dfltgname, 
	char *key, int keylen)
{
	Spuser *user;
	Spgroup *dgrp;
	Xkey *xkey;

	xkey = NULL;
	if (key) {
		xkey = xauth_pubkey_create(key, keylen);
		if (!xkey)
			return -1;
	}

	user = sp_priv_user_add(up, uname, uid, xkey);
	if (!user) {
		if (xkey)
			xauth_destroy(xkey);
		return -1;
	}

	if (dfltgname) {
		dgrp = up->gname2group(up, dfltgname);
		if (!dgrp) {
			sp_werror("%s:%s", EIO, dfltgname, "group not found");
			sp_priv_user_del(user);
			sp_user_decref(user);
			xauth_destroy(xkey);
			return -1;
		}

		sp_priv_group_adduser(dgrp, user);
		sp_priv_user_setdfltgroup(user, dgrp);
	}

	return 0;
}