Cygwin: Add name->SID conversion for self-constructed names

...as far as it makes sense.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2018-08-27 18:28:33 +02:00
parent fcfcc288c4
commit 33b8c406dc
2 changed files with 116 additions and 9 deletions

View File

@ -101,6 +101,7 @@ class pwdgrp
void *add_account_from_cygserver (cygpsid &sid); void *add_account_from_cygserver (cygpsid &sid);
void *add_account_from_cygserver (const char *name); void *add_account_from_cygserver (const char *name);
void *add_account_from_cygserver (uint32_t id); void *add_account_from_cygserver (uint32_t id);
bool construct_sid_from_name (cygsid &sid, wchar_t *name, wchar_t *sep);
char *fetch_account_from_line (fetch_user_arg_t &arg, const char *line); char *fetch_account_from_line (fetch_user_arg_t &arg, const char *line);
char *fetch_account_from_file (fetch_user_arg_t &arg); char *fetch_account_from_file (fetch_user_arg_t &arg);
char *fetch_account_from_windows (fetch_user_arg_t &arg, char *fetch_account_from_windows (fetch_user_arg_t &arg,

View File

@ -1793,6 +1793,116 @@ fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, cyg_ldap *cldap)
return td->PosixOffset; return td->PosixOffset;
} }
/* If LookupAccountName fails, we check the name for a known constructed name
with this function. Return true if we could create a valid SID from name
in sid. sep is either a pointer to thr backslash in name, or NULL if name
is not a qualified DOMAIN\\name string. */
bool
pwdgrp::construct_sid_from_name (cygsid &sid, wchar_t *name, wchar_t *sep)
{
unsigned long rid;
wchar_t *endptr;
if (sep && wcscmp (name, L"no\\body") == 0)
{
/* Special case "nobody" for reproducible construction of a
nobody SID for WinFsp and similar services. We use the
value 65534 which is -2 with 16 bit uid/gids. */
sid.create (0, 1, 0xfffe);
return true;
}
if (sep && wcscmp (name, L"AzureAD\\Group") == 0)
{
get_azure_grp_sid ();
if (PSID (logon_sid) != NO_SID)
{
sid = azure_grp_sid;
return true;
}
return false;
}
if (!sep && wcscmp (name, L"Authentication authority asserted identity") == 0)
{
sid.create (18, 1, 1);
return true;
}
if (!sep && wcscmp (name, L"Service asserted identity") == 0)
{
sid.create (18, 1, 2);
return true;
}
if (sep && wcsncmp (name, L"Unix_", 5) == 0)
{
int type;
if (wcsncmp (name + 5, L"User\\", 5) == 0)
type = 1;
else if (wcsncmp (name + 5, L"Group\\", 6) == 0)
type = 2;
else
return false;
rid = wcstoul (sep + 1, &endptr, 10);
if (*endptr == L'\0')
{
sid.create (22, 2, type, rid);
return true;
}
return false;
}
/* At this point we have to check if the domain name is one of the
known domains, and if the account name is one of "User(DWORD)"
or "Group(DWORD)". */
if (sep)
{
wchar_t *numstr = NULL;
bool have_domain = false;
if (wcsncmp (sep + 1, L"User(", 5) == 0)
numstr = sep + 1 + 5;
else if (wcsncmp (sep + 1, L"Group(", 6) == 0)
numstr = sep + 1 + 6;
if (!numstr)
return false;
rid = wcstoul (numstr, &endptr, 10);
if (wcscmp (endptr, L")") != 0)
return false;
if (wcsncasecmp (name, cygheap->dom.account_flat_name (), sep - name)
== 0)
{
sid = cygheap->dom.account_sid ();
have_domain = true;
}
else if (wcsncasecmp (name, cygheap->dom.primary_flat_name (), sep - name)
== 0)
{
sid = cygheap->dom.primary_sid ();
have_domain = true;
}
else
{
PDS_DOMAIN_TRUSTSW td = NULL;
for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
{
if (wcsncasecmp (name, td->NetbiosDomainName, sep - name) == 0)
{
sid = td->DomainSid;
have_domain = true;
break;
}
}
}
if (have_domain)
{
sid.append (rid);
return true;
}
}
return false;
}
/* CV 2014-05-08: USER_INFO_24 is not yet defined in Mingw64, but will be in /* CV 2014-05-08: USER_INFO_24 is not yet defined in Mingw64, but will be in
the next release. For the time being, define the structure here with the next release. For the time being, define the structure here with
another name which won't collide with the upcoming correct definition another name which won't collide with the upcoming correct definition
@ -1927,14 +2037,10 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
} }
if (!ret) if (!ret)
{ {
if (!strcmp (arg.name, "no+body")) /* For accounts which can't be resolved by Windows, try if
{ it's one of the special names we use for special accounts. */
/* Special case "nobody" for reproducible construction of a if (construct_sid_from_name (csid, name, p))
nobody SID for WinFsp and similar services. We use the break;
value 65534 which is -2 with 16 bit uid/gids. */
csid.create (0, 1, 0xfffe);
break;
}
debug_printf ("LookupAccountNameW (%W), %E", name); debug_printf ("LookupAccountNameW (%W), %E", name);
return NULL; return NULL;
} }
@ -2267,7 +2373,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
/* This shouldn't happen, in theory, but it does. There /* This shouldn't happen, in theory, but it does. There
are cases where the user's logon domain does not show are cases where the user's logon domain does not show
up in the list of trusted domains. We're desperately up in the list of trusted domains. We're desperately
trying to workaround that here bu adding an entry for trying to workaround that here by adding an entry for
this domain to the trusted domains and ask the DC for this domain to the trusted domains and ask the DC for
a posix_offset. There's a good chance this doesn't a posix_offset. There's a good chance this doesn't
work either, but at least we tried, and the user can work either, but at least we tried, and the user can