(#12457) add users primary group, not Process.gid, in initgroups

The Process.gid (real gid) was always included when initialising supplementary
groups in the initgroups method (called when changing the euid via the
change_user method).  This has been replaced by the primary gid of the user.

This led to a privilege leak, as well as a potential surprise when it came to
file ownership, in both the agent and the master.

Fix and analysis by Dominic Cleal <dcleal@redhat.com>

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Facter 1.5.7 compatibility in the test condition.

The `augeasversion` fact was only introduced in Facter 1.6.1, and this test
depends on it - or blows up trying to process `nil` in `versioncmp`.

If we don't have the fact we might as well skip over the test set; it isn't
much worse than working harder at this, and less false positives than guessing
the other way around.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
(#12458) default to users primary group, not root, in `asuser`

When only a user (no group) was given to the asuser method, the egid wouldn't
be changed and would remain the privileged gid.  This has been changed to the
primary gid of the user.

Fix and analysis by Dominic Cleal <dcleal@redhat.com>

Contributed: Daniel Pittman <daniel@puppetlabs.com>
Contributed: Deepak Giridharagopal <deepak@puppetlabs.com>
Contributed: Nick Lewis <nick@puppetlabs.com>
(#12459) drop supplementary groups when permanently dropping UID

On certain platforms, Process::UID.change_privilege doesn't handle
changing supplementary groups. In that case, we need to always
explicitly initgroups, regardless of whether we're using
change_privilege, or change_group/change_user.

Analysis by Dominic Cleal <dcleal@redhat.com>

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
(#12463) add secure `replace_file` to Puppet::Util

There is some complex logic around replacing an existing file safely, and it
used to be scattered all over the tree - making the whole system much harder
to use nicely and pleasantly.

It is much better that we provide a central, and easy to use, method for
achieving that specific and common goal in a consistent, secure, and easy to
audit fashion.

Based on code submitted by me on 2010-04-08.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
(#12462) user_role_add: use `replace_file` for /etc/shadow

The user_role_add provider for user management previously open-coded the safe,
atomic replacement of /etc/shadow after in modified it.

Mostly even safely, except that it didn't enforce permissions on the temporary
file, so might have spilled data to third parties, if tempfile isn't
sufficiently secure.  (Ruby makes no promises about tempfile mode.)

We replace that with the standard, central replace_file API, which ensures
that is done in a safe, correct, and standard fashion.

On the way through this removes the window where this could previously have
lost the content of /etc/shadow due to an unfortunately timed crash, by
ensuring we fsync the content of the temporary file.

It also documents, but doesn't eliminate, the lack of locking and other races
around this update to the shadow file.

Finally, some minor code and test updates to make it easier to test this on
fake data, rather than like on your own /etc/shadow file...

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
(#12460) use `replace_file` for the .k5login file

Previously this hand-coded replacing the .k5login file; Replacing that with
the standard API ensures consistent, safe, and atomic updates of the target
file.

It also reduces the cognitive burden of the provider, since the semantics of
the standard method are clearer than the semantics of the type.

Finally, this commit adds some tests for the type, and the inline provider, to
help ensure that the type continues to work into the future.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
(#12463) eliminate `secure_open` in favour of `replace_file`

None of the users of `secure_open` in the codebase actually want to achieve a
result different from `replace_file`, so we might as well eliminate the older
API in favour of one that is easier to use and clearer in intent.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Copy owner/group in replace_file

If the file doesn't exist, this will still use the current user/group as
the uid/gid of the file.
Document uid/gid-related methods in Puppet::Util
Remove unnecessary fallbacks in change_{user,group}

These methods were attempting to call change_privilege, and rescuing
NotImplementedError, to use our own implementation of similar behavior.
As it turns out, the only system on which change_privilege is not
implemented is Windows, which these methods already don't support. So
there's no reason to have a fallback that would only ever fail or not be
reached.
Prior to this commit we hard coded paths in two tests that depended on
our CI system directory structure. This made it hard to use our
acceptance suite without also including the exact same setup. It also
increased the cost of maintaining our CI setup.

This uses a path relative to the test itself (the file that it SCPs
should always be in the same directory as the test itself)

Signed-off-by: Justin Stoller <justin@puppetlabs.com>
Merge pull request #509 from justinstoller/bug/2.6.x/12692-dont_hard_code_paths_in_tests

(#12692) Don't hard code CI paths into tests
Updating CHANGELOG and lib/puppet.rb for 2.6.14
Merge tag '2.6.14' into 2.6.x
(#9491) Preserve trailing slashes in FileSettings

We use the trailing slash in a FileSetting to determine whether it's a
directory. The change in 97c043f4 caused trailing slashes to be stripped.
This caused errors like:

change from directory to file failed: Could not set 'file on ensure: Is a directory - /var/lib/puppet/facts
Updating puppet.spec for 2.7.11-1, 2.7.11-2
(#7986) Cleanup pkg provider #1

The testing of hash[:error] is apparently dead code because it is never set
to anything different than "ok". Remove the hashkey :missing because it is
never used later.
(#7986) Cleanup pkg provider #2

Switch from Puppet.warning to the warning classmethod. This is mostly
for testing purposes and changes messages produced by puppet slightly.
Instead of

    warning: Failed to match 'pkg list' line foo

The user will now get

    warning: Puppet::Type::Package::ProviderPkg: Failed to match 'pkg
    list' line foo
(#7986) Modify pkg provider to handle publisher

The methods :instances, :query and :latest did not handle pkg list -H
lines correctly when the publisher of a package is not the preferred
publisher.

Modify the parsing method to handle lines with publisher correctly