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.

584 lines
15 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. Names.c
  5. Abstract:
  6. This module contains routines for dealing with network-related names.
  7. Author:
  8. John Rogers (JohnRo) 25-Feb-1991
  9. Environment:
  10. Portable to more or less any environment. (Uses Win32 typedefs.)
  11. Requires ANSI C extensions:
  12. slash-slash comments
  13. long external names
  14. _stricmp(), _strnicmp()
  15. Revision History:
  16. 25-Feb-1991 JohnRo
  17. Created
  18. 15-Mar-1991 JohnRo
  19. Fixed bug in NetpIsRemoteNameValid(). Some minor style changes.
  20. 20-Mar-1991 RitaW
  21. Added NetpCanonRemoteName().
  22. 09-Apr-1991 JohnRo
  23. ANSI-ize (use _stricmp instead of _stricmp). Deleted tabs.
  24. 19-Aug-1991 JohnRo
  25. Allow UNICODE use.
  26. 30-Sep-1991 JohnRo
  27. More work toward UNICODE.
  28. 20-Oct-1992 JohnRo
  29. RAID 9020: setup: PortUas fails ("prompt on conflicts" version).
  30. Do full syntax checks on computer name.
  31. 26-Jan-1993 JohnRo
  32. RAID 8683: PortUAS should set primary group from Mac parms.
  33. Made changes suggested by PC-LINT 5.0
  34. 08-Feb-1993 JohnRo
  35. RAID 10299: portuas: generate assert in netlib/names.c
  36. 15-Apr-1993 JohnRo
  37. RAID 6167: avoid _access violation or assert with WFW print server.
  38. --*/
  39. // These must be included first:
  40. #include <windows.h> // IN, OUT, OPTIONAL, LPTSTR, etc.
  41. #include <lmcons.h> // NET_API_STATUS, CNLEN, RMLEN, etc.
  42. // These may be included in any order:
  43. #include <debuglib.h> // IF_DEBUG().
  44. #include <icanon.h> // ITYPE_ equates, NetpNameCanonicalize(), etc.
  45. #include <names.h> // My prototypes, etc.
  46. #include <netdebug.h> // NetpKdPrint(()).
  47. #include <prefix.h> // PREFIX_ equates.
  48. #include <tstring.h> // ISALPHA(), NetpAlloc routines, TCHAR_EOS, etc.
  49. #include <winerror.h> // NO_ERROR.
  50. //
  51. // Canon routines don't have a print Q support, so we (like everyone else)
  52. // have to treat them as share names.
  53. //
  54. #if (QNLEN != NNLEN)
  55. # error QNLEN and NNLEN are not equal
  56. #endif
  57. #ifndef NAMETYPE_PRINTQ
  58. #define NAMETYPE_PRINTQ NAMETYPE_SHARE
  59. #endif
  60. // This extracts a group name from "mGroup:" format.
  61. // Note that other chars may appear after the colon; they are ignored.
  62. NET_API_STATUS
  63. NetpGetPrimaryGroupFromMacField(
  64. IN LPCTSTR MacPrimaryField, // name in "mGroup:" format.
  65. OUT LPCTSTR * GroupNamePtr // alloc and set ptr.
  66. )
  67. {
  68. LPTSTR ColonPtr;
  69. DWORD GroupLen; // Length of group (in characters).
  70. TCHAR GroupName[LM20_GNLEN+1];
  71. LPTSTR GroupNameCopy;
  72. DWORD StringLen;
  73. // Avoid confusing caller's cleanup code.
  74. if (GroupNamePtr == NULL) {
  75. return (ERROR_INVALID_PARAMETER);
  76. }
  77. *GroupNamePtr = NULL;
  78. // Check for other caller errors.
  79. if (MacPrimaryField==NULL) {
  80. return (ERROR_INVALID_PARAMETER); // Empty field is not valid.
  81. } else if ( (*MacPrimaryField) != TEXT('m') ) {
  82. return (ERROR_INVALID_PARAMETER); // Must start with lower case 'm'.
  83. }
  84. StringLen = STRLEN( MacPrimaryField );
  85. if (StringLen <= 2) { // Must be room for 'm', group, ':' (at least 3).
  86. return (ERROR_INVALID_PARAMETER);
  87. }
  88. ColonPtr = STRCHR( MacPrimaryField, TCHAR_COLON );
  89. if (ColonPtr == NULL) {
  90. return (ERROR_INVALID_PARAMETER); // No, not valid (must have colon).
  91. }
  92. // Compute group length in characters, without 'm' or ':'.
  93. GroupLen = (DWORD) ((ColonPtr - MacPrimaryField) - 1);
  94. if (GroupLen == 0) {
  95. return (ERROR_INVALID_PARAMETER); // No, not valid (missing group).
  96. }
  97. if (GroupLen > LM20_GNLEN) {
  98. return (ERROR_INVALID_PARAMETER); // No, not valid (too long).
  99. }
  100. (VOID) STRNCPY(
  101. GroupName, // dest
  102. &MacPrimaryField[1], // src (after 'm')
  103. GroupLen ); // char count
  104. GroupName[ GroupLen ] = TCHAR_EOS;
  105. if ( !NetpIsGroupNameValid( GroupName ) ) {
  106. return (ERROR_INVALID_PARAMETER);
  107. }
  108. GroupNameCopy = NetpAllocWStrFromWStr( GroupName );
  109. if (GroupNameCopy == NULL) {
  110. return (ERROR_NOT_ENOUGH_MEMORY);
  111. }
  112. *GroupNamePtr = GroupNameCopy;
  113. return (NO_ERROR);
  114. } // NetpGetPrimaryGroupFromMacField
  115. BOOL
  116. NetpIsComputerNameValid(
  117. IN LPTSTR ComputerName
  118. )
  119. /*++
  120. Routine Description:
  121. NetpIsComputerNameValid checks for "server" (not "\\server") format.
  122. The name is only checked syntactically; no attempt is made to determine
  123. whether or not a server with that name actually exists.
  124. Arguments:
  125. ComputerName - Supplies an alleged computer (server) name.
  126. Return Value:
  127. BOOL - TRUE if name is syntactically valid, FALSE otherwise.
  128. --*/
  129. {
  130. NET_API_STATUS ApiStatus;
  131. TCHAR CanonBuf[MAX_PATH];
  132. if (ComputerName == (LPTSTR) NULL) {
  133. return (FALSE);
  134. }
  135. if ( (*ComputerName) == TCHAR_EOS ) {
  136. return (FALSE);
  137. }
  138. ApiStatus = NetpNameCanonicalize(
  139. NULL, // no server name
  140. ComputerName, // name to validate
  141. CanonBuf, // output buffer
  142. sizeof( CanonBuf ), // output buffer size
  143. NAMETYPE_COMPUTER, // type
  144. 0 ); // flags: none
  145. IF_DEBUG( NAMES ) {
  146. if (ApiStatus != NO_ERROR) {
  147. NetpKdPrint(( PREFIX_NETLIB
  148. "NetpIsComputerNameValid: err " FORMAT_API_STATUS
  149. " after canon of '" FORMAT_LPTSTR "'.\n",
  150. ApiStatus, ComputerName ));
  151. }
  152. }
  153. return (ApiStatus == NO_ERROR);
  154. } // NetpIsComputerNameValid
  155. BOOL
  156. NetpIsDomainNameValid(
  157. IN LPTSTR DomainName
  158. )
  159. /*++
  160. Routine Description:
  161. NetpIsDomainNameValid checks for "domain" format.
  162. The name is only checked syntactically; no attempt is made to determine
  163. whether or not a domain with that name actually exists.
  164. Arguments:
  165. DomainName - Supplies an alleged Domain name.
  166. Return Value:
  167. BOOL - TRUE if name is syntactically valid, FALSE otherwise.
  168. --*/
  169. {
  170. NET_API_STATUS ApiStatus;
  171. TCHAR CanonBuf[DNLEN+1];
  172. if (DomainName == (LPTSTR) NULL) {
  173. return (FALSE);
  174. }
  175. if ( (*DomainName) == TCHAR_EOS ) {
  176. return (FALSE);
  177. }
  178. ApiStatus = NetpNameCanonicalize(
  179. NULL, // no server name
  180. DomainName, // name to validate
  181. CanonBuf, // output buffer
  182. (DNLEN+1) * sizeof(TCHAR), // output buffer size
  183. NAMETYPE_DOMAIN, // type
  184. 0 ); // flags: none
  185. IF_DEBUG( NAMES ) {
  186. if (ApiStatus != NO_ERROR) {
  187. NetpKdPrint(( PREFIX_NETLIB
  188. "NetpIsDomainNameValid: err " FORMAT_API_STATUS
  189. " after canon of '" FORMAT_LPTSTR "'.\n",
  190. ApiStatus, DomainName ));
  191. }
  192. }
  193. return (ApiStatus == NO_ERROR);
  194. } // NetpIsDomainNameValid
  195. BOOL
  196. NetpIsShareNameValid(
  197. IN LPTSTR ShareName
  198. )
  199. /*++
  200. Routine Description:
  201. NetpIsShareNameValid checks for "share" format.
  202. The name is only checked syntactically; no attempt is made to determine
  203. whether or not a share with that name actually exists.
  204. Arguments:
  205. ShareName - Supplies an alleged Share name.
  206. Return Value:
  207. BOOL - TRUE if name is syntactically valid, FALSE otherwise.
  208. --*/
  209. {
  210. NET_API_STATUS ApiStatus;
  211. TCHAR CanonBuf[SNLEN+1];
  212. if (ShareName == (LPTSTR) NULL) {
  213. return (FALSE);
  214. }
  215. if ( (*ShareName) == TCHAR_EOS ) {
  216. return (FALSE);
  217. }
  218. ApiStatus = NetpNameCanonicalize(
  219. NULL, // no server name
  220. ShareName, // name to validate
  221. CanonBuf, // output buffer
  222. (SNLEN+1) * sizeof(TCHAR), // output buffer size
  223. NAMETYPE_SHARE, // type
  224. 0 ); // flags: none
  225. IF_DEBUG( NAMES ) {
  226. if (ApiStatus != NO_ERROR) {
  227. NetpKdPrint(( PREFIX_NETLIB
  228. "NetpIsShareNameValid: err " FORMAT_API_STATUS
  229. " after canon of '" FORMAT_LPTSTR "'.\n",
  230. ApiStatus, ShareName ));
  231. }
  232. }
  233. return (ApiStatus == NO_ERROR);
  234. } // NetpIsShareNameValid
  235. BOOL
  236. NetpIsGroupNameValid(
  237. IN LPTSTR GroupName
  238. )
  239. {
  240. NET_API_STATUS ApiStatus;
  241. TCHAR CanonBuf[UNLEN+1];
  242. if (GroupName == (LPTSTR) NULL) {
  243. return (FALSE);
  244. }
  245. if ( (*GroupName) == TCHAR_EOS ) {
  246. return (FALSE);
  247. }
  248. ApiStatus = NetpNameCanonicalize(
  249. NULL, // no server name
  250. GroupName, // name to validate
  251. CanonBuf, // output buffer
  252. (UNLEN+1) * sizeof(TCHAR), // output buffer size
  253. NAMETYPE_GROUP, // type
  254. 0 ); // flags: none
  255. IF_DEBUG( NAMES ) {
  256. if (ApiStatus != NO_ERROR) {
  257. NetpKdPrint(( PREFIX_NETLIB
  258. "NetpIsGroupNameValid: err " FORMAT_API_STATUS
  259. " after canon of '" FORMAT_LPTSTR "'.\n",
  260. ApiStatus, GroupName ));
  261. }
  262. }
  263. return (ApiStatus == NO_ERROR);
  264. } // NetpIsGroupNameValid
  265. // This checks for "mGroup:" format.
  266. // Note that other chars may appear after the colon; they are ignored.
  267. BOOL
  268. NetpIsMacPrimaryGroupFieldValid(
  269. IN LPCTSTR MacPrimaryField
  270. )
  271. {
  272. LPTSTR ColonPtr;
  273. DWORD GroupLen; // Length of group (in characters).
  274. TCHAR GroupName[LM20_GNLEN+1];
  275. DWORD StringLen;
  276. if (MacPrimaryField==NULL) {
  277. return (FALSE); // Empty field is not valid.
  278. } else if ( (*MacPrimaryField) != TEXT('m') ) {
  279. return (FALSE); // Must start with lower case 'm'.
  280. }
  281. StringLen = STRLEN( MacPrimaryField );
  282. if (StringLen <= 2) { // Must be room for 'm', group, ':' (at least 3).
  283. return (FALSE);
  284. }
  285. ColonPtr = STRCHR( MacPrimaryField, TCHAR_COLON );
  286. if (ColonPtr == NULL) {
  287. return (FALSE); // No, not valid (must have colon).
  288. }
  289. // Compute group length in characters, without 'm' or ':'.
  290. GroupLen = (DWORD) ((ColonPtr - MacPrimaryField) - 1);
  291. if (GroupLen == 0) {
  292. return (FALSE); // No, not valid (missing group).
  293. }
  294. if (GroupLen > LM20_GNLEN) {
  295. return (FALSE); // No, not valid (too long).
  296. }
  297. (VOID) STRNCPY(
  298. GroupName, // dest
  299. &MacPrimaryField[1], // src (after 'm')
  300. GroupLen ); // char count
  301. GroupName[ GroupLen ] = TCHAR_EOS;
  302. return (NetpIsGroupNameValid( GroupName ));
  303. } // NetpIsMacPrimaryGroupFieldValid
  304. BOOL
  305. NetpIsPrintQueueNameValid(
  306. IN LPCTSTR QueueName
  307. )
  308. {
  309. NET_API_STATUS ApiStatus;
  310. TCHAR CanonBuf[ MAX_PATH ];
  311. if (QueueName == NULL) {
  312. return (FALSE);
  313. }
  314. if ( (*QueueName) == TCHAR_EOS ) {
  315. return (FALSE);
  316. }
  317. ApiStatus = NetpNameCanonicalize(
  318. NULL, // no server name
  319. (LPTSTR) QueueName, // name to validate
  320. CanonBuf, // output buffer
  321. sizeof( CanonBuf ), // output buffer size
  322. NAMETYPE_PRINTQ, // type
  323. 0 ); // flags: none
  324. IF_DEBUG( NAMES ) {
  325. if (ApiStatus != NO_ERROR) {
  326. NetpKdPrint(( PREFIX_NETLIB
  327. "NetpIsPrintQueuNameValid: err " FORMAT_API_STATUS
  328. " after canon of '" FORMAT_LPTSTR "'.\n",
  329. ApiStatus, QueueName ));
  330. }
  331. }
  332. return (ApiStatus == NO_ERROR);
  333. } // NetpIsPrintQueueNameValid
  334. BOOL
  335. NetpIsRemoteNameValid(
  336. IN LPTSTR RemoteName
  337. )
  338. /*++
  339. Routine Description:
  340. NetpIsRemoteNameValid checks for "\\server\share" format. The name is
  341. only checked syntactically; no attempt is made to determine whether or
  342. not a server or share with that name actually exists. Forward slashes
  343. are acceptable.
  344. Arguments:
  345. RemoteName - Supplies an alleged remote name.
  346. Return Value:
  347. BOOL - TRUE if name is syntactically valid, FALSE otherwise.
  348. --*/
  349. {
  350. if (RemoteName == (LPTSTR) NULL) {
  351. return (FALSE);
  352. }
  353. //
  354. // Shortest is \\x\y (5).
  355. //
  356. if ((STRLEN(RemoteName) < 5) || (STRLEN(RemoteName) > MAX_PATH )) {
  357. return (FALSE);
  358. }
  359. //
  360. // First two characters must be slashes.
  361. //
  362. if (((RemoteName[0] != '\\') && (RemoteName[0] != '/')) ||
  363. ((RemoteName[1] != '\\') && (RemoteName[1] != '/'))) {
  364. return (FALSE);
  365. }
  366. //
  367. // Three leading \ or / is illegal.
  368. //
  369. if ((RemoteName[2] == '\\') || (RemoteName[2] == '/')) {
  370. return (FALSE);
  371. }
  372. //
  373. // Must have a least 1 \ or / inside.
  374. //
  375. if ((STRCHR(&RemoteName[2], '\\') == NULL) &&
  376. (STRCHR(&RemoteName[2], '/') == NULL)) {
  377. return (FALSE);
  378. }
  379. return (TRUE);
  380. } // NetpIsRemoteNameValid
  381. BOOL
  382. NetpIsUncComputerNameValid(
  383. IN LPTSTR ComputerName
  384. )
  385. /*++
  386. Routine Description:
  387. NetpIsUncComputerNameValid checks for "\\server" format. The name is
  388. only checked syntactically; no attempt is made to determine whether or
  389. not a server with that name actually exists.
  390. Arguments:
  391. ComputerName - Supplies an alleged computer (server) name.
  392. Return Value:
  393. BOOL - TRUE if name is syntactically valid, FALSE otherwise.
  394. --*/
  395. {
  396. if (ComputerName == (LPTSTR) NULL) {
  397. return (FALSE);
  398. }
  399. if ( ! IS_PATH_SEPARATOR( ComputerName[0] ) ) {
  400. return (FALSE);
  401. }
  402. if ( ! IS_PATH_SEPARATOR( ComputerName[1] ) ) {
  403. return (FALSE);
  404. }
  405. return (NetpIsComputerNameValid( &ComputerName[2]) );
  406. } // NetpIsUncComputerNameValid
  407. BOOL
  408. NetpIsUserNameValid(
  409. IN LPTSTR UserName
  410. )
  411. {
  412. NET_API_STATUS ApiStatus;
  413. TCHAR CanonBuf[UNLEN+1];
  414. if (UserName == (LPTSTR) NULL) {
  415. return (FALSE);
  416. }
  417. if ( (*UserName) == TCHAR_EOS ) {
  418. return (FALSE);
  419. }
  420. ApiStatus = NetpNameCanonicalize(
  421. NULL, // no server name
  422. UserName, // name to validate
  423. CanonBuf, // output buffer
  424. (UNLEN+1) * sizeof(TCHAR), // output buffer size
  425. NAMETYPE_USER, // type
  426. 0 ); // flags: none
  427. IF_DEBUG( NAMES ) {
  428. if (ApiStatus != NO_ERROR) {
  429. NetpKdPrint(( PREFIX_NETLIB
  430. "NetpIsUserNameValid: err " FORMAT_API_STATUS
  431. " after canon of '" FORMAT_LPTSTR "'.\n",
  432. ApiStatus, UserName ));
  433. }
  434. }
  435. return (ApiStatus == NO_ERROR);
  436. } // NetpIsUserNameValid