Exemplo n.º 1
0
/* Tremove - remove a file or directory.
 */
Npfcall*
diod_remove (Npfid *fid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (remove (f->path) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (!(ret = np_create_rremove ())) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_remove %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 2
0
/* Tstatfs - read file system information.
 * N.B. must call statfs() for f_type and statvfs() for unsigned long f_fsid
 */
Npfcall*
diod_statfs (Npfid *fid)
{
    Fid *f = fid->aux;
    struct statfs sb;
    struct statvfs svb;
    Npfcall *ret = NULL;

    if (statfs (f->path, &sb) < 0) {
        np_uerror (errno);
        goto error;
    }
    if (statvfs (f->path, &svb) < 0) {
        np_uerror (errno);
        goto error;
    }
    if (!(ret = np_create_rstatfs(sb.f_type, sb.f_bsize, sb.f_blocks,
                                  sb.f_bfree, sb.f_bavail, sb.f_files,
                                  sb.f_ffree, (u64) svb.f_fsid,
                                  sb.f_namelen))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_statfs %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 3
0
/* Twrite - write to a file.
 */
Npfcall*
diod_write (Npfid *fid, u64 offset, u32 count, u8 *data, Npreq *req)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    ssize_t n;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if ((n = pwrite (f->fd, data, count, offset)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (!(ret = np_create_rwrite (n))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_write %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 4
0
/* Tread - read from a file or directory.
 */
Npfcall*
diod_read (Npfid *fid, u64 offset, u32 count, Npreq *req)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    ssize_t n;

    if (!f->ioctx) {
        msg ("diod_read: fid is not open");
        np_uerror (EBADF);
        goto error;
    }
    if (!(ret = np_alloc_rread (count))) {
        np_uerror (ENOMEM);
        goto error;
    }
    n = ioctx_pread (f->ioctx, ret->u.rread.data, count, offset);
    if (n < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    np_set_rread_count (ret, n);
    return ret;
error:
    errn (np_rerror (), "diod_read %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    if (ret)
        free (ret);
    return NULL; 
}
Exemplo n.º 5
0
/* Locking note:
 * Implement POSIX locks in terms of BSD flock locks.
 * This at least gets distributed whole-file locking to work.
 * Strategies for distributed record locking will deadlock.
 */
Npfcall*
diod_lock (Npfid *fid, u8 type, u32 flags, u64 start, u64 length, u32 proc_id,
           Npstr *client_id)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    u8 status = P9_LOCK_ERROR;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (flags & ~P9_LOCK_FLAGS_BLOCK) { /* only one valid flag for now */
        np_uerror (EINVAL);             /*  (which we ignore) */
        goto error;
    }
    if (_fidstat(f) < 0)
        goto error_quiet;
    switch (type) {
        case F_UNLCK:
            if (flock (f->fd, LOCK_UN) >= 0) {
                status = P9_LOCK_SUCCESS;
                f->lock_type = LOCK_UN;
            } else
                status = P9_LOCK_ERROR;
            break;
        case F_RDLCK:
            if (flock (f->fd, LOCK_SH | LOCK_NB) >= 0) {
                status = P9_LOCK_SUCCESS;
                f->lock_type = LOCK_SH;
            } else if (errno == EWOULDBLOCK) {
                status = P9_LOCK_BLOCKED;
            } else
                status = P9_LOCK_ERROR;
            break;
        case F_WRLCK:
            if (flock (f->fd, LOCK_EX | LOCK_NB) >= 0) {
                status = P9_LOCK_SUCCESS;
                f->lock_type = LOCK_EX;
            } else if (errno == EWOULDBLOCK) {
                status  = P9_LOCK_BLOCKED;
            }
            break;
        default:
            np_uerror (EINVAL);
            goto error;
    }
    if (!((ret = np_create_rlock (status)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_lock %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 6
0
/* Twrite - write to a file.
 */
Npfcall*
diod_write (Npfid *fid, u64 offset, u32 count, u8 *data, Npreq *req)
{
    Fid *f = fid->aux;
    Npfcall *ret;
    ssize_t n;

    if (!f->ioctx) {
        msg ("diod_write: fid is not open");
        np_uerror (EBADF);
        goto error;
    }
    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if ((n = ioctx_pwrite (f->ioctx, data, count, offset)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (!(ret = np_create_rwrite (n))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_write %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    return NULL;
}
Exemplo n.º 7
0
/* Tstatfs - read file system information.
 */
Npfcall*
diod_statfs (Npfid *fid)
{
    Fid *f = fid->aux;
    struct statfs sb;
    Npfcall *ret;
    u64 fsid;
    u32 type = V9FS_MAGIC;

    if (statfs (path_s (f->path), &sb) < 0) {
        np_uerror (errno);
        goto error;
    }

    fsid = (u64)sb.f_fsid.__val[0] | ((u64)sb.f_fsid.__val[1] << 32);
    if (diod_conf_get_statfs_passthru ())
        type = sb.f_type;

    if (!(ret = np_create_rstatfs(type, sb.f_bsize, sb.f_blocks,
                                  sb.f_bfree, sb.f_bavail, sb.f_files,
                                  sb.f_ffree, fsid,
                                  sb.f_namelen))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_statfs %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
    return NULL;
}
Exemplo n.º 8
0
Npfcall*
diod_lcreate(Npfid *fid, Npstr *name, u32 flags, u32 mode, u32 gid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    char *npath = NULL;
    Npqid qid;
    int fd = -1;
    struct stat sb;
    mode_t saved_umask;
    int created = 0;
    u32 iounit = 0; /* client will use msize-P9_IOHDRSZ */

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(flags & O_CREAT)) /* can't happen? */
        flags |= O_CREAT;
    if (!(npath = _mkpath(f->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    saved_umask = umask(0);
    if ((fd = open (npath, flags, mode)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    created = 1;
    umask(saved_umask);
    if (fstat (fd, &sb) < 0) {
        np_uerror (errno);
        goto error; /* shouldn't happen? */
    }
    _ustat2qid (&sb, &qid);
    //iounit = sb.st_blksize;
    if (!((ret = np_create_rlcreate (&qid, iounit)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (f->path);
    f->path = npath;
    f->fd = fd;
    return ret;
error:
    errn (np_rerror (), "diod_lcreate %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          name->len, name->str);
error_quiet:
    if (fd >= 0) {
        (void)close (fd);
    }
    if (created && npath)
        (void)unlink (npath);
    if (npath)
        free (npath);
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 9
0
Npfcall*
diod_fsync (Npfid *fid)
{
    Fid *f = fid->aux;
    Npfcall *ret;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!f->ioctx) {
        msg ("diod_fsync: fid is not open");
        np_uerror (EBADF);
        goto error;
    }
    if (ioctx_fsync (f->ioctx) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (!((ret = np_create_rfsync ()))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_fsync %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    return NULL;
}
Exemplo n.º 10
0
Npfcall*
diod_readdir(Npfid *fid, u64 offset, u32 count, Npreq *req)
{
    int n;
    Fid *f = fid->aux;
    Npfcall *ret;

    if (!f->ioctx) {
        msg ("diod_readdir: fid is not open");
        np_uerror (EBADF);
        goto error; 
    }
    if (!(ret = np_create_rreaddir (count))) {
        np_uerror (ENOMEM);
        goto error;
    }
    n = _read_dir_linux (f, ret->u.rreaddir.data, offset, count);
    if (np_rerror ()) {
        free (ret);
        ret = NULL;
    } else
        np_finalize_rreaddir (ret, n);
    return ret;
error:
    errn (np_rerror (), "diod_readdir %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
    return NULL;
}
Exemplo n.º 11
0
Npfcall*
diod_readlink(Npfid *fid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    char target[PATH_MAX + 1];
    int n;

    if ((n = readlink (f->path, target, sizeof(target) - 1)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    target[n] = '\0';
    if (!(ret = np_create_rreadlink(target))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_readlink %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 12
0
/* Tread - read from a file or directory.
 */
Npfcall*
diod_read (Npfid *fid, u64 offset, u32 count, Npreq *req)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    ssize_t n;

    if (!(ret = np_alloc_rread (count))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if ((n = pread (f->fd, ret->u.rread.data, count, offset)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    np_set_rread_count (ret, n);
    return ret;
error:
    errn (np_rerror (), "diod_read %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (ret)
        free (ret);
    return NULL; 
}
Exemplo n.º 13
0
/* Tremove - remove a file or directory.
 */
Npfcall*
diod_remove (Npfid *fid)
{
    Fid *f = fid->aux;
    Npfcall *ret;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (remove (path_s (f->path)) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (!(ret = np_create_rremove ())) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_remove %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    return NULL;
}
Exemplo n.º 14
0
Npfcall*
diod_lcreate(Npfid *fid, Npstr *name, u32 flags, u32 mode, u32 gid)
{
    Npsrv *srv = fid->conn->srv;
    Fid *f = fid->aux;
    Npfcall *ret;
    Path opath = NULL;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }

    flags = _remap_oflags (flags);

    if (flags & O_DIRECT) {
        np_uerror (EINVAL); /* O_DIRECT not allowed - see issue 110 */
        goto error_quiet;
    }
    if (!(flags & O_CREAT)) /* can't happen? */
        flags |= O_CREAT;

    if (f->ioctx != NULL) {
        msg ("diod_lcreate: fid is already open");
        np_uerror (EINVAL);
        goto error; 
    }
    opath = f->path;
    if (!(f->path = path_append (srv, opath, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (ioctx_open (fid, flags, mode) < 0) {
        if (np_rerror () == ENOMEM)
            goto error;
        goto error_quiet;
    }
    if (!((ret = np_create_rlcreate (ioctx_qid (f->ioctx),
                                     ioctx_iounit (f->ioctx))))) {
        (void)ioctx_close (fid, 0);
        (void)unlink (path_s (f->path));
        np_uerror (ENOMEM);
        goto error;
    }
    path_decref (srv, opath);
    return ret;
error:
    errn (np_rerror (), "diod_lcreate %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          opath ? path_s (opath) : path_s (f->path), name->len, name->str);
error_quiet:
    if (opath) {
        if (f->path)
            path_decref (srv, f->path);
        f->path = opath;
    }
    return NULL;
}
Exemplo n.º 15
0
Npfcall*
diod_symlink(Npfid *fid, Npstr *name, Npstr *symtgt, u32 gid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;
    char *target = NULL, *npath = NULL;
    Npqid qid;
    struct stat sb;
    mode_t saved_umask;
    int created = 0;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = _mkpath(f->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (!(target = np_strdup (symtgt))) {
        np_uerror (ENOMEM);
        goto error;
    }
    saved_umask = umask(0);
    if (symlink (target, npath) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    created = 1;
    umask(saved_umask);
    if (lstat (npath, &sb) < 0) {
        np_uerror (errno);
        goto error; /* shouldn't happen? */
    }
    _ustat2qid (&sb, &qid);
    if (!((ret = np_create_rsymlink (&qid)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (npath);
    free (target);
    return ret;
error:
    errn (np_rerror (), "diod_symlink %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          name->len, name->str);
error_quiet:
    if (created && npath)
        (void)unlink (npath);
    if (npath)
        free (npath);
    if (target)
        free (target);
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 16
0
Npfcall*
diod_lopen (Npfid *fid, u32 flags)
{
    Fid *f = fid->aux;
    Npfcall *res = NULL;
    Npqid qid;
    u32 iounit = 0; /* client will use msize-P9_IOHDRSZ */

    if ((f->xflags & XFLAGS_RO) && ((flags & O_WRONLY) || (flags & O_RDWR))) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if ((flags & O_CREAT)) /* can't happen? */
        flags &= ~O_CREAT; /* clear and allow to fail with ENOENT */

    if (_fidstat (f) < 0)
        goto error_quiet;

    if (S_ISDIR (f->stat.st_mode)) {
        f->dir = opendir (f->path);
        if (!f->dir) {
            np_uerror (errno);
            goto error_quiet;
        }
    } else {
        f->fd = open (f->path, flags);
        if (f->fd < 0) {
            np_uerror (errno);
            goto error_quiet;
        }
    }
    if (_fidstat (f) < 0)
        goto error; /* can't happen? */
    _ustat2qid (&f->stat, &qid);
    //iounit = f->stat.st_blksize;
    if (!(res = np_create_rlopen (&qid, iounit))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return res;
error:
    errn (np_rerror (), "diod_lopen %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (f->dir) {
        (void)closedir (f->dir);
        f->dir = NULL;
    }
    if (f->fd != -1) {
        (void)close (f->fd); 
        f->fd = -1;
    }
    if (res)
        free (res);
    return NULL;
}
Exemplo n.º 17
0
/* Locking note:
 * Implement POSIX locks in terms of BSD flock locks.
 * This at least gets distributed whole-file locking to work.
 * Strategies for distributed record locking will deadlock.
 */
Npfcall*
diod_lock (Npfid *fid, u8 type, u32 flags, u64 start, u64 length, u32 proc_id,
           Npstr *client_id)
{
    Fid *f = fid->aux;
    Npfcall *ret;
    u8 status = P9_LOCK_ERROR;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (flags & ~P9_LOCK_FLAGS_BLOCK) { /* only one valid flag for now */
        np_uerror (EINVAL);             /*  (which we ignore) */
        goto error;
    }
    if (!f->ioctx) {
        msg ("diod_lock: fid is not open");
        np_uerror (EBADF);
        goto error;
    }
    switch (type) {
        case P9_LOCK_TYPE_UNLCK:
            if (ioctx_flock (f->ioctx, LOCK_UN) == 0)
                status = P9_LOCK_SUCCESS;
            break;
        case P9_LOCK_TYPE_RDLCK:
            if (ioctx_flock (f->ioctx, LOCK_SH | LOCK_NB) == 0)
                status = P9_LOCK_SUCCESS;
            else if (errno == EWOULDBLOCK)
                status = P9_LOCK_BLOCKED;
            break;
        case P9_LOCK_TYPE_WRLCK:
            if (ioctx_flock (f->ioctx, LOCK_EX | LOCK_NB) == 0) 
                status = P9_LOCK_SUCCESS;
            else if (errno == EWOULDBLOCK)
                status  = P9_LOCK_BLOCKED;
            break;
        default:
            np_uerror (EINVAL);
            goto error;
    }
    if (!((ret = np_create_rlock (status)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_lock %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    return NULL;
}
Exemplo n.º 18
0
Arquivo: ops.c Projeto: eugmes/diod
Npfcall*
diod_lopen (Npfid *fid, u32 flags)
{
    Fid *f = fid->aux;
    Npfcall *res;
    Npqid qid;
    u32 iounit = 0; /* if iounit is 0, v9fs will use msize-P9_IOHDRSZ */
    struct stat sb;

    if ((f->xflags & XFLAGS_RO) && ((flags & O_WRONLY) || (flags & O_RDWR))) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if ((flags & O_CREAT)) /* can't happen? */
        flags &= ~O_CREAT; /* clear and allow to fail with ENOENT */

    f->fd = open (f->path, flags);
    if (f->fd < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    f->dir = fdopendir (f->fd);
    if (!f->dir && errno != ENOTDIR) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (fstat (f->fd, &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    _ustat2qid (&sb, &qid);
    //iounit = sb.st_blksize;
    if (!(res = np_create_rlopen (&qid, iounit))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return res;
error:
    errn (np_rerror (), "diod_lopen %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
error_quiet:
    if (f->dir)
        (void)closedir (f->dir);
    else if (f->fd != -1)
        (void)close (f->fd); 
    f->dir = NULL;
    f->fd = -1;
    return NULL;
}
Exemplo n.º 19
0
Npfcall*
diod_symlink(Npfid *fid, Npstr *name, Npstr *symtgt, u32 gid)
{
    Npsrv *srv = fid->conn->srv;
    Fid *f = fid->aux;
    Npfcall *ret;
    char *target = NULL;
    Path npath = NULL;
    Npqid qid;
    struct stat sb;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = path_append (srv, f->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (!(target = np_strdup (symtgt))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (symlink (target, path_s (npath)) < 0 || lstat (path_s (npath),
                                                       &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    diod_ustat2qid (&sb, &qid);
    if (!((ret = np_create_rsymlink (&qid)))) {
        (void)unlink (path_s (npath));
        np_uerror (ENOMEM);
        goto error;
    }
    path_decref (srv, npath);
    free (target);
    return ret;
error:
    errn (np_rerror (), "diod_symlink %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path), name->len, name->str);
error_quiet:
    if (npath)
        path_decref (srv, npath);
    if (target)
        free (target);
    return NULL;
}
Exemplo n.º 20
0
/* Tattach - attach a new user (fid->user) to aname.
 *   diod_auth.c::diod_checkauth first authenticates/authorizes user
 */
Npfcall*
diod_attach (Npfid *fid, Npfid *afid, Npstr *aname)
{
    Npfcall* ret = NULL;
    Fid *f = NULL;
    Npqid qid;
    struct stat sb;
    int xflags;

    if (aname->len == 0 || *aname->str != '/') {
        np_uerror (EPERM);
        goto error;
    }
    if (!(f = diod_fidalloc (fid, aname))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (diod_conf_opt_runasuid ()) {
        if (fid->user->uid != diod_conf_get_runasuid ()) {
            np_uerror (EPERM);
            goto error;
        }
    }
    if (!diod_match_exports (path_s (f->path), fid->conn, fid->user, &xflags))
        goto error;
    if ((xflags & XFLAGS_RO))
        f->flags |= DIOD_FID_FLAGS_ROFS;
    if ((xflags & XFLAGS_SHAREFD))
        f->flags |= DIOD_FID_FLAGS_SHAREFD;
    if (stat (path_s (f->path), &sb) < 0) { /* OK to follow symbolic links */
        np_uerror (errno);
        goto error;
    }
    /* N.B. removed S_ISDIR (sb.st_mode) || return ENOTDIR check.
     * Allow a regular file or a blcok device to be exported.
     */
    diod_ustat2qid (&sb, &qid);
    if ((ret = np_create_rattach (&qid)) == NULL) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_attach %s@%s:%.*s", fid->user->uname,
          np_conn_get_client_id (fid->conn), aname->len, aname->str);
    diod_fiddestroy (fid);
    return NULL;
}
Exemplo n.º 21
0
static char *
_get_one_request (char **sp, int *lp, Npreq *req)
{
	char *uname = req->fid ? req->fid->user->uname : "-";
	char *aname = req->fid && req->fid->aname ? req->fid->aname : "-";
	char reqstr[40];

	np_snprintfcall (reqstr, sizeof (reqstr), req->tcall);
	if (aspf (sp, lp, "%-10.10s %-10.10s %-10.10s %s...\n",
		 			np_conn_get_client_id (req->conn),
					aname, uname, reqstr) < 0) {
		np_uerror (ENOMEM);
		return NULL;
	}
	return *sp;
}
Exemplo n.º 22
0
/* Twalk - walk a file path
 * Called from fcall.c::np_walk () to clone the fid.
 * On error, call np_uerror () and return 0.
 */
int
diod_clone (Npfid *fid, Npfid *newfid)
{
    Fid *f = fid->aux;

    if (!(diod_fidclone (newfid, fid))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return 1;
error:
    errn (np_rerror (), "diod_clone %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
    return 0;
}
Exemplo n.º 23
0
Arquivo: ops.c Projeto: eugmes/diod
/* Tattach - attach a new user (fid->user) to aname.
 *   diod_auth.c::diod_checkauth first authenticates/authorizes user
 */
Npfcall*
diod_attach (Npfid *fid, Npfid *afid, Npstr *aname)
{
    Npfcall* ret = NULL;
    Fid *f = NULL;
    Npqid qid;
    struct stat sb;

    if (aname->len == 0 || *aname->str != '/') {
        np_uerror (EPERM);
        goto error;
    }
    if (!(f = _fidalloc ()) || !(f->path = np_strdup (aname))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (diod_conf_opt_runasuid ()) {
        if (fid->user->uid != diod_conf_get_runasuid ()) {
            np_uerror (EPERM);
            goto error;
        }
    }
    if (!diod_match_exports (f->path, fid->conn, fid->user, &f->xflags))
        goto error;
    if (stat (f->path, &sb) < 0) { /* OK to follow symbolic links */
        np_uerror (errno);
        goto error;
    }
    if (!S_ISDIR (sb.st_mode)) {
        np_uerror (ENOTDIR);
        goto error;
    }
    _ustat2qid (&sb, &qid);
    if ((ret = np_create_rattach (&qid)) == NULL) {
        np_uerror (ENOMEM);
        goto error;
    }
    fid->aux = f;
    np_fid_incref (fid);
    return ret;
error:
    errn (np_rerror (), "diod_attach %s@%s:%.*s", fid->user->uname,
          np_conn_get_client_id (fid->conn), aname->len, aname->str);
    if (f)
        _fidfree (f);
    return NULL;
}
Exemplo n.º 24
0
Npfcall*
diod_getattr(Npfid *fid, u64 request_mask)
{
    Fid *f = fid->aux;
    Npfcall *ret;
    Npqid qid;
    struct stat sb;

    if ((f->flags & DIOD_FID_FLAGS_MOUNTPT)) {
        if (_statmnt (path_s (f->path), &sb) < 0) {
            np_uerror (errno);
            goto error_quiet;
        }
    } else {
        if (lstat (path_s (f->path), &sb) < 0) {
            np_uerror (errno);
            goto error_quiet;
        }
    }
    diod_ustat2qid (&sb, &qid);
    if (!(ret = np_create_rgetattr(request_mask, &qid,
                                    sb.st_mode,
                                    sb.st_uid,
                                    sb.st_gid,
                                    sb.st_nlink,
                                    sb.st_rdev,
                                    sb.st_size,
                                    sb.st_blksize,
                                    sb.st_blocks,
                                    sb.st_atim.tv_sec,
                                    sb.st_atim.tv_nsec,
                                    sb.st_mtim.tv_sec,
                                    sb.st_mtim.tv_nsec,
                                    sb.st_ctim.tv_sec,
                                    sb.st_ctim.tv_nsec,
                                    0, 0, 0, 0))) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_getattr %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    return NULL;
}
Exemplo n.º 25
0
Npfcall*
diod_lopen (Npfid *fid, u32 flags)
{
    Fid *f = fid->aux;
    Npfcall *res;

    if ((f->flags & DIOD_FID_FLAGS_ROFS) && ((flags & O_WRONLY)
                                          || (flags & O_RDWR))) {
        np_uerror (EROFS);
        goto error_quiet;
    }

    flags = _remap_oflags (flags);

    if (flags & O_DIRECT) {
        np_uerror (EINVAL); /* O_DIRECT not allowed - see issue 110 */
        goto error_quiet;
    }
    if ((flags & O_CREAT)) /* can't happen? */
        flags &= ~O_CREAT; /* clear and allow to fail with ENOENT */

    if (f->ioctx != NULL) {
        msg ("diod_lopen: fid is already open");
        np_uerror (EINVAL);
        goto error; 
    }
    if (ioctx_open (fid, flags, 0) < 0) {
        if (np_rerror () == ENOMEM)
            goto error;
        goto error_quiet;
    }
    if (!(res = np_create_rlopen (ioctx_qid (f->ioctx),
                                  ioctx_iounit (f->ioctx)))) {
        (void)ioctx_close (fid, 0);
        np_uerror (ENOMEM);
        goto error;
    }
    return res;
error:
    errn (np_rerror (), "diod_lopen %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    return NULL;
}
Exemplo n.º 26
0
/* Tclunk - close a file.
 */
Npfcall*
diod_clunk (Npfid *fid)
{
    Fid *f = fid->aux;
    Npfcall *ret = NULL;

    if (!(ret = np_create_rclunk ())) {
        np_uerror (ENOMEM);
        goto error;
    }
    return ret;
error:
    errn (np_rerror (), "diod_clunk %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path);
    if (ret)
        free (ret);
    return NULL;
}
Exemplo n.º 27
0
Npfcall*
diod_getlock (Npfid *fid, u8 type, u64 start, u64 length, u32 proc_id,
             Npstr *client_id)
{
    Fid *f = fid->aux;
    Npfcall *ret;
    char *cid = NULL;
    int ftype;

    if ((f->flags & DIOD_FID_FLAGS_ROFS)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!f->ioctx) {
        msg ("diod_getlock: fid is not open");
        np_uerror (EBADF);
        goto error;
    }
    if (!(cid = np_strdup (client_id))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (type != P9_LOCK_TYPE_RDLCK && type != P9_LOCK_TYPE_WRLCK) {
        np_uerror (EINVAL);
        goto error;
    }
    ftype = (type == P9_LOCK_TYPE_RDLCK) ? LOCK_SH : LOCK_EX;
    ftype = ioctx_testlock (f->ioctx, ftype);    
    type = (ftype == LOCK_EX) ? P9_LOCK_TYPE_WRLCK : P9_LOCK_TYPE_UNLCK;
    if (!((ret = np_create_rgetlock(type, start, length, proc_id, cid)))) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (cid);
    return ret;
error:
    errn (np_rerror (), "diod_getlock %s@%s:%s",
          fid->user->uname, np_conn_get_client_id (fid->conn),
          path_s (f->path));
error_quiet:
    if (cid)
        free (cid);
    return NULL;
}
Exemplo n.º 28
0
/* Checkauth is called in the handling of a TATTACH request with valid afid.
 * Validate the credential that should now be dangling off afid.
 * Returns 1=success (auth is good, send RATTACH)
 *         0=failure (send RLERROR with np_rerror ())
 */
static int
checkauth(Npfid *fid, Npfid *afid, char *aname)
{
    da_t da;
    int ret = 0;
    char a[128];

    if (!fid || !afid || !afid->aux) {
        np_uerror (EIO);
        err ("checkauth: invalid arguments");
        goto done;
    }
    da = afid->aux;
    assert (da->magic == DIOD_AUTH_MAGIC);

    snprintf (a, sizeof(a), "checkauth(%s@%s:%s)", fid->user->uname,
              np_conn_get_client_id (fid->conn), aname ? aname : "<NULL>");
#if HAVE_LIBMUNGE
    if (!da->datastr) {
        msg ("%s: munge cred missing", a);
        goto done;
    }
    da->mungerr = munge_decode (da->datastr, da->mungectx, NULL, 0,
                                &da->mungeuid, NULL);
    if (da->mungerr != EMUNGE_SUCCESS) {
        np_uerror (EPERM);
        err ("%s: munge cred decode: %s", a, munge_strerror (da->mungerr));
        goto done;
    }
    assert (afid->user->uid == fid->user->uid); /* enforced in np_attach */
    if (afid->user->uid != da->mungeuid) {
        np_uerror (EPERM);
        err ("%s: munge cred uid mismatch: %d", a, da->mungeuid);
        goto done;
    }
    ret = 1;
#else
    np_uerror (EPERM);
    err ("%s: diod was not built with support for auth services", a);
#endif
done:
    return ret;
}
Exemplo n.º 29
0
/* Trename - rename a file, potentially to another directory
 */
Npfcall*
diod_rename (Npfid *fid, Npfid *dfid, Npstr *name)
{
    Fid *f = fid->aux;
    Fid *d = dfid->aux;
    Npfcall *ret = NULL;
    char *npath = NULL;
    int renamed = 0;

    if ((f->xflags & XFLAGS_RO)) {
        np_uerror (EROFS);
        goto error_quiet;
    }
    if (!(npath = _mkpath(d->path, name))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (rename (f->path, npath) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    renamed = 1;
    if (!(ret = np_create_rrename ())) {
        np_uerror (ENOMEM);
        goto error;
    }
    free (f->path);
    f->path = npath;
    return ret;
error:
    errn (np_rerror (), "diod_rename %s@%s:%s to %s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), f->path,
          d->path, name->len, name->str);
error_quiet:
    if (renamed && npath)
        (void)rename (npath, f->path);
    if (npath)
        free (npath);
    if (ret)
        free (f);
    return NULL;
}
Exemplo n.º 30
0
/* Twalk - walk a file path
 * Called from fcall.c::np_walk () on each wname component in succession.
 * On error, call np_uerror () and return 0.
 */
int
diod_walk (Npfid *fid, Npstr* wname, Npqid *wqid)
{
    Npsrv *srv = fid->conn->srv;
    Fid *f = fid->aux;
    struct stat sb, sb2;
    Path npath = NULL;

    if ((f->flags & DIOD_FID_FLAGS_MOUNTPT)) {
        np_uerror (ENOENT);
        goto error_quiet;
    }
    if (!(npath = path_append (srv, f->path, wname))) {
        np_uerror (ENOMEM);
        goto error;
    }
    if (lstat (path_s (npath), &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    if (lstat (path_s (f->path), &sb2) < 0) {
        np_uerror (errno);
        goto error;
    }
    if (sb.st_dev != sb2.st_dev) {
        if (_statmnt (path_s (npath), &sb) < 0)
            goto error;
        f->flags |= DIOD_FID_FLAGS_MOUNTPT;
    }
    path_decref (srv, f->path);
    f->path = npath; 
    diod_ustat2qid (&sb, wqid);
    return 1;
error:
    errn (np_rerror (), "diod_walk %s@%s:%s/%.*s",
          fid->user->uname, np_conn_get_client_id (fid->conn), path_s (f->path),
          wname->len, wname->str);
error_quiet:
    if (npath)
        path_decref (srv, npath);
    return 0;
}