diff --git a/doc/rest-api.yaml b/doc/rest-api.yaml index 713d87367788..c2c2fb247d72 100644 --- a/doc/rest-api.yaml +++ b/doc/rest-api.yaml @@ -10229,19 +10229,19 @@ paths: - description: Raw file content in: body name: raw_file - - description: File owner UID + - description: Base 10 32-bit integer for the file owner UID example: 1000 in: header name: X-LXD-uid schema: type: integer - - description: File owner GID + - description: Base 10 32-bit integer for the file owner GID example: 1000 in: header name: X-LXD-gid schema: type: integer - - description: File mode + - description: Base 10 (no leading `0`) or base 8 (leading `0`) unix permissions bits (other bits are truncated) example: 420 in: header name: X-LXD-mode diff --git a/lxd/instance_file.go b/lxd/instance_file.go index ae1d9117bcd3..8bbb480a7e95 100644 --- a/lxd/instance_file.go +++ b/lxd/instance_file.go @@ -390,19 +390,19 @@ func instanceFileHead(s *state.State, inst instance.Instance, path string, r *ht // description: Raw file content // - in: header // name: X-LXD-uid -// description: File owner UID +// description: Base 10 32-bit integer for the file owner UID // schema: // type: integer // example: 1000 // - in: header // name: X-LXD-gid -// description: File owner GID +// description: Base 10 32-bit integer for the file owner GID // schema: // type: integer // example: 1000 // - in: header // name: X-LXD-mode -// description: File mode +// description: Base 10 (no leading `0`) or base 8 (leading `0`) unix permissions bits (other bits are truncated) // schema: // type: integer // example: 0644 diff --git a/shared/util.go b/shared/util.go index bf3318d72b68..31eff3da3472 100644 --- a/shared/util.go +++ b/shared/util.go @@ -257,27 +257,43 @@ func LogPath(path ...string) string { return filepath.Join(items...) } +// ParseLXDFileHeaders parses and validates the `X-LXD-*` family of file +// permissions headers. +// - `X-LXD-uid`, `X-LXD-gid` +// Base 10 integer +// - `X-LXD-mode` +// Base 10 integer (no leading `0`) or base 8 integer (leading `0`) for the +// unix permissions bits +// - `X-LXD-type` +// One of `file`, `symlink`, `directory` +// - `X-LXD-write` +// One of `overwrite`, `append` func ParseLXDFileHeaders(headers http.Header) (uid int64, gid int64, mode int, type_ string, write string) { - uid, err := strconv.ParseInt(headers.Get("X-LXD-uid"), 10, 64) + uid, err := strconv.ParseInt(headers.Get("X-LXD-uid"), 10, 32) if err != nil { uid = -1 } - gid, err = strconv.ParseInt(headers.Get("X-LXD-gid"), 10, 64) + gid, err = strconv.ParseInt(headers.Get("X-LXD-gid"), 10, 32) if err != nil { gid = -1 } - mode, err = strconv.Atoi(headers.Get("X-LXD-mode")) + mode64, err := strconv.ParseInt(headers.Get("X-LXD-mode"), 10, 0) if err != nil { - mode = -1 + mode64 = -1 } else { rawMode, err := strconv.ParseInt(headers.Get("X-LXD-mode"), 0, 0) if err == nil { - mode = int(os.FileMode(rawMode) & os.ModePerm) + mode64 = rawMode } } + mode = -1 + if mode64 >= 0 { + mode = int(mode64 & int64(os.ModePerm)) + } + type_ = headers.Get("X-LXD-type") /* backwards compat: before "type" was introduced, we could only * manipulate files