windows-nt/Source/XPSP1/NT/ds/security/authz/test/adl/adl.y
2020-09-26 16:20:57 +08:00

431 lines
8.9 KiB
Plaintext

%{
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
adl.y/adlparser.cpp
Abstract:
YACC parser definition for the ADL language
AdlParser::ParseAdl() function
Author:
t-eugenz - August 2000
Environment:
User mode only.
Revision History:
Created - August 2000
--*/
#include "pch.h"
#include "adl.h"
//
// YACC generates some long->short automatic conversion, disable the warning
//
#pragma warning(disable : 4242)
//
// ISSUE-2000/08/28-t-eugenz
// This is a private netlib function.
//
extern "C" NET_API_STATUS
NetpwNameValidate(
IN LPTSTR Name,
IN DWORD NameType,
IN DWORD Flags
);
//
// Name types for I_NetName* and I_NetListCanonicalize
//
#define NAMETYPE_USER 1
#define NAMETYPE_PASSWORD 2
#define NAMETYPE_GROUP 3
#define NAMETYPE_COMPUTER 4
#define NAMETYPE_EVENT 5
#define NAMETYPE_DOMAIN 6
#define NAMETYPE_SERVICE 7
#define NAMETYPE_NET 8
#define NAMETYPE_SHARE 9
#define NAMETYPE_MESSAGE 10
#define NAMETYPE_MESSAGEDEST 11
#define NAMETYPE_SHAREPASSWORD 12
#define NAMETYPE_WORKGROUP 13
//
// Validate various tokens, with error handling
// have to cast away const, since NetpNameValidate takes a non-const for some
// reason
//
#define VALIDATE_USERNAME(TOK) \
if( NetpwNameValidate( \
(WCHAR *)(TOK)->GetValue(), \
NAMETYPE_USER, \
0) != ERROR_SUCCESS) \
{ \
this->SetErrorToken( TOK ); \
throw AdlStatement::ERROR_INVALID_USERNAME; \
}
#define VALIDATE_DOMAIN(TOK) \
if( NetpwNameValidate( \
(WCHAR *)(TOK)->GetValue(), \
NAMETYPE_DOMAIN, \
0) != ERROR_SUCCESS) \
{ \
this->SetErrorToken( TOK ); \
throw AdlStatement::ERROR_INVALID_DOMAIN; \
}
#define VALIDATE_PERMISSION(TOK) \
{ \
for(DWORD i = 0;; i++) \
{ \
if( (_pControl->pPermissions)[i].str == NULL ) \
{ \
this->SetErrorToken( TOK ); \
throw AdlStatement::ERROR_UNKNOWN_PERMISSION; \
} \
if(!_wcsicmp(TOK->GetValue(), \
(_pControl->pPermissions)[i].str)) \
{ \
break; \
} \
} \
}
//
// YACC value type
//
#define YYSTYPE AdlToken *
//
// YACC error handler: raise an exception
//
void yyerror(char *szErr)
{
throw AdlStatement::ERROR_NOT_IN_LANGUAGE;
}
%}
%token TK_ERROR
%token TK_IDENT
%token TK_AT
%token TK_SLASH
%token TK_PERIOD
%token TK_COMMA
%token TK_OPENPAREN
%token TK_CLOSEPAREN
%token TK_SEMICOLON
%token TK_EXCEPT
%token TK_ON
%token TK_ALLOWED
%token TK_AND
%token TK_AS
%token TK_THIS_OBJECT
%token TK_CONTAINERS
%token TK_OBJECTS
%token TK_CONTAINERS_OBJECTS
%token TK_NO_PROPAGATE
%token TK_LANG_ENGLISH
%token TK_LANG_REVERSE
%start ADL
%%
ADL:
TK_LANG_ENGLISH ACRULE_LIST_ENGLISH
{
//
// At the end of all ADL_STATEMENT's
// pop the extra AdlTree that was pushed
// on when the last ADL_STATEMENT
// was completed
//
this->PopEmpty();
}
|
TK_LANG_REVERSE ACRULE_LIST_REVERSE
{
//
// At the end of all ADL_STATEMENT's
// pop the extra AdlTree that was pushed
// on when the last ADL_STATEMENT
// was completed
//
this->PopEmpty();
}
;
ACRULE_LIST_ENGLISH:
ACRULE_ENGLISH
|
ACRULE_LIST_ENGLISH ACRULE_ENGLISH
;
ACRULE_ENGLISH:
SEC_PRINCIPAL_LIST TK_OPENPAREN TK_EXCEPT EX_SEC_PRINCIPAL_LIST
TK_CLOSEPAREN TK_ALLOWED PERMISSION_LIST
TK_ON OBJECT_SPEC TK_SEMICOLON
{
this->Next();
}
|
SEC_PRINCIPAL_LIST TK_ALLOWED PERMISSION_LIST
TK_ON OBJECT_SPEC TK_SEMICOLON
{
this->Next();
}
;
ACRULE_LIST_REVERSE:
ACRULE_REVERSE
|
ACRULE_LIST_REVERSE ACRULE_REVERSE
;
ACRULE_REVERSE:
TK_OPENPAREN TK_EXCEPT EX_SEC_PRINCIPAL_LIST
TK_CLOSEPAREN SEC_PRINCIPAL_LIST TK_ALLOWED PERMISSION_LIST
TK_ON OBJECT_SPEC TK_SEMICOLON
{
this->Next();
}
|
SEC_PRINCIPAL_LIST TK_ALLOWED PERMISSION_LIST
TK_ON OBJECT_SPEC TK_SEMICOLON
{
this->Next();
}
;
SEC_PRINCIPAL_LIST:
SEC_PRINCIPAL
{
this->Cur()->AddPrincipal( $1 );
}
|
SEC_PRINCIPAL_LIST TK_COMMA SEC_PRINCIPAL
{
this->Cur()->AddPrincipal( $3 );
}
|
SEC_PRINCIPAL_LIST TK_AND SEC_PRINCIPAL
{
this->Cur()->AddPrincipal( $3 );
}
;
EX_SEC_PRINCIPAL_LIST:
SEC_PRINCIPAL
{
this->Cur()->AddExPrincipal( $1 );
}
|
EX_SEC_PRINCIPAL_LIST TK_COMMA SEC_PRINCIPAL
{
this->Cur()->AddExPrincipal( $3 );
}
|
EX_SEC_PRINCIPAL_LIST TK_AND SEC_PRINCIPAL
{
this->Cur()->AddExPrincipal( $3 );
}
;
PERMISSION_LIST:
PERMISSION
{
this->Cur()->AddPermission( $1 );
}
|
PERMISSION_LIST TK_AND PERMISSION
{
this->Cur()->AddPermission( $3 );
}
|
PERMISSION_LIST TK_COMMA PERMISSION
{
this->Cur()->AddPermission( $3 );
}
;
PERMISSION:
IDENTIFIER
{
VALIDATE_PERMISSION($1);
}
;
OBJECT_SPEC:
OBJECT
|
OBJECT_SPEC TK_AND OBJECT
|
OBJECT_SPEC TK_COMMA OBJECT
;
SEC_PRINCIPAL:
SUB_PRINCIPAL
|
SUB_PRINCIPAL TK_AS SUB_PRINCIPAL
{
//
// For now, impersonation is not supported
//
throw AdlStatement::ERROR_IMPERSONATION_UNSUPPORTED;
}
;
SUB_PRINCIPAL:
IDENTIFIER TK_AT DOMAIN
{
VALIDATE_USERNAME($1);
VALIDATE_DOMAIN($3);
AdlToken *newTok = new AdlToken($1->GetValue(),
$3->GetValue(),
$1->GetStart(),
$3->GetEnd());
this->AddToken(newTok);
$$ = newTok;
}
|
DOMAIN TK_SLASH IDENTIFIER
{
VALIDATE_USERNAME($3);
VALIDATE_DOMAIN($1);
AdlToken *newTok = new AdlToken($3->GetValue(),
$1->GetValue(),
$1->GetStart(),
$3->GetEnd());
this->AddToken(newTok);
$$ = newTok;
}
|
IDENTIFIER
{
VALIDATE_USERNAME($1);
$$ = $1;
}
;
DOMAIN:
IDENTIFIER
|
DOMAIN TK_PERIOD IDENTIFIER
{
//
// Concatenate into single domain string
//
wstring newStr;
newStr.append($1->GetValue());
newStr.append($2->GetValue());
newStr.append($3->GetValue());
AdlToken *newTok = new AdlToken(newStr.c_str(),
$1->GetStart(),
$1->GetEnd());
this->AddToken(newTok);
$$ = newTok;
}
;
OBJECT:
TK_THIS_OBJECT
{
this->Cur()->UnsetFlags(INHERIT_ONLY_ACE);
}
|
TK_CONTAINERS
{
this->Cur()->SetFlags(CONTAINER_INHERIT_ACE);
}
|
TK_OBJECTS
{
this->Cur()->SetFlags(OBJECT_INHERIT_ACE);
}
|
TK_CONTAINERS_OBJECTS
{
this->Cur()->SetFlags(CONTAINER_INHERIT_ACE);
this->Cur()->SetFlags(OBJECT_INHERIT_ACE);
}
|
TK_NO_PROPAGATE
{
this->Cur()->SetFlags(NO_PROPAGATE_INHERIT_ACE);
}
;
IDENTIFIER:
TK_IDENT
|
TK_ALLOWED
|
TK_AND
|
TK_AS
|
TK_EXCEPT
|
TK_ON
|
TK_ERROR
{
//
// This should never happen
//
throw AdlStatement::ERROR_FATAL_LEXER_ERROR;
}
;
%%