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.

200 lines
4.8 KiB

  1. #ifdef USE_STDAFX
  2. #include "stdafx.h"
  3. #else
  4. #include <Windows.h>
  5. #endif
  6. #include <memory>
  7. #include <string.h>
  8. #include <ComDef.h>
  9. #include "Common.hpp"
  10. #include "ErrDct.hpp"
  11. extern TErrorDct err;
  12. //---------------------------------------------------------------------------
  13. // StripSamName Function
  14. //
  15. // Replaces invalid SAM account name characters with a replacement character.
  16. //---------------------------------------------------------------------------
  17. void StripSamName(WCHAR* pszName)
  18. {
  19. // invalid punctuation characters in any position
  20. const WCHAR INVALID_CHARACTERS_ABC[] = L"\"*+,/:;<=>?[\\]|";
  21. // invalid punctuation characters only in last position
  22. const WCHAR INVALID_CHARACTERS_C[] = L".";
  23. // replacement character
  24. const WCHAR REPLACEMENT_CHARACTER = L'_';
  25. // if name specified...
  26. if (pszName)
  27. {
  28. size_t cchName = wcslen(pszName);
  29. // if length of name is valid...
  30. if ((cchName > 0) && (cchName < MAX_PATH))
  31. {
  32. bool bChanged = false;
  33. // save old name
  34. WCHAR szOldName[MAX_PATH];
  35. wcscpy(szOldName, pszName);
  36. // get character type information
  37. WORD wTypes[MAX_PATH];
  38. GetStringTypeEx(LOCALE_SYSTEM_DEFAULT, CT_CTYPE1, pszName, cchName, wTypes);
  39. // for each character in name...
  40. for (size_t ich = 0; ich < cchName; ich++)
  41. {
  42. bool bReplace = false;
  43. WORD wType = wTypes[ich];
  44. // if character is of specified type...
  45. if ((wType == 0) || (wType & C1_CNTRL))
  46. {
  47. // replace un-classified or control type
  48. bReplace = true;
  49. }
  50. // Note: Windows 2000 & Windows XP allows space characters as first or last character
  51. // else if (wType & (C1_BLANK|C1_SPACE))
  52. // {
  53. // blank or space type
  54. // if first or last character...
  55. // if ((ich == 0) || (ich == (cchName - 1)))
  56. // {
  57. // then replace
  58. // bReplace = true;
  59. // }
  60. // }
  61. else if (wType & C1_PUNCT)
  62. {
  63. // punctuation type
  64. // if invalid punctuation character in any position...
  65. if (wcschr(INVALID_CHARACTERS_ABC, pszName[ich]))
  66. {
  67. // then replace
  68. bReplace = true;
  69. }
  70. else
  71. {
  72. // otherwise if invalid punctuation character in last position...
  73. if ((ich == (cchName - 1)) && wcschr(INVALID_CHARACTERS_C, pszName[ich]))
  74. {
  75. // then replace
  76. bReplace = true;
  77. }
  78. }
  79. }
  80. else
  81. {
  82. // alphabetic, digit and variations are valid types
  83. }
  84. // if replacement indicated...
  85. if (bReplace)
  86. {
  87. // then replace invalid character with replacement
  88. // character and set name changed to true
  89. pszName[ich] = REPLACEMENT_CHARACTER;
  90. bChanged = true;
  91. }
  92. }
  93. // if name has changed...
  94. if (bChanged)
  95. {
  96. // log name change
  97. err.MsgWrite(ErrW, DCT_MSG_SAMNAME_CHANGED_SS, szOldName, pszName);
  98. }
  99. }
  100. }
  101. }
  102. //---------------------------------------------------------------------------
  103. // GetDomainDNSFromPath Function
  104. //
  105. // Generates a domain DNS name from a distinguished name or ADsPath.
  106. //---------------------------------------------------------------------------
  107. _bstr_t GetDomainDNSFromPath(_bstr_t strPath)
  108. {
  109. static wchar_t s_szDnDelimiter[] = L",";
  110. static wchar_t s_szDcPrefix[] = L"DC=";
  111. static wchar_t s_szDnsDelimiter[] = L".";
  112. #define DC_PREFIX_LENGTH (sizeof(s_szDcPrefix) / sizeof(s_szDcPrefix[0]) - 1)
  113. std::auto_ptr<wchar_t> apDNS;
  114. // if non empty path...
  115. if (strPath.length() > 0)
  116. {
  117. // allocate buffer for DNS name
  118. apDNS = std::auto_ptr<wchar_t>(new wchar_t[strPath.length() + 1]);
  119. // allocate temporary buffer for path
  120. std::auto_ptr<wchar_t> apPath(new wchar_t[strPath.length() + 1]);
  121. // if allocations succeeded...
  122. if ((apDNS.get() != 0) && (apPath.get() != 0))
  123. {
  124. // initialize DNS name to empty
  125. *apDNS = L'\0';
  126. // copy path to temporary buffer
  127. wcscpy(apPath.get(), strPath);
  128. // then for each component in path...
  129. //
  130. // Note: if any path components contain the path delimiter character they will be skipped as
  131. // they wont begin with domain component prefix. The domain component prefix contains
  132. // a special character that must be escaped if part of path component name.
  133. for (wchar_t* pszDC = wcstok(apPath.get(), s_szDnDelimiter); pszDC; pszDC = wcstok(0, s_szDnDelimiter))
  134. {
  135. // if domain component...
  136. if (_wcsnicmp(pszDC, s_szDcPrefix, DC_PREFIX_LENGTH) == 0)
  137. {
  138. //
  139. // then concatenate to DNS name
  140. //
  141. // if not first component...
  142. if (*apDNS)
  143. {
  144. // then append delimiter
  145. wcscat(apDNS.get(), s_szDnsDelimiter);
  146. }
  147. // append domain component name without type prefix
  148. wcscat(apDNS.get(), pszDC + DC_PREFIX_LENGTH);
  149. }
  150. }
  151. }
  152. }
  153. return apDNS.get();
  154. }