The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8088

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From f3c4805b2267aa6e8af890499ee8c72673522b77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Tue, 27 Oct 2020 18:56:45 -0400
Subject: [PATCH 1/5] shared: Drop GroupId and UserId
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 shared/util_linux_cgo.go | 97 ----------------------------------------
 1 file changed, 97 deletions(-)

diff --git a/shared/util_linux_cgo.go b/shared/util_linux_cgo.go
index 72d0794953..155975d265 100644
--- a/shared/util_linux_cgo.go
+++ b/shared/util_linux_cgo.go
@@ -6,7 +6,6 @@ package shared
 import (
        "fmt"
        "os"
-       "unsafe"
 
        // Used by cgo
        _ "github.com/lxc/lxd/lxd/include"
@@ -58,102 +57,6 @@ import "C"
 
 const ABSTRACT_UNIX_SOCK_LEN int = C.ABSTRACT_UNIX_SOCK_LEN
 
-// UserId is an adaption from https://codereview.appspot.com/4589049.
-func UserId(name string) (int, error) {
-       var pw C.struct_passwd
-       var result *C.struct_passwd
-
-       bufSize := C.sysconf(C._SC_GETPW_R_SIZE_MAX)
-       if bufSize < 0 {
-               bufSize = 4096
-       }
-
-       buf := C.malloc(C.size_t(bufSize))
-       if buf == nil {
-               return -1, fmt.Errorf("allocation failed")
-       }
-       defer C.free(buf)
-
-       cname := C.CString(name)
-       defer C.free(unsafe.Pointer(cname))
-
-again:
-       rv, errno := C.getpwnam_r(cname,
-               &pw,
-               (*C.char)(buf),
-               C.size_t(bufSize),
-               &result)
-       if rv < 0 {
-               // OOM killer will take care of us if we end up doing this too
-               // often.
-               if errno == unix.ERANGE {
-                       bufSize *= 2
-                       tmp := C.realloc(buf, C.size_t(bufSize))
-                       if tmp == nil {
-                               return -1, fmt.Errorf("allocation failed")
-                       }
-                       buf = tmp
-                       goto again
-               }
-               return -1, fmt.Errorf("failed user lookup: %s", unix.Errno(rv))
-       }
-
-       if result == nil {
-               return -1, fmt.Errorf("unknown user %s", name)
-       }
-
-       return int(C.int(result.pw_uid)), nil
-}
-
-// GroupId is an adaption from https://codereview.appspot.com/4589049.
-func GroupId(name string) (int, error) {
-       var grp C.struct_group
-       var result *C.struct_group
-
-       bufSize := C.sysconf(C._SC_GETGR_R_SIZE_MAX)
-       if bufSize < 0 {
-               bufSize = 4096
-       }
-
-       buf := C.malloc(C.size_t(bufSize))
-       if buf == nil {
-               return -1, fmt.Errorf("allocation failed")
-       }
-
-       cname := C.CString(name)
-       defer C.free(unsafe.Pointer(cname))
-
-again:
-       rv, errno := C.getgrnam_r(cname,
-               &grp,
-               (*C.char)(buf),
-               C.size_t(bufSize),
-               &result)
-       if rv != 0 {
-               // OOM killer will take care of us if we end up doing this too
-               // often.
-               if errno == unix.ERANGE {
-                       bufSize *= 2
-                       tmp := C.realloc(buf, C.size_t(bufSize))
-                       if tmp == nil {
-                               return -1, fmt.Errorf("allocation failed")
-                       }
-                       buf = tmp
-                       goto again
-               }
-
-               C.free(buf)
-               return -1, fmt.Errorf("failed group lookup: %s", unix.Errno(rv))
-       }
-       C.free(buf)
-
-       if result == nil {
-               return -1, fmt.Errorf("unknown group %s", name)
-       }
-
-       return int(C.int(result.gr_gid)), nil
-}
-
 func ReadPid(r *os.File) int {
        return int(C.read_pid(C.int(r.Fd())))
 }

From 30e814b42b0a19355c2bad3a2e971c7bf44c5f5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Tue, 27 Oct 2020 18:57:23 -0400
Subject: [PATCH 2/5] lxd: Port to os/user
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 lxd/endpoints/socket.go | 14 ++++++++++----
 lxd/sys/os.go           | 24 ++++++++++++++++++------
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/lxd/endpoints/socket.go b/lxd/endpoints/socket.go
index 6eeccba3fc..98a81a2646 100644
--- a/lxd/endpoints/socket.go
+++ b/lxd/endpoints/socket.go
@@ -6,6 +6,7 @@ import (
        "fmt"
        "net"
        "os"
+       "os/user"
        "strconv"
 
        "github.com/lxc/lxd/client"
@@ -86,14 +87,19 @@ func socketUnixSetPermissions(path string, mode 
os.FileMode) error {
 }
 
 // Change the ownership of the given unix socket file,
-func socketUnixSetOwnership(path string, group string) error {
+func socketUnixSetOwnership(path string, groupName string) error {
        var gid int
        var err error
 
-       if group != "" {
-               gid, err = shared.GroupId(group)
+       if groupName != "" {
+               g, err := user.LookupGroup(groupName)
                if err != nil {
-                       return fmt.Errorf("cannot get group ID of '%s': %v", 
group, err)
+                       return fmt.Errorf("cannot get group ID of '%s': %v", 
groupName, err)
+               }
+
+               gid, err = strconv.Atoi(g.Gid)
+               if err != nil {
+                       return err
                }
        } else {
                gid = os.Getgid()
diff --git a/lxd/sys/os.go b/lxd/sys/os.go
index 61cdf47394..0ab6d8f281 100644
--- a/lxd/sys/os.go
+++ b/lxd/sys/os.go
@@ -3,7 +3,9 @@
 package sys
 
 import (
+       "os/user"
        "path/filepath"
+       "strconv"
        "sync"
 
        log "github.com/lxc/lxd/shared/log15"
@@ -115,24 +117,34 @@ func (s *OS) Init() error {
        }
 
        // Detect if it is possible to run daemons as an unprivileged user and 
group.
-       for _, user := range []string{"lxd", "nobody"} {
-               uid, err := shared.UserId(user)
+       for _, userName := range []string{"lxd", "nobody"} {
+               u, err := user.Lookup(userName)
                if err != nil {
                        continue
                }
 
-               s.UnprivUser = user
+               uid, err := strconv.ParseUint(u.Uid, 10, 32)
+               if err != nil {
+                       return err
+               }
+
+               s.UnprivUser = userName
                s.UnprivUID = uint32(uid)
                break
        }
 
-       for _, group := range []string{"lxd", "nogroup"} {
-               gid, err := shared.GroupId(group)
+       for _, groupName := range []string{"lxd", "nogroup"} {
+               g, err := user.LookupGroup(groupName)
                if err != nil {
                        continue
                }
 
-               s.UnprivGroup = group
+               gid, err := strconv.ParseUint(g.Gid, 10, 32)
+               if err != nil {
+                       return err
+               }
+
+               s.UnprivGroup = groupName
                s.UnprivGID = uint32(gid)
                break
        }

From a38f4092d40c68c77a704353776bf7edce98edd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Tue, 27 Oct 2020 19:07:58 -0400
Subject: [PATCH 3/5] lxd/daemon: Log protocol
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 lxd/daemon.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/daemon.go b/lxd/daemon.go
index 52308da8c3..1de4938c70 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -425,7 +425,7 @@ func (d *Daemon) createCmd(restAPI *mux.Router, version 
string, c APIEndpoint) {
 
                untrustedOk := (r.Method == "GET" && c.Get.AllowUntrusted) || 
(r.Method == "POST" && c.Post.AllowUntrusted)
                if trusted {
-                       logger.Debug("Handling", log.Ctx{"method": r.Method, 
"url": r.URL.RequestURI(), "ip": r.RemoteAddr, "user": username})
+                       logger.Debug("Handling", log.Ctx{"method": r.Method, 
"url": r.URL.RequestURI(), "ip": r.RemoteAddr, "username": username, 
"protocol": protocol})
                        r = 
r.WithContext(context.WithValue(context.WithValue(r.Context(), "username", 
username), "protocol", protocol))
                } else if untrustedOk && r.Header.Get("X-LXD-authenticated") == 
"" {
                        logger.Debug(fmt.Sprintf("Allowing untrusted %s", 
r.Method), log.Ctx{"url": r.URL.RequestURI(), "ip": r.RemoteAddr})

From 1694cfd678f4eadeddda4831f3103a1d3aaed439 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Tue, 27 Oct 2020 19:08:35 -0400
Subject: [PATCH 4/5] lxd/daemon: Pass writer to Authenticate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 lxd/certificates.go | 2 +-
 lxd/daemon.go       | 6 +++---
 lxd/images.go       | 2 +-
 lxd/operations.go   | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/lxd/certificates.go b/lxd/certificates.go
index 917f5d1178..673ae5a386 100644
--- a/lxd/certificates.go
+++ b/lxd/certificates.go
@@ -125,7 +125,7 @@ func certificatesPost(d *Daemon, r *http.Request) 
response.Response {
                return response.SmartError(err)
        }
 
-       trusted, _, protocol, err := d.Authenticate(r)
+       trusted, _, protocol, err := d.Authenticate(nil, r)
        if err != nil {
                return response.SmartError(err)
        }
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 1de4938c70..94f6728b1c 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -241,7 +241,7 @@ func allowProjectPermission(feature string, permission 
string) func(d *Daemon, r
 
 // Convenience function around Authenticate
 func (d *Daemon) checkTrustedClient(r *http.Request) error {
-       trusted, _, _, err := d.Authenticate(r)
+       trusted, _, _, err := d.Authenticate(nil, r)
        if !trusted || err != nil {
                if err != nil {
                        return err
@@ -258,7 +258,7 @@ func (d *Daemon) checkTrustedClient(r *http.Request) error {
 // will validate the TLS certificate or Macaroon.
 //
 // This does not perform authorization, only validates authentication
-func (d *Daemon) Authenticate(r *http.Request) (bool, string, string, error) {
+func (d *Daemon) Authenticate(w http.ResponseWriter, r *http.Request) (bool, 
string, string, error) {
        // Allow internal cluster traffic
        if r.TLS != nil {
                cert, _ := 
x509.ParseCertificate(d.endpoints.NetworkCert().KeyPair().Certificate[0])
@@ -403,7 +403,7 @@ func (d *Daemon) createCmd(restAPI *mux.Router, version 
string, c APIEndpoint) {
                }
 
                // Authentication
-               trusted, username, protocol, err := d.Authenticate(r)
+               trusted, username, protocol, err := d.Authenticate(w, r)
                if err != nil {
                        // If not a macaroon discharge request, return the error
                        _, ok := err.(*bakery.DischargeRequiredError)
diff --git a/lxd/images.go b/lxd/images.go
index d97e759408..4fb55b9087 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -696,7 +696,7 @@ func imageCreateInPool(d *Daemon, info *api.Image, 
storagePool string) error {
 }
 
 func imagesPost(d *Daemon, r *http.Request) response.Response {
-       trusted, _, _, _ := d.Authenticate(r)
+       trusted, _, _, _ := d.Authenticate(nil, r)
 
        secret := r.Header.Get("X-LXD-secret")
        fingerprint := r.Header.Get("X-LXD-fingerprint")
diff --git a/lxd/operations.go b/lxd/operations.go
index e5d934c9ed..b46427f1cf 100644
--- a/lxd/operations.go
+++ b/lxd/operations.go
@@ -372,7 +372,7 @@ func operationWaitGet(d *Daemon, r *http.Request) 
response.Response {
        id := mux.Vars(r)["id"]
        secret := r.FormValue("secret")
 
-       trusted, _, _, _ := d.Authenticate(r)
+       trusted, _, _, _ := d.Authenticate(nil, r)
        if !trusted && secret == "" {
                return response.Forbidden(nil)
        }

From e5a01555ba6d1e25ce859be84a5b9b9d4a88b8ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Tue, 27 Oct 2020 19:08:53 -0400
Subject: [PATCH 5/5] lxd/daemon: Record username on unix queries
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #8012

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 lxd/daemon.go | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/lxd/daemon.go b/lxd/daemon.go
index 94f6728b1c..8e8cd12c20 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -11,6 +11,7 @@ import (
        "net/http"
        "net/url"
        "os"
+       "os/user"
        "path/filepath"
        "strings"
        "sync"
@@ -37,6 +38,7 @@ import (
        "github.com/lxc/lxd/lxd/events"
        "github.com/lxc/lxd/lxd/firewall"
        "github.com/lxc/lxd/lxd/instance"
+       "github.com/lxc/lxd/lxd/ucred"
 
        // Import instance/drivers without name so init() runs.
        _ "github.com/lxc/lxd/lxd/instance/drivers"
@@ -273,6 +275,21 @@ func (d *Daemon) Authenticate(w http.ResponseWriter, r 
*http.Request) (bool, str
 
        // Local unix socket queries
        if r.RemoteAddr == "@" {
+               if w != nil {
+                       conn := extractUnderlyingConn(w)
+                       cred, err := ucred.GetCred(conn)
+                       if err != nil {
+                               return false, "", "", err
+                       }
+
+                       u, err := user.LookupId(fmt.Sprintf("%d", cred.Uid))
+                       if err != nil {
+                               return true, fmt.Sprintf("uid=%d", cred.Uid), 
"unix", nil
+                       }
+
+                       return true, u.Username, "unix", nil
+               }
+
                return true, "", "unix", nil
        }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to