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.

336 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1989-91 Microsoft Corporation
  3. Module Name:
  4. namecan.c
  5. Abstract:
  6. Net name canonicalization routines:
  7. NetpwNameCanonicalize
  8. Author:
  9. Richard L Firth (rfirth) 06-Jan-1992
  10. Chandana Surlu (chandans) 19-Dec-1979 Modified to use this util on WIN9x
  11. Revision History:
  12. --*/
  13. #ifdef WIN32_CHICAGO
  14. // yes, this is strange, but all internal data for DsGetDcname are maintained
  15. // in unicode but we don't define UNICODE globally. Therefore, this hack
  16. // -ChandanS
  17. #define UNICODE 1
  18. #endif // WIN32_CHICAGO
  19. #include "nticanon.h"
  20. #include <netlibnt.h> // NetpNtStatusToApiStatus
  21. //
  22. // data
  23. //
  24. static TCHAR szShareTrailChars[] = TEXT(". ");
  25. //
  26. // functions
  27. //
  28. NET_API_STATUS
  29. NetpwNameCanonicalize(
  30. IN LPTSTR Name,
  31. OUT LPTSTR Outbuf,
  32. IN DWORD OutbufLen,
  33. IN DWORD NameType,
  34. IN DWORD Flags
  35. )
  36. /*++
  37. Routine Description:
  38. NetpwNameCanonicalize converts a LANMAN object name to canonical
  39. form. In the current implementation, that simply means converting
  40. the name to upper case (except for passwords).
  41. This function supports canonicalization in place because in the
  42. current world, canonicalization just consists of convert a name to
  43. upper case. If in the future canonicalization becomes more
  44. sophisticated, this function will have to allocate a buffer
  45. internally to allow it to do canonicalization.
  46. Arguments:
  47. Name - The name to canonicalize.
  48. Outbuf - The place to store the canonicalized version of the name.
  49. Note that if <Name> and <Outbuf> are the same it will
  50. canonicalize the name in place.
  51. OutbufLen - The size, in bytes, of <Outbuf>.
  52. NameType - The type of the LANMAN object names. Valid values are
  53. specified by NAMETYPE_* manifests in NET\H\ICANON.H.
  54. Flags - Flags to determine operation. Currently defined values are:
  55. CrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrL
  56. where:
  57. C = LM2.x compatible name canonicalization
  58. r = Reserved. MBZ.
  59. L = If set, the function requires the length of the output
  60. buffer to be sufficient to hold any name of the specified
  61. type (e.g. CNLEN+1 if the name type is NAMETYPE_COMPUTER).
  62. Otherwise, the buffer length only needs to be large
  63. enough to hold the canonicalized version of the input
  64. name specified in this invocation of the function (e.g.
  65. 5, if the canonicalized name is "TEST").
  66. Return Value:
  67. NET_API_STATUS
  68. Success - NERR_Success
  69. Failure - ERROR_INVALID_PARAMETER
  70. Flags has a reserved bit on
  71. ERROR_INVALID_NAME
  72. Supplied name cannot be successfully canonicalized
  73. NERR_BufTooSmall
  74. Caller's output buffer not large enough to hold canonicalized
  75. name, or maximum canonicalized name for type if L bit on in
  76. Flags
  77. --*/
  78. {
  79. NET_API_STATUS RetVal = 0;
  80. DWORD NameLen;
  81. DWORD MaxNameLen;
  82. BOOL UpperCase = FALSE; // default for NT names
  83. #ifdef CANONDBG
  84. DbgPrint("NetpwNameCanonicalize\n");
  85. #endif
  86. //
  87. // Parameter validation
  88. //
  89. if (Flags & INNCA_FLAGS_RESERVED) {
  90. return ERROR_INVALID_PARAMETER;
  91. }
  92. //
  93. // Compute the length of the string
  94. //
  95. // Note that share names need special handling, because trailing
  96. // dots and spaces are not significant.
  97. //
  98. #ifndef WIN32_CHICAGO
  99. if (NameType == NAMETYPE_SHARE) {
  100. NameLen = (DWORD)(strtail(Name, szShareTrailChars) - Name);
  101. } else {
  102. NameLen = STRLEN(Name);
  103. }
  104. #else
  105. NameLen = STRLEN(Name);
  106. #endif // WIN32_CHICAGO
  107. RetVal = NetpwNameValidate(Name, NameType, 0L);
  108. if (RetVal) {
  109. return RetVal;
  110. }
  111. //
  112. // Determine the size of the buffer needed and whether or not to
  113. // upper case the name.
  114. //
  115. switch (NameType) {
  116. case NAMETYPE_USER:
  117. if (Flags & LM2X_COMPATIBLE) {
  118. MaxNameLen = LM20_UNLEN;
  119. UpperCase = TRUE;
  120. } else {
  121. MaxNameLen = UNLEN;
  122. }
  123. break;
  124. case NAMETYPE_GROUP:
  125. if (Flags & LM2X_COMPATIBLE) {
  126. MaxNameLen = LM20_GNLEN;
  127. UpperCase = TRUE;
  128. } else {
  129. MaxNameLen = GNLEN;
  130. }
  131. break;
  132. case NAMETYPE_COMPUTER:
  133. if (Flags & LM2X_COMPATIBLE) {
  134. MaxNameLen = LM20_CNLEN;
  135. UpperCase = TRUE;
  136. } else {
  137. MaxNameLen = MAX_PATH-1; // allow for null
  138. }
  139. break;
  140. case NAMETYPE_EVENT: // Used only by the Alerter service
  141. MaxNameLen = EVLEN;
  142. UpperCase = TRUE;
  143. break;
  144. case NAMETYPE_DOMAIN:
  145. if (Flags & LM2X_COMPATIBLE) {
  146. MaxNameLen = LM20_DNLEN;
  147. UpperCase = TRUE;
  148. } else {
  149. MaxNameLen = DNLEN;
  150. }
  151. break;
  152. case NAMETYPE_SERVICE:
  153. if (Flags & LM2X_COMPATIBLE) {
  154. MaxNameLen = LM20_SNLEN;
  155. UpperCase = TRUE;
  156. } else {
  157. MaxNameLen = SNLEN;
  158. }
  159. break;
  160. case NAMETYPE_NET:
  161. //#if DBG
  162. // DbgPrint("NAMETYPE_NET being used. Please notify rfirth. Hit 'i' to continue\n");
  163. // ASSERT(FALSE);
  164. //#endif
  165. MaxNameLen = MAX_PATH - 1; // allow for NULL
  166. UpperCase = TRUE;
  167. break;
  168. case NAMETYPE_SHARE:
  169. if (Flags & LM2X_COMPATIBLE) {
  170. MaxNameLen = LM20_NNLEN;
  171. UpperCase = TRUE;
  172. } else {
  173. MaxNameLen = NNLEN;
  174. }
  175. break;
  176. case NAMETYPE_PASSWORD:
  177. if (Flags & LM2X_COMPATIBLE) {
  178. MaxNameLen = LM20_PWLEN;
  179. } else {
  180. MaxNameLen = PWLEN;
  181. }
  182. break;
  183. case NAMETYPE_SHAREPASSWORD:
  184. MaxNameLen = SHPWLEN;
  185. break;
  186. case NAMETYPE_MESSAGE:
  187. //#if DBG
  188. // DbgPrint("NAMETYPE_MESSAGE being used. Please notify rfirth. Hit 'i' to continue\n");
  189. // ASSERT(FALSE);
  190. //#endif
  191. MaxNameLen = (MAX_PATH - 1);
  192. UpperCase = TRUE;
  193. break;
  194. case NAMETYPE_MESSAGEDEST:
  195. MaxNameLen = MAX_PATH - 1; // allow for NULL
  196. UpperCase = TRUE;
  197. break;
  198. case NAMETYPE_WORKGROUP:
  199. if (Flags & LM2X_COMPATIBLE) {
  200. MaxNameLen = LM20_DNLEN;
  201. UpperCase = TRUE;
  202. } else {
  203. MaxNameLen = DNLEN;
  204. }
  205. break;
  206. default:
  207. //
  208. // The caller specified an invalid name type.
  209. //
  210. // NOTE: This should already have been caught by
  211. // NetpwNameValidate(), so this code should
  212. // never be reached.
  213. //
  214. return ERROR_INVALID_PARAMETER;
  215. }
  216. //
  217. // Check the buffer is large enough, abort if it isn't
  218. //
  219. if (Flags & INNCA_FLAGS_FULL_BUFLEN) {
  220. NameLen = MaxNameLen;
  221. }
  222. if (OutbufLen < (NameLen + 1) * sizeof(TCHAR)) {
  223. return NERR_BufTooSmall;
  224. }
  225. //
  226. // If the input buffer and output buffer are not the same, copy
  227. // the name to the output buffer.
  228. //
  229. if (Name != Outbuf) {
  230. STRNCPY(Outbuf, Name, NameLen);
  231. }
  232. //
  233. // Note that we copy in a terminating null even if the input and
  234. // output buffer are the same. This is to handle the case of
  235. // a share name from which trailing characters need to be stripped.
  236. //
  237. Outbuf[NameLen] = TCHAR_EOS;
  238. #ifndef WIN32_CHICAGO
  239. // We never set Uppercase anyway. -ChandanS
  240. //
  241. // Upper-case the name, if appropriate
  242. //
  243. if (UpperCase) {
  244. NTSTATUS status;
  245. UNICODE_STRING stringOut;
  246. UNICODE_STRING stringIn;
  247. RtlInitUnicodeString(&stringIn, Name);
  248. stringOut.Buffer = Outbuf;
  249. stringOut.Length = 0;
  250. stringOut.MaximumLength = (USHORT)OutbufLen;
  251. status = RtlUpcaseUnicodeString(&stringOut, &stringIn, FALSE);
  252. if (!NT_SUCCESS(status)) {
  253. return NetpNtStatusToApiStatus(status);
  254. }
  255. }
  256. #endif // WIN32_CHICAGO
  257. return NERR_Success;
  258. }