• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 925
  • Last Modified:

Failure to setup Admin user via NetUserSetInfo

NetUserSetInfo with USER_INFO_1005 (level 1005)
USER_PRIV_ADMIN priviledge produces Error: USER_PRIV_PARMNUM (5)
My account is setup wtih Administrator priviledge so I should be able to create an account with
Administrator priviledge but the API produces the error noted.

I can successfully create the user and password via NetUserAdd.  
However that user must be created as USER_PRIV_USER.
I need to set admin priviledge for the user, but NetUserSetInfo fails to do it.

I have also tried using "NetUserSetGroups" to set the user as a member of Administrators or "Power Users" and get error: NERR_GroupNotFound.

Can an Administrator user be created programatically?
I am installing a service that needs admin privilege.
The installer's account must have Admin priviledge
but I do not want to ask the customer to run Administrator program tools to set up a user account with Administrator privilege for the service to use for logon.
0
skyemail
Asked:
skyemail
  • 3
1 Solution
 
jkrCommented:
>>Can an Administrator user be created programatically?

Yes, but you cannot use 'NetUserSetInfo()' for that. You need to add the user to the admin group.

>>I have also tried using "NetUserSetGroups" to set the user as a member of Administrators or "Power Users" and
>>get error: NERR_GroupNotFound.

If you aren'r using an english windows version the group name can be different. You should never hard-code these names, but determine them at run time, e.g.

DWORD   GetAdminGroupName   (   LPTSTR  pszAdminNameBuf,
                                PDWORD  pdwAdminNameBufSize
                            )
{
    DWORD                       dwErr               =   0;

    TCHAR                       acReferencedDomain  [   LM20_DNLEN  +   1];
    DWORD                       dwDomainBufSize     =   COUNTOF (   acReferencedDomain);

    SID_NAME_USE                eUse;

    PSID                        psidAdmin           =   NULL;

    SID_IDENTIFIER_AUTHORITY    SystemSidAuthority  =   SECURITY_NT_AUTHORITY;

    //  create a SID referencing the 'Administrators' group
    if  (   !AllocateAndInitializeSid   (   &SystemSidAuthority,
                                            2,
                                            SECURITY_BUILTIN_DOMAIN_RID,
                                            DOMAIN_ALIAS_RID_ADMINS,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            0,
                                            &psidAdmin
                                        )
        )  
        {
            dwErr   =   GetLastError    ();
        }
     else
        {
            //  lookup clear text name of the group
            if  (   !LookupAccountSid   (   NULL,
                                            psidAdmin,
                                            pszAdminNameBuf,
                                            pdwAdminNameBufSize,
                                            acReferencedDomain,
                                            &dwDomainBufSize,
                                            &eUse
                                        )
                )
                {
                    dwErr   =   GetLastError    ();
                }
        }

    //  explicitly deallocate SID
    if  (   psidAdmin)
            FreeSid ( psidAdmin);

    return  (   dwErr);

}

    wchar_t                     awcAdminGroupName   [   GNLEN   +   1];
    DWORD                       dwBufSize           =   COUNTOF (   awcAdminGroupName);
    wchar_t                     awcDomUsrName       [   LM20_DNLEN  +   LM20_UNLEN  +   1];
    wchar_t                     awcWkSta            [   MAX_COMPUTERNAME_LENGTH + 2];

    LOCALGROUP_MEMBERS_INFO_3   mi  [   3];

    ZeroMemory  (   mi,     sizeof (    mi));

    GetComputerName (   awcWkSta,   &dwBufSiz);

    wsprintf    (   awcDomUsrName,  
                    L"%s\\%s",  
                    awcWkSta,
                    pwstrName
                );  

    mi  [   0].lgrmi3_domainandname =   awcDomUsrName;

    rc  =   NetLocalGroupAddMembers (   NULL,
                                        awcAdminGroupName,
                                        3,
                                        (LPBYTE) mi,
                                        1
                                    );
0
 
jkrCommented:
Oops, the last part should be

    wchar_t                     awcAdminGroupName   [   GNLEN   +   1];
    DWORD                       dwBufSize           =   COUNTOF (   awcAdminGroupName);
    wchar_t                     awcDomUsrName       [   LM20_DNLEN  +   LM20_UNLEN  +   1];
    wchar_t                     awcWkSta            [   MAX_COMPUTERNAME_LENGTH + 2];

    LOCALGROUP_MEMBERS_INFO_3   mi  [   3];

    ZeroMemory  (   mi,     sizeof (    mi));

    GetComputerName (   awcWkSta,   &dwBufSiz);

    GetAdminGroupName   (   awcAdminGroupName,  &dwBufSize)

    wsprintf    (   awcDomUsrName,  
                    L"%s\\%s",  
                    awcWkSta,
                    pwstrName
                );  

    mi  [   0].lgrmi3_domainandname =   awcDomUsrName;

    rc  =   NetLocalGroupAddMembers (   NULL,
                                        awcAdminGroupName,
                                        3,
                                        (LPBYTE) mi,
                                        1
                                    );
0
 
jkrCommented:
The above is taken from "production code" that performs what was asked for - moving a user to the admin group.
0
 
JohnDiegoCommented:
Thanks to jkr for showing how to solve the problem. There are a few bugs in the code given, here is tested and working code.




#pragma comment (lib, "netapi32")
#include <lmaccess.h>
#include <lm.h>
 
#define ELEM_CNT(a) (((sizeof(a))/(sizeof(a[0]))))
 
DWORD GetAdminGroupName( WCHAR *AdminName, PDWORD AdminNameSize )
{
    DWORD dwErr = ERROR_SUCCESS;
 
    PSID psidAdmin = NULL;
    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
 
    //  create a SID referencing the 'Administrators' group
    if ( AllocateAndInitializeSid(
             &SystemSidAuthority, 2,
             SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
             0, 0, 0, 0, 0, 0, &psidAdmin ) )
    {
        // leave some extra room
        WCHAR ReferencedDomain[ LM20_DNLEN*20 + 1 ];
        DWORD dwDomainBufSize = ELEM_CNT( ReferencedDomain );
        SID_NAME_USE SidNameUse;
    
        //  lookup clear text name of the group
        if ( ! LookupAccountSidW(
                 NULL,
                 psidAdmin, 
                 AdminName, AdminNameSize,
                 ReferencedDomain, &dwDomainBufSize,
                 &SidNameUse ) )
        {
            dwErr = GetLastError( );
        }
    }
    else
    {
        dwErr = GetLastError( );
    }
 
    //  explicitly deallocate SID
    if ( psidAdmin )
        FreeSid ( psidAdmin);
 
    return dwErr;
}
 
// return is NERR_Success
// NERR_GroupNotFound   The group specified does not exist. 
// ERROR_ACCESS_DENIED  The user needs have admin rights
// ERROR_NO_SUCH_MEMBER Some members do not exist. None added. 
// ERROR_MEMBER_IN_ALIAS Some members already in group. None added. 
// ERROR_INVALID_MEMBER Some members have invalid account types. None added.
 
NET_API_STATUS AddUserToAdminGroup( WCHAR *UserName )
{
    DWORD   dwBufSize;
 
    wchar_t WkSta[ MAX_COMPUTERNAME_LENGTH*20 + 2 ] = L"";
    dwBufSize = ELEM_CNT( WkSta );
    DWORD Ret = GetComputerNameW ( WkSta, &dwBufSize);
 
    wchar_t AdminGroupName[ GNLEN*20 + 1 ] = L""; 
    dwBufSize = ELEM_CNT( AdminGroupName );
    Ret = GetAdminGroupName( AdminGroupName, &dwBufSize);
 
    wchar_t LocalDomainUserName[ LM20_DNLEN*20 + 1 ]=L"";
    swprintf( LocalDomainUserName, L"%s\\%s", WkSta, UserName );  
 
    LOCALGROUP_MEMBERS_INFO_3 NewGroupMembers[2] = {0};
    NewGroupMembers[0].lgrmi3_domainandname = LocalDomainUserName;
 
    NET_API_STATUS rc = 
        NetLocalGroupAddMembers( 
            NULL, AdminGroupName, 
            3,     // add array of domain/names to the group
            (LPBYTE) NewGroupMembers,
            1 );   // 1 member in NewGroupMembers array
    return rc;
}

Open in new window

0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now