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.

255 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1989-91 Microsoft Corporation
  3. Module Name:
  4. nameval.c
  5. Abstract:
  6. (Internal) net name validation functions:
  7. NetpwNameValidate
  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. const TCHAR szNull[] = TEXT("");
  21. const TCHAR szStandardIllegalChars[] = ILLEGAL_NAME_CHARS_STR TEXT("*");
  22. const TCHAR szComputerIllegalChars[] = ILLEGAL_NAME_CHARS_STR TEXT("*");
  23. const TCHAR szDomainIllegalChars[] = ILLEGAL_NAME_CHARS_STR TEXT("*") TEXT(" ");
  24. const TCHAR szMsgdestIllegalChars[] = ILLEGAL_NAME_CHARS_STR;
  25. #include <winnls.h>
  26. NET_API_STATUS
  27. NetpwNameValidate(
  28. IN LPTSTR Name,
  29. IN DWORD NameType,
  30. IN DWORD Flags
  31. )
  32. /*++
  33. Routine Description:
  34. Validates a LANMAN object name for character set and length
  35. Arguments:
  36. Name - The name to validate.
  37. NameType - The type of the LANMAN object names. Valid values are
  38. specified by NAMETYPE_* manifests in NET\H\ICANON.H.
  39. Flags - Flags to determine operation. Currently MBZ.
  40. Return Value:
  41. 0 if successful.
  42. The error number (> 0) if unsuccessful.
  43. Possible error returns include:
  44. ERROR_INVALID_PARAMETER
  45. ERROR_INVALID_NAME
  46. --*/
  47. {
  48. DWORD status;
  49. DWORD name_len;
  50. DWORD max_name_len;
  51. DWORD min_name_len = 1;
  52. LPCTSTR illegal_chars = szStandardIllegalChars;
  53. BOOL fNoDotSpaceOnly = TRUE;
  54. DWORD oem_name_len;
  55. #ifdef CANONDBG
  56. DbgPrint("NetpwNameValidate\n");
  57. #endif
  58. //
  59. // Parameter validation
  60. //
  61. if (Flags & INNV_FLAGS_RESERVED) {
  62. return ERROR_INVALID_PARAMETER;
  63. }
  64. name_len = STRLEN(Name);
  65. //
  66. // oem_name_len : length in bytes in oem character set
  67. // name_len : ifdef UNICODE
  68. // character length in unicode
  69. // else
  70. // length in bytes in oem character set
  71. //
  72. {
  73. BOOL fUsedDefault;
  74. oem_name_len = WideCharToMultiByte(
  75. CP_OEMCP, // UINT CodePage
  76. 0, // DWORD dwFlags
  77. Name, // LPWSTR lpWideChar
  78. name_len, // int cchWideChar
  79. NULL, // LPSTR lpMultiByteStr
  80. 0, // int cchMultiByte
  81. NULL, // use system default char
  82. &fUsedDefault); //
  83. }
  84. //
  85. // Determine the minimum and maximum allowable length of the name and
  86. // the set of illegal name characters.
  87. //
  88. switch (NameType) {
  89. case NAMETYPE_USER:
  90. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_UNLEN : UNLEN;
  91. break;
  92. case NAMETYPE_GROUP:
  93. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_GNLEN : GNLEN;
  94. break;
  95. case NAMETYPE_COMPUTER:
  96. max_name_len = MAX_PATH;
  97. illegal_chars = szComputerIllegalChars;
  98. //
  99. // Computer names can't have trailing or leading blanks
  100. //
  101. if ( name_len > 0 && (Name[0] == L' ' || Name[name_len-1] == L' ') ) {
  102. return ERROR_INVALID_NAME;
  103. }
  104. break;
  105. case NAMETYPE_EVENT:
  106. max_name_len = EVLEN;
  107. break;
  108. case NAMETYPE_DOMAIN:
  109. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_DNLEN : DNLEN;
  110. illegal_chars = szDomainIllegalChars;
  111. break;
  112. case NAMETYPE_SERVICE:
  113. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_SNLEN : SNLEN;
  114. break;
  115. case NAMETYPE_NET:
  116. max_name_len = MAX_PATH;
  117. break;
  118. case NAMETYPE_SHARE:
  119. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_NNLEN : NNLEN;
  120. break;
  121. case NAMETYPE_PASSWORD:
  122. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_PWLEN : PWLEN;
  123. min_name_len = 0;
  124. illegal_chars = szNull;
  125. fNoDotSpaceOnly = FALSE;
  126. break;
  127. case NAMETYPE_SHAREPASSWORD:
  128. max_name_len = SHPWLEN;
  129. min_name_len = 0;
  130. illegal_chars = szNull;
  131. fNoDotSpaceOnly = FALSE;
  132. break;
  133. case NAMETYPE_MESSAGE:
  134. max_name_len = NETBIOS_NAME_LEN - 1;
  135. break;
  136. case NAMETYPE_MESSAGEDEST:
  137. max_name_len = MAX_PATH;
  138. illegal_chars = szMsgdestIllegalChars;
  139. break;
  140. case NAMETYPE_WORKGROUP:
  141. //
  142. // workgroup is the same as domain, but allows spaces
  143. //
  144. max_name_len = (Flags & LM2X_COMPATIBLE) ? LM20_DNLEN : DNLEN;
  145. break;
  146. default:
  147. return ERROR_INVALID_PARAMETER; // unknown name type
  148. }
  149. //
  150. // Check the length of the name; return an error if it's out of range
  151. //
  152. if ((oem_name_len < min_name_len) || (oem_name_len > max_name_len)) {
  153. return ERROR_INVALID_NAME;
  154. }
  155. //
  156. // Check for illegal characters; return an error if one is found
  157. //
  158. if (NameType != NAMETYPE_NET && STRCSPN(Name, illegal_chars) < name_len) {
  159. return ERROR_INVALID_NAME;
  160. }
  161. //
  162. // If <fNoDotSpaceOnly> is TRUE, return an error if the name contains
  163. // only dots and spaces.
  164. //
  165. if (fNoDotSpaceOnly && STRSPN(Name, DOT_AND_SPACE_STR) == name_len) {
  166. return ERROR_INVALID_NAME;
  167. }
  168. //
  169. // Special case checking for MESSAGEDEST names: '*' is allowed only as
  170. // the last character, and names of the maximum length must contain a
  171. // trailing '*'.
  172. //
  173. if (NameType == NAMETYPE_MESSAGEDEST) {
  174. LPTSTR pStar;
  175. pStar = STRCHR(Name, TCHAR_STAR);
  176. if (pStar != NULL) {
  177. if ((DWORD)(pStar - Name) != name_len - 1) {
  178. return ERROR_INVALID_NAME;
  179. }
  180. } else {
  181. if (oem_name_len == max_name_len) {
  182. return ERROR_INVALID_NAME;
  183. }
  184. }
  185. }
  186. //
  187. // If we get here, the name passed all of the tests, so it's valid
  188. //
  189. return 0;
  190. }