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.

419 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. msgnbios.c
  5. Abstract:
  6. This file contains Routines used by the messenger to make netbios
  7. calls and to obtain the computer and user names.
  8. The following functions are included:
  9. MsgInit_NetBios
  10. Msgsendncb
  11. MsgAddUserNames
  12. MsgAddAlreadyLoggedOnUserNames (HYDRA specific)
  13. NT_NOTE:
  14. We need some way to determine which NCB's have unanswered listens
  15. pending. For these, we need to send an NCBCANCEL command via
  16. another NetBios call. The buffer will contain a pointer to the
  17. listening NCB. Also, listens that are in the process of being
  18. serviced must either be hung up, or allowed to complete.
  19. All this is done during the MsgrShutdown.
  20. Author:
  21. Dan Lafferty (danl) 27-Jun-1991
  22. Environment:
  23. User Mode -Win32
  24. Notes:
  25. NetBios3.0 is not a handle-based api. Therefore, there is no open or
  26. close associated with it. In order to shut down properly, the
  27. messenger will have to hangup or complete listens that are being
  28. serviced. And it will have to send a cancel NCB for each listen
  29. that is pending.
  30. Revision History:
  31. 08-Apr-1994 danl
  32. MsgAddUserNames: If call to NetWkstaUserEnum failed, this function
  33. was still attempting to free the buffer that was returned.
  34. Since no buffer is allocated in a failure case, the free mem
  35. call in the path is being removed.
  36. 27-Jun-1991 danl
  37. ported from LM2.0
  38. --*/
  39. #include "msrv.h"
  40. #include "msgdbg.h" // MSG_LOG
  41. #include <tstring.h> // Unicode string macros
  42. #include <icanon.h> // I_NetNameCanonicalize
  43. #include <netlib.h> // UNUSED macro
  44. #include <lmwksta.h> // NetWorkstation API prototypes
  45. #include <lmapibuf.h> // NetApiBufferFree
  46. #include <netdebug.h> // NetpAssert, FORMAT_ equates.
  47. #include "msgdata.h"
  48. #include "apiutil.h" // MsgMapNetError
  49. //
  50. // Note: we use the internal entrypoints to the apis because this
  51. // file is shared by the message apis, which cannot call the net
  52. // bios apis because of different required permissions.
  53. //
  54. NET_API_STATUS
  55. MsgInit_NetBios(
  56. VOID
  57. )
  58. /*++
  59. Routine Description:
  60. This function fills the global array called net_lana_num with the
  61. lan adapter numbers retrieved from A NetBios Enum call
  62. NOTE: This assumes that space for the array is already set up.
  63. The LM2.0 version of this also filled an array of NetBios Handles.
  64. In LM2.0, the loopback driver was not included unless it was the only
  65. network installed.
  66. Arguments:
  67. none
  68. Return Value:
  69. TRUE - No Error.
  70. FALSE - An error occured.
  71. --*/
  72. {
  73. DWORD count=0;
  74. NCB ncb;
  75. LANA_ENUM lanaBuffer;
  76. unsigned char i;
  77. unsigned char nbStatus;
  78. //
  79. // Find the number of networks by sending an enum request via Netbios.
  80. //
  81. clearncb(&ncb);
  82. ncb.ncb_command = NCBENUM; // Enumerate LANA nums (wait)
  83. ncb.ncb_buffer = (char FAR *)&lanaBuffer;
  84. ncb.ncb_length = sizeof(LANA_ENUM);
  85. nbStatus = Netbios(&ncb);
  86. if (nbStatus != NRC_GOODRET)
  87. {
  88. MSG_LOG(ERROR, "Netbios LanaEnum failed rc=%d\n",nbStatus);
  89. return MsgMapNetError(nbStatus);
  90. }
  91. //
  92. // Move the Adapter Numbers (lana) into the array that will contain them.
  93. //
  94. for (i=0; i < lanaBuffer.length; i++)
  95. {
  96. MSG_LOG(TRACE,"adapter %d",i);
  97. MSG_LOG(TRACE,"\b\b\b\b\b\b lananum= %d \n", lanaBuffer.lana[i]);
  98. GETNETLANANUM(count) = lanaBuffer.lana[i];
  99. count++;
  100. //
  101. // Internal consistancy check. Make sure the arrays are only
  102. // SD_NUMNETS long.
  103. //
  104. if (count > SD_NUMNETS())
  105. {
  106. MSG_LOG(ERROR,
  107. "NumNets from NetBios greater than value from Wksta count=%d\n",
  108. count);
  109. return NERR_WkstaInconsistentState;
  110. }
  111. }
  112. //
  113. // Internal consistancy check again. We better not have opened
  114. // more nets than the messenger thinks there are.
  115. //
  116. if (count != SD_NUMNETS())
  117. {
  118. return NERR_WkstaInconsistentState;
  119. }
  120. return NERR_Success;
  121. }
  122. UCHAR
  123. Msgsendncb(
  124. PNCB NCB_ptr,
  125. DWORD neti)
  126. /*++
  127. Routine Description:
  128. This function performs a DosDevIOCtl call to send an NCB to the
  129. net bios via a previously openned redirector and netbios handle.
  130. Arguments:
  131. NCB_ptr - Points to the NCB to send to the net bios.
  132. neti - Network index. Which netbios to submit it to?
  133. Return Value:
  134. Error code from Net bios.
  135. --*/
  136. {
  137. //
  138. // NOTE: The new Netbios call doesn't use any handles, so the neti
  139. // info is not used.
  140. //
  141. UNUSED (neti);
  142. return (Netbios(NCB_ptr));
  143. #ifdef remove
  144. return( NetBiosSubmit( NetBios_Hdl[neti], 0, (NCB far *) NCB_ptr));
  145. #endif
  146. }
  147. VOID
  148. MsgAddUserNames(
  149. VOID
  150. )
  151. /*++
  152. Routine Description:
  153. This function used to get it's information about the username and
  154. computername from the workstation service. Now, in NT, the username
  155. is added when the user logs on. It is not automatically added by the
  156. messenger.
  157. Arguments:
  158. CompName - Pointer to buf for computer name. (must be NCBNAMSZ+1)
  159. CompNameSize - Size in bytes of the buffer to receive the name.
  160. UserName - Pointer to buffer for user name. (must be UNLEN+1)
  161. UserNameSize - Size in bytes of the buffer to receive the name.
  162. Return Value:
  163. NERR_Success - Aways returned. (Names are returned as NUL strings).
  164. --*/
  165. {
  166. TCHAR UserName[UNLEN+1];
  167. DWORD UserNameSize = sizeof(UserName);
  168. DWORD i;
  169. LPWKSTA_USER_INFO_0 userInfo0;
  170. DWORD entriesRead;
  171. DWORD totalEntries;
  172. NET_API_STATUS status;
  173. *UserName = TEXT('\0');
  174. status = NetWkstaUserEnum(
  175. NULL,
  176. 0,
  177. (LPBYTE *)&userInfo0,
  178. 0xffffffff, // PreferredMaximiumLength
  179. &entriesRead,
  180. &totalEntries,
  181. NULL); // resume handle
  182. if (status != NERR_Success) {
  183. MSG_LOG(ERROR,"GetWkstaNames:NetWkstaUserEnum FAILURE %X/n",status);
  184. return;
  185. }
  186. for (i=0; i<entriesRead; i++ ) {
  187. if (entriesRead == 0) {
  188. //
  189. // There are no users logged on at the time of this query.
  190. //
  191. MSG_LOG(TRACE,
  192. "GetWkstaNames:NetWkstaUserEnum entriesRead=%d\n",
  193. entriesRead);
  194. }
  195. if(userInfo0[i].wkui0_username != NULL) {
  196. status = I_NetNameCanonicalize(
  197. NULL,
  198. userInfo0[i].wkui0_username,
  199. UserName,
  200. UserNameSize,
  201. NAMETYPE_USER,
  202. 0);
  203. if (status != NERR_Success) {
  204. MSG_LOG(ERROR,"I_NetNameCanonicalize failed %X\n",status);
  205. }
  206. }
  207. if( *UserName != TEXT('\0')) { // Set up in GetWkstaNames */
  208. MSG_LOG(TRACE, "Calling MsgAddName\n",0);
  209. status = MsgAddName(UserName,0);
  210. if (status != NERR_Success) {
  211. MSG_LOG(
  212. TRACE,
  213. "MsgAddUserNames,MessageAddName FAILURE " FORMAT_API_STATUS
  214. "\n",
  215. status);
  216. }
  217. }
  218. }
  219. NetApiBufferFree(userInfo0);
  220. }
  221. VOID
  222. MsgAddAlreadyLoggedOnUserNames(
  223. VOID
  224. )
  225. /*++
  226. Routine Description:
  227. This function is used to get information about the previously logged on usernames
  228. by calling WinStationEnumerate and WinStationQueryInformationW, instead of NetWkstaUserEnum.
  229. (same job as MsgAddUserNames, adapted for multi-user)
  230. Note: It could (should ?) be located elsewhere than in msgnbios. I kept it here just because
  231. MsgAddUserName itself was already here. (NicolasBD)
  232. Arguments:
  233. Return Value:
  234. NERR_Success - Always returned.
  235. --*/
  236. {
  237. TCHAR UserName[NCBNAMSZ+1];
  238. DWORD UserNameSize = sizeof(UserName);
  239. UINT WdCount, i;
  240. PLOGONID pWd, pWdTmp;
  241. ULONG AmountRet;
  242. WINSTATIONINFORMATIONW QueryBuffer;
  243. NET_API_STATUS status;
  244. *UserName = TEXT('\0');
  245. // Enumerate the Sessions
  246. if ( gpfnWinStationEnumerate( SERVERNAME_CURRENT, &pWd, &WdCount ) )
  247. {
  248. // Success; get all the previously logged on user names and session ids
  249. pWdTmp = pWd;
  250. for( i=0; i < WdCount; i++ ) {
  251. if( ((pWdTmp->State == State_Connected) ||
  252. (pWdTmp->State == State_Active) ||
  253. (pWdTmp->State == State_Disconnected)))
  254. {
  255. if( !gpfnWinStationQueryInformation( SERVERNAME_CURRENT,
  256. pWdTmp->LogonId,
  257. WinStationInformation,
  258. &QueryBuffer,
  259. sizeof(QueryBuffer),
  260. &AmountRet ) )
  261. {
  262. // Error
  263. MSG_LOG(ERROR, "MsgAddAlreadyLoggedOnUserNames: Error in QueryInfo %d\n",GetLastError());
  264. }
  265. else
  266. {
  267. if (QueryBuffer.UserName != NULL)
  268. {
  269. MSG_LOG(TRACE,"MsgAddAlreadyLoggedOnUserNames: calling I_NetNameCanonicalize for %ws\n",QueryBuffer.UserName);
  270. status = I_NetNameCanonicalize(
  271. NULL,
  272. QueryBuffer.UserName,
  273. UserName,
  274. UserNameSize,
  275. NAMETYPE_USER,
  276. 0);
  277. if (status != NERR_Success)
  278. {
  279. MSG_LOG(ERROR,"I_NetNameCanonicalize failed %X\n",status);
  280. }
  281. }
  282. if( *UserName != TEXT('\0'))
  283. {
  284. MSG_LOG(TRACE,"MsgAddAlreadyLoggedOnUserNames: Calling MsgAddName for Session %x \n", pWdTmp->LogonId);
  285. status = MsgAddName(UserName, pWdTmp->LogonId);
  286. if (status != NERR_Success)
  287. {
  288. MSG_LOG(TRACE, "MsgAddAlreadyLoggedOnUserNames,MessageAddName FAILURE " FORMAT_API_STATUS "\n", status);
  289. }
  290. }
  291. }
  292. }
  293. pWdTmp++;
  294. }
  295. // Free enumeration memory
  296. gpfnWinStationFreeMemory(pWd);
  297. }
  298. else
  299. {
  300. MSG_LOG (ERROR, "MsgAddAlreadyLoggedOnUserNames: WinStationEnumerate failed, error = %d:\n",GetLastError());
  301. }
  302. return;
  303. }