am f28c916e: remove unused permissions scheme from amend
Merge commit 'f28c916e73ee9f643c67c70d059c70381d774cb0' * commit 'f28c916e73ee9f643c67c70d059c70381d774cb0': remove unused permissions scheme from amend
This commit is contained in:
commit
8caf81fa24
@ -10,13 +10,11 @@ amend_src_files := \
|
||||
ast.c \
|
||||
symtab.c \
|
||||
commands.c \
|
||||
permissions.c \
|
||||
execute.c
|
||||
|
||||
amend_test_files := \
|
||||
test_symtab.c \
|
||||
test_commands.c \
|
||||
test_permissions.c
|
||||
test_commands.c
|
||||
|
||||
# "-x c" forces the lex/yacc files to be compiled as c;
|
||||
# the build system otherwise forces them to be c++.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "amend.h"
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
|
||||
extern const AmCommandList *gCommands;
|
||||
|
||||
|
@ -152,37 +152,30 @@ getCommandArgumentType(Command *cmd)
|
||||
}
|
||||
|
||||
static int
|
||||
callCommandInternal(CommandEntry *entry, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
callCommandInternal(CommandEntry *entry, int argc, const char *argv[])
|
||||
{
|
||||
if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
|
||||
(argc == 0 || (argc > 0 && argv != NULL)))
|
||||
{
|
||||
if (permissions == NULL) {
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] == NULL) {
|
||||
goto bail;
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] == NULL) {
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
TRACE("calling command %s\n", entry->name);
|
||||
return entry->hook(entry->name, entry->cookie, argc, argv, permissions);
|
||||
//xxx if permissions, make sure the entry has added at least one element.
|
||||
return entry->hook(entry->name, entry->cookie, argc, argv);
|
||||
}
|
||||
bail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
callBooleanCommandInternal(CommandEntry *entry, bool arg,
|
||||
PermissionRequestList *permissions)
|
||||
callBooleanCommandInternal(CommandEntry *entry, bool arg)
|
||||
{
|
||||
if (entry != NULL && entry->argType == CMD_ARGS_BOOLEAN) {
|
||||
TRACE("calling boolean command %s\n", entry->name);
|
||||
return entry->hook(entry->name, entry->cookie, arg ? 1 : 0, NULL,
|
||||
permissions);
|
||||
//xxx if permissions, make sure the entry has added at least one element.
|
||||
return entry->hook(entry->name, entry->cookie, arg ? 1 : 0, NULL);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -190,63 +183,37 @@ callBooleanCommandInternal(CommandEntry *entry, bool arg,
|
||||
int
|
||||
callCommand(Command *cmd, int argc, const char *argv[])
|
||||
{
|
||||
return callCommandInternal((CommandEntry *)cmd, argc, argv, NULL);
|
||||
return callCommandInternal((CommandEntry *)cmd, argc, argv);
|
||||
}
|
||||
|
||||
int
|
||||
callBooleanCommand(Command *cmd, bool arg)
|
||||
{
|
||||
return callBooleanCommandInternal((CommandEntry *)cmd, arg, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
getCommandPermissions(Command *cmd, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
{
|
||||
if (permissions != NULL) {
|
||||
return callCommandInternal((CommandEntry *)cmd, argc, argv,
|
||||
permissions);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
getBooleanCommandPermissions(Command *cmd, bool arg,
|
||||
PermissionRequestList *permissions)
|
||||
{
|
||||
if (permissions != NULL) {
|
||||
return callBooleanCommandInternal((CommandEntry *)cmd, arg,
|
||||
permissions);
|
||||
}
|
||||
return -1;
|
||||
return callBooleanCommandInternal((CommandEntry *)cmd, arg);
|
||||
}
|
||||
|
||||
int
|
||||
callFunctionInternal(CommandEntry *entry, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen, PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
|
||||
(argc == 0 || (argc > 0 && argv != NULL)))
|
||||
{
|
||||
if ((permissions == NULL && result != NULL) ||
|
||||
(permissions != NULL && result == NULL))
|
||||
if (result != NULL)
|
||||
{
|
||||
if (permissions == NULL) {
|
||||
/* This is the actual invocation of the function,
|
||||
* which means that none of the arguments are allowed
|
||||
* to be NULL.
|
||||
*/
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] == NULL) {
|
||||
goto bail;
|
||||
}
|
||||
/* This is the actual invocation of the function,
|
||||
* which means that none of the arguments are allowed
|
||||
* to be NULL.
|
||||
*/
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] == NULL) {
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
TRACE("calling function %s\n", entry->name);
|
||||
return ((FunctionHook)entry->hook)(entry->name, entry->cookie,
|
||||
argc, argv, result, resultLen, permissions);
|
||||
//xxx if permissions, make sure the entry has added at least one element.
|
||||
argc, argv, result, resultLen);
|
||||
}
|
||||
}
|
||||
bail:
|
||||
@ -258,16 +225,5 @@ callFunction(Function *fn, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
return callFunctionInternal((CommandEntry *)fn, argc, argv,
|
||||
result, resultLen, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
getFunctionPermissions(Function *fn, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
{
|
||||
if (permissions != NULL) {
|
||||
return callFunctionInternal((CommandEntry *)fn, argc, argv,
|
||||
NULL, NULL, permissions);
|
||||
}
|
||||
return -1;
|
||||
result, resultLen);
|
||||
}
|
||||
|
@ -14,31 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef AMEND_COMMANDS_H_
|
||||
#define AMEND_COMMANDS_H_
|
||||
|
||||
#include "permissions.h"
|
||||
|
||||
/* Invoke or dry-run a command. If "permissions" is non-NULL,
|
||||
* the hook should fill it out with the list of files and operations that
|
||||
* it would need to complete its operation. If "permissions" is NULL,
|
||||
* the hook should do the actual work specified by its arguments.
|
||||
*
|
||||
* When a command is called with non-NULL "permissions", some arguments
|
||||
* may be NULL. A NULL argument indicates that the argument is actually
|
||||
* the output of another function, so is not known at permissions time.
|
||||
* The permissions of leaf-node functions (those that have only literal
|
||||
* strings as arguments) will get appended to the permissions of the
|
||||
* functions that call them. However, to be completely safe, functions
|
||||
* that receive a NULL argument should request the broadest-possible
|
||||
* permissions for the range of the input argument.
|
||||
/* Invoke a command.
|
||||
*
|
||||
* When a boolean command is called, "argc" is the boolean value and
|
||||
* "argv" is NULL.
|
||||
*/
|
||||
typedef int (*CommandHook)(const char *name, void *cookie,
|
||||
int argc, const char *argv[],
|
||||
PermissionRequestList *permissions);
|
||||
int argc, const char *argv[]);
|
||||
|
||||
int commandInit(void);
|
||||
void commandCleanup(void);
|
||||
@ -66,19 +53,13 @@ CommandArgumentType getCommandArgumentType(Command *cmd);
|
||||
int callCommand(Command *cmd, int argc, const char *argv[]);
|
||||
int callBooleanCommand(Command *cmd, bool arg);
|
||||
|
||||
int getCommandPermissions(Command *cmd, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions);
|
||||
int getBooleanCommandPermissions(Command *cmd, bool arg,
|
||||
PermissionRequestList *permissions);
|
||||
|
||||
/*
|
||||
* Function management
|
||||
*/
|
||||
|
||||
typedef int (*FunctionHook)(const char *name, void *cookie,
|
||||
int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions);
|
||||
char **result, size_t *resultLen);
|
||||
|
||||
struct Function;
|
||||
typedef struct Function Function;
|
||||
@ -90,7 +71,4 @@ Function *findFunction(const char *name);
|
||||
int callFunction(Function *fn, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen);
|
||||
|
||||
int getFunctionPermissions(Function *fn, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions);
|
||||
|
||||
#endif // AMEND_COMMANDS_H_
|
||||
|
@ -86,12 +86,6 @@ main(int argc, char *argv[])
|
||||
fprintf(stderr, "test_cmd_fn() failed: %d\n", ret);
|
||||
exit(ret);
|
||||
}
|
||||
extern int test_permissions(void);
|
||||
ret = test_permissions();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "test_permissions() failed: %d\n", ret);
|
||||
exit(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
argc--;
|
||||
|
@ -1,270 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "permissions.h"
|
||||
|
||||
int
|
||||
initPermissionRequestList(PermissionRequestList *list)
|
||||
{
|
||||
if (list != NULL) {
|
||||
list->requests = NULL;
|
||||
list->numRequests = 0;
|
||||
list->requestsAllocated = 0;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
addPermissionRequestToList(PermissionRequestList *list,
|
||||
const char *path, bool recursive, unsigned int permissions)
|
||||
{
|
||||
if (list == NULL || list->numRequests < 0 ||
|
||||
list->requestsAllocated < list->numRequests || path == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (list->numRequests == list->requestsAllocated) {
|
||||
int newSize;
|
||||
PermissionRequest *newRequests;
|
||||
|
||||
newSize = list->requestsAllocated * 2;
|
||||
if (newSize < 16) {
|
||||
newSize = 16;
|
||||
}
|
||||
newRequests = (PermissionRequest *)realloc(list->requests,
|
||||
newSize * sizeof(PermissionRequest));
|
||||
if (newRequests == NULL) {
|
||||
return -2;
|
||||
}
|
||||
list->requests = newRequests;
|
||||
list->requestsAllocated = newSize;
|
||||
}
|
||||
|
||||
PermissionRequest *req;
|
||||
req = &list->requests[list->numRequests++];
|
||||
req->path = strdup(path);
|
||||
if (req->path == NULL) {
|
||||
list->numRequests--;
|
||||
return -3;
|
||||
}
|
||||
req->recursive = recursive;
|
||||
req->requested = permissions;
|
||||
req->allowed = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
freePermissionRequestListElements(PermissionRequestList *list)
|
||||
{
|
||||
if (list != NULL && list->numRequests >= 0 &&
|
||||
list->requestsAllocated >= list->numRequests)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < list->numRequests; i++) {
|
||||
free((void *)list->requests[i].path);
|
||||
}
|
||||
free(list->requests);
|
||||
initPermissionRequestList(list);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Global permission table
|
||||
*/
|
||||
|
||||
static struct {
|
||||
Permission *permissions;
|
||||
int numPermissionEntries;
|
||||
int allocatedPermissionEntries;
|
||||
bool permissionStateInitialized;
|
||||
} gPermissionState = {
|
||||
#if 1
|
||||
NULL, 0, 0, false
|
||||
#else
|
||||
.permissions = NULL,
|
||||
.numPermissionEntries = 0,
|
||||
.allocatedPermissionEntries = 0,
|
||||
.permissionStateInitialized = false
|
||||
#endif
|
||||
};
|
||||
|
||||
int
|
||||
permissionInit()
|
||||
{
|
||||
if (gPermissionState.permissionStateInitialized) {
|
||||
return -1;
|
||||
}
|
||||
gPermissionState.permissions = NULL;
|
||||
gPermissionState.numPermissionEntries = 0;
|
||||
gPermissionState.allocatedPermissionEntries = 0;
|
||||
gPermissionState.permissionStateInitialized = true;
|
||||
//xxx maybe add an "namespace root gets no permissions" fallback by default
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
permissionCleanup()
|
||||
{
|
||||
if (gPermissionState.permissionStateInitialized) {
|
||||
gPermissionState.permissionStateInitialized = false;
|
||||
if (gPermissionState.permissions != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < gPermissionState.numPermissionEntries; i++) {
|
||||
free((void *)gPermissionState.permissions[i].path);
|
||||
}
|
||||
free(gPermissionState.permissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getPermissionCount()
|
||||
{
|
||||
if (gPermissionState.permissionStateInitialized) {
|
||||
return gPermissionState.numPermissionEntries;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const Permission *
|
||||
getPermissionAt(int index)
|
||||
{
|
||||
if (!gPermissionState.permissionStateInitialized) {
|
||||
return NULL;
|
||||
}
|
||||
if (index < 0 || index >= gPermissionState.numPermissionEntries) {
|
||||
return NULL;
|
||||
}
|
||||
return &gPermissionState.permissions[index];
|
||||
}
|
||||
|
||||
int
|
||||
getAllowedPermissions(const char *path, bool recursive,
|
||||
unsigned int *outAllowed)
|
||||
{
|
||||
if (!gPermissionState.permissionStateInitialized) {
|
||||
return -2;
|
||||
}
|
||||
if (outAllowed == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*outAllowed = 0;
|
||||
if (path == NULL) {
|
||||
return -1;
|
||||
}
|
||||
//TODO: implement this for real.
|
||||
recursive = false;
|
||||
*outAllowed = PERMSET_ALL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
countPermissionConflicts(PermissionRequestList *requests, bool updateAllowed)
|
||||
{
|
||||
if (!gPermissionState.permissionStateInitialized) {
|
||||
return -2;
|
||||
}
|
||||
if (requests == NULL || requests->requests == NULL ||
|
||||
requests->numRequests < 0 ||
|
||||
requests->requestsAllocated < requests->numRequests)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int conflicts = 0;
|
||||
int i;
|
||||
for (i = 0; i < requests->numRequests; i++) {
|
||||
PermissionRequest *req;
|
||||
unsigned int allowed;
|
||||
int ret;
|
||||
|
||||
req = &requests->requests[i];
|
||||
ret = getAllowedPermissions(req->path, req->recursive, &allowed);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((req->requested & ~allowed) != 0) {
|
||||
conflicts++;
|
||||
}
|
||||
if (updateAllowed) {
|
||||
req->allowed = allowed;
|
||||
}
|
||||
}
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
int
|
||||
registerPermissionSet(int count, Permission *set)
|
||||
{
|
||||
if (!gPermissionState.permissionStateInitialized) {
|
||||
return -2;
|
||||
}
|
||||
if (count < 0 || (count > 0 && set == NULL)) {
|
||||
return -1;
|
||||
}
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gPermissionState.numPermissionEntries + count >=
|
||||
gPermissionState.allocatedPermissionEntries)
|
||||
{
|
||||
Permission *newList;
|
||||
int newSize;
|
||||
|
||||
newSize = (gPermissionState.allocatedPermissionEntries + count) * 2;
|
||||
if (newSize < 16) {
|
||||
newSize = 16;
|
||||
}
|
||||
newList = (Permission *)realloc(gPermissionState.permissions,
|
||||
newSize * sizeof(Permission));
|
||||
if (newList == NULL) {
|
||||
return -3;
|
||||
}
|
||||
gPermissionState.permissions = newList;
|
||||
gPermissionState.allocatedPermissionEntries = newSize;
|
||||
}
|
||||
|
||||
Permission *p = &gPermissionState.permissions[
|
||||
gPermissionState.numPermissionEntries];
|
||||
int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
*p = set[i];
|
||||
//TODO: cache the strlen of the path
|
||||
//TODO: normalize; strip off trailing /
|
||||
p->path = strdup(p->path);
|
||||
if (p->path == NULL) {
|
||||
/* If we can't add all of the entries, we don't
|
||||
* add any of them.
|
||||
*/
|
||||
Permission *pp = &gPermissionState.permissions[
|
||||
gPermissionState.numPermissionEntries];
|
||||
while (pp != p) {
|
||||
free((void *)pp->path);
|
||||
pp++;
|
||||
}
|
||||
return -4;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
gPermissionState.numPermissionEntries += count;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef AMEND_PERMISSIONS_H_
|
||||
#define AMEND_PERMISSIONS_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define PERM_NONE (0)
|
||||
#define PERM_STAT (1<<0)
|
||||
#define PERM_READ (1<<1)
|
||||
#define PERM_WRITE (1<<2) // including create, delete, mkdir, rmdir
|
||||
#define PERM_CHMOD (1<<3)
|
||||
#define PERM_CHOWN (1<<4)
|
||||
#define PERM_CHGRP (1<<5)
|
||||
#define PERM_SETUID (1<<6)
|
||||
#define PERM_SETGID (1<<7)
|
||||
|
||||
#define PERMSET_READ (PERM_STAT | PERM_READ)
|
||||
#define PERMSET_WRITE (PERMSET_READ | PERM_WRITE)
|
||||
|
||||
#define PERMSET_ALL \
|
||||
(PERM_STAT | PERM_READ | PERM_WRITE | PERM_CHMOD | \
|
||||
PERM_CHOWN | PERM_CHGRP | PERM_SETUID | PERM_SETGID)
|
||||
|
||||
typedef struct {
|
||||
unsigned int requested;
|
||||
unsigned int allowed;
|
||||
const char *path;
|
||||
bool recursive;
|
||||
} PermissionRequest;
|
||||
|
||||
typedef struct {
|
||||
PermissionRequest *requests;
|
||||
int numRequests;
|
||||
int requestsAllocated;
|
||||
} PermissionRequestList;
|
||||
|
||||
/* Properly clear out a PermissionRequestList.
|
||||
*
|
||||
* @return 0 if list is non-NULL, negative otherwise.
|
||||
*/
|
||||
int initPermissionRequestList(PermissionRequestList *list);
|
||||
|
||||
/* Add a permission request to the list, allocating more space
|
||||
* if necessary.
|
||||
*
|
||||
* @return 0 on success or a negative value on failure.
|
||||
*/
|
||||
int addPermissionRequestToList(PermissionRequestList *list,
|
||||
const char *path, bool recursive, unsigned int permissions);
|
||||
|
||||
/* Free anything allocated by addPermissionRequestToList(). The caller
|
||||
* is responsible for freeing the actual PermissionRequestList.
|
||||
*/
|
||||
void freePermissionRequestListElements(PermissionRequestList *list);
|
||||
|
||||
|
||||
/*
|
||||
* Global permission table
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char *path;
|
||||
unsigned int allowed;
|
||||
} Permission;
|
||||
|
||||
int permissionInit(void);
|
||||
void permissionCleanup(void);
|
||||
|
||||
/* Returns the allowed permissions for the path in "outAllowed".
|
||||
* Returns 0 if successful, negative if a parameter or global state
|
||||
* is bad.
|
||||
*/
|
||||
int getAllowedPermissions(const char *path, bool recursive,
|
||||
unsigned int *outAllowed);
|
||||
|
||||
/* More-recently-registered permissions override older permissions.
|
||||
*/
|
||||
int registerPermissionSet(int count, Permission *set);
|
||||
|
||||
/* Check to make sure that each request is allowed.
|
||||
*
|
||||
* @param requests The list of permission requests
|
||||
* @param updateAllowed If true, update the "allowed" field in each
|
||||
* element of the list
|
||||
* @return the number of requests that were denied, or negative if
|
||||
* an error occurred.
|
||||
*/
|
||||
int countPermissionConflicts(PermissionRequestList *requests,
|
||||
bool updateAllowed);
|
||||
|
||||
/* Inspection/testing/debugging functions
|
||||
*/
|
||||
int getPermissionCount(void);
|
||||
const Permission *getPermissionAt(int index);
|
||||
|
||||
#endif // AMEND_PERMISSIONS_H_
|
@ -39,40 +39,15 @@
|
||||
if (argc < 0) return -1; \
|
||||
assert(argc == 0 || argv != NULL); \
|
||||
if (argc != 0 && argv == NULL) return -1; \
|
||||
if (permissions != NULL) { \
|
||||
int CW_I_; \
|
||||
for (CW_I_ = 0; CW_I_ < argc; CW_I_++) { \
|
||||
assert(argv[CW_I_] != NULL); \
|
||||
if (argv[CW_I_] == NULL) return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define CHECK_FN() \
|
||||
do { \
|
||||
CHECK_WORDS(); \
|
||||
if (permissions != NULL) { \
|
||||
assert(result == NULL); \
|
||||
if (result != NULL) return -1; \
|
||||
} else { \
|
||||
assert(result != NULL); \
|
||||
if (result == NULL) return -1; \
|
||||
} \
|
||||
assert(result != NULL); \
|
||||
if (result == NULL) return -1; \
|
||||
} while (false)
|
||||
|
||||
#define NO_PERMS(perms) \
|
||||
do { \
|
||||
PermissionRequestList *NP_PRL_ = (perms); \
|
||||
if (NP_PRL_ != NULL) { \
|
||||
int NP_RET_ = addPermissionRequestToList(NP_PRL_, \
|
||||
"", false, PERM_NONE); \
|
||||
if (NP_RET_ < 0) { \
|
||||
/* Returns from the calling function. \
|
||||
*/ \
|
||||
return NP_RET_; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
/*
|
||||
* Command definitions
|
||||
@ -81,13 +56,11 @@
|
||||
/* assert <boolexpr>
|
||||
*/
|
||||
static int
|
||||
cmd_assert(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_assert(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_BOOL();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
/* If our argument is false, return non-zero (failure)
|
||||
* If our argument is true, return zero (success)
|
||||
@ -102,8 +75,7 @@ cmd_assert(const char *name, void *cookie, int argc, const char *argv[],
|
||||
/* format <root>
|
||||
*/
|
||||
static int
|
||||
cmd_format(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_format(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -115,8 +87,7 @@ cmd_format(const char *name, void *cookie, int argc, const char *argv[],
|
||||
/* copy_dir <srcdir> <dstdir>
|
||||
*/
|
||||
static int
|
||||
cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -128,8 +99,7 @@ cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
/* mark <resource> dirty|clean
|
||||
*/
|
||||
static int
|
||||
cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_mark(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -144,8 +114,7 @@ cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
/* done
|
||||
*/
|
||||
static int
|
||||
cmd_done(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_done(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -174,11 +143,6 @@ registerUpdateCommands()
|
||||
ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, NULL);
|
||||
if (ret < 0) return ret;
|
||||
|
||||
//xxx some way to fix permissions
|
||||
//xxx could have "installperms" commands that build the fs_config list
|
||||
//xxx along with a "commitperms", and any copy_dir etc. needs to see
|
||||
// a commitperms before it will work
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -194,13 +158,11 @@ registerUpdateCommands()
|
||||
*/
|
||||
static int
|
||||
fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 0) {
|
||||
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
|
||||
@ -228,13 +190,11 @@ fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 1) {
|
||||
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
|
||||
@ -255,8 +215,7 @@ fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
@ -273,23 +232,12 @@ fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
dir = argv[0];
|
||||
}
|
||||
|
||||
if (permissions != NULL) {
|
||||
if (dir == NULL) {
|
||||
/* The argument is the result of another function.
|
||||
* Assume the worst case, where the function returns
|
||||
* the root.
|
||||
*/
|
||||
dir = "/";
|
||||
}
|
||||
ret = addPermissionRequestToList(permissions, dir, true, PERM_READ);
|
||||
} else {
|
||||
//xxx build and return the string
|
||||
*result = strdup("hashvalue");
|
||||
if (resultLen != NULL) {
|
||||
*resultLen = strlen(*result);
|
||||
}
|
||||
ret = 0;
|
||||
*result = strdup("hashvalue");
|
||||
if (resultLen != NULL) {
|
||||
*resultLen = strlen(*result);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -302,13 +250,11 @@ fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_matches(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s: not enough arguments (%d < 2)\n",
|
||||
@ -339,13 +285,11 @@ fn_matches(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_concat(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
size_t totalLen = 0;
|
||||
int i;
|
||||
|
@ -27,34 +27,30 @@ static struct {
|
||||
void *cookie;
|
||||
int argc;
|
||||
const char **argv;
|
||||
PermissionRequestList *permissions;
|
||||
int returnValue;
|
||||
char *functionResult;
|
||||
} gTestCommandState;
|
||||
|
||||
static int
|
||||
testCommand(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
testCommand(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
gTestCommandState.called = true;
|
||||
gTestCommandState.name = name;
|
||||
gTestCommandState.cookie = cookie;
|
||||
gTestCommandState.argc = argc;
|
||||
gTestCommandState.argv = argv;
|
||||
gTestCommandState.permissions = permissions;
|
||||
return gTestCommandState.returnValue;
|
||||
}
|
||||
|
||||
static int
|
||||
testFunction(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen, PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
gTestCommandState.called = true;
|
||||
gTestCommandState.name = name;
|
||||
gTestCommandState.cookie = cookie;
|
||||
gTestCommandState.argc = argc;
|
||||
gTestCommandState.argv = argv;
|
||||
gTestCommandState.permissions = permissions;
|
||||
if (result != NULL) {
|
||||
*result = gTestCommandState.functionResult;
|
||||
if (resultLen != NULL) {
|
||||
@ -187,7 +183,6 @@ test_commands()
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 25;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
ret = callCommand(cmd, argc, argv);
|
||||
//xxx also try calling with a null argv element (should fail)
|
||||
assert(ret == 25);
|
||||
@ -196,7 +191,6 @@ test_commands()
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == argc);
|
||||
assert(gTestCommandState.argv == argv);
|
||||
assert(gTestCommandState.permissions == NULL);
|
||||
|
||||
/* Make a boolean call and make sure that it occurred.
|
||||
*/
|
||||
@ -206,7 +200,6 @@ test_commands()
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 12;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
ret = callBooleanCommand(cmd, false);
|
||||
assert(ret == 12);
|
||||
assert(gTestCommandState.called);
|
||||
@ -214,12 +207,10 @@ test_commands()
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == 0);
|
||||
assert(gTestCommandState.argv == NULL);
|
||||
assert(gTestCommandState.permissions == NULL);
|
||||
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 13;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
ret = callBooleanCommand(cmd, true);
|
||||
assert(ret == 13);
|
||||
assert(gTestCommandState.called);
|
||||
@ -227,45 +218,6 @@ test_commands()
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == 1);
|
||||
assert(gTestCommandState.argv == NULL);
|
||||
assert(gTestCommandState.permissions == NULL);
|
||||
|
||||
/* Try looking up permissions.
|
||||
*/
|
||||
PermissionRequestList permissions;
|
||||
cmd = findCommand("one");
|
||||
assert(cmd != NULL);
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 27;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
argv[1] = NULL; // null out an arg, which should be ok
|
||||
ret = getCommandPermissions(cmd, argc, argv, &permissions);
|
||||
assert(ret == 27);
|
||||
assert(gTestCommandState.called);
|
||||
assert(strcmp(gTestCommandState.name, "one") == 0);
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == argc);
|
||||
assert(gTestCommandState.argv == argv);
|
||||
assert(gTestCommandState.permissions == &permissions);
|
||||
|
||||
/* Boolean command permissions
|
||||
*/
|
||||
cmd = findCommand("bool");
|
||||
assert(cmd != NULL);
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 55;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
// argv[1] is still NULL
|
||||
ret = getBooleanCommandPermissions(cmd, true, &permissions);
|
||||
assert(ret == 55);
|
||||
assert(gTestCommandState.called);
|
||||
assert(strcmp(gTestCommandState.name, "bool") == 0);
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == 1);
|
||||
assert(gTestCommandState.argv == NULL);
|
||||
assert(gTestCommandState.permissions == &permissions);
|
||||
|
||||
|
||||
/* Smoke test commandCleanup().
|
||||
*/
|
||||
@ -365,7 +317,6 @@ test_functions()
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 25;
|
||||
gTestCommandState.functionResult = "1234";
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
functionResult = NULL;
|
||||
functionResultLen = 55;
|
||||
ret = callFunction(fn, argc, argv,
|
||||
@ -378,29 +329,9 @@ test_functions()
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == argc);
|
||||
assert(gTestCommandState.argv == argv);
|
||||
assert(gTestCommandState.permissions == NULL);
|
||||
assert(strcmp(functionResult, "1234") == 0);
|
||||
assert(functionResultLen == strlen(functionResult));
|
||||
|
||||
/* Try looking up permissions.
|
||||
*/
|
||||
PermissionRequestList permissions;
|
||||
fn = findFunction("one");
|
||||
assert(fn != NULL);
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 27;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
argv[1] = NULL; // null out an arg, which should be ok
|
||||
ret = getFunctionPermissions(fn, argc, argv, &permissions);
|
||||
assert(ret == 27);
|
||||
assert(gTestCommandState.called);
|
||||
assert(strcmp(gTestCommandState.name, "one") == 0);
|
||||
assert(gTestCommandState.cookie == &gTestCommandState);
|
||||
assert(gTestCommandState.argc == argc);
|
||||
assert(gTestCommandState.argv == argv);
|
||||
assert(gTestCommandState.permissions == &permissions);
|
||||
|
||||
/* Smoke test commandCleanup().
|
||||
*/
|
||||
commandCleanup();
|
||||
@ -470,7 +401,6 @@ test_interaction()
|
||||
memset(&gTestCommandState, 0, sizeof(gTestCommandState));
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 123;
|
||||
gTestCommandState.permissions = (PermissionRequestList *)1;
|
||||
ret = callCommand(cmd, argc, argv);
|
||||
assert(ret == 123);
|
||||
assert(gTestCommandState.called);
|
||||
@ -478,7 +408,6 @@ test_interaction()
|
||||
assert((int)gTestCommandState.cookie == 0xc1);
|
||||
assert(gTestCommandState.argc == argc);
|
||||
assert(gTestCommandState.argv == argv);
|
||||
assert(gTestCommandState.permissions == NULL);
|
||||
|
||||
/* Call the overlapping function and make sure that the cookie is correct.
|
||||
*/
|
||||
@ -490,7 +419,6 @@ test_interaction()
|
||||
gTestCommandState.called = false;
|
||||
gTestCommandState.returnValue = 125;
|
||||
gTestCommandState.functionResult = "5678";
|
||||
gTestCommandState.permissions = (PermissionRequestList *)2;
|
||||
functionResult = NULL;
|
||||
functionResultLen = 66;
|
||||
ret = callFunction(fn, argc, argv, &functionResult, &functionResultLen);
|
||||
@ -500,7 +428,6 @@ test_interaction()
|
||||
assert((int)gTestCommandState.cookie == 0xf1);
|
||||
assert(gTestCommandState.argc == argc);
|
||||
assert(gTestCommandState.argv == argv);
|
||||
assert(gTestCommandState.permissions == NULL);
|
||||
assert(strcmp(functionResult, "5678") == 0);
|
||||
assert(functionResultLen == strlen(functionResult));
|
||||
|
||||
|
@ -1,347 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#include "permissions.h"
|
||||
|
||||
static int
|
||||
test_permission_list()
|
||||
{
|
||||
PermissionRequestList list;
|
||||
int ret;
|
||||
int numRequests;
|
||||
|
||||
/* Bad parameter
|
||||
*/
|
||||
ret = initPermissionRequestList(NULL);
|
||||
assert(ret < 0);
|
||||
|
||||
/* Good parameter
|
||||
*/
|
||||
ret = initPermissionRequestList(&list);
|
||||
assert(ret == 0);
|
||||
|
||||
/* Bad parameters
|
||||
*/
|
||||
ret = addPermissionRequestToList(NULL, NULL, false, 0);
|
||||
assert(ret < 0);
|
||||
|
||||
ret = addPermissionRequestToList(&list, NULL, false, 0);
|
||||
assert(ret < 0);
|
||||
|
||||
/* Good parameters
|
||||
*/
|
||||
numRequests = 0;
|
||||
|
||||
ret = addPermissionRequestToList(&list, "one", false, 1);
|
||||
assert(ret == 0);
|
||||
numRequests++;
|
||||
|
||||
ret = addPermissionRequestToList(&list, "two", false, 2);
|
||||
assert(ret == 0);
|
||||
numRequests++;
|
||||
|
||||
ret = addPermissionRequestToList(&list, "three", false, 3);
|
||||
assert(ret == 0);
|
||||
numRequests++;
|
||||
|
||||
ret = addPermissionRequestToList(&list, "recursive", true, 55);
|
||||
assert(ret == 0);
|
||||
numRequests++;
|
||||
|
||||
/* Validate the list
|
||||
*/
|
||||
assert(list.requests != NULL);
|
||||
assert(list.numRequests == numRequests);
|
||||
assert(list.numRequests <= list.requestsAllocated);
|
||||
bool sawOne = false;
|
||||
bool sawTwo = false;
|
||||
bool sawThree = false;
|
||||
bool sawRecursive = false;
|
||||
int i;
|
||||
for (i = 0; i < list.numRequests; i++) {
|
||||
PermissionRequest *req = &list.requests[i];
|
||||
assert(req->allowed == 0);
|
||||
|
||||
/* Order isn't guaranteed, so we have to switch every time.
|
||||
*/
|
||||
if (strcmp(req->path, "one") == 0) {
|
||||
assert(!sawOne);
|
||||
assert(req->requested == 1);
|
||||
assert(!req->recursive);
|
||||
sawOne = true;
|
||||
} else if (strcmp(req->path, "two") == 0) {
|
||||
assert(!sawTwo);
|
||||
assert(req->requested == 2);
|
||||
assert(!req->recursive);
|
||||
sawTwo = true;
|
||||
} else if (strcmp(req->path, "three") == 0) {
|
||||
assert(!sawThree);
|
||||
assert(req->requested == 3);
|
||||
assert(!req->recursive);
|
||||
sawThree = true;
|
||||
} else if (strcmp(req->path, "recursive") == 0) {
|
||||
assert(!sawRecursive);
|
||||
assert(req->requested == 55);
|
||||
assert(req->recursive);
|
||||
sawRecursive = true;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
assert(sawOne);
|
||||
assert(sawTwo);
|
||||
assert(sawThree);
|
||||
assert(sawRecursive);
|
||||
|
||||
/* Smoke test the teardown
|
||||
*/
|
||||
freePermissionRequestListElements(&list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_permission_table()
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Test the global permissions table.
|
||||
* Try calling functions without initializing first.
|
||||
*/
|
||||
ret = registerPermissionSet(0, NULL);
|
||||
assert(ret < 0);
|
||||
|
||||
ret = countPermissionConflicts((PermissionRequestList *)16, false);
|
||||
assert(ret < 0);
|
||||
|
||||
ret = getPermissionCount();
|
||||
assert(ret < 0);
|
||||
|
||||
const Permission *p;
|
||||
p = getPermissionAt(0);
|
||||
assert(p == NULL);
|
||||
|
||||
/* Initialize.
|
||||
*/
|
||||
ret = permissionInit();
|
||||
assert(ret == 0);
|
||||
|
||||
/* Make sure we can't initialize twice.
|
||||
*/
|
||||
ret = permissionInit();
|
||||
assert(ret < 0);
|
||||
|
||||
/* Test the inspection functions.
|
||||
*/
|
||||
ret = getPermissionCount();
|
||||
assert(ret == 0);
|
||||
|
||||
p = getPermissionAt(-1);
|
||||
assert(p == NULL);
|
||||
|
||||
p = getPermissionAt(0);
|
||||
assert(p == NULL);
|
||||
|
||||
p = getPermissionAt(1);
|
||||
assert(p == NULL);
|
||||
|
||||
/* Test registerPermissionSet().
|
||||
* Try some bad parameter values.
|
||||
*/
|
||||
ret = registerPermissionSet(-1, NULL);
|
||||
assert(ret < 0);
|
||||
|
||||
ret = registerPermissionSet(1, NULL);
|
||||
assert(ret < 0);
|
||||
|
||||
/* Register some permissions.
|
||||
*/
|
||||
Permission p1;
|
||||
p1.path = "one";
|
||||
p1.allowed = 1;
|
||||
ret = registerPermissionSet(1, &p1);
|
||||
assert(ret == 0);
|
||||
ret = getPermissionCount();
|
||||
assert(ret == 1);
|
||||
|
||||
Permission p2[2];
|
||||
p2[0].path = "two";
|
||||
p2[0].allowed = 2;
|
||||
p2[1].path = "three";
|
||||
p2[1].allowed = 3;
|
||||
ret = registerPermissionSet(2, p2);
|
||||
assert(ret == 0);
|
||||
ret = getPermissionCount();
|
||||
assert(ret == 3);
|
||||
|
||||
ret = registerPermissionSet(0, NULL);
|
||||
assert(ret == 0);
|
||||
ret = getPermissionCount();
|
||||
assert(ret == 3);
|
||||
|
||||
p1.path = "four";
|
||||
p1.allowed = 4;
|
||||
ret = registerPermissionSet(1, &p1);
|
||||
assert(ret == 0);
|
||||
|
||||
/* Make sure the table looks correct.
|
||||
* Order is important; more-recent additions
|
||||
* should appear at higher indices.
|
||||
*/
|
||||
ret = getPermissionCount();
|
||||
assert(ret == 4);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ret; i++) {
|
||||
const Permission *p;
|
||||
p = getPermissionAt(i);
|
||||
assert(p != NULL);
|
||||
assert(p->allowed == (unsigned int)(i + 1));
|
||||
switch (i) {
|
||||
case 0:
|
||||
assert(strcmp(p->path, "one") == 0);
|
||||
break;
|
||||
case 1:
|
||||
assert(strcmp(p->path, "two") == 0);
|
||||
break;
|
||||
case 2:
|
||||
assert(strcmp(p->path, "three") == 0);
|
||||
break;
|
||||
case 3:
|
||||
assert(strcmp(p->path, "four") == 0);
|
||||
break;
|
||||
default:
|
||||
assert(!"internal error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
p = getPermissionAt(ret);
|
||||
assert(p == NULL);
|
||||
|
||||
/* Smoke test the teardown
|
||||
*/
|
||||
permissionCleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test_allowed_permissions()
|
||||
{
|
||||
int ret;
|
||||
int numPerms;
|
||||
|
||||
/* Make sure these fail before initialization.
|
||||
*/
|
||||
ret = countPermissionConflicts((PermissionRequestList *)1, false);
|
||||
assert(ret < 0);
|
||||
|
||||
ret = getAllowedPermissions((const char *)1, false, (unsigned int *)1);
|
||||
assert(ret < 0);
|
||||
|
||||
/* Initialize.
|
||||
*/
|
||||
ret = permissionInit();
|
||||
assert(ret == 0);
|
||||
|
||||
/* Make sure countPermissionConflicts() fails with bad parameters.
|
||||
*/
|
||||
ret = countPermissionConflicts(NULL, false);
|
||||
assert(ret < 0);
|
||||
|
||||
/* Register a set of permissions.
|
||||
*/
|
||||
Permission perms[] = {
|
||||
{ "/", PERM_NONE },
|
||||
{ "/stat", PERM_STAT },
|
||||
{ "/read", PERMSET_READ },
|
||||
{ "/write", PERMSET_WRITE },
|
||||
{ "/.stat", PERM_STAT },
|
||||
{ "/.stat/.read", PERMSET_READ },
|
||||
{ "/.stat/.read/.write", PERMSET_WRITE },
|
||||
{ "/.stat/.write", PERMSET_WRITE },
|
||||
};
|
||||
numPerms = sizeof(perms) / sizeof(perms[0]);
|
||||
ret = registerPermissionSet(numPerms, perms);
|
||||
assert(ret == 0);
|
||||
|
||||
/* Build a permission request list.
|
||||
*/
|
||||
PermissionRequestList list;
|
||||
ret = initPermissionRequestList(&list);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = addPermissionRequestToList(&list, "/stat", false, PERM_STAT);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = addPermissionRequestToList(&list, "/read", false, PERM_READ);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = addPermissionRequestToList(&list, "/write", false, PERM_WRITE);
|
||||
assert(ret == 0);
|
||||
|
||||
//TODO: cover more cases once the permission stuff has been implemented
|
||||
|
||||
/* All of the requests in the list should be allowed.
|
||||
*/
|
||||
ret = countPermissionConflicts(&list, false);
|
||||
assert(ret == 0);
|
||||
|
||||
/* Add a request that will be denied.
|
||||
*/
|
||||
ret = addPermissionRequestToList(&list, "/stat", false, 1<<31 | PERM_STAT);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = countPermissionConflicts(&list, false);
|
||||
assert(ret == 1);
|
||||
|
||||
//TODO: more tests
|
||||
|
||||
permissionCleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
test_permissions()
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = test_permission_list();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "test_permission_list() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = test_permission_table();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "test_permission_table() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = test_allowed_permissions();
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "test_permission_table() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
117
commands.c
117
commands.c
@ -57,39 +57,13 @@ static int gDidShowProgress = 0;
|
||||
if (argc < 0) return -1; \
|
||||
assert(argc == 0 || argv != NULL); \
|
||||
if (argc != 0 && argv == NULL) return -1; \
|
||||
if (permissions != NULL) { \
|
||||
int CW_I_; \
|
||||
for (CW_I_ = 0; CW_I_ < argc; CW_I_++) { \
|
||||
assert(argv[CW_I_] != NULL); \
|
||||
if (argv[CW_I_] == NULL) return -1; \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define CHECK_FN() \
|
||||
do { \
|
||||
CHECK_WORDS(); \
|
||||
if (permissions != NULL) { \
|
||||
assert(result == NULL); \
|
||||
if (result != NULL) return -1; \
|
||||
} else { \
|
||||
assert(result != NULL); \
|
||||
if (result == NULL) return -1; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define NO_PERMS(perms) \
|
||||
do { \
|
||||
PermissionRequestList *NP_PRL_ = (perms); \
|
||||
if (NP_PRL_ != NULL) { \
|
||||
int NP_RET_ = addPermissionRequestToList(NP_PRL_, \
|
||||
"", false, PERM_NONE); \
|
||||
if (NP_RET_ < 0) { \
|
||||
/* Returns from the calling function. \
|
||||
*/ \
|
||||
return NP_RET_; \
|
||||
} \
|
||||
} \
|
||||
assert(result != NULL); \
|
||||
if (result == NULL) return -1; \
|
||||
} while (false)
|
||||
|
||||
/*
|
||||
@ -99,13 +73,11 @@ static int gDidShowProgress = 0;
|
||||
/* assert <boolexpr>
|
||||
*/
|
||||
static int
|
||||
cmd_assert(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_assert(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_BOOL();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
/* If our argument is false, return non-zero (failure)
|
||||
* If our argument is true, return zero (success)
|
||||
@ -120,8 +92,7 @@ cmd_assert(const char *name, void *cookie, int argc, const char *argv[],
|
||||
/* format <root>
|
||||
*/
|
||||
static int
|
||||
cmd_format(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_format(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -151,8 +122,7 @@ cmd_format(const char *name, void *cookie, int argc, const char *argv[],
|
||||
* give up early.
|
||||
*/
|
||||
static int
|
||||
cmd_delete(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_delete(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
@ -166,7 +136,6 @@ cmd_delete(const char *name, void *cookie, int argc, const char *argv[],
|
||||
|
||||
recurse = (strcmp(name, "delete_recursive") == 0);
|
||||
ui_print("Deleting files...\n");
|
||||
//xxx permissions
|
||||
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
@ -233,13 +202,11 @@ static void extract_cb(const char *fn, void *cookie)
|
||||
* or a fixed default timestamp will be supplied otherwise.
|
||||
*/
|
||||
static int
|
||||
cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
//xxx permissions
|
||||
|
||||
// To create a consistent system image, never use the clock for timestamps.
|
||||
struct utimbuf timestamp = { 1217592000, 1217592000 }; // 8/1/2008 default
|
||||
@ -331,8 +298,7 @@ cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
* Run an external program included in the update package.
|
||||
*/
|
||||
static int
|
||||
cmd_run_program(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_run_program(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
@ -407,8 +373,7 @@ cmd_run_program(const char *name, void *cookie, int argc, const char *argv[],
|
||||
* User, group, and modes must all be integer values (hex or octal OK).
|
||||
*/
|
||||
static int
|
||||
cmd_set_perm(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_set_perm(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
@ -461,8 +426,7 @@ cmd_set_perm(const char *name, void *cookie, int argc, const char *argv[],
|
||||
* if the actual rate of progress can be determined).
|
||||
*/
|
||||
static int
|
||||
cmd_show_progress(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_show_progress(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
@ -499,8 +463,7 @@ cmd_show_progress(const char *name, void *cookie, int argc, const char *argv[],
|
||||
* for the target filesystem (and may be relative).
|
||||
*/
|
||||
static int
|
||||
cmd_symlink(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_symlink(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
@ -554,7 +517,7 @@ static bool firmware_fn(const unsigned char *data, int data_len, void *cookie)
|
||||
*/
|
||||
static int
|
||||
cmd_write_firmware_image(const char *name, void *cookie,
|
||||
int argc, const char *argv[], PermissionRequestList *permissions)
|
||||
int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
@ -634,11 +597,10 @@ static bool write_raw_image_process_fn(
|
||||
*/
|
||||
static int
|
||||
cmd_write_raw_image(const char *name, void *cookie,
|
||||
int argc, const char *argv[], PermissionRequestList *permissions)
|
||||
int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_WORDS();
|
||||
//xxx permissions
|
||||
|
||||
if (argc != 2) {
|
||||
LOGE("Command %s requires exactly two arguments\n", name);
|
||||
@ -726,8 +688,7 @@ cmd_write_raw_image(const char *name, void *cookie,
|
||||
/* mark <resource> dirty|clean
|
||||
*/
|
||||
static int
|
||||
cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_mark(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -742,8 +703,7 @@ cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
/* done
|
||||
*/
|
||||
static int
|
||||
cmd_done(const char *name, void *cookie, int argc, const char *argv[],
|
||||
PermissionRequestList *permissions)
|
||||
cmd_done(const char *name, void *cookie, int argc, const char *argv[])
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
@ -764,13 +724,11 @@ cmd_done(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_compatible_with(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 1) {
|
||||
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
|
||||
@ -796,13 +754,11 @@ fn_compatible_with(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 0) {
|
||||
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
|
||||
@ -830,13 +786,11 @@ fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 1) {
|
||||
fprintf(stderr, "%s: wrong number of arguments (%d)\n",
|
||||
@ -857,8 +811,7 @@ fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
@ -875,24 +828,6 @@ fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
dir = argv[0];
|
||||
}
|
||||
|
||||
if (permissions != NULL) {
|
||||
if (dir == NULL) {
|
||||
/* The argument is the result of another function.
|
||||
* Assume the worst case, where the function returns
|
||||
* the root.
|
||||
*/
|
||||
dir = "/";
|
||||
}
|
||||
ret = addPermissionRequestToList(permissions, dir, true, PERM_READ);
|
||||
} else {
|
||||
//xxx build and return the string
|
||||
*result = strdup("hashvalue");
|
||||
if (resultLen != NULL) {
|
||||
*resultLen = strlen(*result);
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -904,13 +839,11 @@ fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_matches(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "%s: not enough arguments (%d < 2)\n",
|
||||
@ -941,13 +874,11 @@ fn_matches(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_concat(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(name);
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
size_t totalLen = 0;
|
||||
int i;
|
||||
@ -977,12 +908,10 @@ fn_concat(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_getprop(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 1) {
|
||||
LOGE("Command %s requires exactly one argument\n", name);
|
||||
@ -1005,12 +934,10 @@ fn_getprop(const char *name, void *cookie, int argc, const char *argv[],
|
||||
*/
|
||||
static int
|
||||
fn_file_contains(const char *name, void *cookie, int argc, const char *argv[],
|
||||
char **result, size_t *resultLen,
|
||||
PermissionRequestList *permissions)
|
||||
char **result, size_t *resultLen)
|
||||
{
|
||||
UNUSED(cookie);
|
||||
CHECK_FN();
|
||||
NO_PERMS(permissions);
|
||||
|
||||
if (argc != 2) {
|
||||
LOGE("Command %s requires exactly two arguments\n", name);
|
||||
|
@ -265,7 +265,6 @@ test_amend()
|
||||
{
|
||||
extern int test_symtab(void);
|
||||
extern int test_cmd_fn(void);
|
||||
extern int test_permissions(void);
|
||||
int ret;
|
||||
LOGD("Testing symtab...\n");
|
||||
ret = test_symtab();
|
||||
@ -273,9 +272,6 @@ test_amend()
|
||||
LOGD("Testing cmd_fn...\n");
|
||||
ret = test_cmd_fn();
|
||||
LOGD(" returned %d\n", ret);
|
||||
LOGD("Testing permissions...\n");
|
||||
ret = test_permissions();
|
||||
LOGD(" returned %d\n", ret);
|
||||
}
|
||||
#endif // TEST_AMEND
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user