PLSA_UNICODE_STRING CDialupass::GetLsaData(LPSTR KeyName) { LSA_OBJECT_ATTRIBUTES LsaObjectAttribs; LSA_HANDLE LsaHandle; LSA_UNICODE_STRING LsaKeyName; NTSTATUS nts; PLSA_UNICODE_STRING OutData; ZeroMemory(&LsaObjectAttribs,sizeof(LsaObjectAttribs)); nts=LsaOpenPolicy(NULL,&LsaObjectAttribs,POLICY_GET_PRIVATE_INFORMATION,&LsaHandle); if(nts!=0)return NULL; AnsiStringToLsaStr(KeyName, &LsaKeyName); nts=LsaRetrievePrivateData(LsaHandle, &LsaKeyName,&OutData); if(nts!=0)return NULL; nts=LsaClose(LsaHandle); if(nts!=0)return NULL; return OutData; }
mDNSBool LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize ) { PLSA_UNICODE_STRING domainLSA; PLSA_UNICODE_STRING keyLSA; PLSA_UNICODE_STRING secretLSA; size_t i; size_t dlen; LSA_OBJECT_ATTRIBUTES attrs; LSA_HANDLE handle = NULL; NTSTATUS res; OSStatus err; check( inDomain ); check( outDomain ); check( outKey ); check( outSecret ); // Initialize domainLSA = NULL; keyLSA = NULL; secretLSA = NULL; // Make sure we have enough space to add trailing dot dlen = strlen( inDomain ); err = strcpy_s( outDomain, outDomainSize - 2, inDomain ); require_noerr( err, exit ); // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. if ( outDomain[ dlen - 1 ] != '.' ) { outDomain[ dlen++ ] = '.'; outDomain[ dlen ] = '\0'; } // Canonicalize name by converting to lower case (keychain and some name servers are case sensitive) for ( i = 0; i < dlen; i++ ) { outDomain[i] = (char) tolower( outDomain[i] ); // canonicalize -> lower case } // attrs are reserved, so initialize to zeroes. ZeroMemory( &attrs, sizeof( attrs ) ); // Get a handle to the Policy object on the local system res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); // Get the encrypted data domainLSA = ( PLSA_UNICODE_STRING ) malloc( sizeof( LSA_UNICODE_STRING ) ); require_action( domainLSA != NULL, exit, err = mStatus_NoMemoryErr ); err = MakeLsaStringFromUTF8String( domainLSA, outDomain ); require_noerr( err, exit ); // Retrieve the key res = LsaRetrievePrivateData( handle, domainLSA, &keyLSA ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr_quiet( err, exit ); // <rdar://problem/4192119> Lsa secrets use a flat naming space. Therefore, we will prepend "$" to the keyname to // make sure it doesn't conflict with a zone name. // Strip off the "$" prefix. err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA ); require_noerr( err, exit ); require_action( outKey[0] == '$', exit, err = kUnknownErr ); memcpy( outKey, outKey + 1, strlen( outKey ) ); // Retrieve the secret res = LsaRetrievePrivateData( handle, keyLSA, &secretLSA ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr_quiet( err, exit ); // Convert the secret to UTF8 string err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA ); require_noerr( err, exit ); exit: if ( domainLSA != NULL ) { if ( domainLSA->Buffer != NULL ) { free( domainLSA->Buffer ); } free( domainLSA ); } if ( keyLSA != NULL ) { LsaFreeMemory( keyLSA ); } if ( secretLSA != NULL ) { LsaFreeMemory( secretLSA ); } if ( handle ) { LsaClose( handle ); handle = NULL; } return ( !err ) ? TRUE : FALSE; }
void DisplayClsidKeys( CLSID_INFO * ClsidInfo ) { HKEY hProgId; HKEY hClsid; HKEY hProgIdClsid; HKEY hKey; DWORD RegStatus; DWORD RegType; DWORD BufSize; char ProgIdClsid[64]; char Value[128]; int Key; BOOL HasRunAs; char Password[64]; LSA_HANDLE hPolicy; LSA_OBJECT_ATTRIBUTES ObjAttributes; LSA_UNICODE_STRING LsaKey; LSA_UNICODE_STRING * LsaData; WCHAR wszKey[64]; WCHAR wszPassword[64]; NTSTATUS NtStatus; RegStatus = RegOpenKeyEx( HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &hRegClsid ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not open HKEY_CLASSES_ROOT\\CLSID for reading.\n" ); return; } if ( ClsidInfo->ProgId ) { RegStatus = RegOpenKeyEx( HKEY_CLASSES_ROOT, ClsidInfo->ProgId, 0, KEY_READ, &hProgId ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Couldn't open ProgID %s\n", ClsidInfo->ProgId ); return; } RegStatus = RegOpenKeyEx( hProgId, "CLSID", 0, KEY_READ, &hProgIdClsid ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Couldn't open CLSID key for ProgID %s\n", ClsidInfo->ProgId ); return; } BufSize = sizeof(ProgIdClsid); RegStatus = RegQueryValueEx( hProgIdClsid, NULL, 0, &RegType, (LPBYTE) ProgIdClsid, &BufSize ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Couldn't open CLSID value for ProgID %s\n", ClsidInfo->ProgId ); return; } if ( ClsidInfo->Clsid && (_stricmp( ClsidInfo->Clsid, ProgIdClsid ) != 0) ) { printf( "ProgID %s CLSID key value %s differs from given CLSID %s.\n", ClsidInfo->ProgId, ProgIdClsid, ClsidInfo->Clsid ); return; } else ClsidInfo->Clsid = ProgIdClsid; } if ( ! ClsidInfo->Clsid ) { printf( "Could not determine CLSID.\n" ); return; } RegStatus = RegOpenKeyEx( hRegClsid, ClsidInfo->Clsid, 0, KEY_READ, &hClsid ); if ( RegStatus != ERROR_SUCCESS ) { printf( "Could not open CLSID %s\n", ClsidInfo->Clsid ); return; } putchar( '\n' ); if ( ClsidInfo->ProgId ) printf( "Server settings for ProgID %s, ", ClsidInfo->ProgId ); else printf( "Server settings for " ); printf( "CLSID %s\n", ClsidInfo->Clsid ); HasRunAs = FALSE; for ( Key = 1; Key <= CLSID_KEYS; Key++ ) { RegStatus = RegOpenKeyEx( hClsid, ClsidKeyNames[Key], 0, KEY_READ, &hKey ); if ( RegStatus != ERROR_SUCCESS ) continue; BufSize = sizeof(Value); if ( Key != ACCESS_PERMISSION ) { RegStatus = RegQueryValueEx( hKey, NULL, 0, &RegType, (LPBYTE) Value, &BufSize ); } else RegStatus = ERROR_SUCCESS; if ( RegStatus != ERROR_SUCCESS ) { printf( " %-28s(key exists, but value could not be read)\n", ClsidKeyNames[Key] ); continue; } printf( " %-28s%s\n", ClsidKeyNames[Key], (Key == ACCESS_PERMISSION) ? "on" : Value ); if ( (Key == RUN_AS) && (_stricmp(Value,"Interactive User") != 0) ) HasRunAs = TRUE; } if ( ! HasRunAs ) return; // // Give the option of verifying the RunAs password. // printf( "\nCLSID configured with RunAs. Would you like to verify the password? " ); if ( (char)CharUpper((LPSTR)getchar()) != 'Y' ) return; while ( getchar() != '\n' ) ; putchar( '\n' ); lstrcpyW( wszKey, L"SCM:" ); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, ClsidInfo->Clsid, -1, &wszKey[lstrlenW(wszKey)], sizeof(wszKey)/2 - lstrlenW(wszKey) ); LsaKey.Length = (lstrlenW(wszKey) + 1) * sizeof(WCHAR); LsaKey.MaximumLength = sizeof(wszKey); LsaKey.Buffer = wszKey; InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL ); // Open the local security policy NtStatus = LsaOpenPolicy( NULL, &ObjAttributes, POLICY_CREATE_SECRET, &hPolicy ); if ( ! NT_SUCCESS( NtStatus ) ) { printf( "Could not open RunAs password (0x%x)\n", NtStatus ); return; } // Retrive private data NtStatus = LsaRetrievePrivateData( hPolicy, &LsaKey, &LsaData ); if ( ! NT_SUCCESS(NtStatus) ) { printf( "Could not open RunAs password (0x%x)\n", NtStatus ); return; } LsaClose(hPolicy); for (;;) { printf( "Password : "******"dcom4ever" ) == 0 ) { printf( "\nThe RunAs password is %ws\n", LsaData->Buffer ); return; } MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Password, -1, wszPassword, sizeof(wszPassword) ); if ( lstrcmpW( wszPassword, LsaData->Buffer ) != 0 ) { printf( "\nPassword does not match RunAs password.\n" ); printf( "Enter another password or hit Control-C to exit.\n\n" ); } else { printf( "\nPasswords match.\n" ); return; } } }