Leaked source code of windows server 2003
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
6.7 KiB

  1. /*++
  2. SECPRINC.C
  3. Code for setting security principal data in the DS--
  4. specifically, the UPN, SPN, and AltSecurityIdentity
  5. Copyright (C) 1998 Microsoft Corporation, all rights reserved.
  6. Created, Jun 18, 1998 by DavidCHR.
  7. CONTENTS: SetStringProperty
  8. FindUser
  9. SetUserData
  10. --*/
  11. #include "master.h"
  12. #include "keytab.h"
  13. #include <winldap.h>
  14. #include <malloc.h>
  15. #include "secprinc.h"
  16. #include "delegtools.h"
  17. extern BOOL /* delegation.c */
  18. LdapFindAttributeInMessageA( IN PLDAP pLdap,
  19. IN PLDAPMessage pMessage,
  20. IN LPSTR PropertyName,
  21. OUT OPTIONAL PULONG pcbData,
  22. OUT OPTIONAL PVOID *ppvData );
  23. /*****************************************************************
  24. NAME: ConnectToDsa
  25. connects to the DSA, binds, and searches for the base DN.
  26. TAKES: nothing
  27. RETURNS: TRUE ( and a pLdap and wide-string baseDn ) on success
  28. FALSE and a stderr message on failure.
  29. CALLED BY:
  30. FREE WITH: BaseDN should be freed with free(),
  31. the ldap handle should be closed with ldap_unbind.
  32. *****************************************************************/
  33. BOOL
  34. ConnectToDsa( OUT PLDAP *ppLdap,
  35. OUT LPSTR *BaseDN ) { // free with free()
  36. PLDAP pLdap;
  37. BOOL ret = FALSE;
  38. ULONG lderr;
  39. pLdap = ldap_open( NULL, LDAP_PORT );
  40. if ( pLdap ) {
  41. lderr = ldap_bind_s( pLdap, NULL, NULL, LDAP_AUTH_SSPI );
  42. if ( lderr == LDAP_SUCCESS ) {
  43. LPSTR Context = "defaultNamingContext";
  44. LPSTR Attributes[] = { Context, NULL };
  45. PLDAPMessage pMessage, pEntry;
  46. LPSTR *pValue;
  47. // now, guess the DSA Base:
  48. lderr = ldap_search_sA( pLdap,
  49. NULL,
  50. LDAP_SCOPE_BASE,
  51. "objectClass=*",
  52. Attributes,
  53. FALSE, // just return attributes
  54. &pMessage );
  55. if ( lderr == LDAP_SUCCESS ) {
  56. pEntry = ldap_first_entry( pLdap, pMessage );
  57. if ( pEntry ) {
  58. pValue = ldap_get_valuesA( pLdap, pEntry, Context );
  59. if ( pValue ) {
  60. ULONG size;
  61. size = ldap_count_valuesA( pValue );
  62. if ( 1 == size ) {
  63. LPSTR dn;
  64. size = ( lstrlenA( *pValue ) +1 /*null*/) * sizeof( WCHAR );
  65. dn = (LPSTR) malloc( size );
  66. if ( dn ) {
  67. memcpy( dn, *pValue, size );
  68. *BaseDN = dn;
  69. *ppLdap = pLdap;
  70. ret = TRUE;
  71. } else fprintf( stderr,
  72. "failed to malloc to duplicate \"%s\".\n",
  73. *pValue );
  74. } else fprintf( stderr,
  75. "too many values (expected one, got %ld) for"
  76. " %s.\n",
  77. size,
  78. Context );
  79. ldap_value_freeA( pValue );
  80. } else fprintf( stderr,
  81. "ldap_get_values failed: 0x%x.\n",
  82. GetLastError() );
  83. } else fprintf( stderr,
  84. "ldap_first_entry failed: 0x%x.\n",
  85. GetLastError() );
  86. ldap_msgfree( pMessage );
  87. } else fprintf( stderr,
  88. "ldap_search failed (0x%x). "
  89. "Couldn't search for base DN.\n",
  90. lderr );
  91. if ( !ret ) ldap_unbind_s( pLdap );
  92. } else fprintf( stderr,
  93. "Failed to bind to DSA: 0x%x.\n",
  94. lderr );
  95. // there is no ldap_disconnect.
  96. } else fprintf( stderr,
  97. "Failed to contact DSA: 0x%x.\n",
  98. GetLastError() );
  99. return ret;
  100. }
  101. /*++**************************************************************
  102. NAME: SetStringProperty
  103. sets the given property of the given object to the given string
  104. MODIFIES: object's property value
  105. TAKES: pLdap -- ldap connection handle
  106. Dn -- FQDN of the object whose property is munged
  107. PropertyName -- property to modify
  108. Property -- value to put in the property
  109. Operation -- set / add / delete, etc.
  110. RETURNS: TRUE when the function succeeds.
  111. FALSE otherwise.
  112. LASTERROR: set
  113. LOGGING: on failure
  114. CREATED: Jan 22, 1999
  115. LOCKING: none
  116. CALLED BY: anyone
  117. FREE WITH: n/a -- no resources are returned
  118. **************************************************************--*/
  119. BOOL
  120. SetStringProperty( IN PLDAP pLdap,
  121. IN LPSTR Dn,
  122. IN LPSTR PropertyName,
  123. IN LPSTR Property,
  124. IN ULONG Operation ) {
  125. LPSTR Vals[] = { Property, NULL };
  126. LDAPModA Mod = { Operation,
  127. PropertyName,
  128. Vals };
  129. PLDAPModA Mods[] = { &Mod, NULL };
  130. ULONG lderr;
  131. lderr = ldap_modify_sA( pLdap,
  132. Dn,
  133. Mods );
  134. if ( lderr == LDAP_SUCCESS ) {
  135. return TRUE;
  136. } else {
  137. fprintf( stderr,
  138. "Failed to set property \"%hs\" to \"%hs\" on Dn \"%hs\": "
  139. "0x%x.\n",
  140. PropertyName,
  141. Property,
  142. Dn,
  143. lderr );
  144. SetLastError( lderr );
  145. }
  146. return FALSE;
  147. }
  148. /*++**************************************************************
  149. NAME: FindUser
  150. searches the DS for the given user.
  151. MODIFIES: pDn -- returned DN for that user.
  152. puacflags -- receives the user's AccountControl flags
  153. TAKES: pLdap -- LDAP handle
  154. UserName -- user samaccountname for which to search
  155. RETURNS: TRUE when the function succeeds.
  156. FALSE otherwise.
  157. LASTERROR: not explicitly set
  158. LOGGING: on failure
  159. CREATED: Jan 22, 1999
  160. LOCKING: none
  161. CALLED BY: anyone
  162. FREE WITH: free the dn with ldap_memfree
  163. **************************************************************--*/
  164. BOOL
  165. FindUser( IN PLDAP pLdap,
  166. IN LPSTR UserName,
  167. OUT PULONG puacFlags,
  168. OUT LPSTR *pDn ) {
  169. LPSTR Query;
  170. BOOL ret = FALSE;
  171. LPSTR Attributes[] = { "userAccountControl",
  172. NULL }; // what attributes to fetch; none
  173. PLDAPMessage pMessage = NULL;
  174. LPSTR StringUac;
  175. Query = (LPSTR) malloc( lstrlenA( UserName ) + 100 ); // arbitrary
  176. if ( Query ) {
  177. wsprintfA( Query,
  178. "(& (objectClass=person) (samaccountname=%hs))",
  179. UserName );
  180. if( LdapSearchForUniqueDnA( pLdap,
  181. Query,
  182. Attributes,
  183. pDn,
  184. &pMessage ) ) {
  185. if ( LdapFindAttributeInMessageA( pLdap,
  186. pMessage,
  187. Attributes[ 0 ],
  188. NULL, // length doesn't matter
  189. &StringUac ) ) {
  190. *puacFlags = strtoul( StringUac,
  191. NULL,
  192. 0 );
  193. } else {
  194. /* Signal the caller that we don't know the uacflags. */
  195. *puacFlags = 0;
  196. }
  197. ret = TRUE;
  198. } else {
  199. fprintf( stderr,
  200. "Failed to locate user \"%hs\".\n",
  201. Query );
  202. }
  203. if ( pMessage ) ldap_msgfree( pMessage );
  204. free( Query );
  205. } else {
  206. fprintf( stderr,
  207. "allocation failed building query for LDAP search.\n" );
  208. }
  209. return ret;
  210. }