Exemple #1
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;
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
0
static IOCtx
_ioctx_create_open (Npuser *user, Path path, int flags, u32 mode)
{
    IOCtx ioctx;
    struct stat sb;

    ioctx = malloc (sizeof (*ioctx));
    if (!ioctx) {
        np_uerror (ENOMEM);
        goto error;
    }
    pthread_mutex_init (&ioctx->lock, NULL);
    ioctx->refcount = 1;
    ioctx->lock_type = LOCK_UN;
    ioctx->dir = NULL;
    ioctx->open_flags = flags;
    ioctx->user = user;
    np_user_incref (user);
    ioctx->prev = ioctx->next = NULL;
    ioctx->fd = open (path->s, flags, mode);
    if (ioctx->fd < 0) {
        np_uerror (errno);
        goto error;
    }
    if (fstat (ioctx->fd, &sb) < 0) {
        np_uerror (errno);
        goto error;
    }
    ioctx->iounit = 0; /* if iounit=0, v9fs will use msize-P9_IOHDRSZ */
#ifndef __MACH__
    if (S_ISDIR(sb.st_mode) && !(ioctx->dir = fdopendir (ioctx->fd))) {
        np_uerror (errno);
        goto error;
    }
#endif
    if (S_ISDIR(sb.st_mode) && !(ioctx->dir = opendir (path->s))) {
        np_uerror (errno);
        goto error;
    }
    diod_ustat2qid (&sb, &ioctx->qid);
    return ioctx;
error:
    if (ioctx)
        _ioctx_close_destroy (ioctx, 0);
    return NULL;
}
Exemple #5
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;
}
Exemple #6
0
Npfcall*
diod_mknod(Npfid *fid, Npstr *name, u32 mode, u32 major, u32 minor, u32 gid)
{
    Npsrv *srv = fid->conn->srv;
    Npfcall *ret;
    Fid *f = fid->aux;
    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 (mknod (path_s (npath), mode, makedev (major, minor)) < 0
                                        || lstat (path_s (npath), &sb) < 0) {
        np_uerror (errno);
        goto error_quiet;
    }
    diod_ustat2qid (&sb, &qid);
    if (!((ret = np_create_rmknod (&qid)))) {
        (void)unlink (path_s (npath));
        np_uerror (ENOMEM);
        goto error;
    }
    path_decref (srv, npath);
    return ret;
error:
    errn (np_rerror (), "diod_mknod %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);
    return NULL;
}
Exemple #7
0
static u32
_copy_dirent_linux (Fid *f, struct dirent *dp, u8 *buf, u32 buflen)
{
    Npqid qid;
    u32 ret = 0;

    if (dp->d_type == DT_UNKNOWN) {
        char path[PATH_MAX + 1];
        struct stat sb;
        snprintf (path, sizeof(path), "%s/%s", path_s (f->path), dp->d_name);
        if (lstat (path, &sb) < 0) {
            np_uerror (errno);
            goto done;
        }
        diod_ustat2qid (&sb, &qid);
    } else  {
        _dirent2qid (dp, &qid);
    }
    ret = np_serialize_p9dirent(&qid, dp->d_off, dp->d_type,
                                      dp->d_name, buf, buflen);
done:
    return ret;
}