[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

I get a 2202 status code from NetUserAdd, which indicates NERR_BadUsername. My user ID is tempuser. What is wrong with such a name? Which name does 2202 correspond to?

Posted on 2009-04-20
9
Medium Priority
?
1,469 Views
Last Modified: 2012-05-06
Hi - A call to NetUserAdd is returning 2202, which indicates NERR_BadUsername. A USER_INFO_4 level record is being used to create a local user with a user ID of "testname". Is there something in this name that is bad? Can someone please help me troubleshoot the error code (2202) so that I could successfully create a user account?
0
Comment
Question by:baigmz
  • 3
  • 2
6 Comments
 
LVL 92

Accepted Solution

by:
objects earned 1200 total points
ID: 24190018
0
 

Author Comment

by:baigmz
ID: 24190576
Windows XP
0
 
LVL 92

Expert Comment

by:objects
ID: 24190593
are you passing it a unicode string (NULL terminated) as discussed in the link?

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 86

Expert Comment

by:jkr
ID: 24196144
Try the following:
   //**********************************************************************
   //
   //  This program creates a new user account, forces a profile to be
   //  created for the new user, and retrieves the new profile directory
   //
   //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
   //  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
   //  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
   //  PARTICULAR PURPOSE.
   //
   //  Copyright (C) 1998 Microsoft Corporation. All rights reserved.
   //  Author: Jonathan Russ (jruss)
   //
   //**********************************************************************
 
   // NOTE: This code must be linked with netapi32.lib
 
   #include <windows.h>
   #include <tchar.h>
   #include <stdio.h>
   #include <lm.h>
 
   // Declarations based on USERENV.H for Windows 2000 Beta 2
   #define PI_NOUI         0x00000001   // Prevents displaying of messages
   #define PI_APPLYPOLICY  0x00000002   // Apply NT4 style policy
 
   typedef struct _PROFILEINFO {
      DWORD    dwSize;          // Must be set to sizeof(PROFILEINFO)
      DWORD    dwFlags;         // See flags above
      LPTSTR   lpUserName;      // User name (required)
      LPTSTR   lpProfilePath;   // Roaming profile path
      LPTSTR   lpDefaultPath;   // Default user profile path
      LPTSTR   lpServerName;    // Validating DC name in netbios format
      LPTSTR   lpPolicyPath;    // Path to the NT4 style policy file
      HANDLE   hProfile;        // Registry key handle - filled by function
   } PROFILEINFO, FAR * LPPROFILEINFO;
 
   // Typedefs for function pointers in USERENV.DLL
   typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
      HANDLE hToken,
      LPPROFILEINFO lpProfileInfo
   );
 
   typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
      HANDLE hToken,
      HANDLE hProfile
   );
 
   typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
      HANDLE hToken,
      LPTSTR lpProfileDir,
      LPDWORD lpcchSize
   );
 
   HMODULE                 g_hUserEnvLib           = NULL;
   LPFNLOADUSERPROFILE     LoadUserProfile         = NULL;
   LPFNUNLOADUSERPROFILE   UnloadUserProfile       = NULL;
   LPFNGETUSERPROFILEDIR   GetUserProfileDirectory = NULL;
 
 
   //**********************************************************************
   //
   //  FUNCTION:     InitUserEnv - This function dynamically links to
   //                USERENV.DLL and sets up the required function pointers
   //
   //  PARAMETERS:   none
   //
   //  RETURN VALUE: TRUE if successful. Otherwise, FALSE.
   //
   //**********************************************************************
 
   BOOL InitUserEnv( void ) {
 
      g_hUserEnvLib = LoadLibrary( _T("userenv.dll") );
      if ( !g_hUserEnvLib ) {
         _tprintf( _T("LoadLibrary(userenv.dll) failed.  Error %d\n"),
              GetLastError() );
         return FALSE;
      }
 
   #ifdef UNICODE
      LoadUserProfile =
            (LPFNLOADUSERPROFILE) GetProcAddress( g_hUserEnvLib,
            "LoadUserProfileW" );
   #else
      LoadUserProfile =
            (LPFNLOADUSERPROFILE) GetProcAddress( g_hUserEnvLib,
            "LoadUserProfileA" );
   #endif
 
      if (!LoadUserProfile) {
         _tprintf( _T("GetProcAddress(%s) failed.  Error %d\n"),
               "LoadUserProfile", GetLastError() );
         return FALSE;
      }
 
      UnloadUserProfile =
            (LPFNUNLOADUSERPROFILE) GetProcAddress( g_hUserEnvLib,
            "UnloadUserProfile" );
 
      if (!UnloadUserProfile) {
         _tprintf( _T("GetProcAddress(%s) failed.  Error %d\n"),
               "UnloadUserProfile", GetLastError() );
         return FALSE;
      }
 
   #ifdef UNICODE
      GetUserProfileDirectory =
            (LPFNGETUSERPROFILEDIR) GetProcAddress( g_hUserEnvLib,
            "GetUserProfileDirectoryW" );
   #else
      GetUserProfileDirectory =
            (LPFNGETUSERPROFILEDIR) GetProcAddress( g_hUserEnvLib,
            "GetUserProfileDirectoryA" );
   #endif
 
      if (!GetUserProfileDirectory) {
         _tprintf( _T("GetProcAddress(%s) failed.  Error %d\n"),
               "GetUserProfileDirectory", GetLastError() );
         return FALSE;
      }
 
      return TRUE;
   }
 
 
   //**********************************************************************
   //
   //  FUNCTION:     _tmain - This is the entry point for the program.
   //
   //  PARAMETERS:   argc - the number of command-line arguments
   //                argv - an array of null-terminated strings specifying
   //                       the command-line arguments
   //                envp - an array of null-terminated strings specifying
   //                       the environment strings
   //
   //  RETURN VALUE: Zero if successful. Otherwise, non-zero.
   //
   //**********************************************************************
 
   #ifdef __cplusplus
      extern "C"
   #endif
 
   #ifdef UNICODE
      int _cdecl
   #else
      int
   #endif
 
   _tmain(int argc, _TCHAR **argv, _TCHAR **envp) {
 
      USER_INFO_1   ui1;
      DWORD         dwError;
      HANDLE        hToken;
      PROFILEINFO   pi;
      TCHAR         szProfilePath[1024];
      DWORD         cchPath = 1024;
      WCHAR         szUserName[20];
      WCHAR         szPassword[20];
 
      // Check for the required command-line arguments
      if (argc < 2) {
         _tprintf( _T("Usage: AddUser <user> [password]\n") );
         return -1;
      }
 
      // Set USERENV.DLL function pointers
      if ( !InitUserEnv() ) {
         _tprintf( _T("Failed to set USERENV.DLL function pointers.\n") );
         return -1;
      }
 
      // Create local copies of the user name and password
      #ifdef UNICODE
 
      _tcscpy( szUserName, argv[1] );
      if ( argc == 2 ) {
         _tcscpy( szPassword, szUserName );
      } else {
         _tcscpy( szPassword, argv[2] );
      }
 
      #else
      {
         int n;
 
         n = MultiByteToWideChar(0, 0, argv[1], -1, szUserName, 20);
         if (n == 0)
         {
            _tprintf( _T("Failed to convert username to unicode\n"));
            return -1;
         }
 
         if ( argc == 2 ) {
            n = MultiByteToWideChar(0, 0, argv[1], -1, szPassword, 20);
         } else {
            n = MultiByteToWideChar(0, 0, argv[2], -1, szPassword, 20);
         }
         if (n == 0)
         {
            _tprintf( _T("Failed to convert password to unicode\n"));
            return -1;
         }
      }
      #endif
 
      // Set up the USER_INFO_1 structure that will be used to create the
      // new user account
      ZeroMemory( &ui1, sizeof(ui1) );
      ui1.usri1_name = szUserName;
      ui1.usri1_password = szPassword;
      ui1.usri1_priv = USER_PRIV_USER;
      ui1.usri1_flags = UF_NORMAL_ACCOUNT | UF_SCRIPT;
 
      // Create the new user account
      dwError = NetUserAdd(
            NULL,            // target computer name
            1,               // info level
            (LPBYTE) &ui1,   // address of user info structure
            NULL );          // index to invalid parameter
      if ( dwError != NERR_Success ) {
         _tprintf( _T("NetUserAdd() failed.  Error %d\n"), dwError );
         dwError = ERROR_ACCESS_DENIED;
         return -1;
      }
 
      // Do a network logon because most systems do not grant new users
      // the right to logon interactively (SE_INTERACTIVE_LOGON_NAME)
      // but they do grant the right to do a network logon
      // (SE_NETWORK_LOGON_NAME). A network logon has the added advantage
      // of being quicker.
 
      // NOTE: To call LogonUser(), the current user must have the
      // SE_TCB_NAME privilege
      if ( !LogonUser(
            argv[1],                        // user name
            _T("."),                        // domain or server
            (argc == 2) ? argv[1]:argv[2],  // password
            LOGON32_LOGON_NETWORK,          // type of logon operation
            LOGON32_PROVIDER_DEFAULT,       // logon provider
            &hToken ) ) {                   // pointer to token handle
         _tprintf( _T("LogonUser() failed.  Error %d\n"), GetLastError() );
         return -1;
      }
 
      // Set up the PROFILEINFO structure that will be used to load the
      // new user's profile
      ZeroMemory( &pi, sizeof(pi) );
      pi.dwSize = sizeof(pi);
 
      #ifdef UNICODE
      pi.lpUserName = szUserName;
      #else
      pi.lpUserName = argv[1];
      #endif
 
      pi.dwFlags = PI_NOUI;
 
      // Load the profile. Since it doesn't exist, it will be created
      if ( !LoadUserProfile(
            hToken,        // token for the user
            &pi ) ) {      // pointer to PROFILEINFO structure
         _tprintf( _T("LoadUserProfile() failed.  Error %d\n"),
               GetLastError() );
         return -1;
      }
 
      // Unload the profile when it is no longer needed
      if ( !UnloadUserProfile(
            hToken,              // token for the user
            pi.hProfile ) ) {    // registry key handle
         _tprintf( _T("UnloadUserProfile() failed.  Error %d\n"),
               GetLastError() );
         return -1;
      }
 
      // Retrieve the new user's profile directory
      if ( !GetUserProfileDirectory( hToken, szProfilePath, &cchPath ) ) {
         _tprintf( _T("GetProfilePath() failed.  Error %d\n"),
               GetLastError() );
         return -1;
      }
 
      // Display the new user's profile directory
      _tprintf( _T("The new user's profile path is %s\n"), szProfilePath );
 
      // Release USERENV.DLL
      if ( g_hUserEnvLib ) {
         FreeLibrary( g_hUserEnvLib );
      }
 
      return 0;
   }
			

Open in new window

0
 
LVL 92

Expert Comment

by:objects
ID: 24200389
which does what I suggested above ;)

0
 
LVL 86

Expert Comment

by:jkr
ID: 25445366
Since the code I provided does significant other things also, I tend to object.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Suggested Courses
Course of the Month17 days, 16 hours left to enroll

830 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