📄 policy.c
字号:
filename = FilePath;
else
++filename;
/* if user policy load fails, we loop here again to load the global policy */
ReloadPolicy:
if (UserName != NULL)
_snwprintf(PolicyPath, MAX_PATH, L"\\??\\%s\\policy\\%s\\%s.policy", OzoneInstallPath, UserName, filename);
else
_snwprintf(PolicyPath, MAX_PATH, L"\\??\\%s\\policy\\%s.policy", OzoneInstallPath, filename);
PolicyPath[MAX_PATH - 1] = 0;
LOG(LOG_SS_POLICY, LOG_PRIORITY_VERBOSE, ("FindAndLoadSecurityPolicy: Loading policy for %S (%S)\n", PolicyPath, FilePath));
ret = LoadSecurityPolicy(pSecPolicy, PolicyPath, FilePath);
if (ret == FALSE)
{
/* If we can't find a policy specific to a user, try to load a global policy instead */
if (UserName != NULL)
{
LOG(LOG_SS_POLICY, LOG_PRIORITY_DEBUG, ("FindAndLoadSecurityPolicy: Cannot find '%S' policy for user '%S'. Looking for a global policy..\n", filename, UserName));
UserName = NULL;
goto ReloadPolicy;
}
return FALSE;
}
/* allocate extra space for ".policy" string */
len = wcslen(filename) + 7 + 1;
pSecPolicy->Name = ExAllocatePoolWithTag(NonPagedPool, len * sizeof(WCHAR), _POOL_TAG);
if (pSecPolicy->Name != NULL)
{
_snwprintf(pSecPolicy->Name, len, L"%s.policy", filename);
}
else
{
PolicyDelete(pSecPolicy);
ret = FALSE;
}
return ret;
}
/*
* PolicyParseRule()
*
* Description:
* Parses a specified rule.
*
* Parameters:
* pSecPolicy - pointer to a security policy that will contain the parsed rule.
* rule - string buffer containing a rule to parse.
* Critical - Boolean indicating whether the parser should abort parsing the policy due to a critical error.
*
* Returns:
* TRUE if the policy rule was successfully parsed and loaded, FALSE otherwise.
*/
#define SKIP_WHITESPACE(str) do { while(*(str) == ' ' || *(str) == '\t') ++(str); } while(0)
#define IS_WHITESPACE(c) ((c) == ' ' || (c) == '\t')
/* macro shortcut for bailing out of PolicyParseRule() in case of an error */
#define ABORT_PolicyParseRule(msg) \
do { \
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, ("Encountered an error while parsing %S:%d :\n", gPolicyFilename, gPolicyLineNumber)); \
LOG(LOG_SS_POLICY_PARSER, LOG_PRIORITY_WARNING, msg); \
return FALSE; \
} while (0)
static BOOLEAN
PolicyParseRule(OUT PSECURITY_POLICY pSecPolicy, IN PCHAR rule, OUT BOOLEAN *Critical)
{
CHAR ServiceName[POLICY_MAX_SERVICE_NAME_LENGTH];
PCHAR OriginalRule = rule;
int i = 0, SawSpace = 0, SawUnderscore = 0;
*Critical = FALSE;
SKIP_WHITESPACE(rule);
/* skip empty lines */
if (*rule == 0)
return TRUE;
/* comments start with '#' */
if (*rule == '#')
return TRUE;
/*
* Parse the service name. Format: "ServiceName:" or "ServiceName_OperationType:"
* where ServiceName can be "file", "registry", "event", "memory", etc
* and OperationType can be "read", "write", "rw"
*/
while (*rule != 0 && *rule != ':')
{
/* is the specified syscall name too long? */
if (i > POLICY_MAX_SERVICE_NAME_LENGTH - 1)
ABORT_PolicyParseRule(("Rule type specification is too long. Maximum rule type specification length is %d characters.\n", POLICY_MAX_SERVICE_NAME_LENGTH));
/* allow whitespace before the colon */
if (IS_WHITESPACE(*rule))
{
++rule;
SawSpace = 1;
continue;
}
/* Service Names are not allowed to contain a space */
if (SawSpace)
ABORT_PolicyParseRule(("Rule type specification cannot contain a space\n"));
/* Expecting to see 1 underscore '_' */
if (*rule == '_')
{
/* There can be only be 1 underscore char. and it cannot be the first char. */
if (i == 0 || SawUnderscore)
ABORT_PolicyParseRule(("Rule type specification cannot contain multiple underscore characters\n"));
/* remember the underscore position */
SawUnderscore = i;
}
ServiceName[i++] = *rule++;
}
/* Expecting to have read more than 1 character, finishing with a ':' */
if (i == 0 || *rule++ != ':')
ABORT_PolicyParseRule(("Colon not found. Rule type specification must end with a colon ':'.\n"));
ServiceName[i] = 0;
SKIP_WHITESPACE(rule);
/* didn't see any underscores. assume "system_call_name:" format */
if (SawUnderscore == 0)
ABORT_PolicyParseRule(("Underscore not found. Rule type specification must contain an underscore.\n"));
ServiceName[SawUnderscore] = 0;
// file operation
if (strlen(ServiceName) == 4 && _stricmp(ServiceName, "file") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_FILE, ServiceName + SawUnderscore + 1, rule);
// directory operation
if (strlen(ServiceName) == 9 && _stricmp(ServiceName, "directory") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_DIRECTORY, ServiceName + SawUnderscore + 1, rule);
// registry operation
if (strlen(ServiceName) == 8 && _stricmp(ServiceName, "registry") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_REGISTRY, ServiceName + SawUnderscore + 1, rule);
// memory section operation
if (strlen(ServiceName) == 7 && _stricmp(ServiceName, "section") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_SECTION, ServiceName + SawUnderscore + 1, rule);
// memory section / dll operation
if (strlen(ServiceName) == 3 && _stricmp(ServiceName, "dll") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_DLL, ServiceName + SawUnderscore + 1, rule);
// event operation
if (strlen(ServiceName) == 5 && _stricmp(ServiceName, "event") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_EVENT, ServiceName + SawUnderscore + 1, rule);
// semaphore operation
if (strlen(ServiceName) == 9 && _stricmp(ServiceName, "semaphore") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_SEMAPHORE, ServiceName + SawUnderscore + 1, rule);
// mailslot operation
if (strlen(ServiceName) == 8 && _stricmp(ServiceName, "mailslot") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_MAILSLOT, ServiceName + SawUnderscore + 1, rule);
// named pipe operation
if (strlen(ServiceName) == 9 && _stricmp(ServiceName, "namedpipe") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_NAMEDPIPE, ServiceName + SawUnderscore + 1, rule);
// job object operation
if (strlen(ServiceName) == 3 && _stricmp(ServiceName, "job") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_JOB, ServiceName + SawUnderscore + 1, rule);
// mutant operation
if (strlen(ServiceName) == 5 && _stricmp(ServiceName, "mutex") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_MUTANT, ServiceName + SawUnderscore + 1, rule);
// port operation
if (strlen(ServiceName) == 4 && _stricmp(ServiceName, "port") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_PORT, ServiceName + SawUnderscore + 1, rule);
// symlink operation
if (strlen(ServiceName) == 7 && _stricmp(ServiceName, "symlink") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_SYMLINK, ServiceName + SawUnderscore + 1, rule);
// timer operation
if (strlen(ServiceName) == 5 && _stricmp(ServiceName, "timer") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_TIMER, ServiceName + SawUnderscore + 1, rule);
// process operation
if (strlen(ServiceName) == 7 && _stricmp(ServiceName, "process") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_PROCESS, ServiceName + SawUnderscore + 1, rule);
// driver operation
if (strlen(ServiceName) == 6 && _stricmp(ServiceName, "driver") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_DRIVER, ServiceName + SawUnderscore + 1, rule);
// object directory operation
if (strlen(ServiceName) == 6 && _stricmp(ServiceName, "dirobj") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_DIROBJ, ServiceName + SawUnderscore + 1, rule);
// atom operation
if (strlen(ServiceName) == 4 && _stricmp(ServiceName, "atom") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_ATOM, ServiceName + SawUnderscore + 1, rule);
// network operation
if (strlen(ServiceName) == 7 && _stricmp(ServiceName, "network") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_NETWORK, ServiceName + SawUnderscore + 1, rule);
// service operation
if (strlen(ServiceName) == 7 && _stricmp(ServiceName, "service") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_SERVICE, ServiceName + SawUnderscore + 1, rule);
// time operation
if (strlen(ServiceName) == 4 && _stricmp(ServiceName, "time") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_TIME, ServiceName + SawUnderscore + 1, rule);
// token operation
if (strlen(ServiceName) == 5 && _stricmp(ServiceName, "token") == 0)
return PolicyParseObjectRule(pSecPolicy, RULE_TOKEN, ServiceName + SawUnderscore + 1, rule);
/*
* non object rules
*/
// syscall
if (strlen(ServiceName) == 7 && _stricmp(ServiceName, "syscall") == 0)
return PolicyParseSyscallRule(pSecPolicy, ServiceName + SawUnderscore + 1, rule);
// policy
if (strlen(ServiceName) == 6 && _stricmp(ServiceName, "policy") == 0)
return PolicyParsePolicyRule(pSecPolicy, ServiceName + SawUnderscore + 1, rule, Critical);
// protection
if (strlen(ServiceName) == 10 && _stricmp(ServiceName, "protection") == 0)
return PolicyParseProtectionRule(pSecPolicy, ServiceName + SawUnderscore + 1, rule);
// media
if (strlen(ServiceName) == 5 && _stricmp(ServiceName, "media") == 0)
return PolicyParseMediaRule(pSecPolicy, ServiceName + SawUnderscore + 1, rule);
ABORT_PolicyParseRule(("Invalid rule type specification: '%s'.\n", ServiceName));
}
/*
* ParseDllOperation()
*
* Description:
* Parses an operation (i.e. "load" in "dll_load") specified for a DLL object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseDllOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 4 && _stricmp(Operation, "load") == 0)
return OP_LOAD;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseTimeOperation()
*
* Description:
* Parses an operation (i.e. "change" in "time_change") specified for a Time object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseTimeOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 6 && _stricmp(Operation, "change") == 0)
return OP_LOAD;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseTokenOperation()
*
* Description:
* Parses an operation (i.e. "modify" in "token_modify") specified for a Token object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseTokenOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 6 && _stricmp(Operation, "modify") == 0)
return OP_TOKEN_MODIFY;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParsePortOperation()
*
* Description:
* Parses an operation (i.e. "create" in "port_create") specified for a port object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParsePortOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 6 && _stricmp(Operation, "create") == 0)
return OP_PORT_CREATE;
if (strlen(Operation) == 7 && _stricmp(Operation, "connect") == 0)
return OP_PORT_CONNECT;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseCreateOpenOperation()
*
* Description:
* Parses a create or an open operation (i.e. "create" in "dirobj_create").
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseCreateOpenOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 6 && _stricmp(Operation, "create") == 0)
return OP_CREATE;
if (strlen(Operation) == 4 && _stricmp(Operation, "open") == 0)
return OP_OPEN;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseAtomOperation()
*
* Description:
* Parses an operation (i.e. "find" in "atom_find") specified for an atom object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseAtomOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 4 && _stricmp(Operation, "find") == 0)
return OP_FIND;
if (strlen(Operation) == 3 && _stricmp(Operation, "add") == 0)
return OP_ADD;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseDriverOperation()
*
* Description:
* Parses an operation (i.e. "load" in "driver_load") specified for a driver object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseDriverOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 4 && _stricmp(Operation, "load") == 0)
return OP_LOAD;
if (strlen(Operation) == 7 && _stricmp(Operation, "regload") == 0)
return OP_REGLOAD;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseDirectoryOperation()
*
* Description:
* Parses an operation (i.e. "create" in "directory_create") specified for a directory object rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
UCHAR
ParseDirectoryOperation(IN PCHAR Operation)
{
if (strlen(Operation) == 6 && _stricmp(Operation, "create") == 0)
return OP_DIR_CREATE;
if (strlen(Operation) == 3 && _stricmp(Operation, "all") == 0)
return OP_ALL;
return OP_INVALID;
}
/*
* ParseObjectOperation()
*
* Description:
* Parses an operation (i.e. "read" in "file_read") specified for an object (file, registry, etc) rule.
*
* Parameters:
* Operation - specified operation.
*
* Returns:
* OP_INVALID if a specified operation is invalid or an OP_* value corresponding to the parsed operation.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -