Commit Graph

18 Commits

Author SHA1 Message Date
Tomas Mraz
ee9e506af2 Make the group and user allocation more effective.
Previously, the allocation was optimized for an outdated
deployment style (that of /etc/group alongside nss_db). The issue
here is that this results in extremely poor performance when using
SSSD, Winbind or nss_ldap.

There were actually two serious bugs here that have been addressed:

1) Running getgrent() loops won't work in most SSSD or Winbind
environments, as full group enumeration is disabled by default.
This could easily result in auto-allocating a group that was
already in use. (This might result in a security issue as well, if
the shared GID is a privileged group).

2) For system groups, the loop was always iterating through the
complete SYS_GID_MIN->SYS_GID_MAX range. On SSSD and Winbind, this
means hundreds of round-trips to LDAP (unless the GIDs were
specifically configured to be ignored by the SSSD or winbindd).
To a user with a slow connection to their LDAP server, this would
appear as if groupadd -r was hung. (Though it would eventually
complete).

This patch changes the algorithm to be more favorable for LDAP
environments, at the expense of some performance when using nss_db.
Given that the DB is a local service, this should have a negligible
effect from a user's perspective.

With the new algorithm, we simply first iterate through all entries
in the local database with gr_next(), recording the IDs that are in
use. We then start from the highest presumed-available entry and
call getgrgid() to see if it is available. We continue this until
we come to the first unused GID. We then select that and return it.

If we make it through all the remaining IDs without finding a free
one, we start over from the beginning of the range and try to find
room in one of the gaps in the range.

The patch was originally written by Stephen Gallagher and applied
identically also to the user allocation by Tomáš Mráz.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2017-01-29 14:37:21 -06:00
nekral-guest
019048c555 * libmisc/find_new_uid.c: free (used_uids) on return.
* libmisc/find_new_gid.c: free (used_gids) on return.
2011-07-30 01:38:07 +00:00
nekral-guest
275ffe2e01 * libmisc/find_new_gid.c, libmisc/find_new_uid.c: Fail in case of
invalid configuration. 
	* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Updated
	comments.
	* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Be more strict
	on the loop stop conditions. Stop if we passed the limit, even if
	the limit itself was never noticed.
2011-07-22 21:53:01 +00:00
nekral-guest
58baa7aa61 * libmisc/find_new_uid.c, libmisc/find_new_gid.c: Add missing
memory allocation check.
2011-06-02 18:40:06 +00:00
nekral-guest
07e462f01f * libmisc/limits.c: Avoid implicit conversion of integer to
boolean.
	* libmisc/basename.c: Avoid implicit conversion of pointer to
	boolean.
	* libmisc/basename.c, lib/prototypes.h (Basename): Return a
	constant string.
	* libmisc/basename.c, libmisc/obscure.c, lib/prototypes.h,
	libmisc/xmalloc.c, libmisc/getdate.h, libmisc/system.c,
	libmisc/getgr_nam_gid.c, libmisc/failure.c, libmisc/valid.c: Add
	splint annotations.
	* libmisc/chowndir.c: Avoid memory leak.
	* libmisc/chowndir.c: Do not check *printf/*puts return value.
	* libmisc/chowntty.c: Avoid implicit conversion between integer
	types.
	* libmisc/obscure.c: Return a bool when possible instead of int.
	* libmisc/shell.c: Do not check *printf/*puts return value.
	* libmisc/shell.c: Do not check execle return value.
	* libmisc/setupenv.c: Avoid implicit conversion between integer
	types.
	* libmisc/xmalloc.c: size should not be zero to avoid returning
	NULL pointers.
	* libmisc/hushed.c: Do not check *printf/*puts return value.
	* libmisc/system.c: Avoid implicit conversion of integer to
	boolean. safe_system last argument is a boolean.
	* libmisc/system.c: Check return value of dup2.
	* libmisc/system.c: Do not check *printf/*puts return value.
	* libmisc/system.c: Do not check execve return value. 
	* libmisc/salt.c: Do not check *printf/*puts return value.
	* libmisc/loginprompt.c: Do not check gethostname return value.
	* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Do not check
	gr_rewind/pw_rewind return value.
	* libmisc/ttytype.c: Limit the number of parsed characters in the
	sscanf format.
	* libmisc/ttytype.c: Test if a type was really read.
	* libmisc/sub.c: Do not check *printf/*puts return value.
	* libmisc/sub.c: Avoid implicit conversion of integer to boolean.
	* src/userdel.c: Fix typo in comment.
	* src/userdel.c: Avoid implicit conversion of boolean to integer.
	* src/userdel.c: safe_system last argument is a boolean.
	* src/newusers.c: Avoid implicit conversion of boolean to integer.
	* src/newusers.c: Avoid implicit conversion of integer to boolean.
	* src/usermod.c: Add brackets.
	* src/usermod.c: Avoid implicit conversion of characters or
	integers to booleans.
	* src/vipw.c: Avoid implicit conversion of integer to boolean.
	* src/su.c: Avoid implicit conversion of integer to boolean.
	* src/su.c: Add brackets.
	* src/useradd.c: Avoid implicit conversion of characters or
	integers to booleans.
2010-08-22 19:13:53 +00:00
nekral-guest
4375be4642 * lib/utent.c (getutline): Remove getutline(). This function is
no more used.
	* lib/groupmem.c: Limit the scope of variable i.
	* lib/shadow.c: Avoid implicit conversion of pointers and integers
	to booleans.
	* lib/shadow.c: Added brackets.
	* libmisc/limits.c: Limit the scope of variable tmpmask.
	* libmisc/copydir.c: Close opened file on failure.
	* libmisc/loginprompt.c: Limit the scope of variable envc.
	* libmisc/find_new_uid.c, libmisc/find_new_gid.c: Limit the scope
	of variable id.
2010-03-23 08:56:52 +00:00
nekral-guest
5ebb35654b * libmisc/find_new_gid.c, libmisc/find_new_uid.c: Detect some
misconfigurations of UID_MIN, UID_MAX, SYS_UID_MIN, SYS_UID_MAX (and
	the GID equivalents)
2010-03-21 01:20:50 +00:00
nekral-guest
56c7096000 2009-07-18 Peter Vrabec <pvrabec@redhat.com>
* NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Since
	system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
	reverse order, accounts are packed close to SYS_?ID_MAX if
	SYS_?ID_MIN is already used but there are still dome gaps.
2009-07-18 00:35:35 +00:00
nekral-guest
b0bcb01888 * NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Do not use
getpwent / getgrent for system accounts. Trying the low-IDs with
	getpwuid / getgrgid should be more efficient on LDAP configured
	systems with many accounts.
2009-07-17 22:54:23 +00:00
nekral-guest
7f165aab7f * libmisc/find_new_gid.c, libmisc/find_new_uid.c,
libmisc/isexpired.c, src/groupadd.c, lib/pwauth.h, lib/groupmem.c,
	lib/shadowmem.c, lib/pwmem.c, lib/prototypes.h: Added splint
	annotations.
2009-04-23 17:43:27 +00:00
nekral-guest
b0db85bc04 * libmisc/find_new_gid.c: Use booleans instead of char fo
used_gids.
	* libmisc/find_new_gid.c: Use getdef_ulong and cast to git_t to
	get GID values.
	* libmisc/find_new_gid.c: Use UL as a prefix for ulong values.
	* libmisc/find_new_uid.c: Likewise.
2009-04-23 11:16:38 +00:00
nekral-guest
ca1bb50c24 * libmisc/find_new_gid.c, libmisc/find_new_uid.c: For system
accounts, return the first unused ID, starting from the max value.
	This could be useful later to increase the static IDs range.
2009-04-11 16:00:45 +00:00
nekral-guest
80135cdc17 * libmisc/find_new_gid.c: Fix find_new_gid() the current group
database was not taken into account.
2009-03-15 21:12:57 +00:00
nekral-guest
a62e781248 * libmisc/find_new_gid.c, libmisc/find_new_uid.c: Avoid calling
getgrent()/getpwent() after they return NULL. This caused LDAP to
	return at the beginning of the group/user entries.
2009-02-22 23:23:15 +00:00
nekral-guest
f3df48ab4f * src/useradd.c: Added missing declaration of Mflg.
* src/pwck.c: Only unlock files if they were locked before (e.g.
	not in read-only mode).
	* src/pwck.c: Quote the username in error messages (harmonization
	with other messages).
	* libmisc/find_new_gid.c: Fixed typo (s/grp->gr_gid/group_id/).
	* libmisc/find_new_gid.c: Likewise.
2008-09-14 13:42:10 +00:00
nekral-guest
8c060833c8 From RedHat's patch shadow-4.1.2-sysAccountDownhill.patch
Thanks to Peter Vrabec.
	* NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Build an
	index of used IDs to avoid a database request for each id in the
	allowed range (when the highest allowed ID is already used).
	This speedups the addition of users or groups when the highest
	allowed ID is already used. The additional memory usage of the
	tools should be acceptable when UID_MAX/SYS_UID_MAX are set to a
	reasonable number.
2008-09-13 11:54:49 +00:00
nekral-guest
ee4e367ea8 * src/newgrp.c, src/userdel.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/pwconv.c, src/chpasswd.c, src/logoutd.c,
	src/chfn.c, src/groupmems.c, src/usermod.c, src/pwunconv.c,
	src/expiry.c, src/groupdel.c, src/chgpasswd.c, src/useradd.c,
	src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
	src/groupadd.c, src/chage.c, src/login.c, src/grpconv.c,
	src/groups.c, src/grpunconv.c, src/chsh.c: Prog is now global (not
	static to the file) so that it can be used by the helper functions
	of libmisc.
	* lib/prototypes.h: Added extern char *Prog.
	* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Indicate the
	program name with the warning.
2008-09-06 12:51:53 +00:00
nekral-guest
e1307ea789 * libmisc/find_new_ids.c, libmisc/find_new_gid.c,
libmisc/find_new_uid.c, libmisc/Makefile.am, lib/prototypes.h:
	Split find_new_ids.c into find_new_gid.c and find_new_uid.c to
	ease the description of login.defs variables in the different
	tools.
2008-06-15 18:33:52 +00:00