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"); } }
BOOL lsp_remove(LSA_HANDLE lsa_handle, LPTSTR user, LPTSTR privilegeConstant) { LSA_ACCOUNT account; NTSTATUS nt_status; LSA_UNICODE_STRING privilege; PSID sid; BOOL success = TRUE; if (!valid_privilege(&privilege, privilegeConstant)) return FALSE; if (!valid_user(lsa_handle, &sid, user)) return FALSE; if (!lsa_account_from_sid(lsa_handle, sid, &account)) { FreeSid(sid); return FALSE; } print_string(L"Removing %s from ", privilegeConstant); print_account(&account); print_string(L".\n"); nt_status = LsaRemoveAccountRights(lsa_handle, sid, FALSE, &privilege, 1); if (nt_status != STATUS_SUCCESS) { FreeSid(sid); return lsa_error(nt_status, L"LsaRemoveAccountRights"); } FreeSid(sid); return TRUE; }
HRESULT TCUserAccount::RemoveRight(LPTSTR pszPrivilege) { // Not supported under Windows9x if (IsWin9x()) return S_FALSE; // Fail if Init has not been called successfully if (!m_hPolicy || m_spSIDPrincipal.IsNull()) return E_UNEXPECTED; // Fail if the specified pointer is NULL if (!pszPrivilege) return E_POINTER; // Get a pointer to a UNICODE version of the specified privilege USES_CONVERSION; LPWSTR pszWidePrivilege = T2W(pszPrivilege); // Create an LSA_UNICODE_STRING for the specified privilege name LSA_UNICODE_STRING lsaString; lsaString.Length = (USHORT)(wcslen(pszWidePrivilege) * sizeof(WCHAR)); lsaString.MaximumLength = (USHORT)(lsaString.Length + sizeof(WCHAR)); lsaString.Buffer = pszWidePrivilege; // Attempt to remove the specified privilege from the current user RETURN_FAILED(LsaRemoveAccountRights(m_hPolicy, m_spSIDPrincipal, false, &lsaString, 1)); // Indicate success return S_OK; }
void RevokePrivilege(PSID sid, LPCWSTR userRight) { LSA_HANDLE hPolicy = OpenPolicy(POLICY_LOOKUP_NAMES); try { LSA_UNICODE_STRING lsaUserRight; InitLsaString(&lsaUserRight, (LPWSTR)userRight); CheckRetVal(LsaRemoveAccountRights(hPolicy, sid, FALSE, &lsaUserRight, 1)); LsaClose(hPolicy); } catch (const std::exception&) { LsaClose(hPolicy); throw; } }
NTSTATUS SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LPWSTR PrivilegeName, BOOL bEnable) { LSA_UNICODE_STRING PrivilegeString; /* Create a LSA_UNICODE_STRING for the privilege name. */ InitLsaString(&PrivilegeString, PrivilegeName); /* grant or revoke the privilege, accordingly */ if (bEnable) return (LsaAddAccountRights(PolicyHandle, AccountSid, &PrivilegeString, 1)); else return (LsaRemoveAccountRights(PolicyHandle, AccountSid, FALSE, &PrivilegeString, 1)); }
bool DeleteRightUsers(UserManager *panel,bool selection) { bool res=false; CFarPanelSelection sp((HANDLE)panel,selection); if(sp.Number()) { TCHAR warning[TINY_BUFFER]; if(sp.Number()==1) { TCHAR Truncated[MAX_PATH]; _tcscpy(Truncated,sp[0].FileName); FSF.TruncPathStr(Truncated,50); FSF.sprintf(warning,GetMsg(mDelOne),Truncated); } else FSF.sprintf(warning,GetMsg(mDelUserN+NumberType(sp.Number())),sp.Number()); const TCHAR *MsgItems[]={GetMsg(mButtonDelete),warning,GetMsg(mButtonDelete),GetMsg(mButtonCancel)}; if(!Info.Message(&MainGuid,&DelUserMessageGuid,0,NULL,MsgItems,sizeof(MsgItems)/sizeof(MsgItems[0]),2)) { res=true; LSA_HANDLE PolicyHandle; PolicyHandle=GetPolicyHandle(panel->computer); if(PolicyHandle) { for(int i=0;i<sp.Number();i++) { if(sp[i].UserData.FreeData) { LSA_UNICODE_STRING RightName; RightName.Buffer=panel->nonfixed; RightName.Length=wcslen(RightName.Buffer)*sizeof(wchar_t); RightName.MaximumLength=RightName.Length+sizeof(wchar_t); LsaRemoveAccountRights(PolicyHandle,GetSidFromUserData(sp[i].UserData.Data),FALSE,&RightName,1); } } LsaClose(PolicyHandle); } } } return res; }
NTSTATUS SetPrivilegeOnAccount( LSA_HANDLE PolicyHandle, // open policy handle PSID AccountSid, // SID to grant privilege to LPWSTR PrivilegeName, // privilege to grant (Unicode) BOOL bEnable // enable or disable ) { LSA_UNICODE_STRING PrivilegeString; // // Create a LSA_UNICODE_STRING for the privilege name. // InitLsaString(&PrivilegeString, PrivilegeName); // // grant or revoke the privilege, accordingly // if(bEnable) { return LsaAddAccountRights( PolicyHandle, // open policy handle AccountSid, // target SID &PrivilegeString, // privileges 1 // privilege count ); } else { return LsaRemoveAccountRights( PolicyHandle, // open policy handle AccountSid, // target SID FALSE, // do not disable all rights &PrivilegeString, // privileges 1 // privilege count ); } }
static DWORD ProcessAddRemoveAccountRights( IN PRPC_PARAMETERS pRpcParams, IN BOOLEAN Add, IN PSTR AccountRights, IN BOOLEAN RemoveAll, IN PSTR AccountName ) { DWORD err = ERROR_SUCCESS; NTSTATUS ntStatus = STATUS_SUCCESS; LSA_BINDING hLsa = NULL; LW_PIO_CREDS pCreds = NULL; WCHAR wszSysName[] = {'\\', '\\', '\0'}; DWORD policyAccessMask = LSA_ACCESS_LOOKUP_NAMES_SIDS | LSA_ACCESS_CREATE_SPECIAL_ACCOUNTS; POLICY_HANDLE hPolicy = NULL; PSID pAccountSid = NULL; PSTR *ppszAccountRightNames = NULL; DWORD numAccountRightNames = 0; PWSTR *ppwszAccountRightNames = NULL; DWORD i = 0; err = CreateRpcCredentials(pRpcParams, &pCreds); BAIL_ON_LSA_ERROR(err); err = CreateLsaRpcBinding(pRpcParams, pCreds, &hLsa); BAIL_ON_LSA_ERROR(err); ntStatus = LsaOpenPolicy2(hLsa, wszSysName, NULL, policyAccessMask, &hPolicy); BAIL_ON_NT_STATUS(ntStatus); err = ResolveAccountNameToSid( hLsa, AccountName, &pAccountSid); BAIL_ON_LSA_ERROR(err); if (AccountRights) { err = GetStringListFromString( AccountRights, SEPARATOR_CHAR, &ppszAccountRightNames, &numAccountRightNames); BAIL_ON_LSA_ERROR(err); err = LwAllocateMemory( sizeof(ppwszAccountRightNames[0]) * numAccountRightNames, OUT_PPVOID(&ppwszAccountRightNames)); BAIL_ON_LSA_ERROR(err); for (i = 0; i < numAccountRightNames; i++) { err = LwMbsToWc16s(ppszAccountRightNames[i], &ppwszAccountRightNames[i]); BAIL_ON_LSA_ERROR(err); } } if (Add) { ntStatus = LsaAddAccountRights( hLsa, hPolicy, pAccountSid, ppwszAccountRightNames, numAccountRightNames); BAIL_ON_NT_STATUS(ntStatus); fprintf(stdout, "Successfully added account rights to %s\n", AccountName); } else { ntStatus = LsaRemoveAccountRights( hLsa, hPolicy, pAccountSid, RemoveAll, ppwszAccountRightNames, numAccountRightNames); BAIL_ON_NT_STATUS(ntStatus); fprintf(stdout, "Successfully removed account rights from %s\n", AccountName); } error: if (ntStatus || err) { PCSTR errName = LwNtStatusToName(ntStatus); PCSTR errDescription = LwNtStatusToDescription(ntStatus); if (ntStatus) { errName = LwNtStatusToName(ntStatus); errDescription = LwNtStatusToDescription(ntStatus); } else { errName = LwWin32ErrorToName(err); errDescription = LwWin32ErrorToDescription(err); } fprintf(stderr, "Error: %s (%s)\n", LSA_SAFE_LOG_STRING(errName), LSA_SAFE_LOG_STRING(errDescription)); } if (hPolicy) { LsaClose(hLsa, hPolicy); } if (hLsa) { LsaFreeBinding(&hLsa); } if (pCreds) { LwIoDeleteCreds(pCreds); } for (i = 0; i < numAccountRightNames; i++) { LW_SAFE_FREE_MEMORY(ppwszAccountRightNames[i]); LW_SAFE_FREE_MEMORY(ppszAccountRightNames[i]); } LW_SAFE_FREE_MEMORY(ppwszAccountRightNames); LW_SAFE_FREE_MEMORY(ppszAccountRightNames); if (err == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { err = LwNtStatusToWin32Error(ntStatus); } return err; }