GitLab Commit is coming up on August 3-4. Learn how to innovate together using GitLab, the DevOps platform. Register for free: gitlabcommitvirtual2021.com

Commits (19)
......@@ -7,6 +7,33 @@
> Base libraries for ARPA2, including library for ACLs and a common
> utility library; see also Quick-MEM for other low-level support libraries.
## v2.2.9 (2021-06-23)
- Issue #37, abstract ruleset operations in a2rule :-
- Named it "a2rule ruleset add|del|get|set"
- Always require a Service Key and Access Name
- Optionally use Access Type for (too simple) regex matching with Access Name
- Parse the Rule, if it is provided
- If no Selector is provided, use the most general form "@."
## v2.2.8 (2021-06-23)
- Updates to the `a2rule` command and its man page :-
- Make `a2rule` help with the key derivation process
- Command Parser support for abbreviations
- Added support for Domain Keys
- Added `getpass()` to get the Database Secret
- Stopped `a2rule` mentioning the "dbsecret" cmdarg
- Stopped debugging output with "dbsecret" :-)
## v2.2.7 (2021-06-22)
- Issue #39, Crash of a2rule in v2.2.6
- Updates to the a2rule(8) man page
- Document Access added to src/tool/a2rule.c
- Added the long-confused =n<newuserid>
- Removed the <userid>@ before <volume> in Document Access
## v2.2.6 (2021-06-21)
- Explicit error when $ARPA2_RULES_DIR is not an absolute path
......
......@@ -7,7 +7,7 @@
# SPDX-FileCopyrightText: 2020 Rick van Rein
cmake_minimum_required (VERSION 3.13 FATAL_ERROR)
project ("ARPA2 Common Libraries" VERSION 2.2.6 LANGUAGES C)
project ("ARPA2 Common Libraries" VERSION 2.2.9 LANGUAGES C)
set (CMAKE_C_STANDARD 11)
set (CMAKE_C_STANDARD_REQUIRED ON)
......
......@@ -28,9 +28,8 @@ Here are a few concepts that are useful to understand:
These are general.
Document Access references documents under an Access Name following a
`//<volume>/<path>` grammar or, if a volume is specific to a user,
following a `//<user>@<volume>/<path>` grammar. The `<user>` and
`<volume>` strings must not contain any `@` or `/` symbols. This
`//<volume>/<path>` grammar. The `<volume>` string must not contain
any `/` symbols, but `@` is permitted, perhaps to hint a user. This
string combines with an Access Domain to uniquely specify a Document.
......@@ -81,10 +80,12 @@ after `/<colluuid>/` is removed before the Access Rights lookup.
Any `<volume>` name can be introduced by operators as required, and
its `%RIGHTS` can be bestowed as desired. The form of the Access Name
is `//<volume>/<path>` or `//<user>@<volume>/<path>` and this combines
with an Access Domain under which it is defined. The use of `//` at the
start sets these operator-defined Volumes apart from Access Names as
used by ARPA2 Reservoir.
is `//<volume>/<path>` and this combines with an Access Domain under
which it is defined. The use of `//` at the start sets these
operator-defined Volumes apart from Access Names as used by ARPA2
Reservoir. End the `<path>` with `/` if and only if it is a directory;
never start a `<path>` with a slash however, as that is part of the
prefixed `//<volume>/` form.
An example of an Access Name for an internally shared NFS export for a
company's products could be
......
This diff is collapsed.
......@@ -15,8 +15,8 @@ library_pair(
OUTPUT_NAME arpa2access
SOURCES
comm.c
document.c
group.c
document.c
group.c
${RAGEL_rules_OUTPUTS}
database.c
editor.c
......@@ -26,6 +26,6 @@ library_pair(
LIBRARIES
lmdb::lmdb
OpenSSL::Crypto
com_err::arpa2access
com_err::arpa2access
EXPORT ARPA2Common
)
This diff is collapsed.
......@@ -13,6 +13,8 @@ enum parse_variables {
//NO_DBNAME, /* Database name in envdir, default NULL */
VAR_DBTRUNK, /* Default 0, overlay database versions for DUP_SORT */
VAR_DBSECRET, /* Scatter/encryption key, default none */
VAR_DOMAINKEY, /* Domain Key, used by domain admins instead DBsecret */
VAR_SERVICEKEY, /* Service Key, used by service providers */
/* For selecting the database lookup keys: */
//NO_OBJTYPE, /* For instance "communication" (or abbreviations) */
......@@ -26,17 +28,32 @@ enum parse_variables {
VAR_ALIAS, /* Comm setup for particular local aliases/svcarg */
VAR_ENDALIAS, /* Comm setup for ending alias */
VAR_SIGNFLAGS, /* Comm: required signature flags */
VAR_NEWUSERID, /* Comm: set the userid to a desired value, drop aliases */
VAR_NEWALIAS, /* Comm: set the alias(es) to a desired value */
VAR_GROUPID, /* Comm: set group identity (no member alias, no domain) */
VAR_ACTORID, /* Comm: set actor identity (no member alias, no domain) */
/* End marker */
VAR_ENDMARKER
};
#define VAR_MEMBER VAR_LOCAL
#define VAR_IDENTITY VAR_REMOTE
#define VAR_MARKS VAR_RIGHTS
/* Changes for groups */
#define VAR_MEMBER VAR_LOCAL
#define VAR_IDENTITY VAR_REMOTE
#define VAR_MARKS VAR_RIGHTS
/* Changes for documents */
#define VAR_DOMAIN VAR_LOCAL
#define VAR_COLLECTION VAR_ITERATE
#define VAR_USERID VAR_ALIAS
#define VAR_PATH VAR_SIGNFLAGS
#define VAR_VOLUME VAR_NEWALIAS
/* Changes for (abstract) rulesets */
#define VAR_TYPE VAR_RIGHTS
#define VAR_NAME VAR_LOCAL
#define VAR_SELECTOR VAR_REMOTE
#define VAR_RULE VAR_LIST
#define VAR_FIRST VAR_DBTRUNK
#define VAR_LAST (VAR_ENDMARKER-1)
......@@ -55,6 +72,8 @@ enum parse_variables {
// #define VAL_DBNAME values [VAR_DBNAME]
#define VAL_DBTRUNK values [VAR_DBTRUNK]
#define VAL_DBSECRET values [VAR_DBSECRET]
#define VAL_DOMAINKEY values [VAR_DOMAINKEY]
#define VAL_SERVICEKEY values [VAR_SERVICEKEY]
// #define VAL_OBJTYPE values [VAR_OBJTYPE]
#define VAL_LOCAL values [VAR_LOCAL]
#define VAL_REMOTE values [VAR_REMOTE]
......@@ -64,19 +83,36 @@ enum parse_variables {
#define VAL_ALIAS values [VAR_ALIAS]
#define VAL_ENDALIAS values [VAR_ENDALIAS]
#define VAL_SIGNFLAGS values [VAR_SIGNFLAGS]
#define VAL_NEWUSERID values [VAR_NEWUSERID]
#define VAL_NEWALIAS values [VAR_NEWALIAS]
#define VAL_GROUPID values [VAR_GROUPID]
#define VAL_ACTORID values [VAR_ACTORID]
/* Changes for groups */
#define VAL_MEMBER values [VAR_LOCAL]
#define VAL_IDENTITY values [VAR_REMOTE]
#define VAL_MARKS values [VAR_RIGHTS]
/* Changes for documents */
#define VAL_DOMAIN values [VAR_LOCAL]
#define VAL_COLLECTION values [VAR_ITERATE]
#define VAL_USERID values [VAR_ALIAS]
#define VAL_PATH values [VAR_SIGNFLAGS]
#define VAL_VOLUME values [VAR_NEWALIAS]
/* Changes for (abstract) rulesets */
#define VAL_TYPE values [VAR_TYPE]
#define VAL_NAME values [VAR_NAME]
#define VAL_SELECTOR values [VAR_SELECTOR]
#define VAL_RULE values [VAR_RULE]
/* Flags to compose in the combinations */
// #define FLAG_DBENV (1 << VAR_DBENV )
// #define FLAG_DBNAME (1 << VAR_DBNAME )
#define FLAG_DBTRUNK (1 << VAR_DBTRUNK )
#define FLAG_DBSECRET (1 << VAR_DBSECRET )
#define FLAG_DOMAINKEY (1 << VAR_DOMAINKEY)
#define FLAG_SERVICEKEY (1 << VAR_SERVICEKEY)
// #define FLAG_OBJTYPE (1 << VAR_OBJTYPE )
#define FLAG_LOCAL (1 << VAR_LOCAL )
#define FLAG_REMOTE (1 << VAR_REMOTE )
......@@ -86,12 +122,27 @@ enum parse_variables {
#define FLAG_ALIAS (1 << VAR_ALIAS )
#define FLAG_ENDALIAS (1 << VAR_ENDALIAS )
#define FLAG_SIGNFLAGS (1 << VAR_SIGNFLAGS)
#define FLAG_NEWUSERID (1 << VAR_NEWUSERID)
#define FLAG_NEWALIAS (1 << VAR_NEWALIAS )
#define FLAG_GROUPID (1 << VAR_GROUPID )
#define FLAG_ACTORID (1 << VAR_ACTORID )
/* Changes for groups */
#define FLAG_MEMBER (1 << VAR_MEMBER )
#define FLAG_IDENTITY (1 << VAR_IDENTITY )
#define FLAG_MARKS (1 << VAR_MARKS )
/* Changes for documents */
#define FLAG_DOMAIN (1 << VAR_DOMAIN )
#define FLAG_COLLECTION (1 << VAR_COLLECTION)
#define FLAG_USERID (1 << VAR_USERID )
#define FLAG_PATH (1 << VAR_PATH )
#define FLAG_VOLUME (1 << VAR_VOLUME )
/* Changes for (abstract) rulesets */
#define FLAG_TYPE (1 << VAR_TYPE )
#define FLAG_NAME (1 << VAR_NAME )
#define FLAG_SELECTOR (1 << VAR_SELECTOR )
#define FLAG_RULE (1 << VAR_RULE )
......@@ -38,16 +38,22 @@ bool cmdparse_keyword_value (struct cmdparser *prs, char *keyword, char *value)
// Iterate over keywords in the grammar
const char * const *kwdv = prs->grammar->keywords;
bool found = false;
unsigned keywordlen = strlen (keyword);
for (int kwdi = 0; kwdi < 32 ; kwdi++, kwdv++) {
//
// See if the keyword is a match
if (*kwdv == NULL) {
continue;
}
if (strcasecmp (keyword, *kwdv) != 0) {
if (strncasecmp (keyword, *kwdv, keywordlen) != 0) {
continue;
}
//
// Avoid ambiguous keyword recognition (and prefix extensions...)
if (found) {
goto fail;
}
//
// Avoid repeated keywords with different values
if ((prs->values [kwdi] != NULL) &&
(0 != strcmp (prs->values [kwdi], value))) {
......@@ -271,42 +277,52 @@ bool cmdparse_class_action (int argc, char *argv [],
}
//
// Look for argv [1]
struct cmdparse_class *class_found = NULL;
while (clsarray->classstr != NULL) {
if (strncmp (argv [1], clsarray->classstr, strlen (argv [1])) == 0) {
break;
if (class_found != NULL) {
/* Ambiguous command */
goto parser_error;
}
class_found = clsarray;
}
clsarray ++;
}
if (clsarray->classstr == NULL) {
if (class_found == NULL) {
goto parser_error;
}
argi++;
//
// Look for argv [2]
usage = clsarray->usage;
const struct cmdparse_action *clsactarray = clsarray->actions;
usage = class_found->usage;
const struct cmdparse_action *clsactarray = class_found->actions;
const struct cmdparse_action *action_found = NULL;
while (clsactarray->actionstr != NULL) {
if (strncmp (argv [2], clsactarray->actionstr, strlen (argv [2])) == 0) {
break;
if (action_found != NULL) {
/* Ambiguous command */
goto parser_error;
}
action_found = clsactarray;
}
clsactarray++;
}
if (clsactarray->actionstr == NULL) {
if (action_found == NULL) {
goto parser_error;
}
short opcode = clsactarray->opcode;
short opcode = action_found->opcode;
argi++;
//
// Construct the parser for the remaining keyword arguments
usage = clsactarray->usage;
struct cmdparser prs = NEW_CMDPARSER (clsactarray->grammar);
usage = action_found->usage;
struct cmdparser prs = NEW_CMDPARSER (action_found->grammar);
if (!cmdparse_kwargs (&prs, argc-3, argv+3)) {
goto parser_error;
}
//
// We found a function to call for the actionfun
usage = clsactarray->usage;
bool retval = clsactarray->actionfun (opcode, &prs, usage, argc, argv);
usage = action_found->usage;
bool retval = action_found->actionfun (opcode, &prs, usage, argc, argv);
return retval;
//
// We hit a parser error
......