static void process_mkdir(u_int32_t id) { Attrib *a; char *name; int ret, mode, status = SSH2_FX_FAILURE; name = get_string(NULL); a = get_attrib(); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); ret = mkdir(name, mode); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); }
static void process_symlink(void) { u_int32_t id; char *oldpath, *newpath; int ret, status; id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); TRACE("symlink id %u old %s new %s", id, oldpath, newpath); /* this will fail if 'newpath' exists */ ret = symlink(oldpath, newpath); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); xfree(oldpath); xfree(newpath); }
static void process_extended_statvfs(u_int32_t id) { char *path; struct statvfs st; int r; if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: statvfs", id); logit("statvfs \"%s\"", path); if (statvfs(path, &st) != 0) send_status(id, errno_to_portable(errno)); else send_statvfs(id, &st); free(path); }
static void process_extended_fstatvfs(u_int32_t id) { int handle, fd; struct statvfs st; handle = get_handle(); debug("request %u: fstatvfs \"%s\" (handle %u)", id, handle_to_name(handle), handle); if ((fd = handle_to_fd(handle)) < 0) { send_status(id, SSH2_FX_FAILURE); return; } if (fstatvfs(fd, &st) != 0) send_status(id, errno_to_portable(errno)); else send_statvfs(id, &st); }
static void process_extended_posix_rename(u_int32_t id) { char *oldpath, *newpath; int r, status; if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); r = rename(oldpath, newpath); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); }
static void process_symlink(u_int32_t id) { char *oldpath, *newpath; int r, status; if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ r = symlink(oldpath, newpath); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); }
static void process_mkdir(void) { Attrib *a; u_int32_t id; char *name; int ret, mode, status = SSH2_FX_FAILURE; id = get_int(); name = get_string(NULL); a = get_attrib(); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm & 0777 : 0777; TRACE("mkdir id %u name %s mode 0%o", id, name, mode); ret = mkdir(name, mode); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); xfree(name); }
void SFTP::process_remove(void) { char *utf8_name; u_int32_t id; int status = SSH2_FX_FAILURE; id = get_int(); utf8_name = (char*) get_string(NULL); debug3("request %u: remove", (unsigned) id); logit("remove name \"%s\"", utf8_name); const SFTPFilePath path = pathFact.create_path (utf8_name); BOOL res = ::DeleteFileW (path.get_for_call ().c_str ()); status = (!res) ? errno_to_portable(::GetLastError ()) : SSH2_FX_OK; send_status(id, status); xfree(utf8_name); }
static void process_extended_fstatvfs(u_int32_t id) { int r, handle, fd; struct statvfs st; if ((r = get_handle(iqueue, &handle)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fstatvfs \"%s\" (handle %u)", id, handle_to_name(handle), handle); if ((fd = handle_to_fd(handle)) < 0) { send_status(id, SSH2_FX_FAILURE); return; } if (fstatvfs(fd, &st) != 0) send_status(id, errno_to_portable(errno)); else send_statvfs(id, &st); }
static void process_rmdir(void) { u_int32_t id; char *name; int ret, status; id = get_int(); name = get_string(NULL); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); if (readonly) status = SSH2_FX_PERMISSION_DENIED; else { ret = rmdir(name); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); xfree(name); }
static void process_mkdir(u_int32_t id) { Attrib a; char *name; int r, mode, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); r = mkdir(name, mode); status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); }
static void process_extended_posix_rename(u_int32_t id) { char *oldpath, *newpath; int ret, status; oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); if (readonly) status = SSH2_FX_PERMISSION_DENIED; else { ret = rename(oldpath, newpath); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); xfree(oldpath); xfree(newpath); }
static void process_open(u_int32_t id) { u_int32_t pflags; Attrib a; char *name; int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: open flags %d", id, pflags); flags = flags_from_portable(pflags); mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) { verbose("Refusing open request in read-only mode"); status = SSH2_FX_PERMISSION_DENIED; } else { fd = open(name, flags, mode); if (fd < 0) { status = errno_to_portable(errno); } else { handle = handle_new(HANDLE_FILE, name, fd, flags, NULL); if (handle < 0) { close(fd); } else { send_handle(id, handle); status = SSH2_FX_OK; } } } if (status != SSH2_FX_OK) send_status(id, status); free(name); }
static void process_symlink(void) { u_int32_t id; struct stat st; char *oldpath, *newpath; int ret, status = SSH2_FX_FAILURE; id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); TRACE("symlink id %u old %s new %s", id, oldpath, newpath); /* fail if 'newpath' exists */ if (stat(newpath, &st) == -1) { ret = symlink(oldpath, newpath); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); xfree(oldpath); xfree(newpath); }
static void process_remove(void) { char *name; u_int32_t id; int status = SSH2_FX_FAILURE; int ret; id = get_int(); name = get_string(NULL); debug3("request %u: remove", id); logit("remove name \"%s\"", name); if (readonly) status = SSH2_FX_PERMISSION_DENIED; else { ret = unlink(name); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); xfree(name); }
static void process_rmdir(u_int32_t id) { char *name; int ret, status; name = get_string(NULL); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); ret = rmdir(name); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); #ifdef NERSC_MOD char* t1buf = encode_string(name, strlen(name)); s_audit("sftp_process_rmdir_3", "count=%i int=%d uristring=%s", get_client_session_id(), (int)getppid(), t1buf); free(t1buf); #endif free(name); }
static void process_open(u_int32_t id) { u_int32_t pflags; Attrib *a; char *name; int handle, fd, flags, mode, status = SSH2_FX_FAILURE; name = get_string(NULL); pflags = get_int(); /* portable flags */ debug3("request %u: open flags %d", id, pflags); a = get_attrib(); flags = flags_from_portable(pflags); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) { verbose("Refusing open request in read-only mode"); status = SSH2_FX_PERMISSION_DENIED; } else { fd = open(name, flags, mode); if (fd < 0) { status = errno_to_portable(errno); } else { handle = handle_new(HANDLE_FILE, name, fd, flags, NULL); if (handle < 0) { close(fd); } else { send_handle(id, handle); status = SSH2_FX_OK; } } } if (status != SSH2_FX_OK) send_status(id, status); free(name); }
void SFTP::process_symlink(void) { u_int32_t id; char *utf8_oldpath, *utf8_newpath; id = get_int(); utf8_oldpath = (char*) get_string(NULL); utf8_newpath = (char*) get_string(NULL); debug3("request %u: symlink", (unsigned) id); logit("symlink old \"%s\" new \"%s\"", utf8_oldpath, utf8_newpath); // TODO can be added on Vista+ #if 0 /* this will fail if 'newpath' exists */ ret = symlink(oldpath, newpath); status = (ret == -1) ? errno_to_portable(::GetLastError ()) : SSH2_FX_OK; #endif const u_int32_t status = SSH2_FX_OP_UNSUPPORTED; send_status(id, status); xfree(utf8_oldpath); xfree(utf8_newpath); }
static void process_readlink(u_int32_t id) { int len; char buf[MAXPATHLEN]; char *path; path = get_string(NULL); debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) send_status(id, errno_to_portable(errno)); else { Stat s; buf[len] = '\0'; attrib_clear(&s.attrib); s.name = s.long_name = buf; send_names(id, 1, &s); } free(path); }
static void process_do_stat(u_int32_t id, int do_lstat) { Attrib a; struct stat st; char *name; int ret, status = SSH2_FX_FAILURE; name = get_string(NULL); debug3("request %u: %sstat", id, do_lstat ? "l" : ""); verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); ret = do_lstat ? lstat(name, &st) : stat(name, &st); if (ret < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); send_attrib(id, &a); status = SSH2_FX_OK; } if (status != SSH2_FX_OK) send_status(id, status); free(name); }
static void process_readlink(void) { u_int32_t id; int len; char link[MAXPATHLEN]; char *path; id = get_int(); path = get_string(NULL); TRACE("readlink id %u path %s", id, path); if ((len = readlink(path, link, sizeof(link) - 1)) == -1) send_status(id, errno_to_portable(errno)); else { Stat s; link[len] = '\0'; attrib_clear(&s.attrib); s.name = s.long_name = link; send_names(id, 1, &s); } xfree(path); }
static void process_symlink(void) { u_int32_t id; char *oldpath, *newpath; int ret, status; id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ if (readonly) status = SSH2_FX_PERMISSION_DENIED; else { ret = symlink(oldpath, newpath); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); xfree(oldpath); xfree(newpath); }
static void process_realpath(u_int32_t id) { char resolvedname[MAXPATHLEN]; char *path; path = get_string(NULL); if (path[0] == '\0') { free(path); path = xstrdup("."); } debug3("request %u: realpath", id); verbose("realpath \"%s\"", path); if (realpath(path, resolvedname) == NULL) { send_status(id, errno_to_portable(errno)); } else { Stat s; attrib_clear(&s.attrib); s.name = s.long_name = resolvedname; send_names(id, 1, &s); } free(path); }
static void process_do_stat(int do_lstat) { Attrib a; struct stat st; u_int32_t id; char *name; int ret, status = SSH2_FX_FAILURE; id = get_int(); name = get_string(NULL); TRACE("%sstat id %u name %s", do_lstat ? "l" : "", id, name); ret = do_lstat ? lstat(name, &st) : stat(name, &st); if (ret < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); send_attrib(id, &a); status = SSH2_FX_OK; } if (status != SSH2_FX_OK) send_status(id, status); xfree(name); }
static void process_realpath(void) { char resolvedname[MAXPATHLEN]; u_int32_t id; char *path; id = get_int(); path = get_string(NULL); if (path[0] == '\0') { xfree(path); path = xstrdup("."); } TRACE("realpath id %u path %s", id, path); if (realpath(path, resolvedname) == NULL) { send_status(id, errno_to_portable(errno)); } else { Stat s; attrib_clear(&s.attrib); s.name = s.long_name = resolvedname; send_names(id, 1, &s); } xfree(path); }
static void process_fstat(u_int32_t id) { Attrib a; struct stat st; int fd, ret, handle, status = SSH2_FX_FAILURE; handle = get_handle(); debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); fd = handle_to_fd(handle); if (fd >= 0) { ret = fstat(fd, &st); if (ret < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); send_attrib(id, &a); status = SSH2_FX_OK; } } if (status != SSH2_FX_OK) send_status(id, status); }
static void process_readlink(u_int32_t id) { int r, len; char buf[PATH_MAX]; char *path; if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) send_status(id, errno_to_portable(errno)); else { Stat s; buf[len] = '\0'; attrib_clear(&s.attrib); s.name = s.long_name = buf; send_names(id, 1, &s); } free(path); }
static void process_fsetstat(u_int32_t id) { Attrib a; int handle, fd, r; int status = SSH2_FX_OK; if ((r = get_handle(iqueue, &handle)) != 0 || (r = decode_attrib(iqueue, &a)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); if (fd < 0) status = SSH2_FX_FAILURE; else { char *name = handle_to_name(handle); if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a.size); r = ftruncate(fd, a.size); if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a.perm); #ifdef HAVE_FCHMOD r = fchmod(fd, a.perm & 07777); #else r = chmod(name, a.perm & 07777); #endif if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { char buf[64]; time_t t = a.mtime; strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", localtime(&t)); logit("set \"%s\" modtime %s", name, buf); #ifdef HAVE_FUTIMES r = futimes(fd, attrib_to_tv(&a)); #else r = utimes(name, attrib_to_tv(&a)); #endif if (r == -1) status = errno_to_portable(errno); } if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { logit("set \"%s\" owner %lu group %lu", name, (u_long)a.uid, (u_long)a.gid); #ifdef HAVE_FCHOWN r = fchown(fd, a.uid, a.gid); #else r = chown(name, a.uid, a.gid); #endif if (r == -1) status = errno_to_portable(errno); } } send_status(id, status); }
static void process_rename(void) { u_int32_t id; char *oldpath, *newpath; int status; struct stat sb; id = get_int(); oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; if (readonly) status = SSH2_FX_PERMISSION_DENIED; else if (lstat(oldpath, &sb) == -1) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ if (link(oldpath, newpath) == -1) { if (errno == EOPNOTSUPP || errno == ENOSYS #ifdef EXDEV || errno == EXDEV #endif #ifdef LINK_OPNOTSUPP_ERRNO || errno == LINK_OPNOTSUPP_ERRNO #endif ) { struct stat st; /* * fs doesn't support links, so fall back to * stat+rename. This is racy. */ if (stat(newpath, &st) == -1) { if (rename(oldpath, newpath) == -1) status = errno_to_portable(errno); else status = SSH2_FX_OK; } } else { status = errno_to_portable(errno); } } else if (unlink(oldpath) == -1) { status = errno_to_portable(errno); /* clean spare link */ unlink(newpath); } else status = SSH2_FX_OK; } else if (stat(newpath, &sb) == -1) { if (rename(oldpath, newpath) == -1) status = errno_to_portable(errno); else status = SSH2_FX_OK; } send_status(id, status); xfree(oldpath); xfree(newpath); }
static void process_fsetstat(u_int32_t id) { Attrib *a; int handle, fd, ret; int status = SSH2_FX_OK; handle = get_handle(); a = get_attrib(); debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); if (fd < 0) status = SSH2_FX_FAILURE; else { char *name = handle_to_name(handle); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a->size); ret = ftruncate(fd, a->size); if (ret == -1) status = errno_to_portable(errno); } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a->perm); #ifdef HAVE_FCHMOD ret = fchmod(fd, a->perm & 07777); #else ret = chmod(name, a->perm & 07777); #endif if (ret == -1) status = errno_to_portable(errno); } if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { char buf[64]; time_t t = a->mtime; strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", localtime(&t)); logit("set \"%s\" modtime %s", name, buf); #ifdef HAVE_FUTIMES ret = futimes(fd, attrib_to_tv(a)); #else ret = utimes(name, attrib_to_tv(a)); #endif if (ret == -1) status = errno_to_portable(errno); } if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { logit("set \"%s\" owner %lu group %lu", name, (u_long)a->uid, (u_long)a->gid); #ifdef HAVE_FCHOWN ret = fchown(fd, a->uid, a->gid); #else ret = chown(name, a->uid, a->gid); #endif if (ret == -1) status = errno_to_portable(errno); } } send_status(id, status); }