Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate unique UIDs and GIDs #663

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open

Generate unique UIDs and GIDs #663

wants to merge 21 commits into from

Conversation

adombeck
Copy link
Contributor

@adombeck adombeck commented Dec 2, 2024

These changes have already partly been reviewed in https://github.com/canonical/authd-private/pull/9.

Closes #509
UDENG-5416
UDENG-4352

@adombeck adombeck force-pushed the 509-random-unique-ids branch 3 times, most recently from cb2ba1b to 8e15caf Compare December 3, 2024 00:05
internal/users/localgroups/getpwent_c.go Outdated Show resolved Hide resolved
internal/users/localgroups/getpwent_c.go Outdated Show resolved Hide resolved
internal/testsdetection/testsdetection.go Outdated Show resolved Hide resolved
internal/users/localgroups/getpwent_c.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/localentries/getpwent_c.go Show resolved Hide resolved
internal/users/localentries/getpwent_test.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
internal/users/manager.go Outdated Show resolved Hide resolved
@adombeck adombeck force-pushed the 509-random-unique-ids branch from 8e15caf to 745d7c6 Compare December 5, 2024 23:18
@adombeck
Copy link
Contributor Author

adombeck commented Dec 5, 2024

rebased on main and resolved conflicts

@adombeck adombeck force-pushed the 509-random-unique-ids branch 5 times, most recently from 12c61bb to 75fe88c Compare December 20, 2024 15:03
@adombeck adombeck marked this pull request as ready for review December 21, 2024 16:20
@adombeck adombeck requested a review from a team as a code owner December 21, 2024 16:20
@adombeck
Copy link
Contributor Author

I extracted the new code to handle temporary users and groups into a separate package and added some more tests.

@adombeck adombeck requested a review from 3v1n0 January 6, 2025 13:53
@adombeck adombeck force-pushed the 509-random-unique-ids branch from 75fe88c to 0eb85a5 Compare January 6, 2025 13:54
Should have been removed by 4fd03a4.
Combine TestUserByID and TestUserByName, TestGroupByID and
TestGroupByName, because the test bodies were identical (except for the
called function).
* Remove obsolete tests: They were testing behavior which has changed.
* Fix tests by using either predictable UIDs or replacing UIDs in golden
  files with placeholders (normalizing)
* Limit number of pre-auth user records to avoid denial of service by
  sending many SSH requests for unique users to fill up the UID range.
* Remove field UID from users.UserInfo struct because it's not set in
  internal/brokers/broker.go anymore and there is no need to expose this
  field.
* Rename localgroups package to localentries because it now also
  provides functions for passwd entries.
* Check for error when calling getpwent or getgrent
@adombeck adombeck force-pushed the 509-random-unique-ids branch from 0eb85a5 to e186eca Compare January 8, 2025 15:54
Copy link
Collaborator

@3v1n0 3v1n0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're almost there, some further nits and suggestions.

I was wondering, since there are some common code paths in groups and users temporary entries registration, would be possible to do some logic deduplication, or is it not possible?


func TestMain(m *testing.M) {
log.SetLevel(log.DebugLevel)
os.Exit(m.Run())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use m.Run() as per #691

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

internal/services/nss/nss.go Outdated Show resolved Hide resolved
Comment on lines 32 to 33
registerMutex: sync.Mutex{},
rwMutex: sync.RWMutex{},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We normally call them just Mu in the codebase here, so can shorten the suffixes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I've seen that. I thought rwMutex would be a bit easier to understand than rwMu, but I don't care much, so I'll change it.

Comment on lines 65 to 67
func (r *temporaryGroupRecords) groupEntry(group groupRecord) types.GroupEntry {
return types.GroupEntry{Name: group.name, GID: group.gid, Passwd: group.passwd}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be part of temporaryGroupRecords?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 105 to 107
if cleanupErr := cleanup(); cleanupErr != nil {
err = errors.Join(err, cleanupErr)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it just be errors.Join(err, cleanup())?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could, but I would find that harder to read. When you read that, you need to know and remember that errors.Join ignores nil arguments.

internal/users/localentries/getgrent_c.go Outdated Show resolved Hide resolved
internal/users/localentries/getgrent_c.go Show resolved Hide resolved
internal/users/localentries/getgrent_c.go Show resolved Hide resolved
Comment on lines 12 to 18
void unset_errno(void) {
errno = 0;
}

int get_errno(void) {
return errno;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this will fit better in the new errno.go file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I try to move it:

diff --git a/internal/users/localentries/errno.go b/internal/users/localentries/errno.go
index 8f345f3c..1cbf30ba 100644
--- a/internal/users/localentries/errno.go
+++ b/internal/users/localentries/errno.go
@@ -2,4 +2,22 @@ package localentries
 
 import "sync"
 
+/*
+#include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <string.h>
+
+void unset_errno(void) {
+  errno = 0;
+}
+
+int get_errno(void) {
+  return errno;
+}
+*/
+//#cgo LDFLAGS: -Wl,--allow-multiple-definition
+import "C"
+
 var errnoMutex sync.Mutex
diff --git a/internal/users/localentries/getgrent_c.go b/internal/users/localentries/getgrent_c.go
index e99bc254..c4a5a8a2 100644
--- a/internal/users/localentries/getgrent_c.go
+++ b/internal/users/localentries/getgrent_c.go
@@ -7,16 +7,7 @@ package localentries
 #include <stdlib.h>
 #include <pwd.h>
 #include <grp.h>
-#include <errno.h>
 #include <string.h>
-
-void unset_errno(void) {
-  errno = 0;
-}
-
-int get_errno(void) {
-  return errno;
-}
 */
 //#cgo LDFLAGS: -Wl,--allow-multiple-definition
 import "C"
diff --git a/internal/users/localentries/getpwent_c.go b/internal/users/localentries/getpwent_c.go
index b635b474..aca04aed 100644
--- a/internal/users/localentries/getpwent_c.go
+++ b/internal/users/localentries/getpwent_c.go
@@ -7,16 +7,7 @@ package localentries
 #include <stdlib.h>
 #include <pwd.h>
 #include <grp.h>
-#include <errno.h>
 #include <string.h>
-
-void unset_errno(void) {
-  errno = 0;
-}
-
-int get_errno(void) {
-  return errno;
-}
 */
 //#cgo LDFLAGS: -Wl,--allow-multiple-definition
 import "C"

then building the package fails:

go test ./internal/users/localentries/...
# github.com/ubuntu/authd/internal/users/localentries
internal/users/localentries/getgrent_c.go:94:30: could not determine kind of name for C.EBADF
internal/users/localentries/getgrent_c.go:40:15: could not determine kind of name for C.ENOENT
internal/users/localentries/getgrent_c.go:94:39: could not determine kind of name for C.EPERM
internal/users/localentries/getgrent_c.go:94:21: could not determine kind of name for C.ESRCH
internal/users/localentries/getgrent_c.go:37:12: could not determine kind of name for C.get_errno
internal/users/localentries/getgrent_c.go:34:2: could not determine kind of name for C.unset_errno
FAIL	github.com/ubuntu/authd/internal/users/localentries [build failed]
FAIL	github.com/ubuntu/authd/internal/users/localentries/testutils [build failed]
FAIL

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done some cleanups on this regards, please see commits at https://github.com/3v1n0/authd/commits/509-random-unique-ids/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if you get a notification, I have a question here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think I did, however check the branch again as I've moved things to a more central place and added tests, in case we need to reuse it

internal/users/localentries/getpwent_c.go Outdated Show resolved Hide resolved
@adombeck adombeck requested a review from 3v1n0 January 10, 2025 09:10

import "sync"

var errnoMutex sync.Mutex
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var errnoMutex sync.Mutex
var errnoMu sync.Mutex

Passwd string
}

var getgrentMutex sync.Mutex
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var getgrentMutex sync.Mutex
var getgrentMu sync.Mutex

Gecos string
}

var getpwentMutex sync.Mutex
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var getpwentMutex sync.Mutex
var getpwentMu sync.Mutex

@@ -61,7 +61,7 @@ func (r *TemporaryRecords) UserByName(name string) (types.UserEntry, error) {
//
// Returns the generated UID and a cleanup function that should be called to remove the temporary user once the user was
// added to the database.
func (r *TemporaryRecords) RegisterUser(name string) (uid uint32, cleanup func() error, err error) {
func (r *TemporaryRecords) RegisterUser(name string) (uid uint32, cleanup func(), err error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a reason to have named values here (a part from clarity, that I agree is nice)?

As the cleanup can be a bit dangerous, since it's going to be set to nil by default, and calling it by mistake before being set, will lead to a crash without being caught before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue: GID for group already in use by a different group
2 participants