예제 #1
0
파일: nfs.c 프로젝트: UIKit0/unfs3
FSINFO3res *nfsproc3_fsinfo_3_svc(FSINFO3args * argp, struct svc_req * rqstp)
{
    static FSINFO3res result;
    char *path;
    unsigned int maxdata;

    if (get_socket_type(rqstp) == SOCK_STREAM)
	maxdata = NFS_MAXDATA_TCP;
    else
	maxdata = NFS_MAXDATA_UDP;

    PREP(path, argp->fsroot);

    result.FSINFO3res_u.resok.obj_attributes = get_post_cached(rqstp);

    result.status = NFS3_OK;
    result.FSINFO3res_u.resok.rtmax = maxdata;
    result.FSINFO3res_u.resok.rtpref = maxdata;
    result.FSINFO3res_u.resok.rtmult = 4096;
    result.FSINFO3res_u.resok.wtmax = maxdata;
    result.FSINFO3res_u.resok.wtpref = maxdata;
    result.FSINFO3res_u.resok.wtmult = 4096;
    result.FSINFO3res_u.resok.dtpref = 4096;
    result.FSINFO3res_u.resok.maxfilesize = ~0ULL;
    result.FSINFO3res_u.resok.time_delta.seconds = backend_time_delta_seconds;
    result.FSINFO3res_u.resok.time_delta.nseconds = 0;
    result.FSINFO3res_u.resok.properties = backend_fsinfo_properties;

    return &result;
}
예제 #2
0
파일: nfs.c 프로젝트: UIKit0/unfs3
SYMLINK3res *nfsproc3_symlink_3_svc(SYMLINK3args * argp,
				    struct svc_req * rqstp)
{
    static SYMLINK3res result;
    char *path;
    pre_op_attr pre;
    post_op_attr post;
    char obj[NFS_MAXPATHLEN];
    int res;
    mode_t new_mode;

    PREP(path, argp->where.dir);
    pre = get_pre_cached();
    result.status =
	join3(cat_name(path, argp->where.name, obj),
	      atomic_attr(argp->symlink.symlink_attributes), exports_rw());

    cluster_create(obj, rqstp, &result.status);

    if (argp->symlink.symlink_attributes.mode.set_it == TRUE)
	new_mode = create_mode(argp->symlink.symlink_attributes);
    else {
	/* default rwxrwxrwx */
	new_mode =
	    S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP |
	    S_IROTH | S_IWOTH | S_IXOTH;
    }

    if (result.status == NFS3_OK) {
	umask(~new_mode);
	res = backend_symlink(argp->symlink.symlink_data, obj);
	umask(0);
	if (res == -1)
	    result.status = symlink_err();
	else {
	    result.SYMLINK3res_u.resok.obj =
		fh_extend_type(argp->where.dir, obj, S_IFLNK);
	    result.SYMLINK3res_u.resok.obj_attributes =
		get_post_cached(rqstp);
	}
    }

    post = get_post_attr(path, argp->where.dir, rqstp);

    /* overlaps with resfail */
    result.SYMLINK3res_u.resok.dir_wcc.before = pre;
    result.SYMLINK3res_u.resok.dir_wcc.after = post;

    return &result;
}
예제 #3
0
파일: nfs.c 프로젝트: UIKit0/unfs3
GETATTR3res *nfsproc3_getattr_3_svc(GETATTR3args * argp,
				    struct svc_req * rqstp)
{
    static GETATTR3res result;
    char *path;
    post_op_attr post;

    PREP(path, argp->object);
    post = get_post_cached(rqstp);

    result.status = NFS3_OK;
    result.GETATTR3res_u.resok.obj_attributes =
	post.post_op_attr_u.attributes;

    return &result;
}
예제 #4
0
파일: nfs.c 프로젝트: UIKit0/unfs3
FSSTAT3res *nfsproc3_fsstat_3_svc(FSSTAT3args * argp, struct svc_req * rqstp)
{
    static FSSTAT3res result;
    char *path;
    backend_statvfsstruct buf;
    int res;

    PREP(path, argp->fsroot);

    /* overlaps with resfail */
    result.FSSTAT3res_u.resok.obj_attributes = get_post_cached(rqstp);

    res = backend_statvfs(path, &buf);
    if (res == -1) {
	/* statvfs fell on its nose */
	if ((exports_opts & OPT_REMOVABLE) && export_point(path)) {
	    /* Removable media export point; probably no media inserted.
	       Return dummy values. */
	    result.status = NFS3_OK;
	    result.FSSTAT3res_u.resok.tbytes = 0;
	    result.FSSTAT3res_u.resok.fbytes = 0;
	    result.FSSTAT3res_u.resok.abytes = 0;
	    result.FSSTAT3res_u.resok.tfiles = 0;
	    result.FSSTAT3res_u.resok.ffiles = 0;
	    result.FSSTAT3res_u.resok.afiles = 0;
	    result.FSSTAT3res_u.resok.invarsec = 0;
	} else {
	    result.status = NFS3ERR_IO;
	}
    } else {
	result.status = NFS3_OK;
	result.FSSTAT3res_u.resok.tbytes =
	    (uint64) buf.f_blocks * buf.f_frsize;
	result.FSSTAT3res_u.resok.fbytes = 
	    (uint64) buf.f_bfree * buf.f_frsize;
	result.FSSTAT3res_u.resok.abytes =
	    (uint64) buf.f_bavail * buf.f_frsize;
	result.FSSTAT3res_u.resok.tfiles = buf.f_files;
	result.FSSTAT3res_u.resok.ffiles = buf.f_ffree;
	result.FSSTAT3res_u.resok.afiles = buf.f_ffree;
	result.FSSTAT3res_u.resok.invarsec = 0;
    }

    return &result;
}
예제 #5
0
파일: nfs.c 프로젝트: UIKit0/unfs3
MKNOD3res *nfsproc3_mknod_3_svc(MKNOD3args * argp, struct svc_req * rqstp)
{
    static MKNOD3res result;
    char *path;
    pre_op_attr pre;
    post_op_attr post;
    char obj[NFS_MAXPATHLEN];
    int res;
    mode_t new_mode = 0;
    dev_t dev = 0;

    PREP(path, argp->where.dir);
    pre = get_pre_cached();
    result.status =
	join3(cat_name(path, argp->where.name, obj),
	      mknod_args(argp->what, obj, &new_mode, &dev), exports_rw());

    cluster_create(obj, rqstp, &result.status);

    if (result.status == NFS3_OK) {
	if (argp->what.type == NF3CHR || argp->what.type == NF3BLK)
	    res = backend_mknod(obj, new_mode, dev);	/* device */
	else if (argp->what.type == NF3FIFO)
	    res = backend_mkfifo(obj, new_mode);	/* FIFO */
	else
	    res = backend_mksocket(obj, new_mode);	/* socket */

	if (res == -1) {
	    result.status = mknod_err();
	} else {
	    result.MKNOD3res_u.resok.obj =
		fh_extend_type(argp->where.dir, obj,
			       type_to_mode(argp->what.type));
	    result.MKNOD3res_u.resok.obj_attributes = get_post_cached(rqstp);
	}
    }

    post = get_post_attr(path, argp->where.dir, rqstp);

    /* overlaps with resfail */
    result.MKNOD3res_u.resok.dir_wcc.before = pre;
    result.MKNOD3res_u.resok.dir_wcc.after = post;

    return &result;
}
예제 #6
0
파일: nfs.c 프로젝트: auristor/unfs3
ACCESS3res *nfsproc3_access_3_svc(ACCESS3args * argp, struct svc_req * rqstp)
{
    static ACCESS3res result;
    char *path;
    post_op_attr post;
    mode_t mode;
    int newaccess = 0;

    PREP(path, argp->object);
    post = get_post_cached(rqstp);
    mode = post.post_op_attr_u.attributes.mode;

    if (access(path, R_OK) != -1)
        newaccess |= ACCESS3_READ;

    if (access(path, W_OK) != -1)
        newaccess |= ACCESS3_MODIFY | ACCESS3_EXTEND;

    if (access(path, X_OK) != -1) {
        newaccess |= ACCESS3_EXECUTE;
        if (opt_readable_executables)
            newaccess |= ACCESS3_READ;
    }

    /* root is allowed everything */
    if (get_uid(rqstp) == 0)
	newaccess |= ACCESS3_READ | ACCESS3_MODIFY | ACCESS3_EXTEND;

    /* adjust if directory */
    if (post.post_op_attr_u.attributes.type == NF3DIR) {
	if (newaccess & (ACCESS3_READ | ACCESS3_EXECUTE))
	    newaccess |= ACCESS3_LOOKUP;
	if (newaccess & ACCESS3_MODIFY)
	    newaccess |= ACCESS3_DELETE;
	newaccess &= ~ACCESS3_EXECUTE;
    }

    result.status = NFS3_OK;
    result.ACCESS3res_u.resok.access = newaccess & argp->access;
    result.ACCESS3res_u.resok.obj_attributes = post;

    return &result;
}
예제 #7
0
파일: nfs.c 프로젝트: UIKit0/unfs3
PATHCONF3res *nfsproc3_pathconf_3_svc(PATHCONF3args * argp,
				      struct svc_req * rqstp)
{
    static PATHCONF3res result;
    char *path;

    PREP(path, argp->object);

    result.PATHCONF3res_u.resok.obj_attributes = get_post_cached(rqstp);

    result.status = NFS3_OK;
    result.PATHCONF3res_u.resok.linkmax = 0xFFFFFFFF;
    result.PATHCONF3res_u.resok.name_max = NFS_MAXPATHLEN;
    result.PATHCONF3res_u.resok.no_trunc = TRUE;
    result.PATHCONF3res_u.resok.chown_restricted = FALSE;
    result.PATHCONF3res_u.resok.case_insensitive =
	backend_pathconf_case_insensitive;
    result.PATHCONF3res_u.resok.case_preserving = TRUE;

    return &result;
}
예제 #8
0
파일: nfs.c 프로젝트: UIKit0/unfs3
MKDIR3res *nfsproc3_mkdir_3_svc(MKDIR3args * argp, struct svc_req * rqstp)
{
    static MKDIR3res result;
    char *path;
    pre_op_attr pre;
    post_op_attr post;
    char obj[NFS_MAXPATHLEN];
    int res;

    PREP(path, argp->where.dir);
    pre = get_pre_cached();
    result.status =
	join3(cat_name(path, argp->where.name, obj),
	      atomic_attr(argp->attributes), exports_rw());

    cluster_create(obj, rqstp, &result.status);

    if (result.status == NFS3_OK) {
	res = backend_mkdir(obj, create_mode(argp->attributes));
	if (res == -1)
	    result.status = mkdir_err();
	else {
	    result.MKDIR3res_u.resok.obj =
		fh_extend_type(argp->where.dir, obj, S_IFDIR);
	    result.MKDIR3res_u.resok.obj_attributes = get_post_cached(rqstp);
	}
    }

    post = get_post_attr(path, argp->where.dir, rqstp);

    /* overlaps with resfail */
    result.MKDIR3res_u.resok.dir_wcc.before = pre;
    result.MKDIR3res_u.resok.dir_wcc.after = post;

    return &result;
}
예제 #9
0
파일: nfs.c 프로젝트: UIKit0/unfs3
ACCESS3res *nfsproc3_access_3_svc(ACCESS3args * argp, struct svc_req * rqstp)
{
    static ACCESS3res result;
    char *path;
    post_op_attr post;
    mode_t mode;
    int access = 0;

    PREP(path, argp->object);
    post = get_post_cached(rqstp);
    mode = post.post_op_attr_u.attributes.mode;

    /* owner permissions */
    if (is_owner(st_cache.st_uid, rqstp)) {
	if (mode & S_IRUSR)
	    access |= ACCESS3_READ;
	if (mode & S_IWUSR)
	    access |= ACCESS3_MODIFY | ACCESS3_EXTEND;
	if (mode & S_IXUSR) {
	    access |= ACCESS3_EXECUTE;
	    if (opt_readable_executables)
		access |= ACCESS3_READ;
	}
    } else if (has_group(st_cache.st_gid, rqstp)) {
	/* group permissions */
	if (mode & S_IRGRP)
	    access |= ACCESS3_READ;
	if (mode & S_IWGRP)
	    access |= ACCESS3_MODIFY | ACCESS3_EXTEND;
	if (mode & S_IXGRP) {
	    access |= ACCESS3_EXECUTE;
	    if (opt_readable_executables)
		access |= ACCESS3_READ;
	}
    } else {
	/* other permissions */
	if (mode & S_IROTH)
	    access |= ACCESS3_READ;
	if (mode & S_IWOTH)
	    access |= ACCESS3_MODIFY | ACCESS3_EXTEND;
	if (mode & S_IXOTH) {
	    access |= ACCESS3_EXECUTE;
	    if (opt_readable_executables)
		access |= ACCESS3_READ;
	}
    }

    /* root is allowed everything */
    if (get_uid(rqstp) == 0)
	access |= ACCESS3_READ | ACCESS3_MODIFY | ACCESS3_EXTEND;

    /* adjust if directory */
    if (post.post_op_attr_u.attributes.type == NF3DIR) {
	if (access & (ACCESS3_READ | ACCESS3_EXECUTE))
	    access |= ACCESS3_LOOKUP;
	if (access & ACCESS3_MODIFY)
	    access |= ACCESS3_DELETE;
	access &= ~ACCESS3_EXECUTE;
    }

    result.status = NFS3_OK;
    result.ACCESS3res_u.resok.access = access & argp->access;
    result.ACCESS3res_u.resok.obj_attributes = post;

    return &result;
}