Source code of Windows XP (NT5)
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.

530 lines
15 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. sess_lm.c
  5. Abstract:
  6. This file contains MIB_sess_lmget, which actually call lan manager
  7. for the session table, copies it into structures, and sorts it to
  8. return ready to use by the higher level functions.
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. 10-May-1996 DonRyan
  13. Removed banner from Technology Dynamics, Inc.
  14. --*/
  15. //--------------------------- WINDOWS DEPENDENCIES --------------------------
  16. //--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
  17. #ifdef WIN32
  18. #include <windows.h>
  19. #include <lm.h>
  20. #endif
  21. #include <tchar.h>
  22. #include <string.h>
  23. #include <search.h>
  24. #include <stdlib.h>
  25. #include <time.h>
  26. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  27. #include "mib.h"
  28. #include "mibfuncs.h"
  29. #include "sess_tbl.h"
  30. #include "lmcache.h"
  31. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  32. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  33. //--------------------------- PRIVATE CONSTANTS -----------------------------
  34. #define SafeBufferFree(x) if(NULL != x) NetApiBufferFree( x )
  35. #define SafeFree(x) if(NULL != x) SnmpUtilMemFree( x )
  36. //--------------------------- PRIVATE STRUCTS -------------------------------
  37. //--------------------------- PRIVATE VARIABLES -----------------------------
  38. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  39. int __cdecl sess_entry_cmp(
  40. IN const SESS_ENTRY *A,
  41. IN const SESS_ENTRY *B
  42. ) ;
  43. void build_sess_entry_oids( );
  44. //--------------------------- PRIVATE PROCEDURES ----------------------------
  45. //--------------------------- PUBLIC PROCEDURES -----------------------------
  46. //
  47. // MIB_sess_lmset
  48. // Perform the necessary actions to SET a field in the Session Table.
  49. //
  50. // Notes:
  51. //
  52. // Return Codes:
  53. //
  54. // Error Codes:
  55. // None.
  56. //
  57. UINT MIB_sess_lmset(
  58. IN AsnObjectIdentifier *Index,
  59. IN UINT Field,
  60. IN AsnAny *Value
  61. )
  62. {
  63. NET_API_STATUS lmCode;
  64. int Found;
  65. UINT Entry;
  66. AsnInteger ErrStat = SNMP_ERRORSTATUS_NOERROR;
  67. char Client[100];
  68. char User[100];
  69. #ifdef UNICODE
  70. LPWSTR UniClient;
  71. LPWSTR UniUser;
  72. #endif
  73. // Must make sure the table is in memory
  74. if ( SNMPAPI_ERROR == MIB_sess_lmget() )
  75. {
  76. ErrStat = SNMP_ERRORSTATUS_GENERR;
  77. goto Exit;
  78. }
  79. // Find a match in the table
  80. if ( MIB_TBL_POS_FOUND != MIB_sess_match(Index, &Entry, FALSE) )
  81. {
  82. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  83. goto Exit;
  84. }
  85. // Check for action on Table
  86. if ( Value->asnValue.number == SESS_STATE_DELETED )
  87. {
  88. strcpy( Client, "\\\\" );
  89. strncpy( &Client[2], MIB_SessionTable.Table[Entry].svSesClientName.stream,
  90. MIB_SessionTable.Table[Entry].svSesClientName.length );
  91. Client[MIB_SessionTable.Table[Entry].svSesClientName.length+2] = '\0';
  92. strncpy( User, MIB_SessionTable.Table[Entry].svSesUserName.stream,
  93. MIB_SessionTable.Table[Entry].svSesUserName.length );
  94. User[MIB_SessionTable.Table[Entry].svSesUserName.length] = '\0';
  95. #ifdef UNICODE
  96. SnmpUtilUTF8ToUnicode( &UniClient,
  97. Client,
  98. TRUE );
  99. SnmpUtilUTF8ToUnicode( &UniUser,
  100. User,
  101. TRUE );
  102. lmCode = NetSessionDel( NULL, UniClient, UniUser );
  103. SnmpUtilMemFree(UniClient);
  104. SnmpUtilMemFree(UniUser);
  105. #else
  106. // Call the LM API to delete it
  107. lmCode = NetSessionDel( NULL, Client, User );
  108. #endif
  109. // Check for successful operation
  110. switch( lmCode )
  111. {
  112. case NERR_Success:
  113. // Make cache be reloaded next time
  114. cache_table[C_SESS_TABLE].bufptr = NULL;
  115. break;
  116. case NERR_ClientNameNotFound:
  117. case NERR_UserNotFound:
  118. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  119. break;
  120. default:
  121. ErrStat = SNMP_ERRORSTATUS_GENERR;
  122. }
  123. }
  124. Exit:
  125. return ErrStat;
  126. } // MIB_sess_lmset
  127. //
  128. // MIB_sess_lmget
  129. // Retrieve session table information from Lan Manager.
  130. // If not cached, sort it and then
  131. // cache it.
  132. //
  133. // Notes:
  134. //
  135. // Return Codes:
  136. // SNMPAPI_NOERROR
  137. // SNMPAPI_ERROR
  138. //
  139. // Error Codes:
  140. // None.
  141. //
  142. SNMPAPI MIB_sess_lmget(
  143. )
  144. {
  145. DWORD entriesread;
  146. DWORD totalentries;
  147. LPBYTE bufptr=NULL;
  148. unsigned lmCode;
  149. unsigned i;
  150. SESSION_INFO_2 *DataTable;
  151. SESS_ENTRY *MIB_SessionTableElement ;
  152. int First_of_this_block;
  153. time_t curr_time ;
  154. SNMPAPI nResult = SNMPAPI_NOERROR;
  155. LPSTR tempbuff ;
  156. DWORD resumehandle=0;
  157. time(&curr_time); // get the time
  158. //return nResult; // OPENISSUE remember the problem with the error
  159. // every time a free is done from this call to Enum?
  160. //
  161. //
  162. // If cached, return piece of info.
  163. //
  164. //
  165. if((NULL != cache_table[C_SESS_TABLE].bufptr) &&
  166. (curr_time <
  167. (cache_table[C_SESS_TABLE].acquisition_time
  168. + cache_expire[C_SESS_TABLE] ) ) )
  169. { // it has NOT expired!
  170. goto Exit ; // the global table is valid
  171. }
  172. //
  173. //
  174. // Do network call to gather information and put it in a nice array
  175. //
  176. //
  177. // free the old table LOOK OUT!!
  178. MIB_SessionTableElement = MIB_SessionTable.Table ;
  179. // iterate over the whole table
  180. for(i=0; i<MIB_SessionTable.Len ;i++)
  181. {
  182. // free any alloc'ed elements of the structure
  183. SnmpUtilOidFree(&(MIB_SessionTableElement->Oid));
  184. SafeFree(MIB_SessionTableElement->svSesClientName.stream);
  185. SafeFree(MIB_SessionTableElement->svSesUserName.stream);
  186. MIB_SessionTableElement ++ ; // increment table entry
  187. }
  188. SafeFree(MIB_SessionTable.Table) ; // free the base Table
  189. MIB_SessionTable.Table = NULL ; // just for safety
  190. MIB_SessionTable.Len = 0 ; // just for safety
  191. First_of_this_block = 0;
  192. do { // as long as there is more data to process
  193. lmCode =
  194. NetSessionEnum( NULL, // local server
  195. NULL, // get server stats
  196. NULL,
  197. 2, // level
  198. &bufptr, // data structure to return
  199. MAX_PREFERRED_LENGTH,
  200. &entriesread,
  201. &totalentries,
  202. NULL //&resumehandle // resume handle
  203. );
  204. if(NULL == bufptr) return nResult ;
  205. DataTable = (SESSION_INFO_2 *) bufptr ;
  206. if((NERR_Success == lmCode) || (ERROR_MORE_DATA == lmCode))
  207. { // valid so process it, otherwise error
  208. if(0 == MIB_SessionTable.Len) { // 1st time, alloc the whole table
  209. // alloc the table space
  210. MIB_SessionTable.Table = SnmpUtilMemAlloc(totalentries *
  211. sizeof(SESS_ENTRY) );
  212. }
  213. MIB_SessionTableElement = MIB_SessionTable.Table + First_of_this_block ;
  214. for(i=0; i<entriesread; i++) { // once for each entry in the buffer
  215. // increment the entry number
  216. MIB_SessionTable.Len ++;
  217. // Stuff the data into each item in the table
  218. // client name
  219. MIB_SessionTableElement->svSesClientName.dynamic = TRUE;
  220. #ifdef UNICODE
  221. if (SnmpUtilUnicodeToUTF8(
  222. &MIB_SessionTableElement->svSesClientName.stream,
  223. DataTable->sesi2_cname,
  224. TRUE))
  225. {
  226. MIB_SessionTableElement->svSesClientName.stream = NULL;
  227. MIB_SessionTableElement->svSesClientName.length = 0;
  228. }
  229. else
  230. {
  231. MIB_SessionTableElement->svSesClientName.length =
  232. strlen (MIB_SessionTableElement->svSesClientName.stream);
  233. }
  234. #else
  235. MIB_SessionTableElement->svSesClientName.stream = SnmpUtilMemAlloc (
  236. strlen( DataTable->sesi2_cname )+1 ) ;
  237. MIB_SessionTableElement->svSesClientName.length =
  238. strlen( DataTable->sesi2_cname ) ;
  239. memcpy( MIB_SessionTableElement->svSesClientName.stream,
  240. DataTable->sesi2_cname,
  241. strlen( DataTable->sesi2_cname ) ) ;
  242. #endif
  243. // user name
  244. MIB_SessionTableElement->svSesUserName.dynamic = TRUE;
  245. #ifdef UNICODE
  246. if (SnmpUtilUnicodeToUTF8(
  247. &MIB_SessionTableElement->svSesUserName.stream,
  248. DataTable->sesi2_username,
  249. TRUE))
  250. {
  251. MIB_SessionTableElement->svSesUserName.length = 0;
  252. MIB_SessionTableElement->svSesUserName.stream = NULL;
  253. }
  254. else
  255. {
  256. MIB_SessionTableElement->svSesUserName.length =
  257. strlen(MIB_SessionTableElement->svSesUserName.stream);
  258. }
  259. #else
  260. MIB_SessionTableElement->svSesUserName.stream = SnmpUtilMemAlloc (
  261. strlen( DataTable->sesi2_username ) + 1 ) ;
  262. MIB_SessionTableElement->svSesUserName.length =
  263. strlen( DataTable->sesi2_username ) ;
  264. memcpy( MIB_SessionTableElement->svSesUserName.stream,
  265. DataTable->sesi2_username,
  266. strlen( DataTable->sesi2_username ) ) ;
  267. #endif
  268. // number of connections
  269. MIB_SessionTableElement->svSesNumConns =
  270. // DataTable->sesi2_num_conns ; LM_NOT_THERE
  271. 0 ; // so get ready in case somebody implements
  272. // number of opens
  273. MIB_SessionTableElement->svSesNumOpens =
  274. DataTable->sesi2_num_opens ;
  275. // session time
  276. MIB_SessionTableElement->svSesTime =
  277. DataTable->sesi2_time ;
  278. // session idle time
  279. MIB_SessionTableElement->svSesIdleTime =
  280. DataTable->sesi2_idle_time ;
  281. // client type parsing
  282. // first convert from unicode if needed
  283. #ifdef UNICODE
  284. SnmpUtilUnicodeToUTF8(
  285. &tempbuff,
  286. DataTable->sesi2_cltype_name,
  287. TRUE);
  288. #else
  289. tempbuff = SnmpUtilMemAlloc( strlen(DataTable->sesi2_cltype_name) + 1 );
  290. memcpy( tempbuff,
  291. DataTable->sesi2_cltype_name,
  292. strlen( DataTable->sesi2_cltype_name ) ) ;
  293. #endif
  294. // let's assume 0 is undefined but better than garbage ...
  295. MIB_SessionTableElement->svSesClientType = 0 ;
  296. if(0==strcmp( "DOWN LEVEL",
  297. tempbuff))
  298. MIB_SessionTableElement->svSesClientType = 1 ;
  299. else if(0==strcmp("DOS LM",
  300. tempbuff))
  301. MIB_SessionTableElement->svSesClientType = 2 ;
  302. else if(0==strcmp("DOS LM 2.0",
  303. tempbuff))
  304. MIB_SessionTableElement->svSesClientType = 3 ;
  305. else if(0==strcmp("OS/2 LM 1.0",
  306. tempbuff))
  307. MIB_SessionTableElement->svSesClientType = 4 ;
  308. else if(0==strcmp("OS/2 LM 2.0",
  309. tempbuff))
  310. MIB_SessionTableElement->svSesClientType = 5 ;
  311. else if(0==strcmp("DOS LM 2.1",
  312. tempbuff))
  313. MIB_SessionTableElement->svSesClientType = 6 ;
  314. else if(0==strcmp("OS/2 LM 2.1",
  315. tempbuff))
  316. MIB_SessionTableElement->svSesClientType = 7 ;
  317. else if(0==strcmp("AFP 1.1",
  318. tempbuff))
  319. MIB_SessionTableElement->svSesClientType = 8 ;
  320. else if(0==strcmp("AFP 2.0",
  321. tempbuff))
  322. MIB_SessionTableElement->svSesClientType = 9 ;
  323. else if(0==strcmp("NT",
  324. tempbuff))
  325. MIB_SessionTableElement->svSesClientType = 10 ;
  326. SnmpUtilMemFree(tempbuff);
  327. // state is always active, set uses to indicate delete request
  328. MIB_SessionTableElement->svSesState = 1; //always active
  329. DataTable ++ ; // advance pointer to next sess entry in buffer
  330. MIB_SessionTableElement ++ ; // and table entry
  331. } // for each entry in the data table
  332. // free all of the lan man data
  333. SafeBufferFree( bufptr ) ;
  334. // indicate where to start adding on next pass, if any
  335. First_of_this_block = i ;
  336. } // if data is valid to process
  337. else
  338. {
  339. // Signal error
  340. nResult = SNMPAPI_ERROR;
  341. goto Exit;
  342. }
  343. } while (ERROR_MORE_DATA == lmCode) ;
  344. // iterate over the table populating the Oid field
  345. build_sess_entry_oids();
  346. // Sort the table information using MSC QuickSort routine
  347. qsort( (void *)&MIB_SessionTable.Table[0], (size_t)MIB_SessionTable.Len,
  348. (size_t)sizeof(SESS_ENTRY), sess_entry_cmp );
  349. //
  350. //
  351. // Cache table
  352. //
  353. //
  354. if(0 != MIB_SessionTable.Len) {
  355. cache_table[C_SESS_TABLE].acquisition_time = curr_time ;
  356. cache_table[C_SESS_TABLE].bufptr = bufptr ;
  357. }
  358. //
  359. //
  360. // Return piece of information requested
  361. //
  362. //
  363. Exit:
  364. return nResult;
  365. } // MIB_sess_get
  366. //
  367. // MIB_sess_cmp
  368. // Routine for sorting the session table.
  369. //
  370. // Notes:
  371. //
  372. // Return Codes:
  373. // SNMPAPI_NOERROR
  374. // SNMPAPI_ERROR
  375. //
  376. // Error Codes:
  377. // None.
  378. //
  379. int __cdecl sess_entry_cmp(
  380. IN const SESS_ENTRY *A,
  381. IN const SESS_ENTRY *B
  382. )
  383. {
  384. // Compare the OID's
  385. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  386. (AsnObjectIdentifier *)&B->Oid );
  387. } // MIB_sess_cmp
  388. //
  389. // None.
  390. //
  391. void build_sess_entry_oids(
  392. )
  393. {
  394. AsnOctetString OSA ;
  395. AsnObjectIdentifier UserNameOid ;
  396. SESS_ENTRY *SessEntry ;
  397. unsigned i;
  398. // start pointer at 1st guy in the table
  399. SessEntry = MIB_SessionTable.Table ;
  400. // now iterate over the table, creating an oid for each entry
  401. for( i=0; i<MIB_SessionTable.Len ; i++) {
  402. // for each entry in the session table
  403. // copy the client name into the oid buffer first
  404. MakeOidFromStr( &SessEntry->svSesClientName, &SessEntry->Oid );
  405. // copy the user name into a temporary oid buffer
  406. MakeOidFromStr( &SessEntry->svSesUserName, &UserNameOid );
  407. // append the two entries forming the index
  408. SnmpUtilOidAppend( &SessEntry->Oid, &UserNameOid );
  409. // free the temporary buffer
  410. SnmpUtilOidFree( &UserNameOid );
  411. SessEntry++; // point to the next guy in the table
  412. } // for
  413. } // build_sess_entry_oids
  414. //-------------------------------- END --------------------------------------