[1/3] advapi32: Factor out lookup of local usernames and well-known SIDs.
Hans Leidekker
hans at codeweavers.com
Thu Aug 6 04:12:51 CDT 2009
This version does not depend on strings being null-terminated.
Based on a patch by Aric Stewart.
-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/security.c b/dlls/advapi32/security.c
index e1cbb1a..31c43f9 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -2653,61 +2653,86 @@ static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR Referenc
return ret;
}
-/******************************************************************************
- * LookupAccountNameW [ADVAPI32.@]
- */
-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;
+ WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
- FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
- Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
+ while (*p != '\\' && p > str->Buffer) p--;
- if (!ADVAPI_IsLocalComputer(lpSystemName))
+ if (*p == '\\')
{
- 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;
+}
- for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
+/*
+ * 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 ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
{
if (*cbSid < sidLen)
{
@@ -2718,47 +2743,57 @@ 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 ) &&
+ (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
{
SetLastError(ERROR_NONE_MAPPED);
ret = FALSE;
@@ -2766,28 +2801,70 @@ BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSI
nameLen = UNLEN + 1;
}
- if (GetUserNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
- ret = lookup_user_account_name(Sid, cbSid, ReferencedDomainName,
- cchReferencedDomainName, peUse);
+ if (GetUserNameW( userName, &nameLen ) &&
+ account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
+ {
+ ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
+ *handled = TRUE;
+ }
else
{
nameLen = UNLEN + 1;
- if (GetComputerNameW(userName, &nameLen) && !strcmpW(lpAccountNamePtr, userName))
- ret = lookup_computer_account_name(Sid, cbSid, ReferencedDomainName,
- cchReferencedDomainName, peUse);
- else
+ if (GetComputerNameW( userName, &nameLen ) &&
+ account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
{
- SetLastError(ERROR_NONE_MAPPED);
- ret = FALSE;
+ ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
+ *handled = TRUE;
}
}
HeapFree(GetProcessHeap(), 0, userName);
-
return ret;
}
/******************************************************************************
+ * LookupAccountNameW [ADVAPI32.@]
+ */
+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 [ADVAPI32.@]
*/
BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
More information about the wine-patches
mailing list