Voici un code source C # qui implémente une DLL non géré (Advapi32). Les valeurs de variable au moment de l'exécution sont les suivantes: p> privilege: "SeServiceLogonRight"
account: "named"
ret: 3221225485 (STATUS_INVALID_PARAMETER)
error: 87
6 Réponses :
Je ne pouvais pas obtenir cela pour travailler, j'ai donc utilisé le code source du projet CodeProject, Fonctions LSA - Privilèges et impersonnations qui fonctionne bien. P>
Je suis tombé sur la même erreur lors de l'appel de LsaaddacCounTrights et j'ai découvert que j'utilisais Taillef (Char) au lieu de Tailleof (WRCHAR) lors de l'initialisation de lsa_unicode_string.
J'ai vérifié le code à devrait être quelque chose comme: p>
J'ai pu obtenir cela fonctionnant sur une case, puis sur une autre case, elle a échoué avec l'erreur que vous avez reçue: p>
système.componentmodel.win32Exception: le paramètre est incorrect p>
J'ai découvert que la cause fondamentale de ce problème devait faire avec l'architecture du processus qui exécutait le code. J'exécutais un processus de Msbuild 32 bits qui fonctionnait bien, mais lorsque j'ai utilisé Msbuild.exe 64 bits pour exécuter cela, il a échoué avec cette erreur. P>
J'espère que cela aide! P>
Cordialement, Brandon p>
J'ai trouvé que ce problème est lié à .NET 4.0. Duplorez votre projet à .NET 3.5 et cela fonctionnera. P>
La dégradation n'est pas une véritable option. À l'avance avec un correctif, c'est mieux que d'aller en arrière.
Après le lien fourni au code de http: //www.hightechats .com / csharp / lsa-fonctions-276626.html lts em> (une structure LSA_TRANSLATE_SID2) contient un pointeur qui pointe la mémoire qui est libérée Par appel à win32sec.lsafreemorory em>. Utilisation du pointeur après la libération de la mémoire est une mauvaise pratique et aura des résultats imprévisibles - il pourrait même "travailler". P> modifier le code sur la liaison à l'aide de la classe SecurityIdentififier (.NET 2 et ci-dessus) Le long d'un peu de nettoyage de code inutile évite le problème de la mémoire. P>
lts.sid est libéré avant de retourner dans RetiLInformation. Déplacer les codes de RetiestInformation. Cela a fonctionné bien pour .NET 4.5.
public void AddPrivileges(string account, string privilege)
{
LSA_UNICODE_STRING[] names = new LSA_UNICODE_STRING[1];
LSA_TRANSLATED_SID2 lts;
IntPtr tsids = IntPtr.Zero;
IntPtr tdom = IntPtr.Zero;
names[0] = InitLsaString(account);
lts.Sid = IntPtr.Zero;
Console.WriteLine("String account: {0}", names[0].Length);
int ret1 = Win32Sec.LsaLookupNames2(lsaHandle, 0, 1, names, ref tdom, ref tsids);
if (ret1 != 0)
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError(ret1));
lts = (LSA_TRANSLATED_SID2)Marshal.PtrToStructure(tsids, typeof(LSA_TRANSLATED_SID2));
IntPtr pSid = lts.Sid;
//IntPtr pSid = GetSIDInformation(account);
LSA_UNICODE_STRING[] privileges = new LSA_UNICODE_STRING[1];
privileges[0] = InitLsaString(privilege);
uint ret = Win32Sec.LsaAddAccountRights(lsaHandle, pSid, privileges, 1);
Win32Sec.LsaFreeMemory(tsids);
Win32Sec.LsaFreeMemory(tdom);
if (ret == 0)
return;
if (ret == STATUS_ACCESS_DENIED)
{
throw new UnauthorizedAccessException();
}
if ((ret == STATUS_INSUFFICIENT_RESOURCES) || (ret == STATUS_NO_MEMORY))
{
throw new OutOfMemoryException();
}
throw new Win32Exception(Win32Sec.LsaNtStatusToWinError((int)ret));
}