Solved

Retrieving User Rights Information

Posted on 1997-09-17
1
660 Views
Last Modified: 2013-12-03
OK, I've seen the NetGroupAdd API, but how do I give a group it's permissions?  In UserManager, one can click on the User Rights Policy (Policies->User Rights).  This will show a list of rights that one can give to a group.  How does one retrieve these rights?  The GROUP_INFO_2 structure doesn't seem to allow setting these rights.  How does one retrieve the rights, and how does one give a group these rights?  I would like to be able to access all of those rights, (including the advanced rights).  Thank you very much for any information that you have.
0
Comment
Question by:bogus1
1 Comment
 
LVL 5

Accepted Solution

by:
y96andha earned 100 total points
Comment Utility
This is a sample from the Microsoft Knowledge Base (Q132958) describing how to do it. If you have MS VC 4.0, you can find this  article in the online help.

PSS ID Number: Q132958
Article last modified on 07-24-1995
 
3.51
 
WINDOWS NT
 

----------------------------------------------------------------------
The information in this article applies to:
 
 - Microsoft Win32 Software Development Kit (SDK) version 3.51
----------------------------------------------------------------------
 
SUMMARY
=======
 
In Windows NT, privileges are used to provide a means of access control
that differs from discretionary access control. A system manager uses
privileges to control which users/groups are able to manipulate various
aspects of the system. An application may use privileges when it changes a
system resource, such as the system time, or when it shuts down the system.
 
The User Manager tool can be used to grant and revoke privileges from
accounts.
 
Windows NT 3.51 provides functionality which allows the developer to manage
privileges programmatically. This functionality is made available through
LSA (Local Security Authority).
 
An example of an application that would benefit from LSA is a service
install program. If the service is configured to run under a user account,
it is necessary for that account to have the  SeServiceLogonRight "logon as
a service" privilege. This article discusses how to take advantage of LSA
to grant and revoke privileges from users and groups.
 
MORE INFORMATION
================
 
Managing user privileges can be achieved programmatically using the
following steps:
 
1. Open the policy on the target machine with LsaOpenPolicy(). To grant
   privileges, open the policy with POLICY_CREATE_ACCOUNT and
   POLICY_LOOKUP_NAMES access. To revoke privileges, open the policy with
   POLICY_LOOKUP_NAMES access.
 
2. Obtain a SID (security identifier) representing the user/group of
   interest. The LookupAccountName() and LsaLookupNames() APIs can obtain a
   SID from an account name.
 
3. Call LsaAddAccountRights() to grant privileges to the user(s)
   represented by the supplied SID.
 
4. Call LsaRemoveAccountRights() to revoke privileges from the user(s)
   represented by the supplied SID.
 
5. Close the policy with LsaClose().
 
To successfully grant and revoke privileges, the caller needs to be an
administrator on the target system.
 
The LSA API LsaEnumerateAccountRights() can be used to determine which
privileges have been granted to an account.
 
The LSA API LsaEnumerateAccountsWithUserRight() can be used to determine
which accounts have been granted a specified privilege.
 
Documentation and header files for these LSA APIs is provided in the
Windows 32 SDK in the MSTOOLS\SECURITY directory.
 
NOTE: These LSA APIs are currently implemented as Unicode only.
 
This sample will grant the privilege SeServiceLogonRight to the account
specified on argv[1].
 
This sample is dependant on these import libs
 
   advapi32.lib (for LsaXxx)
   user32.lib (for wsprintf)
 
This sample will work properly compiled ANSI or Unicode.
 
Sample Code
-----------
 
/*++
 
You can use domain\account as argv[1]. For instance, mydomain\scott will
grant the privilege to the mydomain domain account scott.
 
The optional target machine is specified as argv[2], otherwise, the
account database is updated on the local machine.
 
The LSA APIs used by this sample are Unicode only.
 
Use LsaRemoveAccountRights() to remove account rights.
 
Scott Field (sfield)    12-Jul-95
--*/
 
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
 
#include <windows.h>
#include <stdio.h>
 
#include "ntsecapi.h"
 
NTSTATUS
OpenPolicy(
    LPWSTR ServerName,          // machine to open policy on (Unicode)
    DWORD DesiredAccess,        // desired access to policy
    PLSA_HANDLE PolicyHandle    // resultant policy handle
    );
 
BOOL
GetAccountSid(
    LPTSTR SystemName,          // where to lookup account
    LPTSTR AccountName,         // account of interest
    PSID *Sid                   // resultant buffer containing SID
 
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
    );
 
void
InitLsaString(
    PLSA_UNICODE_STRING LsaString, // destination
    LPWSTR String                  // source (Unicode)
    );
 
void
DisplayNtStatus(
    LPSTR szAPI,                // pointer to function name (ANSI)
    NTSTATUS Status             // NTSTATUS error value
    );
 
void
DisplayWinError(
    LPSTR szAPI,                // pointer to function name (ANSI)
    DWORD WinError              // DWORD WinError
    );
 
#define RTN_OK 0
#define RTN_USAGE 1
#define RTN_ERROR 13
 
//
// If you have the ddk, include ntstatus.h.
//
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
#endif
 
int _cdecl
main(int argc, char *argv[])
{
    LSA_HANDLE PolicyHandle;
    WCHAR wComputerName[256]=L"";   // static machine name buffer
    TCHAR AccountName[256];         // static account name buffer
    PSID pSid;
    NTSTATUS Status;
    int iRetVal=RTN_ERROR;          // assume error from main
 
    if(argc == 1)
    {
        fprintf(stderr,"Usage: %s <Account> [TargetMachine]\n",
            argv[0]);
        return RTN_USAGE;
    }
 
    //
    // Pick up account name on argv[1].
    // Assumes source is ANSI. Resultant string is ANSI or Unicode
    //
    wsprintf(AccountName, TEXT("%hS"), argv[1]);
 
    //
    // Pick up machine name on argv[2], if appropriate
    // assumes source is ANSI. Resultant string is Unicode.
    //
    if(argc == 3) wsprintfW(wComputerName, L"%hS", argv[2]);
 
    //
    // Open the policy on the target machine.
    //
    if((Status=OpenPolicy(
                wComputerName,      // target machine
                POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,
                &PolicyHandle       // resultant policy handle
                )) != STATUS_SUCCESS) {
        DisplayNtStatus("OpenPolicy", Status);
        return RTN_ERROR;
    }
 
    //
    // Obtain the SID of the user/group.
    // Note that we could target a specific machine, but we don't.
    // Specifying NULL for target machine searches for the SID in the
    // following order: well-known, Built-in and local, primary domain,
    // trusted domains.
    //
    if(GetAccountSid(
            NULL,       // default lookup logic
            AccountName,// account to obtain SID
            &pSid       // buffer to allocate to contain resultant SID
            )) {
        //
        // We only grant the privilege if we succeeded in obtaining the
        // SID. We can actually add SIDs which cannot be looked up, but
        // looking up the SID is a good sanity check which is suitable for
        // most cases.
 
        //
        // Grant the SeServiceLogonRight to users represented by pSid.
        //
        if((Status=SetPrivilegeOnAccount(
                    PolicyHandle,           // policy handle
                    pSid,                   // SID to grant privilege
                    L"SeServiceLogonRight", // Unicode privilege
                    TRUE                    // enable the privilege
                    )) == STATUS_SUCCESS)
            iRetVal=RTN_OK;
        else
            DisplayNtStatus("AddUserRightToAccount", Status);
    }
    else {
        //
        // Error obtaining SID.
        //
        DisplayWinError("GetAccountSid", GetLastError());
    }
 
    //
    // Close the policy handle.
    //
    LsaClose(PolicyHandle);
 
    //
    // Free memory allocated for SID.
    //
    if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid);
 
    return iRetVal;
}
 
void
InitLsaString(
    PLSA_UNICODE_STRING LsaString,
    LPWSTR String
    )
{
    DWORD StringLength;
 
    if (String == NULL) {
        LsaString->Buffer = NULL;
        LsaString->Length = 0;
        LsaString->MaximumLength = 0;
        return;
    }
 
    StringLength = wcslen(String);
    LsaString->Buffer = String;
    LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
    LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
}
 
NTSTATUS
OpenPolicy(
    LPWSTR ServerName,
    DWORD DesiredAccess,
    PLSA_HANDLE PolicyHandle
    )
{
    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
    LSA_UNICODE_STRING ServerString;
    PLSA_UNICODE_STRING Server = NULL;
 
    //
    // Always initialize the object attributes to all zeroes.
    //
    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
 
    if (ServerName != NULL) {
        //
        // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
        //
        InitLsaString(&ServerString, ServerName);
        Server = &ServerString;
    }
 
    //
    // Attempt to open the policy.
    //
    return LsaOpenPolicy(
                Server,
                &ObjectAttributes,
                DesiredAccess,
                PolicyHandle
                );
}
 
/*++
This function attempts to obtain a SID representing the supplied
account on the supplied system.
 
If the function succeeds, the return value is TRUE. A buffer is
allocated which contains the SID representing the supplied account.
This buffer should be freed when it is no longer needed by calling
HeapFree(GetProcessHeap(), 0, buffer)
 
If the function fails, the return value is FALSE. Call GetLastError()
to obtain extended error information.
 
Scott Field (sfield)    12-Jul-95
--*/
 
BOOL
GetAccountSid(
    LPTSTR SystemName,
    LPTSTR AccountName,
    PSID *Sid
    )
{
    LPTSTR ReferencedDomain=NULL;
    DWORD cbSid=128;    // initial allocation attempt
    DWORD cbReferencedDomain=16; // initial allocation size
    SID_NAME_USE peUse;
    BOOL bSuccess=FALSE; // assume this function will fail
 
    __try {
 
    //
    // initial memory allocations
    //
    if((*Sid=HeapAlloc(
                    GetProcessHeap(),
                    0,
                    cbSid
                    )) == NULL) __leave;
 
    if((ReferencedDomain=HeapAlloc(
                    GetProcessHeap(),
                    0,
                    cbReferencedDomain
                    )) == NULL) __leave;
 
    //
    // Obtain the SID of the specified account on the specified system.
    //
    while(!LookupAccountName(
                    SystemName,         // machine to lookup account on
                    AccountName,        // account to lookup
                    *Sid,               // SID of interest
                    &cbSid,             // size of SID
                    ReferencedDomain,   // domain account was found on
                    &cbReferencedDomain,
                    &peUse
                    )) {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            //
            // reallocate memory
            //
            if((*Sid=HeapReAlloc(
                        GetProcessHeap(),
                        0,
                        *Sid,
                        cbSid
                        )) == NULL) __leave;
 
            if((ReferencedDomain=HeapReAlloc(
                        GetProcessHeap(),
                        0,
                        ReferencedDomain,
                        cbReferencedDomain
                        )) == NULL) __leave;
        }
        else __leave;
    }
 
    //
    // Indicate success.
    //
    bSuccess=TRUE;
 
    } // finally
    __finally {
 
    //
    // Cleanup and indicate failure, if appropriate.
    //
 
    HeapFree(GetProcessHeap(), 0, ReferencedDomain);
 
    if(!bSuccess) {
        if(*Sid != NULL) {
            HeapFree(GetProcessHeap(), 0, *Sid);
            *Sid = NULL;
        }
    }
 
    } // finally
 
    return bSuccess;
}
 
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
                );
    }
}
 
void
DisplayNtStatus(
    LPSTR szAPI,
    NTSTATUS Status
    )
{
    //
    // Convert the NTSTATUS to Winerror. Then call DisplayWinError().
    //
    DisplayWinError(szAPI, LsaNtStatusToWinError(Status));
}
 
void
DisplayWinError(
    LPSTR szAPI,
    DWORD WinError
    )
{
    LPSTR MessageBuffer;
    DWORD dwBufferLength;
 
    //
    // TODO: Get this fprintf out of here!
    //
    fprintf(stderr,"%s error!\n", szAPI);
 
    if(dwBufferLength=FormatMessageA(
                        FORMAT_MESSAGE_ALLOCATE_BUFFER |
                        FORMAT_MESSAGE_FROM_SYSTEM,
                        NULL,
                        WinError,
                        GetUserDefaultLangID(),
                        (LPSTR) &MessageBuffer,
                        0,
                        NULL
                        ))
    {
        DWORD dwBytesWritten; // unused
 
        //
        // Output message string on stderr.
        //
        WriteFile(
            GetStdHandle(STD_ERROR_HANDLE),
            MessageBuffer,
            dwBufferLength,
            &dwBytesWritten,
            NULL
            );
 
        //
        // Free the buffer allocated by the system.
        //
        LocalFree(MessageBuffer);
    }
}
 
Additional reference words: Privilege User Right
KBCategory: kbprg
KBSubcategory: BseSecurity CodeSam

0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now