[1/4] advapi32: Factor out lookup of local usernames and well-known SIDs.

Hans Leidekker hans at codeweavers.com
Tue Aug 4 05:21:19 CDT 2009


Another attempt to fix the dotnet30 installer, using LSA_UNICODE_STRING
throughout this time.

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..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 [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;
-
-    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 [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