Skip to content

Commit e4ea640

Browse files
committed
Added policy function to get ACLs
Ticket: CFE-4529 Changelog: Title Signed-off-by: Lars Erik Wik <lars.erik.wik@northern.tech>
1 parent 2f16047 commit e4ea640

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

libpromises/acl_tools.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@
2525
#ifndef CFENGINE_ACL_TOOLS_H
2626
#define CFENGINE_ACL_TOOLS_H
2727

28+
#include <stdbool.h>
29+
#include <rlist.h>
30+
31+
32+
/**
33+
* @brief Get ACLs from a file or directory
34+
* @param Path to file or directory
35+
* @param access Get access ACLs if true, otherwise default ACLs
36+
* @return List of ACLs. On error, NULL is returned and errno is set to
37+
* indicate the error.
38+
*/
39+
Rlist *GetACLs(const char *path, bool access);
40+
2841
bool CopyACLs(const char *src, const char *dst, bool *change);
2942

3043
/**

libpromises/acl_tools_posix.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,39 @@ bool AllowAccessForUsers(const char *path, StringSet *users, bool allow_writes,
259259
return true;
260260
}
261261

262+
Rlist *GetACLs(const char *path, bool access)
263+
{
264+
assert(path != NULL);
265+
266+
acl_t acl = acl_get_file(path, access ? ACL_TYPE_ACCESS : ACL_TYPE_DEFAULT);
267+
if (acl == NULL)
268+
{
269+
return NULL;
270+
}
271+
272+
char *text = acl_to_any_text(acl, NULL, ',', 0);
273+
if (text == NULL)
274+
{
275+
acl_free(acl);
276+
return NULL;
277+
}
278+
279+
Rlist *lst = RlistFromSplitString(text, ',');
280+
281+
acl_free(text);
282+
acl_free(acl);
283+
return lst;
284+
}
285+
262286
#elif !defined(__MINGW32__) /* !HAVE_LIBACL */
263287

288+
Rlist *GetACLs(ARG_UNUSED const char *path, ARG_UNUSED bool access)
289+
{
290+
/* TODO: Handle Windows ACLs (see ENT-13019) */
291+
errno = ENOTSUP;
292+
return NULL;
293+
}
294+
264295
bool CopyACLs(ARG_UNUSED const char *src, ARG_UNUSED const char *dst, bool *change)
265296
{
266297
if (change != NULL)

libpromises/evalfunction.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
#include <libgen.h>
8383

8484
#include <ctype.h>
85+
#include <cf3.defs.h>
86+
#include <compiler.h>
87+
#include <rlist.h>
88+
#include <acl_tools.h>
8589

8690
#ifdef HAVE_LIBCURL
8791
#include <curl/curl.h>
@@ -654,6 +658,32 @@ static Rlist *GetHostsFromLastseenDB(Seq *host_data, time_t horizon, HostsSeenFi
654658

655659
/*********************************************************************/
656660

661+
static FnCallResult FnCallGetACLs(ARG_UNUSED EvalContext *ctx,
662+
ARG_UNUSED const Policy *policy,
663+
const FnCall *fp,
664+
const Rlist *final_args)
665+
{
666+
assert(fp != NULL);
667+
assert(final_args != NULL);
668+
assert(final_args->next != NULL);
669+
670+
const char *path = RlistScalarValue(final_args);
671+
const char *type = RlistScalarValue(final_args->next);
672+
assert(StringEqual(type, "default") || StringEqual(type, "access"));
673+
674+
Rlist *acls = GetACLs(path, StringEqual(type, "access"));
675+
if (acls == NULL)
676+
{
677+
Log(LOG_LEVEL_ERR, "Function %s failed to get ACLs for '%s': %s",
678+
fp->name, path, GetErrorStr());
679+
return FnFailure();
680+
}
681+
682+
return (FnCallResult) { FNCALL_SUCCESS, { acls, RVAL_TYPE_LIST } };
683+
}
684+
685+
/*********************************************************************/
686+
657687
static FnCallResult FnCallAnd(EvalContext *ctx,
658688
ARG_UNUSED const Policy *policy,
659689
ARG_UNUSED const FnCall *fp,
@@ -9754,6 +9784,13 @@ static const FnCallArg AND_ARGS[] =
97549784
{NULL, CF_DATA_TYPE_NONE, NULL}
97559785
};
97569786

9787+
static const FnCallArg GET_ACLS_ARGS[] =
9788+
{
9789+
{CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Path to file or directory"},
9790+
{"default,access", CF_DATA_TYPE_OPTION, "Whether to get default- or access ACL"},
9791+
{NULL, CF_DATA_TYPE_NONE, NULL},
9792+
};
9793+
97579794
static const FnCallArg AGO_ARGS[] =
97589795
{
97599796
{"0,1000", CF_DATA_TYPE_INT, "Years"},
@@ -10791,6 +10828,8 @@ const FnCallType CF_FNCALL_TYPES[] =
1079110828
FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL),
1079210829
FnCallTypeNew("accumulated", CF_DATA_TYPE_INT, ACCUM_ARGS, &FnCallAccumulatedDate, "Convert an accumulated amount of time into a system representation",
1079310830
FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL),
10831+
FnCallTypeNew("getacls", CF_DATA_TYPE_STRING_LIST, GET_ACLS_ARGS, &FnCallGetACLs, "Get ACLs of a given file",
10832+
FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL),
1079410833
FnCallTypeNew("ago", CF_DATA_TYPE_INT, AGO_ARGS, &FnCallAgoDate, "Convert a time relative to now to an integer system representation",
1079510834
FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL),
1079610835
FnCallTypeNew("and", CF_DATA_TYPE_CONTEXT, AND_ARGS, &FnCallAnd, "Calculate whether all arguments evaluate to true",

0 commit comments

Comments
 (0)