257 lines
4.9 KiB
C++
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 ] );
|
|
|
|
}
|