On Saturday 01 August 2009 12:47:33 am Dan Kegel wrote: > But I didn't have any joy when I tried it, hence my question.
Here's a recipe for the standalone installer that works for me after applying the patch attached to this e-mail: $ sha1sum dotnetfx3.exe f3d2c3c7e4c0c35450cf6dab1f9f2e9e7ff50039 dotnetfx3.exe $ rm -rf ~/.wine $ sh winetricks dotnet20 $ export _SFX_CAB_SHUTDOWN_REQUEST=1 $ wine dotnetfx3.exe It's slow towards the end, too slow I think, but eventually it completes here. -Hans
diff --git a/dlls/advapi32/advapi32_misc.h b/dlls/advapi32/advapi32_misc.h index 35f806e..6ec18f6 100644 --- a/dlls/advapi32/advapi32_misc.h +++ b/dlls/advapi32/advapi32_misc.h @@ -24,4 +24,7 @@ const char * debugstr_sid(PSID sid); BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName); BOOL ADVAPI_GetComputerSid(PSID sid); +BOOL lookup_local_wellknown_name(LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*); +BOOL lookup_local_user_name(LSA_UNICODE_STRING*, PSID, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE, BOOL*); + #endif /* __WINE_ADVAPI32MISC_H */ diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c index 315cce9..edb20d8 100644 --- a/dlls/advapi32/lsa.c +++ b/dlls/advapi32/lsa.c @@ -297,19 +297,88 @@ NTSTATUS WINAPI LsaLookupNames( return STATUS_NONE_MAPPED; } +static BOOL lookup_name(LSA_UNICODE_STRING *name, SID *sid, DWORD *sid_size, WCHAR *domain, + DWORD *domain_size, SID_NAME_USE *use, BOOL *handled) +{ + BOOL ret; + + ret = lookup_local_wellknown_name(name, sid, sid_size, domain, domain_size, use, handled); + if (!handled) + ret = lookup_local_user_name(name, sid, sid_size, domain, domain_size, use, handled); + + return ret; +} + /****************************************************************************** * LsaLookupNames2 [advapi...@] * */ -NTSTATUS WINAPI LsaLookupNames2( - LSA_HANDLE policy, - ULONG flags, - ULONG count, - PLSA_UNICODE_STRING names, - PLSA_REFERENCED_DOMAIN_LIST *domains, - PLSA_TRANSLATED_SID2 *sids) +NTSTATUS WINAPI LsaLookupNames2( LSA_HANDLE policy, ULONG flags, ULONG count, + PLSA_UNICODE_STRING names, PLSA_REFERENCED_DOMAIN_LIST *domains, + PLSA_TRANSLATED_SID2 *sids) { - FIXME("(%p,0x%08x,0x%08x,%p,%p,%p) stub\n", policy, flags, count, names, domains, sids); + ULONG i, sid_size_total = 0, domain_size_total = 0, size, num_domains; + ULONG sid_size, domain_size, mapped; + BOOL ret, handled = FALSE; + SID_NAME_USE use; + SID *sid; + + TRACE("(%p,0x%08x,0x%08x,%p,%p,%p)\n", policy, flags, count, names, domains, sids); + + mapped = num_domains = 0; + for (i = 0; i < count; i++) + { + handled = FALSE; + sid_size = domain_size = 0; + ret = lookup_name(&names[i], NULL, &sid_size, NULL, &domain_size, &use, &handled); + if (handled) + { + sid_size_total += sid_size; + if (domain_size) + { + FIXME("domain not handled\n"); + domain_size_total += domain_size; + num_domains++; + } + mapped++; + } + } + TRACE("mapped %u out of %u\n", mapped, count); + + size = sizeof(LSA_TRANSLATED_SID2) * count + sid_size_total; + if (!(*sids = HeapAlloc(GetProcessHeap(), 0, size))) return STATUS_NO_MEMORY; + + sid = (SID *)*sids + sizeof(LSA_TRANSLATED_SID2) * mapped; + + if (!(*domains = HeapAlloc(GetProcessHeap(), 0, sizeof(LSA_REFERENCED_DOMAIN_LIST)))) + { + HeapFree(GetProcessHeap(), 0, *sids); + return STATUS_NO_MEMORY; + } + (*domains)->Entries = 0; + (*domains)->Domains = NULL; + + for (i = 0; i < count; i++) + { + (*sids)[i].Use = SidTypeUnknown; + (*sids)[i].DomainIndex = -1; + + handled = FALSE; + sid_size = sid_size_total; + ret = lookup_name(&names[i], sid, &sid_size, NULL, &domain_size, &use, &handled); + if (handled) + { + (*sids)[i].Sid = sid; + (*sids)[i].Use = use; + (*sids)[i].Flags = 0; + + sid += sid_size; + sid_size_total -= sid_size; + } + } + + if (mapped == count) return STATUS_SUCCESS; + if (mapped > 0 && mapped < count) return STATUS_SOME_NOT_MAPPED; return STATUS_NONE_MAPPED; } diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index e1cbb1a..7a2c384 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -2653,60 +2653,84 @@ static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR Referenc return ret; } -/****************************************************************************** - * LookupAccountNameW [advapi...@] - */ -BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid, - LPDWORD cbSid, LPWSTR ReferencedDomainName, - LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse ) +static void split_domain_account(const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account, + LSA_UNICODE_STRING *domain) { - BOOL ret; - PSID pSid; - unsigned int i; - DWORD nameLen; - LPWSTR userName = NULL; - LPCWSTR domainName; - LPCWSTR lpAccountNamePtr; - LPCWSTR lpDomainNamePtr = NULL; - - FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName), - Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse); + WCHAR *p; - if (!ADVAPI_IsLocalComputer(lpSystemName)) + if ((p = strrchrW(str->Buffer, '\\'))) { - SetLastError(RPC_S_SERVER_UNAVAILABLE); - return FALSE; - } + domain->Buffer = str->Buffer; + domain->Length = (p - str->Buffer) * sizeof(WCHAR); - if (!lpAccountName || !strcmpW(lpAccountName, Blank)) + account->Buffer = p + 1; + account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR)); + } + else { - lpAccountName = BUILTIN; + domain->Buffer = NULL; + domain->Length = 0; + + account->Buffer = str->Buffer; + account->Length = str->Length; } +} - /* Check well known SIDs first */ - if ((lpAccountNamePtr = strrchrW(lpAccountName,'\\'))) +static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain ) +{ + ULONG len = strlenW( ACCOUNT_SIDS[idx].domain ); + + if (len == domain->Length/sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len )) + return TRUE; + + return FALSE; +} + +static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account ) +{ + ULONG len = strlenW( ACCOUNT_SIDS[idx].account ); + + if (len == account->Length/sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len )) + return TRUE; + + if (ACCOUNT_SIDS[idx].alias) { - lpAccountNamePtr++; - lpDomainNamePtr = lpAccountName; + len = strlenW( ACCOUNT_SIDS[idx].alias ); + if (len == account->Length/sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len )) + return TRUE; } - else - lpAccountNamePtr = lpAccountName; + return FALSE; +} + +/* + * Helper function for LookupAccountNameW + */ +BOOL lookup_local_wellknown_name(LSA_UNICODE_STRING *account_and_domain, + PSID Sid, LPDWORD cbSid, + LPWSTR ReferencedDomainName, + LPDWORD cchReferencedDomainName, + PSID_NAME_USE peUse, BOOL *handled) +{ + PSID pSid; + LSA_UNICODE_STRING account, domain; + BOOL ret = TRUE; + ULONG i; + + *handled = FALSE; + split_domain_account(account_and_domain, &account, &domain); for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++) { /* check domain first */ - if (lpDomainNamePtr && (strncmpiW(lpDomainNamePtr, ACCOUNT_SIDS[i].domain, strlenW(ACCOUNT_SIDS[i].domain)) || lpDomainNamePtr[strlenW(ACCOUNT_SIDS[i].domain)]!='\\')) - continue; + if (domain.Buffer && !match_domain( i, &domain )) continue; - if (!strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].account) || - (ACCOUNT_SIDS[i].alias && !strcmpiW(lpAccountNamePtr, ACCOUNT_SIDS[i].alias))) + if (match_account( i, &account )) { - DWORD sidLen = SECURITY_MAX_SID_SIZE; + DWORD len, sidLen = SECURITY_MAX_SID_SIZE; - pSid = HeapAlloc(GetProcessHeap(), 0, sidLen); + if (!(pSid = HeapAlloc(GetProcessHeap(), 0, sidLen))) return FALSE; ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen); - if (ret) { if (*cbSid < sidLen) @@ -2718,47 +2742,56 @@ BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSI { CopySid(*cbSid, Sid, pSid); } - *cbSid = sidLen; } - domainName = ACCOUNT_SIDS[i].domain; - nameLen = strlenW(domainName); - - if (*cchReferencedDomainName <= nameLen || !ret) + len = strlenW(ACCOUNT_SIDS[i].domain); + if (*cchReferencedDomainName <= len || !ret) { SetLastError(ERROR_INSUFFICIENT_BUFFER); - nameLen += 1; + len++; ret = FALSE; } else if (ReferencedDomainName) { - strcpyW(ReferencedDomainName, domainName); + strcpyW(ReferencedDomainName, ACCOUNT_SIDS[i].domain); } - *cchReferencedDomainName = nameLen; - + *cchReferencedDomainName = len; if (ret) - { *peUse = ACCOUNT_SIDS[i].name_use; - } HeapFree(GetProcessHeap(), 0, pSid); - + *handled = TRUE; return ret; } } + return ret; +} + +BOOL lookup_local_user_name(LSA_UNICODE_STRING *account_and_domain, + PSID Sid, LPDWORD cbSid, + LPWSTR ReferencedDomainName, + LPDWORD cchReferencedDomainName, + PSID_NAME_USE peUse, BOOL *handled) +{ + DWORD nameLen; + LPWSTR userName = NULL; + LSA_UNICODE_STRING account, domain; + BOOL ret = TRUE; + + *handled = FALSE; + split_domain_account(account_and_domain, &account, &domain); /* Let the current Unix user id masquerade as first Windows user account */ nameLen = UNLEN + 1; + if (!(userName = HeapAlloc(GetProcessHeap(), 0, nameLen * sizeof(WCHAR)))) return FALSE; - userName = HeapAlloc(GetProcessHeap(), 0, nameLen*sizeof(WCHAR)); - - if (lpDomainNamePtr) + if (domain.Buffer) { /* check to make sure this account is on this computer */ - if (GetComputerNameW(userName, &nameLen) && strcmpW(lpDomainNamePtr, userName)) + if (GetComputerNameW(userName, &nameLen) && strcmpW(domain.Buffer, userName)) { SetLastError(ERROR_NONE_MAPPED); ret = FALSE; @@ -2766,28 +2799,72 @@ BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSI nameLen = UNLEN + 1; } - if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName)) + if (GetUserNameW(userName, &nameLen) && !strcmpW(account.Buffer, userName)) + { ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse); + *handled = TRUE; + } else { nameLen = UNLEN + 1; - if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName)) + if (GetComputerNameW(userName, &nameLen) && !strcmpW(account.Buffer, userName)) + { ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse); - else - { - SetLastError(ERROR_NONE_MAPPED); - ret = FALSE; + *handled = TRUE; } } HeapFree(GetProcessHeap(), 0, userName); - return ret; } /****************************************************************************** + * LookupAccountNameW [advapi...@] + */ +BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid, + LPDWORD cbSid, LPWSTR ReferencedDomainName, + LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse ) +{ + BOOL ret, handled; + LSA_UNICODE_STRING account; + + FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName), + Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse); + + if (!ADVAPI_IsLocalComputer(lpSystemName)) + { + SetLastError(RPC_S_SERVER_UNAVAILABLE); + return FALSE; + } + + if (!lpAccountName || !strcmpW(lpAccountName, Blank)) + { + lpAccountName = BUILTIN; + } + + RtlInitUnicodeString(&account, lpAccountName); + + /* Check well known SIDs first */ + ret = lookup_local_wellknown_name(&account, Sid, cbSid, + ReferencedDomainName, cchReferencedDomainName, + peUse, &handled); + if (handled) + return ret; + + /* Check user names */ + ret = lookup_local_user_name(&account, Sid, cbSid, + ReferencedDomainName, cchReferencedDomainName, + peUse, &handled); + if (handled) + return ret; + + SetLastError(ERROR_NONE_MAPPED); + return FALSE; +} + +/****************************************************************************** * PrivilegeCheck [advapi...@] */ BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)