* sec_auth.cc (get_server_groups): Call get_logon_server only for

non-builtin accounts.
	* uinfo.cc (pwdgrp::fetch_account_from_windows): Check incoming
	account name for validity in terms of the current name prefixing rules
	and refuse invalid names.
This commit is contained in:
Corinna Vinschen 2014-05-14 11:27:47 +00:00
parent d4ff931bf8
commit 6506454fb3
3 changed files with 95 additions and 7 deletions

View File

@ -1,3 +1,11 @@
2014-05-14 Corinna Vinschen <corinna@vinschen.de>
* sec_auth.cc (get_server_groups): Call get_logon_server only for
non-builtin accounts.
* uinfo.cc (pwdgrp::fetch_account_from_windows): Check incoming
account name for validity in terms of the current name prefixing rules
and refuse invalid names.
2014-05-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::ioctl): Handle the different

View File

@ -465,7 +465,11 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
__seterrno ();
return false;
}
if (get_logon_server (domain, server, DS_IS_FLAT_NAME))
/* If the SID does NOT start with S-1-5-21, the domain is some builtin
domain. The search for a logon server is moot. */
if (sid_id_auth (usersid) == 5 /* SECURITY_NT_AUTHORITY */
&& sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
&& get_logon_server (domain, server, DS_IS_FLAT_NAME))
get_user_groups (server, grp_list, user, domain);
get_user_local_groups (server, domain, grp_list, user);
return true;

View File

@ -1189,7 +1189,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
SID_NAME_USE acc_type;
BOOL ret = false;
/* Cygwin user name style. */
enum {
enum name_style_t {
name_only,
plus_prepended,
fully_qualified
@ -1251,19 +1251,24 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
standalone machine, or the username must be from the primary domain.
In the latter case, prepend the primary domain name so as not to
collide with an account from the account domain with the same name. */
name_style_t nstyle;
nstyle = name_only;
p = name;
if (*arg.name == cygheap->pg.nss_separator ()[0])
++arg.name;
else if (!strchr (arg.name, cygheap->pg.nss_separator ()[0])
&& cygheap->dom.member_machine ())
nstyle = plus_prepended;
else if (strchr (arg.name, cygheap->pg.nss_separator ()[0]))
nstyle = fully_qualified;
else if (cygheap->dom.member_machine ())
p = wcpcpy (wcpcpy (p, cygheap->dom.primary_flat_name ()),
cygheap->pg.nss_separator ());
/* Now fill up with name to search. */
sys_mbstowcs (p, UNLEN + 1, arg.name);
sys_mbstowcs (p, UNLEN + 1,
arg.name + (nstyle == plus_prepended ? 1 : 0));
/* Replace domain separator char with backslash and make sure p is NULL
or points to the backslash, so... */
if ((p = wcschr (name, cygheap->pg.nss_separator ()[0])))
*p = L'\\';
*p = L'\\';
sid = csid;
ret = LookupAccountNameW (NULL, name, sid, &slen, dom, &dlen, &acc_type);
if (!ret)
@ -1274,6 +1279,77 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
/* ... we can skip the backslash in the rest of this function. */
if (p)
name = p + 1;
/* Last but not least, some validity checks on the name style. */
switch (nstyle)
{
case name_only:
/* name_only account must start with S-1-5-21 */
if (sid_id_auth (sid) != 5 /* SECURITY_NT_AUTHORITY */
|| sid_sub_auth (sid, 0) != SECURITY_NT_NON_UNIQUE)
{
debug_printf ("Invalid account name <%s> (name only/"
"not NON_UNIQUE)", arg.name);
return NULL;
}
/* name_only only if db_prefix is auto. */
if (!cygheap->pg.nss_prefix_auto ())
{
debug_printf ("Invalid account name <%s> (name only/"
"db_prefix not auto)", arg.name);
return NULL;
}
break;
case plus_prepended:
/* plus_prepended account must not start with S-1-5-21. */
if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
&& sid_sub_auth (sid, 0) == SECURITY_NT_NON_UNIQUE)
{
debug_printf ("Invalid account name <%s> (plus prependend/"
"NON_UNIQUE)", arg.name);
return NULL;
}
/* plus_prepended only if db_prefix is not always. */
if (cygheap->pg.nss_prefix_always ())
{
debug_printf ("Invalid account name <%s> (plus prependend/"
"db_prefix not always)", arg.name);
return NULL;
}
break;
case fully_qualified:
/* All is well if db_prefix is always. */
if (cygheap->pg.nss_prefix_always ())
break;
/* Otherwise, no fully_qualified for builtin accounts. */
if (sid_id_auth (sid) != 5 /* SECURITY_NT_AUTHORITY */
|| sid_sub_auth (sid, 0) != SECURITY_NT_NON_UNIQUE)
{
debug_printf ("Invalid account name <%s> (fully qualified/"
"not NON_UNIQUE)", arg.name);
return NULL;
}
/* All is well if db_prefix is primary. */
if (cygheap->pg.nss_prefix_primary ())
break;
/* Domain member and domain == primary domain? */
if (cygheap->dom.member_machine ())
{
if (!wcscasecmp (dom, cygheap->dom.primary_flat_name ()))
{
debug_printf ("Invalid account name <%s> (fully qualified/"
"primary domain account)", arg.name);
return NULL;
}
}
/* Not domain member and domain == account domain? */
else if (!wcscasecmp (dom, cygheap->dom.account_flat_name ()))
{
debug_printf ("Invalid account name <%s> (fully qualified/"
"local account)", arg.name);
return NULL;
}
break;
}
break;
case ID_arg:
/* Construct SID from ID using the SFU rules, just like the code below