Función NtDuplicateToken (ntifs.h)

La función NtDuplicateToken crea un identificador para un nuevo token de acceso que duplica un token existente. Esta función puede crear un token principal o un token de suplantación.

Sintaxis

__kernel_entry NTSYSCALLAPI NTSTATUS NtDuplicateToken(
  [in]  HANDLE             ExistingTokenHandle,
  [in]  ACCESS_MASK        DesiredAccess,
  [in]  POBJECT_ATTRIBUTES ObjectAttributes,
  [in]  BOOLEAN            EffectiveOnly,
  [in]  TOKEN_TYPE         TokenType,
  [out] PHANDLE            NewTokenHandle
);

Parámetros

[in] ExistingTokenHandle

Identificador de un token de acceso existente que se abrió con el derecho de acceso TOKEN_DUPLICATE. Este parámetro es obligatorio y no puede ser NULL.

[in] DesiredAccess

Máscara de bits que especifica los derechos de acceso solicitados para el nuevo token. NtDuplicateToken compara los derechos de acceso solicitados con la lista de control de acceso discrecional (DACL) del token existente para determinar qué derechos se conceden o deniegan al nuevo token. Para solicitar los mismos derechos de acceso que el token existente, especifique cero. Para solicitar todos los derechos de acceso válidos para el autor de la llamada, especifique MAXIMUM_ALLOWED. Este parámetro es opcional y puede ser cero, MAXIMUM_ALLOWED o una combinación OR bit a bit de uno o varios de los valores siguientes:

Valor Significado
Delete Necesario para eliminar el objeto.
READ_CONTROL Necesario para leer la DACL y la información de propiedad del objeto. Para obtener acceso a la lista de control de acceso del sistema (SACL), consulte ACCESS_SYSTEM_SECURITY más adelante en esta tabla.
WRITE_DAC Necesario para cambiar la información de DACL del objeto.
WRITE_OWNER Necesario para cambiar la información de propiedad en el descriptor de seguridad del objeto (SECURITY_DESCRIPTOR).
ACCESS_SYSTEM_SECURITY Necesario para obtener o establecer la SACL en la ACL de un objeto. El sistema operativo concede este derecho al nuevo token solo si el privilegio SE_SECURITY_NAME está habilitado en el token de acceso del subproceso que realiza la llamada.
STANDARD_RIGHTS_READ Actualmente se define para que sea igual a READ_CONTROL.
STANDARD_RIGHTS_WRITE Actualmente se define para que sea igual a READ_CONTROL.
STANDARD_RIGHTS_EXECUTE Actualmente se define para que sea igual a READ_CONTROL.
STANDARD_RIGHTS_REQUIRED Combina DELETE, READ_CONTROL, WRITE_DAC y acceso WRITE_OWNER.
STANDARD_RIGHTS_ALL Combina el acceso DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER y SYNCHRONIZE. Sin embargo, el valor SYNCHRONIZE no es aplicable a los objetos de token. Por lo tanto, STANDARD_RIGHTS_ALL tiene un equivalente funcional a STANDARD_RIGHTS_REQUIRED.
TOKEN_ADJUST_DEFAULT Necesario para cambiar el propietario predeterminado, el grupo principal o la DACL de un token de acceso.
TOKEN_ADJUST_GROUPS Se requiere para ajustar los atributos de los grupos en un token de acceso.
TOKEN_ADJUST_PRIVILEGES Se requiere para habilitar o deshabilitar los privilegios en un token de acceso.
TOKEN_ADJUST_SESSIONID Necesario para ajustar el identificador de sesión (SID) de un token de acceso. El sistema operativo concede este derecho al nuevo token solo si el SE_TCB_NAME privilegio está habilitado en el token de acceso del subproceso que realiza la llamada.
TOKEN_ASSIGN_PRIMARY Necesario para adjuntar un token principal a un proceso. El sistema operativo concede este derecho al nuevo token solo si el SE_ASSIGNPRIMARYTOKEN_NAME privilegio está habilitado en el token de acceso del subproceso que realiza la llamada.
TOKEN_DUPLICATE Necesario para duplicar un token de acceso. Tenga en cuenta que el token ExistingTokenHandle especificado debe contener este derecho para poder usar correctamente esta rutina.
TOKEN_EXECUTE Combina STANDARD_RIGHTS_EXECUTE y TOKEN_IMPERSONATE.
TOKEN_IMPERSONATE Necesario para adjuntar un token de acceso de suplantación a un proceso.
TOKEN_QUERY Necesario para consultar un token de acceso.
TOKEN_QUERY_SOURCE Necesario para consultar el origen de un token de acceso.
TOKEN_READ Combina STANDARD_RIGHTS_READ y TOKEN_QUERY.
TOKEN_WRITE Combina STANDARD_RIGHTS_WRITE, TOKEN_ADJUST_PRIVILEGES, TOKEN_ADJUST_GROUPS y TOKEN_ADJUST_DEFAULT.
TOKEN_ALL_ACCESS Combina todos los permisos de acceso de token posibles para un token.

Para obtener más información, vea Derechos de acceso para objetos Access-Token. Tenga en cuenta que los tokens de acceso no admiten el derecho SYNCHRONIZE.

[in] ObjectAttributes

Puntero a una estructura de OBJECT_ATTRIBUTES que describe las propiedades solicitadas para el nuevo token. El parámetro ObjectAttributes es opcional y puede ser NULL. Si el parámetro ObjectAttributes es NULL o si el miembro SecurityDescriptor de la estructura a la que apunta el parámetro ObjectAttributes es NULL, el nuevo token recibe un descriptor de seguridad predeterminado y el nuevo identificador de token no se puede heredar. En ese caso, este descriptor de seguridad predeterminado se crea a partir del grupo de usuarios, el grupo principal y la información de DACL que se almacena en el token del autor de la llamada.

Cuando el parámetro TokenType se establece en TokenImpersonation:

  • El parámetro ObjectAttributes se puede usar para especificar el nivel de suplantación del nuevo token. Esto se puede lograr estableciendo ObjectAttributes-SecurityQualityOfService.ImpersonationLevel >en un valor de enumeración SECURITY_IMPERSONATION_LEVEL adecuado. Para obtener más información, consulte SECURITY_QUALITY_OF_SERVICE.
  • Si el token existente es un token de suplantación y el parámetro ObjectAttributes no proporciona información de suplantación, el nivel de suplantación del nuevo token se establece en el nivel de suplantación del token existente.
  • Si el token existente es un token principal y no se proporciona información de nivel de suplantación, el nuevo token de suplantación tendrá un nivel de suplantación SECURITY_IMPERSONATION_LEVEL .

[in] EffectiveOnly

Valor booleano que indica si todo el token existente debe duplicarse en el nuevo token o solo en la parte efectiva (actualmente habilitada) del token. Si se establece en TRUE, solo se duplicarán las partes habilitadas actualmente del token de origen. Si se establece en FALSE, se duplicará todo el token existente. Esto proporciona un medio para que un autor de llamada de un subsistema protegido limite los grupos y privilegios opcionales que están disponibles para el subsistema protegido. Por ejemplo, si EffectiveOnly es TRUE, el autor de la llamada podría duplicar un token, pero quitar el grupo Administradores y el derecho SeTcbPrivilege. El token resultante podría pasarse a un proceso secundario (CreateProcessAsUser), lo que restringiría lo que puede hacer el proceso secundario. Este parámetro es obligatorio.

[in] TokenType

Especifica uno de los siguientes valores de la enumeración TOKEN_TYPE .

Valor Significado
TokenPrimary El nuevo token es un token principal. Si el token existente es un token de suplantación, el token de suplantación existente debe tener un nivel de suplantación (según lo proporcionado por el parámetro ObjectAttributes ) de SecurityImpersonation o SecurityDelegation. De lo contrario, NtDuplicateToken devuelve STATUS_BAD_IMPERSONATION_LEVEL.
TokenImpersonation El nuevo token es un token de suplantación. Si el token existente es un token de suplantación, el nivel de suplantación solicitado (según lo proporcionado por el parámetro ObjectAttributes ) del nuevo token no debe ser mayor que el nivel de suplantación del token existente. De lo contrario, NtDuplicateToken devuelve STATUS_BAD_IMPERSONATION_LEVEL.

El parámetro TokenType es necesario y no puede ser NULL.

[out] NewTokenHandle

Puntero a una variable asignada por el autor de la llamada, de tipo HANDLE, que recibe un identificador para el nuevo token. Este parámetro es obligatorio y no puede ser NULL.

Valor devuelto

NtDuplicateToken devuelve STATUS_SUCCESS si la llamada es correcta. Entre los posibles códigos de retorno de error se incluyen los siguientes:

Código devuelto Descripción
STATUS_ACCESS_VIOLATION Se ha producido una infracción de acceso a la memoria. Por ejemplo, si el modo anterior era modo de usuario y se proporcionó memoria en modo de usuario no válida, NtDuplicateToken devuelve STATUS_ACCESS_VIOLATION.
STATUS_INSUFFICIENT_RESOURCES No se pudo asignar memoria suficiente para duplicar el nuevo token.
STATUS_INVALID_PARAMETER Se ha detectado un parámetro no válido.
STATUS_BAD_IMPERSONATION_LEVEL El nivel de suplantación solicitado para el nuevo token es mayor que el nivel de suplantación del token existente.
STATUS_ACCESS_DENIED NtDuplicateToken no pudo acceder a ExistingTokenHandle. Esto ocurriría si el token existente no tiene el derecho de acceso TOKEN_DUPLICATE.
STATUS_INVALID_HANDLE ExistingTokenHandle hace referencia a un identificador no válido.

Comentarios

Si el parámetro ObjectAttributes no proporcionó información de nivel de suplantación, el nivel de suplantación del token existente se usará para el nuevo token.

Con respecto a la estructura a la que apunta el parámetro ObjectAttributes opcional, el miembro SecurityQualityOfService de OBJECT_ATTRIBUTES apunta a una estructura de tipo SECURITY_QUALITY_OF_SERVICE. Consulte SECURITY_QUALITY_OF_SERVICE para obtener información sobre los miembros de esta estructura.

El miembro SecurityQualityOfService debe establecerse después de llamar a la macro InitializeObjectAttributes porque InitializeObjectAttributes establece actualmente SecurityQualityOfService en NULL.

Para obtener información sobre la analogía en modo de usuario de NtDuplicateToken, consulte DuplicateTokenEx en la documentación de Windows SDK.

Cuando haya terminado de usar el nuevo token, llame a la función NtClose para cerrar el identificador del token.

Si la llamada a la función NtDuplicateToken se produce en modo de usuario, debe usar el nombre "NtDuplicateToken" en lugar de "NtDuplicateToken".

En el caso de las llamadas desde controladores en modo kernel, las versiones NtXxx y ZwXxx de una rutina de Servicios del sistema nativo de Windows se pueden comportar de forma diferente en la forma en que controlan e interpretan los parámetros de entrada. Para obtener más información sobre la relación entre las versiones NtXxx y ZwXxx de una rutina, vea Using Nt and Zw Versions of the Native System Services Routines.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 2000
Plataforma de destino Universal
Encabezado ntifs.h (incluya Ntifs.h, FltKernel.h)
Library NtosKrnl.lib
Archivo DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
Reglas de cumplimiento de DDI HwStorPortProhibitedDIs, PowerIrpDDis

Consulte también

ACCESS_MASK

InitializeObjectAttributes

OBJECT_ATTRIBUTES

SECURITY_IMPERSONATION_LEVEL