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.
skyemailAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.