tags:

views:

170

answers:

1

I am calling NetUserAdd and it is returning 24 for every call. Does anyone know what 24 stands for? It is kind of hard to debug it when I don't know what the error means.

I am calling this from an Windows XP machine running as a local admin. I am also a local admin on the target computer. I tried this with USER_INFO_1 and it worked fine. I just need the level of control given by USER_INFO_2.

This link shows the return values for this call. They are further defined here with numeric values. Sadly none of these values = 24.

I know this is a very specific question. I guess I am hoping to find a PInvoke/NetAddUser expert out there who can help me out.

Here is my code in case it matters:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct USER_INFO_2
    {
        public string name;
        public string password;
        public int password_age;
        public int priv;
        public string home_dir;
        public string comment;
        public int flags;
        public string script_path;
        public int auth_flags;
        public string full_name;
        public string usr_comment;
        public string parms;
        public string workstations;
        public int last_logon;
        public int last_logoff;
        public ulong acct_expires;
        public int max_storage;
        public int units_per_week;
        public IntPtr logon_hours;    // This is a PBYTE
        public int bad_pw_count;
        public int num_logons;
        public string logon_server;
        public int country_code;
        public int code_page;
    }

    [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int NetUserAdd(
         [MarshalAs(UnmanagedType.LPWStr)] string servername,
         UInt32 level,
         ref USER_INFO_2 userinfo,
         out UInt32 parm_err); 

    private static uint CreateUser(string computer, string userName,
       string psswrd, string fullname)
    {
        const int UF_DONT_EXPIRE_PASSWD = 0x10000;
        const int UF_ACCOUNTDISABLE = 0x000002;

        const int USER_PRIV_GUEST = 0; // lmaccess.h:656
        const int USER_PRIV_USER = 1;   // lmaccess.h:657
        const int USER_PRIV_ADMIN = 2;  // lmaccess.h:658

        USER_INFO_2 userInfo2 = new USER_INFO_2()
        {
            acct_expires = long.MaxValue,
            auth_flags = 0, // Must be 0 for NetUserAddCalls
            bad_pw_count = -1,  //ignored for NetUserAdd calls
            //code_page = ?,
            comment = "ScanTrack Account",
            //country_code = ?,
            flags = UF_DONT_EXPIRE_PASSWD,// & UF_ACCOUNTDISABLE,
            full_name = fullname,
            home_dir = "",
            last_logoff = 0,
            last_logon = 0,
            logon_hours = IntPtr.Zero, // User is given no logon time.
            logon_server = "", //ignored for NetUserAdd calls
            max_storage = 0,
            name = userName,
            num_logons = -1, //ignored for NetUserAdd calls
            parms = "",
            password = psswrd,
            password_age = -1,
            priv = USER_PRIV_GUEST,
            script_path = "",
            units_per_week = -1, //ignored for NetUserAdd calls
            usr_comment = "",
            workstations = ""
        };

        uint output;
        NetUserAdd(computer, 2, ref userInfo2, out output);
        return output;
    }

    private void button1_Click(object sender, EventArgs e)
    {

        string computer = "ComputerName";
        string userName = "testName";
        string psswrd = "!t3st4Stuff";
        string fullname = "Test Name Full";

        uint output = CreateUser(computer, userName, psswrd, fullname);
        MessageBox.Show(output.ToString());
    }
+1  A: 

From Error.h:

#define ERROR_BAD_LENGTH        24

...not sure how that relates to your code, but there it is.

Edit: I wonder whether it's this:

home_dir = ""

or similar - the documentation says "Pointer to a Unicode string specifying the path of the home directory for the user specified by the usri2_name member. The string can be null." - there's no mention of the string being given but empty, as you have it. Try null - maybe zero length strings can mean ERROR_BAD_LENGTH..

RichieHindle
I went back to using a USER_INFO_1. I am awarding the answer because it got me back to debugging it again.Thanks for the help!
Vaccano
At the command line if you type "net helpmsg <error number>" that will return to you in human terms what the error is. Pretty useful. For 24 it returned: "The program issued a command but the command length is incorrect."
Mike