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

/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
Names.c
Abstract:
This module contains routines for dealing with network-related names.
Author:
John Rogers (JohnRo) 25-Feb-1991
Environment:
Portable to more or less any environment. (Uses Win32 typedefs.)
Requires ANSI C extensions:
slash-slash comments
long external names
_stricmp(), _strnicmp()
Revision History:
25-Feb-1991 JohnRo
Created
15-Mar-1991 JohnRo
Fixed bug in NetpIsRemoteNameValid(). Some minor style changes.
20-Mar-1991 RitaW
Added NetpCanonRemoteName().
09-Apr-1991 JohnRo
ANSI-ize (use _stricmp instead of _stricmp). Deleted tabs.
19-Aug-1991 JohnRo
Allow UNICODE use.
30-Sep-1991 JohnRo
More work toward UNICODE.
20-Oct-1992 JohnRo
RAID 9020: setup: PortUas fails ("prompt on conflicts" version).
Do full syntax checks on computer name.
26-Jan-1993 JohnRo
RAID 8683: PortUAS should set primary group from Mac parms.
Made changes suggested by PC-LINT 5.0
08-Feb-1993 JohnRo
RAID 10299: portuas: generate assert in netlib/names.c
15-Apr-1993 JohnRo
RAID 6167: avoid _access violation or assert with WFW print server.
--*/
// These must be included first:
#include <windows.h> // IN, OUT, OPTIONAL, LPTSTR, etc.
#include <lmcons.h> // NET_API_STATUS, CNLEN, RMLEN, etc.
// These may be included in any order:
#include <debuglib.h> // IF_DEBUG().
#include <icanon.h> // ITYPE_ equates, NetpNameCanonicalize(), etc.
#include <names.h> // My prototypes, etc.
#include <netdebug.h> // NetpKdPrint(()).
#include <prefix.h> // PREFIX_ equates.
#include <tstring.h> // ISALPHA(), NetpAlloc routines, TCHAR_EOS, etc.
#include <winerror.h> // NO_ERROR.
//
// Canon routines don't have a print Q support, so we (like everyone else)
// have to treat them as share names.
//
#if (QNLEN != NNLEN)
# error QNLEN and NNLEN are not equal
#endif
#ifndef NAMETYPE_PRINTQ
#define NAMETYPE_PRINTQ NAMETYPE_SHARE
#endif
// This extracts a group name from "mGroup:" format.
// Note that other chars may appear after the colon; they are ignored.
NET_API_STATUS
NetpGetPrimaryGroupFromMacField(
IN LPCTSTR MacPrimaryField, // name in "mGroup:" format.
OUT LPCTSTR * GroupNamePtr // alloc and set ptr.
)
{
LPTSTR ColonPtr;
DWORD GroupLen; // Length of group (in characters).
TCHAR GroupName[LM20_GNLEN+1];
LPTSTR GroupNameCopy;
DWORD StringLen;
// Avoid confusing caller's cleanup code.
if (GroupNamePtr == NULL) {
return (ERROR_INVALID_PARAMETER);
}
*GroupNamePtr = NULL;
// Check for other caller errors.
if (MacPrimaryField==NULL) {
return (ERROR_INVALID_PARAMETER); // Empty field is not valid.
} else if ( (*MacPrimaryField) != TEXT('m') ) {
return (ERROR_INVALID_PARAMETER); // Must start with lower case 'm'.
}
StringLen = STRLEN( MacPrimaryField );
if (StringLen <= 2) { // Must be room for 'm', group, ':' (at least 3).
return (ERROR_INVALID_PARAMETER);
}
ColonPtr = STRCHR( MacPrimaryField, TCHAR_COLON );
if (ColonPtr == NULL) {
return (ERROR_INVALID_PARAMETER); // No, not valid (must have colon).
}
// Compute group length in characters, without 'm' or ':'.
GroupLen = (DWORD) ((ColonPtr - MacPrimaryField) - 1);
if (GroupLen == 0) {
return (ERROR_INVALID_PARAMETER); // No, not valid (missing group).
}
if (GroupLen > LM20_GNLEN) {
return (ERROR_INVALID_PARAMETER); // No, not valid (too long).
}
(VOID) STRNCPY(
GroupName, // dest
&MacPrimaryField[1], // src (after 'm')
GroupLen ); // char count
GroupName[ GroupLen ] = TCHAR_EOS;
if ( !NetpIsGroupNameValid( GroupName ) ) {
return (ERROR_INVALID_PARAMETER);
}
GroupNameCopy = NetpAllocWStrFromWStr( GroupName );
if (GroupNameCopy == NULL) {
return (ERROR_NOT_ENOUGH_MEMORY);
}
*GroupNamePtr = GroupNameCopy;
return (NO_ERROR);
} // NetpGetPrimaryGroupFromMacField
BOOL
NetpIsComputerNameValid(
IN LPTSTR ComputerName
)
/*++
Routine Description:
NetpIsComputerNameValid checks for "server" (not "\\server") format.
The name is only checked syntactically; no attempt is made to determine
whether or not a server with that name actually exists.
Arguments:
ComputerName - Supplies an alleged computer (server) name.
Return Value:
BOOL - TRUE if name is syntactically valid, FALSE otherwise.
--*/
{
NET_API_STATUS ApiStatus;
TCHAR CanonBuf[MAX_PATH];
if (ComputerName == (LPTSTR) NULL) {
return (FALSE);
}
if ( (*ComputerName) == TCHAR_EOS ) {
return (FALSE);
}
ApiStatus = NetpNameCanonicalize(
NULL, // no server name
ComputerName, // name to validate
CanonBuf, // output buffer
sizeof( CanonBuf ), // output buffer size
NAMETYPE_COMPUTER, // type
0 ); // flags: none
IF_DEBUG( NAMES ) {
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_NETLIB
"NetpIsComputerNameValid: err " FORMAT_API_STATUS
" after canon of '" FORMAT_LPTSTR "'.\n",
ApiStatus, ComputerName ));
}
}
return (ApiStatus == NO_ERROR);
} // NetpIsComputerNameValid
BOOL
NetpIsDomainNameValid(
IN LPTSTR DomainName
)
/*++
Routine Description:
NetpIsDomainNameValid checks for "domain" format.
The name is only checked syntactically; no attempt is made to determine
whether or not a domain with that name actually exists.
Arguments:
DomainName - Supplies an alleged Domain name.
Return Value:
BOOL - TRUE if name is syntactically valid, FALSE otherwise.
--*/
{
NET_API_STATUS ApiStatus;
TCHAR CanonBuf[DNLEN+1];
if (DomainName == (LPTSTR) NULL) {
return (FALSE);
}
if ( (*DomainName) == TCHAR_EOS ) {
return (FALSE);
}
ApiStatus = NetpNameCanonicalize(
NULL, // no server name
DomainName, // name to validate
CanonBuf, // output buffer
(DNLEN+1) * sizeof(TCHAR), // output buffer size
NAMETYPE_DOMAIN, // type
0 ); // flags: none
IF_DEBUG( NAMES ) {
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_NETLIB
"NetpIsDomainNameValid: err " FORMAT_API_STATUS
" after canon of '" FORMAT_LPTSTR "'.\n",
ApiStatus, DomainName ));
}
}
return (ApiStatus == NO_ERROR);
} // NetpIsDomainNameValid
BOOL
NetpIsShareNameValid(
IN LPTSTR ShareName
)
/*++
Routine Description:
NetpIsShareNameValid checks for "share" format.
The name is only checked syntactically; no attempt is made to determine
whether or not a share with that name actually exists.
Arguments:
ShareName - Supplies an alleged Share name.
Return Value:
BOOL - TRUE if name is syntactically valid, FALSE otherwise.
--*/
{
NET_API_STATUS ApiStatus;
TCHAR CanonBuf[SNLEN+1];
if (ShareName == (LPTSTR) NULL) {
return (FALSE);
}
if ( (*ShareName) == TCHAR_EOS ) {
return (FALSE);
}
ApiStatus = NetpNameCanonicalize(
NULL, // no server name
ShareName, // name to validate
CanonBuf, // output buffer
(SNLEN+1) * sizeof(TCHAR), // output buffer size
NAMETYPE_SHARE, // type
0 ); // flags: none
IF_DEBUG( NAMES ) {
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_NETLIB
"NetpIsShareNameValid: err " FORMAT_API_STATUS
" after canon of '" FORMAT_LPTSTR "'.\n",
ApiStatus, ShareName ));
}
}
return (ApiStatus == NO_ERROR);
} // NetpIsShareNameValid
BOOL
NetpIsGroupNameValid(
IN LPTSTR GroupName
)
{
NET_API_STATUS ApiStatus;
TCHAR CanonBuf[UNLEN+1];
if (GroupName == (LPTSTR) NULL) {
return (FALSE);
}
if ( (*GroupName) == TCHAR_EOS ) {
return (FALSE);
}
ApiStatus = NetpNameCanonicalize(
NULL, // no server name
GroupName, // name to validate
CanonBuf, // output buffer
(UNLEN+1) * sizeof(TCHAR), // output buffer size
NAMETYPE_GROUP, // type
0 ); // flags: none
IF_DEBUG( NAMES ) {
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_NETLIB
"NetpIsGroupNameValid: err " FORMAT_API_STATUS
" after canon of '" FORMAT_LPTSTR "'.\n",
ApiStatus, GroupName ));
}
}
return (ApiStatus == NO_ERROR);
} // NetpIsGroupNameValid
// This checks for "mGroup:" format.
// Note that other chars may appear after the colon; they are ignored.
BOOL
NetpIsMacPrimaryGroupFieldValid(
IN LPCTSTR MacPrimaryField
)
{
LPTSTR ColonPtr;
DWORD GroupLen; // Length of group (in characters).
TCHAR GroupName[LM20_GNLEN+1];
DWORD StringLen;
if (MacPrimaryField==NULL) {
return (FALSE); // Empty field is not valid.
} else if ( (*MacPrimaryField) != TEXT('m') ) {
return (FALSE); // Must start with lower case 'm'.
}
StringLen = STRLEN( MacPrimaryField );
if (StringLen <= 2) { // Must be room for 'm', group, ':' (at least 3).
return (FALSE);
}
ColonPtr = STRCHR( MacPrimaryField, TCHAR_COLON );
if (ColonPtr == NULL) {
return (FALSE); // No, not valid (must have colon).
}
// Compute group length in characters, without 'm' or ':'.
GroupLen = (DWORD) ((ColonPtr - MacPrimaryField) - 1);
if (GroupLen == 0) {
return (FALSE); // No, not valid (missing group).
}
if (GroupLen > LM20_GNLEN) {
return (FALSE); // No, not valid (too long).
}
(VOID) STRNCPY(
GroupName, // dest
&MacPrimaryField[1], // src (after 'm')
GroupLen ); // char count
GroupName[ GroupLen ] = TCHAR_EOS;
return (NetpIsGroupNameValid( GroupName ));
} // NetpIsMacPrimaryGroupFieldValid
BOOL
NetpIsPrintQueueNameValid(
IN LPCTSTR QueueName
)
{
NET_API_STATUS ApiStatus;
TCHAR CanonBuf[ MAX_PATH ];
if (QueueName == NULL) {
return (FALSE);
}
if ( (*QueueName) == TCHAR_EOS ) {
return (FALSE);
}
ApiStatus = NetpNameCanonicalize(
NULL, // no server name
(LPTSTR) QueueName, // name to validate
CanonBuf, // output buffer
sizeof( CanonBuf ), // output buffer size
NAMETYPE_PRINTQ, // type
0 ); // flags: none
IF_DEBUG( NAMES ) {
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_NETLIB
"NetpIsPrintQueuNameValid: err " FORMAT_API_STATUS
" after canon of '" FORMAT_LPTSTR "'.\n",
ApiStatus, QueueName ));
}
}
return (ApiStatus == NO_ERROR);
} // NetpIsPrintQueueNameValid
BOOL
NetpIsRemoteNameValid(
IN LPTSTR RemoteName
)
/*++
Routine Description:
NetpIsRemoteNameValid checks for "\\server\share" format. The name is
only checked syntactically; no attempt is made to determine whether or
not a server or share with that name actually exists. Forward slashes
are acceptable.
Arguments:
RemoteName - Supplies an alleged remote name.
Return Value:
BOOL - TRUE if name is syntactically valid, FALSE otherwise.
--*/
{
if (RemoteName == (LPTSTR) NULL) {
return (FALSE);
}
//
// Shortest is \\x\y (5).
//
if ((STRLEN(RemoteName) < 5) || (STRLEN(RemoteName) > MAX_PATH )) {
return (FALSE);
}
//
// First two characters must be slashes.
//
if (((RemoteName[0] != '\\') && (RemoteName[0] != '/')) ||
((RemoteName[1] != '\\') && (RemoteName[1] != '/'))) {
return (FALSE);
}
//
// Three leading \ or / is illegal.
//
if ((RemoteName[2] == '\\') || (RemoteName[2] == '/')) {
return (FALSE);
}
//
// Must have a least 1 \ or / inside.
//
if ((STRCHR(&RemoteName[2], '\\') == NULL) &&
(STRCHR(&RemoteName[2], '/') == NULL)) {
return (FALSE);
}
return (TRUE);
} // NetpIsRemoteNameValid
BOOL
NetpIsUncComputerNameValid(
IN LPTSTR ComputerName
)
/*++
Routine Description:
NetpIsUncComputerNameValid checks for "\\server" format. The name is
only checked syntactically; no attempt is made to determine whether or
not a server with that name actually exists.
Arguments:
ComputerName - Supplies an alleged computer (server) name.
Return Value:
BOOL - TRUE if name is syntactically valid, FALSE otherwise.
--*/
{
if (ComputerName == (LPTSTR) NULL) {
return (FALSE);
}
if ( ! IS_PATH_SEPARATOR( ComputerName[0] ) ) {
return (FALSE);
}
if ( ! IS_PATH_SEPARATOR( ComputerName[1] ) ) {
return (FALSE);
}
return (NetpIsComputerNameValid( &ComputerName[2]) );
} // NetpIsUncComputerNameValid
BOOL
NetpIsUserNameValid(
IN LPTSTR UserName
)
{
NET_API_STATUS ApiStatus;
TCHAR CanonBuf[UNLEN+1];
if (UserName == (LPTSTR) NULL) {
return (FALSE);
}
if ( (*UserName) == TCHAR_EOS ) {
return (FALSE);
}
ApiStatus = NetpNameCanonicalize(
NULL, // no server name
UserName, // name to validate
CanonBuf, // output buffer
(UNLEN+1) * sizeof(TCHAR), // output buffer size
NAMETYPE_USER, // type
0 ); // flags: none
IF_DEBUG( NAMES ) {
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_NETLIB
"NetpIsUserNameValid: err " FORMAT_API_STATUS
" after canon of '" FORMAT_LPTSTR "'.\n",
ApiStatus, UserName ));
}
}
return (ApiStatus == NO_ERROR);
} // NetpIsUserNameValid