|
|
/*++
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 ] );
}
|