Skip to content

Commit a614be4

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 90e7ea1 commit a614be4

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-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: 50 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,43 @@ 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+
#ifdef _WIN32
675+
/* TODO: Policy function to read Windows ACLs (ENT-13019) */
676+
Rlist *acls = NULL;
677+
errno = ENOTSUP;
678+
#else
679+
Rlist *acls = GetACLs(path, StringEqual(type, "access"));
680+
#endif /* _WIN32 */
681+
if (acls == NULL)
682+
{
683+
Log((errno != ENOTSUP) ? LOG_LEVEL_ERR : LOG_LEVEL_VERBOSE,
684+
"Function %s failed to get ACLs for '%s': %s",
685+
fp->name, path, GetErrorStr());
686+
687+
if (errno != ENOTSUP)
688+
{
689+
return FnFailure();
690+
} /* else we'll just return an empty list instead */
691+
}
692+
693+
return (FnCallResult) { FNCALL_SUCCESS, { acls, RVAL_TYPE_LIST } };
694+
}
695+
696+
/*********************************************************************/
697+
657698
static FnCallResult FnCallAnd(EvalContext *ctx,
658699
ARG_UNUSED const Policy *policy,
659700
ARG_UNUSED const FnCall *fp,
@@ -9776,6 +9817,13 @@ static const FnCallArg AND_ARGS[] =
97769817
{NULL, CF_DATA_TYPE_NONE, NULL}
97779818
};
97789819

9820+
static const FnCallArg GET_ACLS_ARGS[] =
9821+
{
9822+
{CF_ABSPATHRANGE, CF_DATA_TYPE_STRING, "Path to file or directory"},
9823+
{"default,access", CF_DATA_TYPE_OPTION, "Whether to get default or access ACL"},
9824+
{NULL, CF_DATA_TYPE_NONE, NULL},
9825+
};
9826+
97799827
static const FnCallArg AGO_ARGS[] =
97809828
{
97819829
{"0,1000", CF_DATA_TYPE_INT, "Years"},
@@ -10820,6 +10868,8 @@ const FnCallType CF_FNCALL_TYPES[] =
1082010868
FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL),
1082110869
FnCallTypeNew("accumulated", CF_DATA_TYPE_INT, ACCUM_ARGS, &FnCallAccumulatedDate, "Convert an accumulated amount of time into a system representation",
1082210870
FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL),
10871+
FnCallTypeNew("getacls", CF_DATA_TYPE_STRING_LIST, GET_ACLS_ARGS, &FnCallGetACLs, "Get ACLs of a given file",
10872+
FNCALL_OPTION_NONE, FNCALL_CATEGORY_FILES, SYNTAX_STATUS_NORMAL),
1082310873
FnCallTypeNew("ago", CF_DATA_TYPE_INT, AGO_ARGS, &FnCallAgoDate, "Convert a time relative to now to an integer system representation",
1082410874
FNCALL_OPTION_NONE, FNCALL_CATEGORY_DATA, SYNTAX_STATUS_NORMAL),
1082510875
FnCallTypeNew("and", CF_DATA_TYPE_CONTEXT, AND_ARGS, &FnCallAnd, "Calculate whether all arguments evaluate to true",

0 commit comments

Comments
 (0)