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.

256 lines
4.9 KiB

  1. /*++
  2. MAPUSER.CXX
  3. Copyright (C) 1999 Microsoft Corporation, all rights reserved.
  4. DESCRIPTION: code for MapUser()
  5. Created, May 21, 1999 by DavidCHR.
  6. --*/
  7. #include "everything.hxx"
  8. extern "C" {
  9. #include <malloc.h> // alloca
  10. #include "..\keytab2\keytab\ldlib\delegtools.h"
  11. }
  12. static CHAR AltSecId[] = "AltSecurityIdentities";
  13. static CHAR AltSecPrefix[] = "KERBEROS:";
  14. static CHAR PreQuery[] = "(objectClass=user)"; /* For performance
  15. reasons, we should
  16. query an indexed type */
  17. NTSTATUS
  18. MapUserInDirectory( IN LPWSTR Principal,
  19. IN OPTIONAL LPWSTR Account ) {
  20. LPSTR Attributes[] = { NULL }; // request no attributes
  21. PCHAR PrincValues[] = { NULL, NULL };
  22. LDAPModA TheMod = { LDAP_MOD_DELETE,
  23. AltSecId,
  24. PrincValues };
  25. PLDAPModA Mods[] = { &TheMod, NULL };
  26. CHAR SearchBuffer [ UNLEN + 100 ]; /* The most we could have to
  27. search for is UNLEN (for either
  28. the principalname or the
  29. accountname) + 100 for the
  30. semantics of the query */
  31. NTSTATUS ret = STATUS_INTERNAL_ERROR;
  32. LPSTR ObjectDn;
  33. ULONG lderr;
  34. if ( ( lstrcmpW( Principal, L"*" ) == 0 ) ||
  35. ( Account && ( lstrcmpW( Account, L"*" ) == 0 ) ) ) {
  36. printf( "Wildcard account mappings are not supported"
  37. " at the domain level.\n" );
  38. return STATUS_NOT_SUPPORTED;
  39. }
  40. if ( ConnectedToDsa() ) {
  41. if ( Account ) { // changing the attribute -- search for the account
  42. wsprintfA( SearchBuffer,
  43. "(& %hs (samAccountName=%ws))",
  44. PreQuery,
  45. Account );
  46. } else { // deleting the attribute -- search for the attr
  47. wsprintfA( SearchBuffer,
  48. "(& %hs (%hs=%hs%ws))",
  49. PreQuery,
  50. AltSecId,
  51. AltSecPrefix,
  52. Principal );
  53. }
  54. if ( LdapSearchForUniqueDnA( GlobalLdap,
  55. SearchBuffer,
  56. Attributes,
  57. &ObjectDn,
  58. NULL ) ) {
  59. PrincValues[ 0 ] = (PCHAR) alloca( lstrlenW( Principal ) + 30 );
  60. if ( !PrincValues[ 0 ] ) {
  61. return STATUS_NO_MEMORY; /* NOTE: 73954: This leaks, but the
  62. app terminates immediately afterwards,
  63. so we don't actually care. */
  64. }
  65. wsprintfA( PrincValues[ 0 ],
  66. "%hs%ws",
  67. AltSecPrefix,
  68. Principal );
  69. if ( Account ) {
  70. TheMod.mod_op = LDAP_MOD_ADD;
  71. } else {
  72. TheMod.mod_op = LDAP_MOD_DELETE;
  73. }
  74. lderr = ldap_modify_sA( GlobalLdap,
  75. ObjectDn,
  76. Mods );
  77. // special-case output here:
  78. switch( lderr ) {
  79. case LDAP_SUCCESS:
  80. printf( "Mapping %hs successfully.\n",
  81. Account ? "created" : "deleted" );
  82. ret = STATUS_SUCCESS;
  83. break;
  84. default:
  85. printf( "Failed to %hs %hs on %hs; error 0x%x.\n",
  86. Account ? "set" : "delete",
  87. AltSecId,
  88. ObjectDn,
  89. lderr );
  90. ret = STATUS_UNSUCCESSFUL;
  91. break;
  92. }
  93. free( ObjectDn );
  94. } else {
  95. printf( "Could not locate the account mapping in the directory.\n" );
  96. }
  97. }
  98. return ret;
  99. }
  100. NTSTATUS
  101. MapUserInRegistry( IN LPWSTR Principal,
  102. IN OPTIONAL LPWSTR Account ) {
  103. DWORD RegErr;
  104. HKEY KerbHandle = NULL;
  105. HKEY UserListHandle = NULL;
  106. DWORD Disposition;
  107. RegErr = OpenKerberosKey(&KerbHandle);
  108. if (RegErr)
  109. {
  110. goto Cleanup;
  111. }
  112. RegErr = RegCreateKeyEx(
  113. KerbHandle,
  114. L"UserList",
  115. 0,
  116. NULL,
  117. 0, // no options
  118. KEY_CREATE_SUB_KEY | KEY_SET_VALUE,
  119. NULL,
  120. &UserListHandle,
  121. &Disposition
  122. );
  123. if (RegErr)
  124. {
  125. printf("Failed to create UserList key: %d\n",RegErr);
  126. goto Cleanup;
  127. }
  128. if ( Account && Account[0] ) {
  129. RegErr = RegSetValueEx( UserListHandle,
  130. Principal,
  131. 0,
  132. REG_SZ,
  133. (PBYTE) Account,
  134. (wcslen(Account) + 1) * sizeof(WCHAR)
  135. );
  136. if (RegErr)
  137. {
  138. printf("Failed to set name mapping value: %d\n",RegErr);
  139. goto Cleanup;
  140. }
  141. } else {
  142. /* if no second parameter was supplied,
  143. delete the mapping. */
  144. RegErr = RegDeleteValue( UserListHandle,
  145. Principal );
  146. switch( RegErr ) {
  147. case ERROR_PATH_NOT_FOUND:
  148. case ERROR_FILE_NOT_FOUND:
  149. RegErr = ERROR_SUCCESS;
  150. // fallthrough to success case
  151. case ERROR_SUCCESS:
  152. break;
  153. default:
  154. printf( "Failed to delete mapping for %ws: error 0x%x.\n",
  155. Principal,
  156. RegErr );
  157. goto Cleanup;
  158. }
  159. }
  160. Cleanup:
  161. if (KerbHandle)
  162. {
  163. RegCloseKey(KerbHandle);
  164. }
  165. if (UserListHandle)
  166. {
  167. RegCloseKey(UserListHandle);
  168. }
  169. if (RegErr)
  170. {
  171. return(STATUS_UNSUCCESSFUL);
  172. }
  173. return(STATUS_SUCCESS);
  174. }
  175. NTSTATUS
  176. MapUser( IN LPWSTR * Parameters ) {
  177. return ( GlobalDomainSetting ?
  178. MapUserInDirectory :
  179. MapUserInRegistry )( Parameters[ 0 ],
  180. Parameters[ 1 ] );
  181. }