Skip to content
This repository has been archived by the owner on May 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #59 from ubuntu/adapting-nss-integration-tests
Browse files Browse the repository at this point in the history
Adapting nss integration tests
  • Loading branch information
denisonbarbosa committed Sep 8, 2022
2 parents 6865782 + 114743a commit ff7b1fe
Show file tree
Hide file tree
Showing 86 changed files with 299 additions and 963 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/qa.yaml
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Install dependencies
run: |
sudo DEBIAN_FRONTEND=noninteractive apt update
sudo DEBIAN_FRONTEND=noninteractive apt install -y libpam-dev
sudo DEBIAN_FRONTEND=noninteractive apt install -y libpam-dev libglib2.0-dev gcc
- uses: actions/checkout@v3
- name: Code formatting, vet, static checker Security…
uses: golangci/golangci-lint-action@v3
Expand All @@ -38,8 +38,12 @@ jobs:
# Build PAM library
go build -ldflags='-s -w' -buildmode=c-shared -o pam_aad.so ./pam
# Build NSS library
go build -ldflags='-s -w' -buildmode=c-shared -o libnss_aad.so.2 ./nss/integration_tests
# Build NSS CLI executable
go build -o aad-auth ./nss/aad-auth
# Build NSS C library
make -C nss/ libnss_aad.so.2
if: ${{ always() }}

tests:
Expand Down
Expand Up @@ -10,21 +10,6 @@ import (
"github.com/ubuntu/aad-auth/internal/cache"
)

/*
#include <nss.h>
#include <stdlib.h>
static void __attribute__((constructor))
nsstest_ctor(void)
{
__nss_configure_lookup("passwd", "files aad");
__nss_configure_lookup("group", "files aad");
__nss_configure_lookup("shadow", "go aad");
}
*/
import "C"

// initialize via env variables in mock test
func init() {
uidEnv := os.Getenv("NSS_AAD_ROOT_UID")
Expand Down
13 changes: 6 additions & 7 deletions nss/aad-auth/getent.go
Expand Up @@ -17,30 +17,29 @@ import (
var supportedDbs = []string{"group", "passwd", "shadow"}

// Getent processes the args and queries the database for the requested entries.
func Getent(ctx context.Context, dbName, key string, cacheOpts ...cache.Option) (string, error) {
func Getent(ctx context.Context, dbName string, key *string, cacheOpts ...cache.Option) (string, error) {
if !dbIsSupported(dbName) {
return "", fmt.Errorf("database %q is not supported", dbName)
}

logger.Debug(ctx, "Getting entry %q from %s ", key, dbName)

var entries []fmt.Stringer
var err error
if key != "" {
if key == nil {
entries, err = getAllEntries(ctx, dbName, cacheOpts...)
} else {
var e fmt.Stringer
e, err = getEntryByKey(ctx, dbName, key, cacheOpts...)
e, err = getEntryByKey(ctx, dbName, *key, cacheOpts...)
entries = []fmt.Stringer{e}
if err != nil {
entries = nil
}
} else {
entries, err = getAllEntries(ctx, dbName, cacheOpts...)
}

return fmtGetentOutput(ctx, entries, err), nil
}

func getEntryByKey(ctx context.Context, dbName, key string, cacheOpts ...cache.Option) (entry fmt.Stringer, err error) {
logger.Debug(ctx, "Getting entry %q from %s", key, dbName)
u, err := strconv.ParseUint(key, 10, 64)
if err != nil {
return getEntryByName(ctx, dbName, key, cacheOpts...)
Expand Down
25 changes: 16 additions & 9 deletions nss/aad-auth/aadauth_test.go → nss/aad-auth/getent_test.go
Expand Up @@ -2,16 +2,16 @@ package main

import (
"context"
"flag"
"testing"

"github.com/stretchr/testify/require"
"github.com/ubuntu/aad-auth/internal/cache"
"github.com/ubuntu/aad-auth/internal/testutils"
)

func TestGetEnt(t *testing.T) {
func TestGetent(t *testing.T) {
noShadow := 0
//nolint:dupl // We use the same table for the integration and the package tests.
tests := map[string]struct {
db string
key string
Expand Down Expand Up @@ -72,6 +72,11 @@ func TestGetEnt(t *testing.T) {
"try to list group without permission on cache": {db: "group", rootUID: 4242},
"try to list shadow without permission on cache": {db: "shadow", rootUID: 4242},

// Try to get entry with empty value
"try to get passwd entry with explicit empty key": {db: "passwd", key: "-"},
"try to get group entry with explicit empty key": {db: "group", key: "-"},
"try to get shadow entry with explicit empty key": {db: "shadow", key: "-"},

// Error when trying to list from unsupported database
"error trying to list entry by name from unsupported db": {db: "unsupported", key: "myuser@domain.com", wantErr: true},
"error trying to list unsupported db": {db: "unsupported", wantErr: true},
Expand Down Expand Up @@ -105,7 +110,15 @@ func TestGetEnt(t *testing.T) {
opts = append(opts, cache.WithShadowMode(*tc.shadowMode))
}

got, err := Getent(context.Background(), tc.db, tc.key, opts...)
var key *string
var emptyString string
if tc.key == "-" {
key = &emptyString
} else if tc.key != "" {
key = &tc.key
}

got, err := Getent(context.Background(), tc.db, key, opts...)
if tc.wantErr {
require.Error(t, err, "Expected an error but got none.")
return
Expand All @@ -117,9 +130,3 @@ func TestGetEnt(t *testing.T) {
})
}
}

func TestMain(m *testing.M) {
testutils.InstallUpdateFlag()
flag.Parse()
m.Run()
}
Expand Up @@ -2,23 +2,20 @@ package main

import (
"bytes"
"flag"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"github.com/ubuntu/aad-auth/internal/testutils"
)

var libPath string
var libPath, execPath string

// outNSSCommandForLib returns the specific part by the nss command to got, filtering originOut.
// It uses the locally build aad nss module.
func outNSSCommandForLib(t *testing.T, rootUID, rootGID, shadowMode int, cacheDir string, originOut []byte, cmds ...string) (got string, err error) {
// outNSSCommandForLib returns the specific part for the nss command, filtering originOut.
// It uses the locally build aad nss module for the integration tests.
func outNSSCommandForLib(t *testing.T, rootUID, rootGID, shadowMode int, cacheDir string, originOut string, cmds ...string) (got string, err error) {
t.Helper()

// #nosec:G204 - we control the command arguments in tests
Expand All @@ -42,7 +39,7 @@ func outNSSCommandForLib(t *testing.T, rootUID, rootGID, shadowMode int, cacheDi
cmd.Stdout = io.MultiWriter(os.Stdout, &out)
cmd.Stderr = os.Stderr
err = cmd.Run()
got = strings.Replace(out.String(), string(originOut), "", 1)
got = strings.Replace(out.String(), originOut, "", 1)

return got, err
}
Expand All @@ -60,24 +57,34 @@ func createTempDir() (tmp string, cleanup func(), err error) {
}, nil
}

func TestMain(m *testing.M) {
// Build the pam module in a temporary directory and allow linking to it.
libDir, cleanup, err := createTempDir()
func buildNSSCLib() error {
// Gets the .c files required to build the NSS C library.
cFiles, err := filepath.Glob("../*.c")
if err != nil {
os.Exit(1)
return fmt.Errorf("error when fetching the required c files: %w", err)
}

libPath = filepath.Join(libDir, "libnss_aad.so.2")
// #nosec:G204 - we control the command arguments in tests
out, err := exec.Command("go", "build", "-buildmode=c-shared", "-tags", "integrationtests", "-o", libPath).CombinedOutput()
// Gets the cflags and ldflags.
flags := []string{"-g", "-Wall", "-Wextra"}
out, err := exec.Command("pkg-config", "--cflags", "--libs", "glib-2.0").CombinedOutput()
if err != nil {
cleanup()
fmt.Fprintf(os.Stderr, "Can not build nss module (%v) : %s", err, out)
os.Exit(1)
return fmt.Errorf("could not get the required cflags (%s): %w", out, err)
}
flags = append(flags, strings.Fields(string(out))...)

// Assembles the flags required to build the NSS library.
c := []string{fmt.Sprintf(`-DSCRIPTPATH="%s"`, execPath)}
c = append(c, "-DINTEGRATIONTESTS=1")
c = append(c, cFiles...)
c = append(c, flags...)
c = append(c, "-fPIC", "-shared", "-Wl,-soname,libnss_aad.so.2", "-o", libPath)

testutils.InstallUpdateFlag()
flag.Parse()
// #nosec:G204 - we control the command arguments in tests.
cmd := exec.Command("gcc", c...)
out, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("can not build nss library (%s): %w", out, err)
}

m.Run()
return nil
}

0 comments on commit ff7b1fe

Please sign in to comment.