* grp.cc (internal_getgroups): Drop unused cygsid variable.

* sec_helper.cc (cygpsid::pstring): Use sid_sub_auth_count macro.
	(cygsid::get_sid): Use MAX_SUBAUTH_CNT rather than wrong constant 8.
	Don't call memcpy to copy subauthorities into SID, use assignment.
	(cygsid::getfromstr): Use MAX_SUBAUTH_CNT rather than wrong constant 8.
	* security.h (MAX_SUBAUTH_CNT): New definition.  Set to 11 to cover
	Microsoft Accounts.
	(MAX_SID_LEN): Define in terms of SID member sizes and MAX_SUBAUTH_CNT.
	(DBGSID): Use MAX_SUBAUTH_CNT to define size of SubAuthority array.
	* uinfo.cc (pwdgrp::fetch_account_from_windows): Handle Micosoft
	Accounts.  Handle them as well known group.  Compare domain names
	case-insensitive.
	* winlean.h (PIPE_REJECT_REMOTE_CLIENTS): Drop temporary definition
	since Mingw64 catched up.
	(DNLEN): Redefine as 16.  Explain why.
This commit is contained in:
Corinna Vinschen 2014-05-06 12:02:48 +00:00
parent 67797a9560
commit 439b7db785
6 changed files with 52 additions and 25 deletions

View File

@ -1,3 +1,21 @@
2014-05-06 Corinna Vinschen <corinna@vinschen.de>
* grp.cc (internal_getgroups): Drop unused cygsid variable.
* sec_helper.cc (cygpsid::pstring): Use sid_sub_auth_count macro.
(cygsid::get_sid): Use MAX_SUBAUTH_CNT rather than wrong constant 8.
Don't call memcpy to copy subauthorities into SID, use assignment.
(cygsid::getfromstr): Use MAX_SUBAUTH_CNT rather than wrong constant 8.
* security.h (MAX_SUBAUTH_CNT): New definition. Set to 11 to cover
Microsoft Accounts.
(MAX_SID_LEN): Define in terms of SID member sizes and MAX_SUBAUTH_CNT.
(DBGSID): Use MAX_SUBAUTH_CNT to define size of SubAuthority array.
* uinfo.cc (pwdgrp::fetch_account_from_windows): Handle Micosoft
Accounts. Handle them as well known group. Compare domain names
case-insensitive.
* winlean.h (PIPE_REJECT_REMOTE_CLIENTS): Drop temporary definition
since Mingw64 catched up.
(DNLEN): Redefine as 16. Explain why.
2014-05-05 Corinna Vinschen <corinna@vinschen.de> 2014-05-05 Corinna Vinschen <corinna@vinschen.de>
* net.cc (cygwin_getsockopt): Rearrange code slightly and handle * net.cc (cygwin_getsockopt): Rearrange code slightly and handle

View File

@ -512,8 +512,6 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap)
status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size); status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size);
if (NT_SUCCESS (status)) if (NT_SUCCESS (status))
{ {
cygsid sid;
for (DWORD pg = 0; pg < groups->GroupCount; ++pg) for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
{ {
cygpsid sid = groups->Groups[pg].Sid; cygpsid sid = groups->Groups[pg].Sid;

View File

@ -198,7 +198,7 @@ cygpsid::pstring (char *nsidstr) const
strcpy (nsidstr, "S-1-"); strcpy (nsidstr, "S-1-");
t = nsidstr + sizeof ("S-1-") - 1; t = nsidstr + sizeof ("S-1-") - 1;
t += __small_sprintf (t, "%u", sid_id_auth (psid)); t += __small_sprintf (t, "%u", sid_id_auth (psid));
for (i = 0; i < *RtlSubAuthorityCountSid (psid); ++i) for (i = 0; i < sid_sub_auth_count (psid); ++i)
t += __small_sprintf (t, "-%lu", sid_sub_auth (psid, i)); t += __small_sprintf (t, "-%lu", sid_sub_auth (psid, i));
return t; return t;
} }
@ -218,7 +218,7 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known)
SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_NULL_SID_AUTHORITY }; SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_NULL_SID_AUTHORITY };
# define SECURITY_NT_AUTH 5 # define SECURITY_NT_AUTH 5
if (s > 255 || cnt < 1 || cnt > 8) if (s > 255 || cnt < 1 || cnt > MAX_SUBAUTH_CNT)
{ {
psid = NO_SID; psid = NO_SID;
return NULL; return NULL;
@ -226,8 +226,9 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known)
sid_auth.Value[5] = s; sid_auth.Value[5] = s;
set (); set ();
RtlInitializeSid (psid, &sid_auth, cnt); RtlInitializeSid (psid, &sid_auth, cnt);
PDBGSID dsid = (PDBGSID) psid;
for (i = 0; i < cnt; ++i) for (i = 0; i < cnt; ++i)
memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD)); dsid->SubAuthority[i] = r[i];
/* If the well_known flag isn't set explicitely, we check the SID /* If the well_known flag isn't set explicitely, we check the SID
for being a well-known SID ourselves. That's necessary because this for being a well-known SID ourselves. That's necessary because this
cygsid is created from a SID string, usually from /etc/passwd or cygsid is created from a SID string, usually from /etc/passwd or
@ -247,12 +248,12 @@ cygsid::getfromstr (PCWSTR nsidstr, bool well_known)
{ {
PWCHAR lasts; PWCHAR lasts;
DWORD s, cnt = 0; DWORD s, cnt = 0;
DWORD r[8]; DWORD r[MAX_SUBAUTH_CNT];
if (nsidstr && !wcsncmp (nsidstr, L"S-1-", 4)) if (nsidstr && !wcsncmp (nsidstr, L"S-1-", 4))
{ {
s = wcstoul (nsidstr + 4, &lasts, 10); s = wcstoul (nsidstr + 4, &lasts, 10);
while (cnt < 8 && *lasts == '-') while (cnt < MAX_SUBAUTH_CNT && *lasts == '-')
r[cnt++] = wcstoul (lasts + 1, &lasts, 10); r[cnt++] = wcstoul (lasts + 1, &lasts, 10);
if (!*lasts) if (!*lasts)
return get_sid (s, cnt, r, well_known); return get_sid (s, cnt, r, well_known);
@ -265,12 +266,12 @@ cygsid::getfromstr (const char *nsidstr, bool well_known)
{ {
char *lasts; char *lasts;
DWORD s, cnt = 0; DWORD s, cnt = 0;
DWORD r[8]; DWORD r[MAX_SUBAUTH_CNT];
if (nsidstr && !strncmp (nsidstr, "S-1-", 4)) if (nsidstr && !strncmp (nsidstr, "S-1-", 4))
{ {
s = strtoul (nsidstr + 4, &lasts, 10); s = strtoul (nsidstr + 4, &lasts, 10);
while (cnt < 8 && *lasts == '-') while (cnt < MAX_SUBAUTH_CNT && *lasts == '-')
r[cnt++] = strtoul (lasts + 1, &lasts, 10); r[cnt++] = strtoul (lasts + 1, &lasts, 10);
if (!*lasts) if (!*lasts)
return get_sid (s, cnt, r, well_known); return get_sid (s, cnt, r, well_known);

View File

@ -44,8 +44,10 @@ void uinfo_init ();
#define gid16togid32(g16) ((g16)==ILLEGAL_GID16?ILLEGAL_GID:(gid_t)(g16)) #define gid16togid32(g16) ((g16)==ILLEGAL_GID16?ILLEGAL_GID:(gid_t)(g16))
#endif #endif
#define MAX_SUBAUTH_CNT 11
#define MAX_SID_LEN 40 #define MAX_SID_LEN (2 * sizeof (BYTE) \
+ sizeof (SID_IDENTIFIER_AUTHORITY) \
+ MAX_SUBAUTH_CNT * sizeof (DWORD))
#define MAX_DACL_LEN(n) (sizeof (ACL) \ #define MAX_DACL_LEN(n) (sizeof (ACL) \
+ (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + MAX_SID_LEN)) + (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + MAX_SID_LEN))
#define SD_MIN_SIZE (sizeof (SECURITY_DESCRIPTOR) + MAX_DACL_LEN (1)) #define SD_MIN_SIZE (sizeof (SECURITY_DESCRIPTOR) + MAX_DACL_LEN (1))
@ -99,7 +101,7 @@ typedef struct {
BYTE Revision; BYTE Revision;
BYTE SubAuthorityCount; BYTE SubAuthorityCount;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority; SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
DWORD SubAuthority[8]; DWORD SubAuthority[MAX_SUBAUTH_CNT];
} DBGSID, *PDBGSID; } DBGSID, *PDBGSID;
/* Macro to define variable length SID structures */ /* Macro to define variable length SID structures */

View File

@ -1384,8 +1384,13 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
if (ret) if (ret)
{ {
/* Builtin account? SYSTEM, for instance, is returned as SidTypeUser, /* Builtin account? SYSTEM, for instance, is returned as SidTypeUser,
if a process is running as LocalSystem service. */ if a process is running as LocalSystem service.
if (acc_type == SidTypeUser && sid_sub_auth_count (sid) <= 3) Microsoft Account? These show up in the user's group list, using the
undocumented security authority 11. Even though this is officially a
user account, it only matters as part of the group list, so we convert
it to a well-known group here. */
if (acc_type == SidTypeUser
&& (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11))
acc_type = SidTypeWellKnownGroup; acc_type = SidTypeWellKnownGroup;
switch (acc_type) switch (acc_type)
{ {
@ -1409,7 +1414,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
is_domain_account = false; is_domain_account = false;
} }
/* Account domain account? */ /* Account domain account? */
else if (!wcscmp (dom, cygheap->dom.account_flat_name ())) else if (!wcscasecmp (dom, cygheap->dom.account_flat_name ()))
{ {
posix_offset = 0x30000; posix_offset = 0x30000;
if (cygheap->dom.member_machine () if (cygheap->dom.member_machine ()
@ -1422,7 +1427,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
else if (cygheap->dom.member_machine ()) else if (cygheap->dom.member_machine ())
{ {
/* Primary domain account? */ /* Primary domain account? */
if (!wcscmp (dom, cygheap->dom.primary_flat_name ())) if (!wcscasecmp (dom, cygheap->dom.primary_flat_name ()))
{ {
posix_offset = 0x100000; posix_offset = 0x100000;
/* In theory domain should have been set to /* In theory domain should have been set to
@ -1447,7 +1452,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
for (ULONG idx = 0; for (ULONG idx = 0;
(td = cygheap->dom.trusted_domain (idx)); (td = cygheap->dom.trusted_domain (idx));
++idx) ++idx)
if (!wcscmp (dom, td->NetbiosDomainName)) if (!wcscasecmp (dom, td->NetbiosDomainName))
{ {
domain = td->DnsDomainName; domain = td->DnsDomainName;
posix_offset = posix_offset =
@ -1636,8 +1641,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
} }
break; break;
case SidTypeWellKnownGroup: case SidTypeWellKnownGroup:
name_style = (cygheap->pg.nss_prefix_always ()) ? fully_qualified name_style = (cygheap->pg.nss_prefix_always ()
: plus_prepended; || sid_id_auth (sid) == 11) /* Microsoft Account */
? fully_qualified : plus_prepended;
#ifdef INTERIX_COMPATIBLE #ifdef INTERIX_COMPATIBLE
if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */ if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
&& sid_sub_auth_count (sid) > 1) && sid_sub_auth_count (sid) > 1)

View File

@ -1,6 +1,6 @@
/* winlean.h - Standard "lean" windows include /* winlean.h - Standard "lean" windows include
Copyright 2010, 2011, 2012, 2013 Red Hat, Inc. Copyright 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -58,11 +58,6 @@ details. */
#include <lmcons.h> #include <lmcons.h>
#include <ntdef.h> #include <ntdef.h>
/* Temporary kludge for missing flag in Mingw64's w32api. */
#ifndef PIPE_REJECT_REMOTE_CLIENTS
#define PIPE_REJECT_REMOTE_CLIENTS 8
#endif
#ifdef __undef_IN #ifdef __undef_IN
#undef IN #undef IN
#endif #endif
@ -79,6 +74,13 @@ details. */
#undef CRITICAL #undef CRITICAL
#endif #endif
/* So-called "Microsoft Account" SIDs have a netbios domain name
"MicrosoftAccounts". The problem is, while DNLEN is 15, that domain
name is 16 chars :-P So we override DNLEN here to be 16, so that calls
to LookupAccountSid/Name don't fail if the buffer is based on DNLEN. */
#undef DNLEN
#define DNLEN 16
/* When Terminal Services are installed, the GetWindowsDirectory function /* When Terminal Services are installed, the GetWindowsDirectory function
does not return the system installation dir, but a user specific directory does not return the system installation dir, but a user specific directory
instead. That's not what we have in mind when calling GetWindowsDirectory instead. That's not what we have in mind when calling GetWindowsDirectory