windows-nt/Source/XPSP1/NT/ds/security/tools/ksetup/mapuser.cxx
2020-09-26 16:20:57 +08:00

257 lines
4.9 KiB
C++

/*++
MAPUSER.CXX
Copyright (C) 1999 Microsoft Corporation, all rights reserved.
DESCRIPTION: code for MapUser()
Created, May 21, 1999 by DavidCHR.
--*/
#include "everything.hxx"
extern "C" {
#include <malloc.h> // alloca
#include "..\keytab2\keytab\ldlib\delegtools.h"
}
static CHAR AltSecId[] = "AltSecurityIdentities";
static CHAR AltSecPrefix[] = "KERBEROS:";
static CHAR PreQuery[] = "(objectClass=user)"; /* For performance
reasons, we should
query an indexed type */
NTSTATUS
MapUserInDirectory( IN LPWSTR Principal,
IN OPTIONAL LPWSTR Account ) {
LPSTR Attributes[] = { NULL }; // request no attributes
PCHAR PrincValues[] = { NULL, NULL };
LDAPModA TheMod = { LDAP_MOD_DELETE,
AltSecId,
PrincValues };
PLDAPModA Mods[] = { &TheMod, NULL };
CHAR SearchBuffer [ UNLEN + 100 ]; /* The most we could have to
search for is UNLEN (for either
the principalname or the
accountname) + 100 for the
semantics of the query */
NTSTATUS ret = STATUS_INTERNAL_ERROR;
LPSTR ObjectDn;
ULONG lderr;
if ( ( lstrcmpW( Principal, L"*" ) == 0 ) ||
( Account && ( lstrcmpW( Account, L"*" ) == 0 ) ) ) {
printf( "Wildcard account mappings are not supported"
" at the domain level.\n" );
return STATUS_NOT_SUPPORTED;
}
if ( ConnectedToDsa() ) {
if ( Account ) { // changing the attribute -- search for the account
wsprintfA( SearchBuffer,
"(& %hs (samAccountName=%ws))",
PreQuery,
Account );
} else { // deleting the attribute -- search for the attr
wsprintfA( SearchBuffer,
"(& %hs (%hs=%hs%ws))",
PreQuery,
AltSecId,
AltSecPrefix,
Principal );
}
if ( LdapSearchForUniqueDnA( GlobalLdap,
SearchBuffer,
Attributes,
&ObjectDn,
NULL ) ) {
PrincValues[ 0 ] = (PCHAR) alloca( lstrlenW( Principal ) + 30 );
if ( !PrincValues[ 0 ] ) {
return STATUS_NO_MEMORY; /* NOTE: 73954: This leaks, but the
app terminates immediately afterwards,
so we don't actually care. */
}
wsprintfA( PrincValues[ 0 ],
"%hs%ws",
AltSecPrefix,
Principal );
if ( Account ) {
TheMod.mod_op = LDAP_MOD_ADD;
} else {
TheMod.mod_op = LDAP_MOD_DELETE;
}
lderr = ldap_modify_sA( GlobalLdap,
ObjectDn,
Mods );
// special-case output here:
switch( lderr ) {
case LDAP_SUCCESS:
printf( "Mapping %hs successfully.\n",
Account ? "created" : "deleted" );
ret = STATUS_SUCCESS;
break;
default:
printf( "Failed to %hs %hs on %hs; error 0x%x.\n",
Account ? "set" : "delete",
AltSecId,
ObjectDn,
lderr );
ret = STATUS_UNSUCCESSFUL;
break;
}
free( ObjectDn );
} else {
printf( "Could not locate the account mapping in the directory.\n" );
}
}
return ret;
}
NTSTATUS
MapUserInRegistry( IN LPWSTR Principal,
IN OPTIONAL LPWSTR Account ) {
DWORD RegErr;
HKEY KerbHandle = NULL;
HKEY UserListHandle = NULL;
DWORD Disposition;
RegErr = OpenKerberosKey(&KerbHandle);
if (RegErr)
{
goto Cleanup;
}
RegErr = RegCreateKeyEx(
KerbHandle,
L"UserList",
0,
NULL,
0, // no options
KEY_CREATE_SUB_KEY | KEY_SET_VALUE,
NULL,
&UserListHandle,
&Disposition
);
if (RegErr)
{
printf("Failed to create UserList key: %d\n",RegErr);
goto Cleanup;
}
if ( Account && Account[0] ) {
RegErr = RegSetValueEx( UserListHandle,
Principal,
0,
REG_SZ,
(PBYTE) Account,
(wcslen(Account) + 1) * sizeof(WCHAR)
);
if (RegErr)
{
printf("Failed to set name mapping value: %d\n",RegErr);
goto Cleanup;
}
} else {
/* if no second parameter was supplied,
delete the mapping. */
RegErr = RegDeleteValue( UserListHandle,
Principal );
switch( RegErr ) {
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
RegErr = ERROR_SUCCESS;
// fallthrough to success case
case ERROR_SUCCESS:
break;
default:
printf( "Failed to delete mapping for %ws: error 0x%x.\n",
Principal,
RegErr );
goto Cleanup;
}
}
Cleanup:
if (KerbHandle)
{
RegCloseKey(KerbHandle);
}
if (UserListHandle)
{
RegCloseKey(UserListHandle);
}
if (RegErr)
{
return(STATUS_UNSUCCESSFUL);
}
return(STATUS_SUCCESS);
}
NTSTATUS
MapUser( IN LPWSTR * Parameters ) {
return ( GlobalDomainSetting ?
MapUserInDirectory :
MapUserInRegistry )( Parameters[ 0 ],
Parameters[ 1 ] );
}