Id. de artículo: 142790 - Última revisión: lunes, 11 de julio de 2005 - Versión: 2.2

Cómo extraer la ruta de acceso del perfil de una GINA en Windows 2000, Windows NT o Windows XP

En esta página

Expandir todo | Contraer todo

Resumen

En este artículo se explica cómo obtener una ruta de perfil para devolver de un GINA en Microsoft Windows 2000, Windows NT, Windows XP.

Más información

En un sistema estándar de Windows 2000, Windows NT o Windows XP, los usuarios de sesión interactiva reciben un perfil. Un perfil es un subárbol del registro que se ajusta a un usuario determinado. El perfil se utiliza normalmente para guardar información específica de usuario, como la apariencia de la pantalla, mouse (ratón) haga clic en velocidades, si hay un protector de pantalla, si el protector de pantalla es seguro y así sucesivamente. Este perfil, hace referencia utilizando la clave de registro especial HKEY_CURRENT_USER, carga Winlogon durante el proceso de inicio interactiva.

La interfaz entre archivos DLL de GINA y Winlogon incluye información pasada desde GINA que permite Winlogon localizar y cargar el perfil del usuario ha iniciado la sesión. El parámetro de pProfile WlxLoggedOutSAS() se utiliza para devolver un puntero a una estructura de tipo WLX_PROFILE_V1_0.

La estructura WLX_PROFILE_V1_0 actualmente se utiliza para admitir perfiles remotos y obligatorios, que pueden configurarse con el Administrador de usuarios para dominios (usrmgr) | propiedades de usuario | perfil | ruta de acceso de perfil de usuario. Esta acción puede realizarse mediante programación a través de la NetUserSetInfo() de API de Windows NT LAN Manager en información de nivel 3.

Si se devuelve un puntero NULL desde WlxLoggedOutSAS() como el parámetro pProfile, Winlogon controlará la carga del perfil de usuario (y creación). En este caso, se omitirá la ruta de acceso del perfil opcional, definido por el administrador para el inicio de sesión.

Procedimiento paso a paso

Según el nombre proporcionado de nombre de usuario y dominio, se los pasos siguientes pueden utilizarse para determinar si y se lo que se establece la ruta del perfil definido por el administrador en:
  1. Determine el nombre de dominio actual, con una llamada a la NetUserModalsGet() de API de Windows LAN Manager en información de nivel 2. El usrmod2_domain_name de miembro de estructura USER_MODALS_INFO_2 devuelto contendrá el nombre de dominio. Esta llamada necesita sólo realizarse una vez, durante el primer intento de inicio de sesión. El resultado de la primera llamada se almacena en una variable global. El nombre de dominio actual es necesario para comparar con el nombre de dominio de inicio de sesión para determinar dónde buscar información de cuenta.
  2. Si el nombre de dominio proporcionado no es igual al nombre de dominio actual, obtener nombre de equipo del controlador de dominio asociado al dominio proporcionado. Utilice el lstrcmpiW() API Win32 para la comparación de cadenas y NetGetDCName() de API de LAN Manager de Windows para obtener nombre de equipo del controlador de dominio.
  3. Utilice el NetUserGetInfo() de API de Windows LAN Manager en información de nivel 3 para adquirir la información de cuenta de usuario para el usuario especificado. Cuando se llama a NetUserGetInfo(), el equipo approriate--el equipo local por medio de NULL o nombre de equipo de controlador de dominio de destino se adquirió de NetGetDCName().
  4. Si el usri3_profile de miembro de estructura USER_INFO_3 devuelto por NetUserGetInfo() es una cadena vacía, no se definió ningún perfil por un administrador. En este caso, WlxLoggedOutSAS() puede devolver un puntero NULL como parámetro pProfile y no más acciones necesiten realizarse; de lo contrario continúe.
  5. Copie el usri3_profile de miembro de estructura USER_INFO_3 en almacenamiento asignado por HeapAlloc(GetProcessHeap()...). El código siguiente ilustra este punto:
       HeapAlloc( GetProcessHeap(), 0,
          (lstrlenW(usri3_profile) + 1) * sizeof(WCHAR) // string + NULL
          );
    						
  6. Asignar un bloque de memoria de tamaño WLX_PROFILE_V1_0. El código siguiente ilustra este punto:
     HeapAlloc( GetProcessHeap(), 0, sizeof(WLX_PROFILE_V1_0) );
  7. Establecer al miembro dwType de la estructura WLX_PROFILE_V1_0 a WLX_PROFILE_TYPE_V1_0.
  8. Establezca el miembro pszProfile de la estructura WLX_PROFILE_V1_0 para señalar a la copia del miembro de estructura usri3_profile USER_INFO_3.
  9. Devolver un puntero a la estructura WLX_PROFILE_V1_0 asignada desde WlxLoggedOutSAS() como el parámetro pProfile.
Nota : la API de Windows LAN Manager sólo son Unicode. Las cadenas pasadas a estas API deben estar en forma de Unicode. GINA es también Unicode, por lo que esto no es normalmente un problema.

Nota : es importante para los búferes asignados por la API de Windows LAN Manager. NetApiBufferFree() de API de LAN Manager de Windows puede utilizarse para este propósito.

Información específica de versión de Windows

En Windows NT 3.51 y posterior, Microsoft recomienda que llame a la LogonUser() de API de Win32 para obtener un acceso token que representa el nombre proporcionado nombre de usuario y dominio. Esta API no devuelve información específica a cualquier paquete de autenticación, como la ruta de acceso del perfil de usuario. Por este motivo, es necesario seguir los pasos descritos en este artículo.

En Windows NT 3.5, la LsaLogonUser() debe utilizarse para obtener un token de acceso que representa el nombre de usuario proporcionado y el nombre de dominio. Esta API devuelve una ruta de acceso del perfil, por lo que no se aplican los pasos descritos en este artículo. Sin embargo, la interfaz para LsaLogonUser() es sujeta a cambios en futuras versiones de Windows NT; LogonUser() debe utilizarse cuando sea posible.

Código de ejemplo

   /*
    The following function illustrates a WlxLoggedOutSAS() which obtains
    the user profile path, and returns the result if a profile path is
    found. This function is a modified version of WlxLoggedOutSAS() taken
    from the Win32 SDK version 3.51 gina sample, found in
    Mstools/Samples/Win32/Winnt/Gina on the MSDN CD-ROM.
   */ 

   int
   WINAPI
   WlxLoggedOutSAS(
       PVOID                   pWlxContext,
       DWORD                   dwSasType,
       PLUID                   pAuthenticationId,
       PSID                    pLogonSid,
       PDWORD                  pdwOptions,
       PHANDLE                 phToken,
       PWLX_MPR_NOTIFY_INFO    pMprNotifyInfo,
       PVOID *                 pProfile
       )
   {
       int         result;
       PWLX_PROFILE_V1_0   pWlxProfile;
       PWSTR szProfile;
       // PMiniAccount    pAccount;
       PGlobals        pGlobals;

       pGlobals = (PGlobals) pWlxContext;

       result = pWlxFuncs->WlxDialogBoxParam(
                   hGlobalWlx,
                   hDllInstance,
                   (LPTSTR) MAKEINTRESOURCE(IDD_LOGON_DIALOG),
                   NULL,
                   LogonDlgProc,
                   (LPARAM) pGlobals );

       if (result == WLX_SAS_ACTION_LOGON)
       {
           result = AttemptLogon(pGlobals, pGlobals->pAccount,
                                   pLogonSid, pAuthenticationId);

           if (result == WLX_SAS_ACTION_LOGON)
           {
               *pdwOptions = 0;
               *phToken = pGlobals->hUserToken;

               if(!GetUserProfilePath(
                   pGlobals->pAccount->pszUsername,
                   pGlobals->pAccount->pszDomain,
                   &szProfile
                   )) {
                   // 
                   // error occurred acquiring profile path. Log error
                   // here if appropriate. Default is to not provide
                   // profile information as szProfile will be NULL
                   // which causes *pProfile to be set to NULL
                   // 
               }

               // 
               // if no profile is specified in the userinfo, let winlogon
               // handle locating the registry hive
               // 
               if(szProfile == NULL) {
                   *pProfile = NULL;
               }
               else {
                   pWlxProfile = (PWLX_PROFILE_V1_0)HeapAlloc(
                       GetProcessHeap(), 0, sizeof(WLX_PROFILE_V1_0) );

                   if(pWlxProfile == NULL) {
                       // 
                       // error occurred allocating memory. Log error
                       // here if appropriate. Free memory associated
                       // with the acquired profile path. Default is to
                       // not provide profile information by supplying
                       // NULL as pProfile.
                       // 
                       HeapFree(GetProcessHeap(), 0, szProfile);
                       *pProfile = NULL;
                   }
                   else {
                       // 
                       // the allocation succeeded -- fill in the profile
                       // information
                       // 
                       pWlxProfile->dwType = WLX_PROFILE_TYPE_V1_0;
                       pWlxProfile->pszProfile = szProfile;
                       *pProfile = pWlxProfile;
                   }
               }

               pMprNotifyInfo->pszUserName =
                   DupString(pGlobals->pAccount->pszUsername);
               pMprNotifyInfo->pszDomain =
                   DupString(pGlobals->pAccount->pszDomain);
               pMprNotifyInfo->pszPassword =
                   DupString(pGlobals->pAccount->pszPassword);
               pMprNotifyInfo->pszOldPassword = NULL;
           }
       }
       return(result);
   }

   /*
    The following function obtains the profile path for the supplied user
    on the supplied domain.

    If the function succeeds, the return value is TRUE.
    If the function fails, the return value is FALSE, and the ProfilePath
    is set to NULL.

    If no profile path exists for the supplied user, the ProfilePath
    parameter will be set to NULL. If ProfilePath is non-NULL, the caller
    is responsible for freeing the string via HeapFree(GetProcessHeap...).

    This source code relies on the lm.h header file and the netapi32.lib
    import library.
   */ 
   BOOL
   GetUserProfilePath(
       IN LPWSTR UserName,     // UserName to retrieve profile path
       IN LPWSTR Domain,       // Domain user resides on
       OUT LPWSTR *ProfilePath // result profile path.  NULL == no profile
       )
   {
       LPWSTR wTargetComputer;
       PUSER_INFO_3 ui3 = NULL;
       PUSER_MODALS_INFO_2 umi2 = NULL;
       NET_API_STATUS nas;
       BOOL bSuccess = FALSE; // assume this function will fail

       *ProfilePath = NULL;

       // 
       // get the local domain name.
       // NOTE: in a gina, it would be wise to retrieve this only once,
       // in DllMain during DLL_PROCESS_ATTACH. The pointer could be
       // saved in a global variable and then compared against below.
       // 
       nas=NetUserModalsGet(NULL, 2, (LPBYTE *)&umi2);
       if(nas != NO_ERROR) {
           return FALSE;
       }

       __try {

       // 
       // determine if you need to look up at the domain controller
       // 
       if(lstrcmpiW(Domain, umi2->usrmod2_domain_name) == 0) {
           // 
           // target computer is local machine
           // 
           wTargetComputer = NULL;
       }
       else {
           // 
           // target computer is the PDC computer name for the specified
           // domain
           // 
           nas=NetGetDCName(NULL, Domain, (LPBYTE *)&wTargetComputer);
           if(nas != NO_ERROR) {
               __leave;
           }
       }

       // 
       // fetch the info for the user on the appropriate machine
       // 
       nas=NetUserGetInfo(
           wTargetComputer,
           UserName,            // user name
           3,                   // info-level
           (LPBYTE *) &ui3
           );

       if(nas != NO_ERROR) {
           __leave;
       }

       // 
       // if there is no profile, indicate success.
       // Note that *ProfilePath will be a NULL pointer
       // 
       if(*ui3->usri3_profile == L'\0') {
           bSuccess = TRUE;
           __leave;
       }

       // 
       // allocate storage for profile string
       // 
       *ProfilePath = HeapAlloc(GetProcessHeap(), 0,
           (lstrlenW(ui3->usri3_profile) + 1) * sizeof(WCHAR) );

       if(*ProfilePath == NULL) __leave;

       // 
       // copy the appropriate structure memory to allocated storage
       // 
       if(lstrcpyW(*ProfilePath, ui3->usri3_profile) != NULL)
           bSuccess = TRUE; // indicate success if the copy succeeded

       } // try
       __finally {

       // 
       // free the allocated buffers
       // 
       if(umi2 != NULL)
           NetApiBufferFree(umi2);

       if(ui3 != NULL)
           NetApiBufferFree(ui3);

       if(wTargetComputer != NULL)
           NetApiBufferFree(wTargetComputer);

       if(!bSuccess) {
           if(*ProfilePath != NULL) {
               HeapFree(GetProcessHeap(), 0, *ProfilePath);
               *ProfilePath = NULL;
           }
       }

       } // finally

       return bSuccess;
   }
				

La información de este artículo se refiere a:
  • Microsoft Platform Software Development Kit-January 2000 Edition sobre las siguientes plataformas
    • Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows XP
Palabras clave: 
kbmt kbcode kbgina kbhowto kbkernbase kbnetwork kbsecurity KB142790 KbMtes
Traducción automáticaTraducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 142790  (http://support.microsoft.com/kb/142790/en-us/ )
 

Seleccione idioma