コード例 #1
2
ファイル: symlink.c プロジェクト: dra27/opam-experiments
int main(void)
{
  // GetCurrentProcess cannot fail
  HANDLE hProcess = GetCurrentProcess();

  if (OpenProcessToken(hProcess, TOKEN_READ, &hProcess))
  {
    LUID seCreateSymbolicLinkPrivilege;

    if (LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &seCreateSymbolicLinkPrivilege))
    {
      DWORD length;

      printf("SeCreateSymbolicLinkPrivilege = %ld, %ld\n", seCreateSymbolicLinkPrivilege.HighPart, seCreateSymbolicLinkPrivilege.LowPart);

      if (!GetTokenInformation(hProcess, TokenPrivileges, NULL, 0, &length))
      {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
          TOKEN_PRIVILEGES* privileges = (TOKEN_PRIVILEGES*)malloc(length);
          if (GetTokenInformation(hProcess, TokenPrivileges, privileges, length, &length))
          {
            BOOL found = FALSE;
            DWORD count = privileges->PrivilegeCount;

            printf("User has %ld privileges\n", count);

            if (count > 0)
            {
              LUID_AND_ATTRIBUTES* privs = privileges->Privileges;
              while (count-- > 0 && !luid_eq(privs->Luid, seCreateSymbolicLinkPrivilege))
                privs++;
              found = (count > 0);
            }

            printf("User does%s have the SeCreateSymbolicLinkPrivilege\n", (found ? "" : "n't"));
          }
          else
          {
            fprintf(stderr, "Second GetTokenInformation failed\n");
          }

          free(privileges);
        }
        else
        {
          fprintf(stderr, "First GetTokenInformation failed\n");
        }
      }
      else
      {
        fprintf(stderr, "Impossible output from GetTokenInformation\n");
      }
    }
    else
    {
      fprintf(stderr, "LookupPrivilegeValue failed\n");
    }

    CloseHandle(hProcess);
  }
  else
  {
    fprintf(stderr, "OpenProcessToken failed\n");
  }

  LSA_HANDLE hPolicy;
  NTSTATUS r;
  LSA_OBJECT_ATTRIBUTES attributes = {0, NULL, NULL, 0, NULL, NULL};
  attributes.Length = sizeof(attributes);

  LUID seCreateSymbolicLinkPrivilege;

  if (LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &seCreateSymbolicLinkPrivilege))
  {
    // POLICY_LOOKUP_NAMES: LsaLookupNames2, LsaEnumerateAccountRights, LsaLookupSids, LsaAddAccountRights
    // POLICY_VIEW_LOCAL_INFORMATION: LsaEnumerateAccountsWithUserRight
    // Elevation: LsaEnumerateAccountRights, LsaEnumerateAccountsWithUserRight, LsaRemoveAccountRights, LsaAddAccountRights
    if (NT_SUCCESS(r = LsaOpenPolicy(NULL, &attributes, POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION, &hPolicy)))
    {
      LSA_REFERENCED_DOMAIN_LIST* referencedDomains;
      LSA_TRANSLATED_SID2* sids;
      LSA_UNICODE_STRING name;
      name.Buffer = L"Users";
      name.Length = wcslen(name.Buffer) * sizeof(WCHAR);
      name.MaximumLength = name.Length + sizeof(WCHAR);
  
      if (NT_SUCCESS(r = LsaLookupNames2(hPolicy, LSA_LOOKUP_ISOLATED_AS_LOCAL, 1, &name, &referencedDomains, &sids)))
      {
        LSA_UNICODE_STRING* rights;
        ULONG count;
        LsaFreeMemory(referencedDomains);

        if (NT_SUCCESS(r = LsaEnumerateAccountRights(hPolicy, sids->Sid, &rights, &count)))
        {
          LSA_UNICODE_STRING* right = rights;
          printf("%ld right%s found\n", count, PLURAL(count));
          while (count-- > 0)
          {
            printf("  %.*S\n", right->Length / 2, right->Buffer);
            right++;
          }

          LsaFreeMemory(rights);

          LSA_ENUMERATION_INFORMATION* allSidsRaw;
          LSA_UNICODE_STRING lsaCreateSymbolicLinkPrivilege;
          lsaCreateSymbolicLinkPrivilege.Buffer = SE_CREATE_SYMBOLIC_LINK_NAME;
          lsaCreateSymbolicLinkPrivilege.Length = wcslen(lsaCreateSymbolicLinkPrivilege.Buffer) * sizeof(WCHAR);
          lsaCreateSymbolicLinkPrivilege.MaximumLength = lsaCreateSymbolicLinkPrivilege.Length + sizeof(WCHAR);
          if (NT_SUCCESS(r = LsaEnumerateAccountsWithUserRight(hPolicy, &lsaCreateSymbolicLinkPrivilege, (void**)&allSidsRaw, &count)))
          {
            LSA_ENUMERATION_INFORMATION* sid = allSidsRaw;
            PSID* allSids;
            PSID* p;
            PLSA_TRANSLATED_NAME names;
            ULONG i = count;

            printf("%ld SID%s found\n", count, PLURAL(count));
            p = allSids = (PSID*)malloc(count * sizeof(PSID));

            while (i-- > 0)
              *p++ = (sid++)->Sid;

            if (NT_SUCCESS(r = LsaLookupSids(hPolicy, count, allSids, &referencedDomains, &names)))
            {
              PLSA_TRANSLATED_NAME name = names;
              BOOL usersAssigned = FALSE;

              LsaFreeMemory(referencedDomains);

              while (count-- > 0)
              {
                LPTSTR sidString;
                USHORT len = name->Name.Length / 2;
                ConvertSidToStringSid(*allSids++, &sidString);
                printf("  %.*S (%S)\n", len, name->Name.Buffer, sidString);
                usersAssigned |= (len > 4 && !wcsncmp(L"Users", name->Name.Buffer, len));
                name++;
                LocalFree(sidString);
              }

              printf("Users had%s got SeCreateSymbolicLinkPrivilege\n", (usersAssigned ? "" : "n't"));
              if (usersAssigned)
              {
                if (!NT_SUCCESS(r = LsaRemoveAccountRights(hPolicy, sids->Sid, FALSE, &lsaCreateSymbolicLinkPrivilege, 1)))
                {
                  fprintf(stderr, "Lsa failed with code %x\n", r);
                }
              }
              else
              {
                if (!NT_SUCCESS(r = LsaAddAccountRights(hPolicy, sids->Sid, &lsaCreateSymbolicLinkPrivilege, 1)))
                {
                  fprintf(stderr, "LsaAddAccountRights failed with code %x\n", r);
                }
              }

              LsaFreeMemory(names);
            }
            else
            {
              fprintf(stderr, "LsaLookupSids2 failed with code %x\n", r);
            }
              
            LsaFreeMemory(allSidsRaw);
            free(allSids);
          }
          else
          {
            fprintf(stderr, "LsaEnumerateAccountsWithUserRight failed with code %x\n", r);
          }
        }
        else
        {
          fprintf(stderr, "LsaEnumerateAccountRights failed with code %x\n", r);
        }

        LsaFreeMemory(sids);
      }
      else
      {
        fprintf(stderr, "LsaLookupNames2 failed with code %x\n", r);
      }
  
      LsaClose(hPolicy);
    }
    else
    {
      fprintf(stderr, "LsaOpenPolicy failed with code %x\n", r);
    }
  }
  else
  {
    fprintf(stderr, "LookupPrivilegeValue failed\n");
  }
}
コード例 #2
0
ファイル: lsa.c プロジェクト: Jactry/wine
static void test_LsaLookupNames2(void)
{
    static const WCHAR n1[] = {'L','O','C','A','L',' ','S','E','R','V','I','C','E'};
    static const WCHAR n2[] = {'N','T',' ','A','U','T','H','O','R','I','T','Y','\\','L','o','c','a','l','S','e','r','v','i','c','e'};

    NTSTATUS status;
    LSA_HANDLE handle;
    LSA_OBJECT_ATTRIBUTES attrs;
    PLSA_REFERENCED_DOMAIN_LIST domains;
    PLSA_TRANSLATED_SID2 sids;
    LSA_UNICODE_STRING name[3];
    LPSTR account, sid_dom;

    if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) ||
        (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH))
    {
        skip("Non-English locale (skipping LsaLookupNames2 tests)\n");
        return;
    }

    memset(&attrs, 0, sizeof(attrs));
    attrs.Length = sizeof(attrs);

    status = LsaOpenPolicy(NULL, &attrs, POLICY_ALL_ACCESS, &handle);
    ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
       "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status);

    /* try a more restricted access mask if necessary */
    if (status == STATUS_ACCESS_DENIED)
    {
        trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n");
        status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &handle);
        ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status);
    }
    if (status != STATUS_SUCCESS)
    {
        skip("Cannot acquire policy handle\n");
        return;
    }

    name[0].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1));
    name[0].Length = name[0].MaximumLength = sizeof(n1);
    memcpy(name[0].Buffer, n1, sizeof(n1));

    name[1].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1));
    name[1].Length = name[1].MaximumLength = sizeof(n1) - sizeof(WCHAR);
    memcpy(name[1].Buffer, n1, sizeof(n1) - sizeof(WCHAR));

    name[2].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n2));
    name[2].Length = name[2].MaximumLength = sizeof(n2);
    memcpy(name[2].Buffer, n2, sizeof(n2));

    /* account name only */
    sids = NULL;
    domains = NULL;
    status = LsaLookupNames2(handle, 0, 1, &name[0], &domains, &sids);
    ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\n", status);
    ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use);
    ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags);
    ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries);
    get_sid_info(sids[0].Sid, &account, &sid_dom);
    ok(!strcmp(account, "LOCAL SERVICE"), "expected \"LOCAL SERVICE\", got \"%s\"\n", account);
    ok(!strcmp(sid_dom, "NT AUTHORITY"), "expected \"NT AUTHORITY\", got \"%s\"\n", sid_dom);
    LsaFreeMemory(sids);
    LsaFreeMemory(domains);

    /* unknown account name */
    sids = NULL;
    domains = NULL;
    status = LsaLookupNames2(handle, 0, 1, &name[1], &domains, &sids);
    ok(status == STATUS_NONE_MAPPED, "expected STATUS_NONE_MAPPED, got %x)\n", status);
    ok(sids[0].Use == SidTypeUnknown, "expected SidTypeUnknown, got %u\n", sids[0].Use);
    ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags);
    ok(domains->Entries == 0, "expected 0, got %u\n", domains->Entries);
    LsaFreeMemory(sids);
    LsaFreeMemory(domains);

    /* account + domain */
    sids = NULL;
    domains = NULL;
    status = LsaLookupNames2(handle, 0, 1, &name[2], &domains, &sids);
    ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\n", status);
    ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use);
    ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags);
    ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries);
    get_sid_info(sids[0].Sid, &account, &sid_dom);
    ok(!strcmp(account, "LOCAL SERVICE"), "expected \"LOCAL SERVICE\", got \"%s\"\n", account);
    ok(!strcmp(sid_dom, "NT AUTHORITY"), "expected \"NT AUTHORITY\", got \"%s\"\n", sid_dom);
    LsaFreeMemory(sids);
    LsaFreeMemory(domains);

    /* all three */
    sids = NULL;
    domains = NULL;
    status = LsaLookupNames2(handle, 0, 3, name, &domains, &sids);
    ok(status == STATUS_SOME_NOT_MAPPED, "expected STATUS_SOME_NOT_MAPPED, got %x)\n", status);
    ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use);
    ok(sids[1].Use == SidTypeUnknown, "expected SidTypeUnknown, got %u\n", sids[1].Use);
    ok(sids[2].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[2].Use);
    ok(sids[0].DomainIndex == 0, "expected 0, got %u\n", sids[0].DomainIndex);
    ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries);
    LsaFreeMemory(sids);
    LsaFreeMemory(domains);

    HeapFree(GetProcessHeap(), 0, name[0].Buffer);
    HeapFree(GetProcessHeap(), 0, name[1].Buffer);
    HeapFree(GetProcessHeap(), 0, name[2].Buffer);

    status = LsaClose(handle);
    ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status);
}