Skip to content

Commit

Permalink
Cleanly exit if cepces or getcert are not present
Browse files Browse the repository at this point in the history
In case certmonger or the cepces library are not installed we do not
want to fail hard. Check for the existence of the binaries instead of
debs to be more future-proof given that cepces is not yet packaged in
Ubuntu.

Fixes UDENG-1156
  • Loading branch information
GabrielNagy committed Aug 9, 2023
1 parent f156b82 commit 4f33c8b
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 2 deletions.
9 changes: 9 additions & 0 deletions cmd/adsysd/integration_tests/adsysctl_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,15 @@ func TestPolicyUpdate(t *testing.T) {

t.Setenv("ADSYS_WBCLIENT_BEHAVIOR", tc.winbindMockBehavior)

// Create fake certmonger and cepces binaries for the certificate manager
binDir := t.TempDir()
for _, executable := range []string{"getcert", "cepces-submit"} {
// #nosec G306. We want this asset to be executable.
err := os.WriteFile(filepath.Join(binDir, executable), []byte("#!/bin/sh\necho $@\n"), 0755)
require.NoError(t, err, "Setup: could not create %q binary", executable)
}
t.Setenv("PATH", binDir+":"+os.Getenv("PATH"))

// Some tests will need some initial state assets
for _, k := range tc.clearDirs {
err := os.RemoveAll(filepath.Join(adsysDir, k))
Expand Down
13 changes: 12 additions & 1 deletion internal/policies/certificate/cert-autoenroll
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ from samba.dcerpc import preg

from vendor_samba.gp.gpclass import GPOStorage
from vendor_samba.gp import gp_cert_auto_enroll_ext as cae
from vendor_samba.gp.util.logging import logger_init
from vendor_samba.gp.util.logging import logger_init, log

class adsys_cert_auto_enroll(cae.gp_cert_auto_enroll_ext):
def enroll(self, guid, entries, trust_dir, private_dir, global_trust_dir):
Expand Down Expand Up @@ -78,6 +78,10 @@ def main():
# Set up logging
logger_init('cert-autoenroll', lp.log_level())

if not cepces_submit() or not certmonger():
log.warning('certmonger and/or cepces not found, skipping certificate enrollment')
return

ext = adsys_cert_auto_enroll(lp, c, username, store)
guid = f'adsys-cert-autoenroll-{args.object_name}'
if args.action == 'enroll':
Expand Down Expand Up @@ -126,6 +130,13 @@ def gpo_entries(entries_json):
raise ValueError(f'GPO data must be a JSON array of objects') from exc
return entries

def cepces_submit():
certmonger_dirs = [os.environ.get('PATH'), '/usr/lib/certmonger',
'/usr/libexec/certmonger']
return shutil.which('cepces-submit', path=':'.join(certmonger_dirs))

def certmonger():
return shutil.which('getcert')

if __name__ == "__main__":
sys.exit(main())
23 changes: 22 additions & 1 deletion internal/policies/certificate/cert-autoenroll_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ func TestCertAutoenrollScript(t *testing.T) {
readOnlyPath bool
autoenrollError bool

missingCertmonger bool
missingCepces bool

wantErr bool
}{
"Enroll with simple configuration": {args: []string{"enroll", "keypress", "example.com"}},
Expand All @@ -89,6 +92,10 @@ func TestCertAutoenrollScript(t *testing.T) {

"Unenroll": {args: []string{"unenroll", "keypress", "example.com"}},

// Missing binary cases
"Enroll with certmonger not installed": {args: []string{"enroll", "keypress", "example.com"}, missingCertmonger: true},
"Enroll with cepces not installed": {args: []string{"enroll", "keypress", "example.com"}, missingCepces: true},

// Error cases
"Error on missing arguments": {args: []string{"enroll"}, wantErr: true},
"Error on invalid flags": {args: []string{"enroll", "keypress", "example.com", "--invalid_flag"}, wantErr: true},
Expand All @@ -109,6 +116,17 @@ func TestCertAutoenrollScript(t *testing.T) {
stateDir := t.TempDir()
sambaCacheDir := filepath.Join(stateDir, "samba")
globalTrustDir := filepath.Join(stateDir, "ca-certificates")
binDir := t.TempDir()
if !tc.missingCertmonger {
// #nosec G306. We want this asset to be executable.
err := os.WriteFile(filepath.Join(binDir, "getcert"), []byte("#!/bin/sh\necho $@\n"), 0755)
require.NoError(t, err, "Setup: could not create getcert binary")
}
if !tc.missingCepces {
// #nosec G306. We want this asset to be executable.
err := os.WriteFile(filepath.Join(binDir, "cepces-submit"), []byte("#!/bin/sh\necho $@\n"), 0755)
require.NoError(t, err, "Setup: could not create cepces binary")
}

// Create a dummy cache file to ensure we don't fail when removing a non-empty directory
testutils.CreatePath(t, filepath.Join(sambaCacheDir, "cert_gpo_state_HOST.tdb"))
Expand All @@ -121,7 +139,10 @@ func TestCertAutoenrollScript(t *testing.T) {

// #nosec G204: we control the command line name and only change it for tests
cmd := exec.Command(certAutoenrollCmd, args...)
cmd.Env = append(os.Environ(), "PYTHONPATH="+pythonPath)
cmd.Env = append(os.Environ(),
"PYTHONPATH="+pythonPath,
"PATH="+binDir+":"+os.Getenv("PATH"),
)
if tc.autoenrollError {
cmd.Env = append(os.Environ(), "ADSYS_WANT_AUTOENROLL_ERROR=1")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Loading smb.conf
[global]
realm = example.com

Loading state file: #STATEDIR#/samba/cert_gpo_state_keypress.tdb
WARNING: certmonger and/or cepces not found, skipping certificate enrollment
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Loading smb.conf
[global]
realm = example.com

Loading state file: #STATEDIR#/samba/cert_gpo_state_keypress.tdb
WARNING: certmonger and/or cepces not found, skipping certificate enrollment
5 changes: 5 additions & 0 deletions internal/testutils/admock/vendor_samba/gp/util/logging.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
def logger_init(_name, _level):
pass

class log(object):
@staticmethod
def warning(msg):
print(f'WARNING: {msg}')

0 comments on commit 4f33c8b

Please sign in to comment.