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.

339 lines
13 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. isremote.c
  5. Abstract:
  6. Contains the NetpIsRemote routine. This checks if a computer name
  7. designates the local machine
  8. Author:
  9. Richard L Firth (rfirth) 24th April 1991
  10. Revision History:
  11. 01-Nov-1991 JohnRo
  12. Fixed RAID 3414: allow explicit local server name. (NetpIsRemote was
  13. not canonizaling the computer name from NetWkstaGetInfo, so it was
  14. always saying that the local computer name was remote if it wasn't
  15. already canonicalized.)
  16. 07-Jun-1991 rfirth
  17. * Changed name of routine to conform to Nt naming conventions
  18. * Added LocalOrRemote parameter - returning just ISLOCAL or ISREMOTE
  19. is not sufficient - we can return error codes too
  20. * Added CanonicalizedName parameter - now passes back canonicalized
  21. name if requested. This is because, usually, subsequent routines call
  22. to NetRemoteComputerSupports which performs minimal checking on the
  23. name. Ergo, if we hand it a canonicalized name (which we have to do
  24. with this routine anyway) it can't complain. Can it?
  25. * NetpIsRemote no longer a NET_API_FUNCTION
  26. * Made semantics of CanonicalizedName orhogonal - if NULL or NUL passed
  27. in as ComputerName, caller still gets back the local computer name
  28. IF CanonicalizedName NOT NULL AND IF THE REDIRECTOR HAS BEEN STARTED
  29. --*/
  30. #include "nticanon.h"
  31. NET_API_STATUS
  32. NetpIsRemote(
  33. IN LPWSTR ComputerName OPTIONAL,
  34. OUT LPDWORD LocalOrRemote,
  35. OUT LPWSTR CanonicalizedName OPTIONAL,
  36. IN DWORD cchCanonName,
  37. IN DWORD Flags
  38. )
  39. /*++
  40. Routine Description:
  41. Determines whether a computer name designates this machine or a renote
  42. one. Values of ComputerName which equate to the local machine are:
  43. NULL pointer to name
  44. pointer to NULL name
  45. pointer to non-NULL name which is lexically equivalent to this
  46. machine's name
  47. NB. This routine expects that the canonicalized version of ComputerName
  48. will fit into the buffer pointed at by CanonicalizedName. Since this
  49. is an INTERNAL function, this assumption is deemed valid
  50. Arguments:
  51. IN LPTSTR ComputerName OPTIONAL
  52. Pointer to computer name to check. May assume any of
  53. the above forms
  54. If a non-NULL string is passed in, then it may have
  55. preceeding back-slashes. This is kind of expected since
  56. this routine is called by remotable APIs and it is they
  57. who specify that the form a computer name is \\<name>
  58. OUT LPDWORD LocalOrRemote
  59. Points to the DWORD where the specifier for the
  60. symbolic location will be returned. MUST NOT BE NULL. On
  61. return will be one of:
  62. ISLOCAL The name defined by ComputerName specifies
  63. the local machine specifically or by default
  64. (ie. was NULL)
  65. ISREMOTE The name defined by ComputerName was non-NULL
  66. and was not the name of this machine
  67. OUT LPTSTR CanonicalizedName OPTIONAL
  68. Pointer to caller's buffer into which a copy of the
  69. canonicalized name will be placed if requested. This
  70. can then be used in subsequent calls, with the knowledge
  71. that no further checking of the computer name is required.
  72. Note that the format of this buffer will be \\<computername>
  73. on return. The contents of this buffer will not be
  74. modified unless this routine returns success
  75. IN DWORD Flags
  76. A bitmap. Flags are:
  77. NIRFLAG_MAPLOCAL if set, will map (ie canonicalize)
  78. the NULL local name to this
  79. computer's name proper. Used in
  80. conjunction with CanonicalizedName
  81. This stops extraneous calls to
  82. NetpNameCanonicalize with the
  83. inherited CanonicalizedName
  84. parameter. See below for elucidation
  85. Return Value:
  86. NET_API_STATUS
  87. Success = NERR_Success
  88. Failure = return code from:
  89. NetpNameCanonicalize
  90. NetWkstaGetInfo
  91. NetpNameCompare
  92. --*/
  93. {
  94. LPBYTE wksta_buffer_pointer;
  95. BOOL map_local_name = FALSE;
  96. LONG result;
  97. NET_API_STATUS rc;
  98. WCHAR name[MAX_PATH]; // canonicalized version of ComputerName
  99. LPWSTR wksta_name_uncanon; // our computer name (from NetWkstaGetInfo)
  100. WCHAR wksta_name_canon[MAX_PATH]; // our computer name (from canon)
  101. LPWSTR canonicalized_name; // as returned to caller
  102. //
  103. // Assert that we have a valid pointer in LocalOrRemote
  104. //
  105. //
  106. // Once again, shouldn't have to do this, since this routine is internal
  107. // and there is no interpretation about inputs. However, lets catch any
  108. // possible problems...
  109. //
  110. NetpAssert(ARGUMENT_PRESENT(LocalOrRemote));
  111. #ifdef CANONDBG
  112. DbgPrint("NetpIsRemote(%s, %x, %x, %x)\n",
  113. ComputerName,
  114. LocalOrRemote,
  115. CanonicalizedName,
  116. Flags
  117. );
  118. #endif
  119. //
  120. // NB. It is important to check this case first, before we call any Netp
  121. // routines since these could call back to this routine and we may get
  122. // stuck in an infinite loop
  123. //
  124. if (!ARGUMENT_PRESENT(ComputerName) || (*ComputerName == TCHAR_EOS)) {
  125. //
  126. // in this case its probably an internal call from one of our routines
  127. // and we want to return as quickly as possible. This will be borne out
  128. // by the NIRFLAG_MAPLOCAL flag being reset in the Flags parameter
  129. //
  130. //
  131. // A note about NIRFLAG_MAPLOCAL
  132. // This routine makes local calls to NetpNameValidate and
  133. // NetpNameCompare. If the NIRFLAG_MAPLOCAL flag is not reset then
  134. // these routines in turn will cause the local name to be returned
  135. // (because they always pass in non-NULL CanonicalizedName parameter)
  136. // which in most cases is inefficient, since the name won't be used
  137. // so we always say (in the Netp routines) that we don't want local
  138. // name canonicalization
  139. // Therefore, if (local) name canonicalization is implied by non-NULL
  140. // CanonicalizedName, verify this by checking Flags.NIRFLAG_MAPLOCAL
  141. // If it, too, is set then local name canonicalization is performed
  142. //
  143. if (!ARGUMENT_PRESENT(CanonicalizedName) || !(Flags & NIRFLAG_MAPLOCAL)) {
  144. *LocalOrRemote = ISLOCAL;
  145. #ifdef CANONDBG
  146. DbgPrint("NetpIsRemote(%s) - returning early\n", ComputerName);
  147. #endif
  148. return NERR_Success;
  149. } else {
  150. //
  151. // signify that the input name was NULL or NUL string but that the
  152. // caller wants a canonicalized name returned (from NetWkstaGetInfo)
  153. //
  154. map_local_name = TRUE;
  155. }
  156. } else {
  157. //
  158. // if the computername starts with \\ or // or any combination thereof,
  159. // skip the path separators - the canonicalization routines expect
  160. // computer names NOT to have these.
  161. //
  162. if (IS_PATH_SEPARATOR(ComputerName[0]) && IS_PATH_SEPARATOR(ComputerName[1])) {
  163. ComputerName += 2;
  164. }
  165. //
  166. // here's a use for canonicalization (!): ensure that we have been passed
  167. // a real and proper computer name and not some pale imitation
  168. //
  169. rc = NetpNameCanonicalize(
  170. NULL, // performed here, on our own premises
  171. ComputerName, // this is input
  172. name, // this is output
  173. sizeof(name), // how much buffer we have
  174. NAMETYPE_COMPUTER, // what we think it is
  175. INNCA_FLAGS_FULL_BUFLEN // say that o/p buffer must be large
  176. // enough for maximum-sized computer
  177. // name. Why? you ask, well its a fair
  178. // cop - the reason is that we can't
  179. // get into trouble on the one time that
  180. // we exercise the maximum requirement
  181. );
  182. if (rc) {
  183. return rc; // duff name (?)
  184. } else {
  185. canonicalized_name = name;
  186. }
  187. }
  188. //
  189. // get the name of this machine from the redirector. If we can't get the
  190. // name for whatever reason, return the error code.
  191. //
  192. if (rc = NetWkstaGetInfo(NULL, 100, &wksta_buffer_pointer)) {
  193. #ifdef CANONDBG
  194. DbgPrint("error: NetWkstaGetInfo returns %lu\n", rc);
  195. #endif
  196. return rc; // didn't work
  197. }
  198. wksta_name_uncanon =
  199. ((LPWKSTA_INFO_100) wksta_buffer_pointer)->wki100_computername;
  200. #ifdef CANONDBG
  201. DbgPrint("NetWkstaGetInfo returns level 100 computer name (uncanon)= %s\n",
  202. wksta_name_uncanon);
  203. #endif
  204. rc = NetpNameCanonicalize(
  205. NULL, // performed here, on our own premises
  206. wksta_name_uncanon, // this is input
  207. wksta_name_canon, // this is output
  208. sizeof(wksta_name_canon), // how much buffer we have
  209. NAMETYPE_COMPUTER, // what we think it is
  210. INNCA_FLAGS_FULL_BUFLEN // say that o/p buffer must be large
  211. // enough for maximum-sized computer
  212. // name. Why? you ask, well its a fair
  213. // cop - the reason is that we can't
  214. // get into trouble on the one time that
  215. // we exercise the maximum requirement
  216. );
  217. NetpAssert( rc == NERR_Success );
  218. //
  219. // compare our name and the name passed to us. NetpNameCompare returns
  220. // 0 if the names match else 1 or -1 (a la strcmp)
  221. //
  222. //
  223. // if the caller gave us a NULL computer name but wants a canonicalized
  224. // name output then get a pointer to the canonicalized name from
  225. // NetWkstaGetInfo
  226. //
  227. if (map_local_name) {
  228. *LocalOrRemote = ISLOCAL;
  229. canonicalized_name = wksta_name_canon;
  230. } else {
  231. //
  232. // otherwise, we have a non-NULL computername to compare with this
  233. // computer's name
  234. //
  235. result = NetpNameCompare(
  236. NULL, // performed here, on our own premises
  237. name, // canonicalized version of passed name
  238. wksta_name_canon, // name of our computer
  239. NAMETYPE_COMPUTER,
  240. INNC_FLAGS_NAMES_CANONICALIZED
  241. );
  242. //
  243. // if the specified name equates to our computer name then its still local
  244. //
  245. *LocalOrRemote = (DWORD)((result == 0) ? ISLOCAL : ISREMOTE);
  246. }
  247. //
  248. // if the caller specified that the canonicalized name be returned, then
  249. // give it to 'em. Note that the returned name is prefixed with \\ - it
  250. // is assumed the name is then used in a call to eg NetRemoteComputerSupports
  251. //
  252. if (ARGUMENT_PRESENT(CanonicalizedName))
  253. {
  254. if (cchCanonName < wcslen(canonicalized_name) + 2 + 1)
  255. {
  256. //
  257. // Buffer's too small for \\ + <name> + \0. Since this is a private
  258. // routine, the too-small buffer size is hardcoded. Return invalid
  259. // parameter instead of buffer too small since there's nothing the
  260. // caller can do at this point (and we're not returning a length).
  261. //
  262. NetApiBufferFree(wksta_buffer_pointer);
  263. return ERROR_INVALID_PARAMETER;
  264. }
  265. wcscpy(CanonicalizedName, L"\\\\");
  266. wcscat(CanonicalizedName, canonicalized_name);
  267. }
  268. //
  269. // free the buffer created by NetWkstaGetInfo
  270. //
  271. NetApiBufferFree(wksta_buffer_pointer);
  272. return NERR_Success;
  273. }