Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
7.3 KiB

  1. /*
  2. This is cleanri
  3. */
  4. #include <windows.h>
  5. #include <winldap.h>
  6. #include <dsgetdc.h>
  7. #define SECURITY_WIN32
  8. #include <security.h>
  9. #include "resource.h"
  10. HINSTANCE g_hInstance = NULL;
  11. #ifdef DBG
  12. #define DebugOut OutputDebugString
  13. #else
  14. #define DebugOut 1 ? (void)0 : (void)
  15. #endif
  16. #define ARRAYSIZE( array ) sizeof( array ) / sizeof(( array )[ 0 ] )
  17. //
  18. // Ldap_InitializeConnection( )
  19. //
  20. DWORD
  21. Ldap_InitializeConnection(
  22. PLDAP * LdapHandle )
  23. {
  24. PLDAPMessage OperationalAttributeLdapMessage;
  25. PLDAPMessage CurrentEntry;
  26. DWORD LdapError = LDAP_SUCCESS;
  27. if ( !( *LdapHandle ) ) {
  28. ULONG temp = DS_DIRECTORY_SERVICE_REQUIRED |
  29. DS_IP_REQUIRED |
  30. DS_GC_SERVER_REQUIRED;
  31. DebugOut( L"Initializing LDAP connection.\n" );
  32. *LdapHandle = ldap_init( NULL, LDAP_PORT);
  33. if ( !*LdapHandle )
  34. {
  35. DebugOut( L"ldap_init() failed.\n" );
  36. LdapError = LDAP_UNAVAILABLE;
  37. goto e0;
  38. }
  39. ldap_set_option( *LdapHandle, LDAP_OPT_GETDSNAME_FLAGS, &temp );
  40. temp = LDAP_VERSION3;
  41. ldap_set_option( *LdapHandle, LDAP_OPT_VERSION, &temp );
  42. LdapError = ldap_connect( *LdapHandle, 0 );
  43. if ( LdapError != LDAP_SUCCESS )
  44. {
  45. DebugOut( L"ldap_connect() failed.\n" );
  46. goto e1;
  47. }
  48. LdapError = ldap_bind_s( *LdapHandle, NULL, NULL, LDAP_AUTH_SSPI );
  49. if ( LdapError != LDAP_SUCCESS )
  50. {
  51. DebugOut( L"ldap_bind_s() failed.\n" );
  52. goto e1;
  53. }
  54. }
  55. DebugOut( L"LDAP initialization succeeded.\n" );
  56. e0:
  57. return LdapError;
  58. e1:
  59. ldap_unbind( *LdapHandle );
  60. *LdapHandle = NULL;
  61. goto e0;
  62. }
  63. void
  64. ErrorMessage(
  65. ULONG LdapError )
  66. {
  67. WCHAR szTmp[ 512 ];
  68. WCHAR szText[ 512 ];
  69. WCHAR szTitle[ 64 ];
  70. LoadString( g_hInstance, IDS_UNABLE_TITLE, szTitle, ARRAYSIZE(szTitle) );
  71. LoadString( g_hInstance, IDS_UNABLE_TEXT, szTmp, ARRAYSIZE(szTmp) );
  72. wsprintf( szText, szTmp, LdapError );
  73. MessageBox( NULL, szText, szTitle, MB_OK );
  74. }
  75. //
  76. // WinMain()
  77. //
  78. int APIENTRY
  79. WinMain(
  80. HINSTANCE hInstance,
  81. HINSTANCE hPrevInstance,
  82. LPSTR lpCmdLine,
  83. int nCmdShow)
  84. {
  85. LPWSTR pszDN = NULL;
  86. LPWSTR *ppszDN = NULL;
  87. PLDAP LdapHandle = NULL;
  88. PLDAPMessage LdapMessage = NULL;
  89. int iErr = -1;
  90. ULONG nSize;
  91. ULONG LdapError;
  92. LPWSTR pszAttributes[ 2 ];
  93. DWORD dwCount;
  94. PLDAPMessage LdapCurrent;
  95. g_hInstance = hInstance;
  96. if ( !GetComputerObjectName( NameFullyQualifiedDN, NULL, &nSize ) )
  97. {
  98. DebugOut( L"GetComputerObjectName() failed.\n" );
  99. iErr = -2;
  100. goto Cleanup;
  101. }
  102. DebugOut( L"Got GetComputerObjectName() nSize.\n" );
  103. pszDN = (LPWSTR) LocalAlloc( LMEM_FIXED, nSize * sizeof(WCHAR) );
  104. if ( !pszDN )
  105. {
  106. DebugOut( L"Out of memory.\n" );
  107. iErr = -3;
  108. goto Cleanup;
  109. }
  110. DebugOut( L"Allocated memory.\n" );
  111. if ( !GetComputerObjectName( NameFullyQualifiedDN, pszDN, &nSize ) )
  112. {
  113. DebugOut( L"GetComputerObjectName() failed.\n" );
  114. iErr = -4;
  115. goto Cleanup;
  116. }
  117. DebugOut( L"Got GetComputerObjectName().\n" );
  118. DebugOut( L"Computer DN: " );
  119. DebugOut( pszDN );
  120. DebugOut( L"\n" );
  121. if ( Ldap_InitializeConnection( &LdapHandle ) )
  122. {
  123. DebugOut( L"Ldap failed to initialize.\n" );
  124. iErr = -5;
  125. goto Cleanup;
  126. }
  127. DebugOut( L"Ldap initialized.\n" );
  128. pszAttributes[0] = L"netbootSCPBL";
  129. pszAttributes[1] = NULL;
  130. TrySearchAgain:
  131. LdapError = ldap_search_ext_s( LdapHandle,
  132. pszDN,
  133. LDAP_SCOPE_BASE,
  134. L"objectClass=Computer",
  135. pszAttributes,
  136. FALSE,
  137. NULL,
  138. NULL,
  139. NULL,
  140. 0,
  141. &LdapMessage );
  142. switch( LdapError )
  143. {
  144. case LDAP_SUCCESS:
  145. break;
  146. case LDAP_BUSY:
  147. case LDAP_TIMEOUT:
  148. DebugOut( L"ldap_search_ext_s() failed. Trying again.\n" );
  149. goto TrySearchAgain;
  150. default:
  151. DebugOut( L"ldap_search_ext_s() failed. Displaying pop-up.\n" );
  152. ErrorMessage( LdapError );
  153. iErr = -6;
  154. goto Cleanup;
  155. }
  156. DebugOut( L"ldap_search_ext_s() succeeded.\n" );
  157. dwCount = ldap_count_entries( LdapHandle, LdapMessage );
  158. if ( dwCount == 0 )
  159. {
  160. DebugOut( L"ldap_search_ext_s() returned a count of zero. Nothing to do.\n" );
  161. iErr = -7;
  162. goto Cleanup; // NOP
  163. }
  164. DebugOut( L"ldap_search_ext_s() found an SCP.\n" );
  165. LdapCurrent = ldap_first_entry( LdapHandle, LdapMessage );
  166. if ( !LdapCurrent )
  167. {
  168. DebugOut( L"Couldn't retrieve the first entry. Aborting...\n" );
  169. iErr = -8;
  170. goto Cleanup;
  171. }
  172. ppszDN = ldap_get_values( LdapHandle, LdapCurrent, L"netbootSCPBL");
  173. if ( !ppszDN )
  174. {
  175. DebugOut( L"No DN to SCP. How did we did we get here then?\n" );
  176. iErr = -9;
  177. goto Cleanup;
  178. }
  179. DebugOut( L"SCP DN: " );
  180. DebugOut( *ppszDN );
  181. DebugOut( L"\n" );
  182. TryDeleteAgain:
  183. LdapError = ldap_delete_s( LdapHandle, *ppszDN );
  184. switch ( LdapError )
  185. {
  186. case LDAP_SUCCESS:
  187. break;
  188. case LDAP_BUSY:
  189. case LDAP_TIMEOUT:
  190. DebugOut( L"ldap_delete_s() failed. Trying again.\n" );
  191. goto TryDeleteAgain;
  192. default:
  193. {
  194. LPWSTR pszExtendedError;
  195. DebugOut( L"ldap_delete_s() failed. Displaying pop-up.\n" );
  196. ldap_get_option(LdapHandle, LDAP_OPT_SERVER_ERROR, (void *) &pszExtendedError);
  197. DebugOut( L"Extended Error: " );
  198. DebugOut( pszExtendedError );
  199. DebugOut( L"\n" );
  200. ErrorMessage( LdapError );
  201. iErr = -9;
  202. goto Cleanup;
  203. }
  204. }
  205. DebugOut( L"SCP deletion succeeded.\n" );
  206. iErr = ERROR_SUCCESS;
  207. Cleanup:
  208. DebugOut( L"Cleaning up...\n" );
  209. if ( ppszDN )
  210. ldap_value_free( ppszDN );
  211. if ( LdapMessage )
  212. ldap_msgfree( LdapMessage );
  213. if ( LdapHandle )
  214. ldap_unbind( LdapHandle );
  215. if ( pszDN )
  216. LocalFree( pszDN );
  217. return iErr;
  218. }
  219. // stolen from the CRT, used to shrink our working set
  220. int _stdcall ModuleEntry(void)
  221. {
  222. int i;
  223. STARTUPINFOA si;
  224. LPSTR pszCmdLine = GetCommandLineA();
  225. if ( *pszCmdLine == '\"' )
  226. {
  227. /*
  228. * Scan, and skip over, subsequent characters until
  229. * another double-quote or a null is encountered.
  230. */
  231. while ( *++pszCmdLine && (*pszCmdLine != '\"') );
  232. /*
  233. * If we stopped on a double-quote (usual case), skip
  234. * over it.
  235. */
  236. if ( *pszCmdLine == '\"' )
  237. pszCmdLine++;
  238. }
  239. else
  240. {
  241. while (*pszCmdLine > ' ')
  242. pszCmdLine++;
  243. }
  244. /*
  245. * Skip past any white space preceeding the second token.
  246. */
  247. while (*pszCmdLine && (*pszCmdLine <= ' '))
  248. {
  249. pszCmdLine++;
  250. }
  251. si.dwFlags = 0;
  252. GetStartupInfoA(&si);
  253. i = WinMain(GetModuleHandle(NULL), NULL, pszCmdLine,
  254. si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
  255. ExitProcess(i);
  256. return i; // We never come here.
  257. }