Print this page
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
*** 19,28 ****
--- 19,30 ----
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#define _REENTRANT
*** 47,56 ****
--- 49,59 ----
#include <sys/inttypes.h>
#include <sys/mkdev.h>
#include <sys/types.h>
#include <aclutils.h>
+ #include <smbsrv/libsmb.h>
#include "praudit.h"
#include "toktable.h"
#include "adt_xlate.h"
*** 3112,3122 ****
return (0);
}
static int
! pa_ace_access_mask(pr_context_t *context, ace_t *ace, int status, int flag)
{
int returnstat, i;
uval_t uval;
char *permstr = NULL;
size_t permstr_alloc = 0;
--- 3115,3125 ----
return (0);
}
static int
! pa_ace_access_mask(pr_context_t *context, uint32_t mask, int status, int flag)
{
int returnstat, i;
uval_t uval;
char *permstr = NULL;
size_t permstr_alloc = 0;
*** 3124,3169 ****
if (status < 0)
return (status);
/*
* TRANSLATION_NOTE
! * ace->a_access_mask refers to access mask of ZFS/NFSv4 ACL entry.
*/
if ((returnstat = open_tag(context, TAG_ACEMASK)) != 0)
return (returnstat);
if (context->format & PRF_SHORTM &&
((permstr = malloc(15)) != NULL)) {
for (i = 0; i < 14; i++)
permstr[i] = '-';
! if (ace->a_access_mask & ACE_READ_DATA)
permstr[0] = 'r';
! if (ace->a_access_mask & ACE_WRITE_DATA)
permstr[1] = 'w';
! if (ace->a_access_mask & ACE_EXECUTE)
permstr[2] = 'x';
! if (ace->a_access_mask & ACE_APPEND_DATA)
permstr[3] = 'p';
! if (ace->a_access_mask & ACE_DELETE)
permstr[4] = 'd';
! if (ace->a_access_mask & ACE_DELETE_CHILD)
permstr[5] = 'D';
! if (ace->a_access_mask & ACE_READ_ATTRIBUTES)
permstr[6] = 'a';
! if (ace->a_access_mask & ACE_WRITE_ATTRIBUTES)
permstr[7] = 'A';
! if (ace->a_access_mask & ACE_READ_NAMED_ATTRS)
permstr[8] = 'R';
! if (ace->a_access_mask & ACE_WRITE_NAMED_ATTRS)
permstr[9] = 'W';
! if (ace->a_access_mask & ACE_READ_ACL)
permstr[10] = 'c';
! if (ace->a_access_mask & ACE_WRITE_ACL)
permstr[11] = 'C';
! if (ace->a_access_mask & ACE_WRITE_OWNER)
permstr[12] = 'o';
! if (ace->a_access_mask & ACE_SYNCHRONIZE)
permstr[13] = 's';
permstr[14] = '\0';
uval.uvaltype = PRA_STRING;
uval.string_val = permstr;
} else if (!(context->format & PRF_RAWM)) {
--- 3127,3172 ----
if (status < 0)
return (status);
/*
* TRANSLATION_NOTE
! * mask refers to access mask of ZFS/NFSv4 ACL entry.
*/
if ((returnstat = open_tag(context, TAG_ACEMASK)) != 0)
return (returnstat);
if (context->format & PRF_SHORTM &&
((permstr = malloc(15)) != NULL)) {
for (i = 0; i < 14; i++)
permstr[i] = '-';
! if (mask & ACE_READ_DATA)
permstr[0] = 'r';
! if (mask & ACE_WRITE_DATA)
permstr[1] = 'w';
! if (mask & ACE_EXECUTE)
permstr[2] = 'x';
! if (mask & ACE_APPEND_DATA)
permstr[3] = 'p';
! if (mask & ACE_DELETE)
permstr[4] = 'd';
! if (mask & ACE_DELETE_CHILD)
permstr[5] = 'D';
! if (mask & ACE_READ_ATTRIBUTES)
permstr[6] = 'a';
! if (mask & ACE_WRITE_ATTRIBUTES)
permstr[7] = 'A';
! if (mask & ACE_READ_NAMED_ATTRS)
permstr[8] = 'R';
! if (mask & ACE_WRITE_NAMED_ATTRS)
permstr[9] = 'W';
! if (mask & ACE_READ_ACL)
permstr[10] = 'c';
! if (mask & ACE_WRITE_ACL)
permstr[11] = 'C';
! if (mask & ACE_WRITE_OWNER)
permstr[12] = 'o';
! if (mask & ACE_SYNCHRONIZE)
permstr[13] = 's';
permstr[14] = '\0';
uval.uvaltype = PRA_STRING;
uval.string_val = permstr;
} else if (!(context->format & PRF_RAWM)) {
*** 3172,3234 ****
* Note this differs from acltext.c:ace_perm_txt()
* because we don't know if the acl belongs to a file
* or directory. ace mask value are the same
* nonetheless, see sys/acl.h
*/
! if (ace->a_access_mask & ACE_LIST_DIRECTORY) {
returnstat = strappend(&permstr, gettext(READ_DIR_TXT),
&permstr_alloc);
}
! if (ace->a_access_mask & ACE_ADD_FILE) {
returnstat = strappend(&permstr, gettext(ADD_FILE_TXT),
&permstr_alloc);
}
! if (ace->a_access_mask & ACE_ADD_SUBDIRECTORY) {
returnstat = strappend(&permstr, gettext(ADD_DIR_TXT),
&permstr_alloc);
}
! if (ace->a_access_mask & ACE_READ_NAMED_ATTRS) {
returnstat = strappend(&permstr,
gettext(READ_XATTR_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_WRITE_NAMED_ATTRS) {
returnstat = strappend(&permstr,
gettext(WRITE_XATTR_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_EXECUTE) {
returnstat = strappend(&permstr,
gettext(EXECUTE_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_DELETE_CHILD) {
returnstat = strappend(&permstr,
gettext(DELETE_CHILD_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_READ_ATTRIBUTES) {
returnstat = strappend(&permstr,
gettext(READ_ATTRIBUTES_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_WRITE_ATTRIBUTES) {
returnstat = strappend(&permstr,
gettext(WRITE_ATTRIBUTES_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_DELETE) {
returnstat = strappend(&permstr, gettext(DELETE_TXT),
&permstr_alloc);
}
! if (ace->a_access_mask & ACE_READ_ACL) {
returnstat = strappend(&permstr, gettext(READ_ACL_TXT),
&permstr_alloc);
}
! if (ace->a_access_mask & ACE_WRITE_ACL) {
returnstat = strappend(&permstr, gettext(WRITE_ACL_TXT),
&permstr_alloc);
}
! if (ace->a_access_mask & ACE_WRITE_OWNER) {
returnstat = strappend(&permstr,
gettext(WRITE_OWNER_TXT), &permstr_alloc);
}
! if (ace->a_access_mask & ACE_SYNCHRONIZE) {
returnstat = strappend(&permstr,
gettext(SYNCHRONIZE_TXT), &permstr_alloc);
}
if (permstr[strlen(permstr) - 1] == '/')
permstr[strlen(permstr) - 1] = '\0';
--- 3175,3237 ----
* Note this differs from acltext.c:ace_perm_txt()
* because we don't know if the acl belongs to a file
* or directory. ace mask value are the same
* nonetheless, see sys/acl.h
*/
! if (mask & ACE_LIST_DIRECTORY) {
returnstat = strappend(&permstr, gettext(READ_DIR_TXT),
&permstr_alloc);
}
! if (mask & ACE_ADD_FILE) {
returnstat = strappend(&permstr, gettext(ADD_FILE_TXT),
&permstr_alloc);
}
! if (mask & ACE_ADD_SUBDIRECTORY) {
returnstat = strappend(&permstr, gettext(ADD_DIR_TXT),
&permstr_alloc);
}
! if (mask & ACE_READ_NAMED_ATTRS) {
returnstat = strappend(&permstr,
gettext(READ_XATTR_TXT), &permstr_alloc);
}
! if (mask & ACE_WRITE_NAMED_ATTRS) {
returnstat = strappend(&permstr,
gettext(WRITE_XATTR_TXT), &permstr_alloc);
}
! if (mask & ACE_EXECUTE) {
returnstat = strappend(&permstr,
gettext(EXECUTE_TXT), &permstr_alloc);
}
! if (mask & ACE_DELETE_CHILD) {
returnstat = strappend(&permstr,
gettext(DELETE_CHILD_TXT), &permstr_alloc);
}
! if (mask & ACE_READ_ATTRIBUTES) {
returnstat = strappend(&permstr,
gettext(READ_ATTRIBUTES_TXT), &permstr_alloc);
}
! if (mask & ACE_WRITE_ATTRIBUTES) {
returnstat = strappend(&permstr,
gettext(WRITE_ATTRIBUTES_TXT), &permstr_alloc);
}
! if (mask & ACE_DELETE) {
returnstat = strappend(&permstr, gettext(DELETE_TXT),
&permstr_alloc);
}
! if (mask & ACE_READ_ACL) {
returnstat = strappend(&permstr, gettext(READ_ACL_TXT),
&permstr_alloc);
}
! if (mask & ACE_WRITE_ACL) {
returnstat = strappend(&permstr, gettext(WRITE_ACL_TXT),
&permstr_alloc);
}
! if (mask & ACE_WRITE_OWNER) {
returnstat = strappend(&permstr,
gettext(WRITE_OWNER_TXT), &permstr_alloc);
}
! if (mask & ACE_SYNCHRONIZE) {
returnstat = strappend(&permstr,
gettext(SYNCHRONIZE_TXT), &permstr_alloc);
}
if (permstr[strlen(permstr) - 1] == '/')
permstr[strlen(permstr) - 1] = '\0';
*** 3235,3246 ****
uval.uvaltype = PRA_STRING;
uval.string_val = permstr;
}
if ((permstr == NULL) || (returnstat != 0) ||
(context->format & PRF_RAWM)) {
! uval.uvaltype = PRA_UINT32;
! uval.uint32_val = ace->a_access_mask;
}
returnstat = pa_print(context, &uval, flag);
if (permstr != NULL)
free(permstr);
--- 3238,3249 ----
uval.uvaltype = PRA_STRING;
uval.string_val = permstr;
}
if ((permstr == NULL) || (returnstat != 0) ||
(context->format & PRF_RAWM)) {
! uval.uvaltype = PRA_HEX32;
! uval.int32_val = mask;
}
returnstat = pa_print(context, &uval, flag);
if (permstr != NULL)
free(permstr);
*** 3312,3321 ****
if ((returnstat = pa_ace_flags(context, &ace, returnstat, 0)) != 0)
return (returnstat);
/* pa_ace_who can returns 1 if uid/gid is not found */
if ((returnstat = pa_ace_who(context, &ace, returnstat, 0)) < 0)
return (returnstat);
! if ((returnstat = pa_ace_access_mask(context, &ace,
returnstat, 0)) != 0)
return (returnstat);
return (pa_ace_type(context, &ace, returnstat, flag));
}
--- 3315,3382 ----
if ((returnstat = pa_ace_flags(context, &ace, returnstat, 0)) != 0)
return (returnstat);
/* pa_ace_who can returns 1 if uid/gid is not found */
if ((returnstat = pa_ace_who(context, &ace, returnstat, 0)) < 0)
return (returnstat);
! if ((returnstat = pa_ace_access_mask(context, ace.a_access_mask,
returnstat, 0)) != 0)
return (returnstat);
return (pa_ace_type(context, &ace, returnstat, flag));
+ }
+
+ int
+ pa_access_mask(pr_context_t *context, int status, int flag)
+ {
+ int returnstat;
+ uint32_t mask;
+
+ if (status < 0)
+ return (status);
+
+ returnstat = pr_adr_u_int32(context, &mask, 1);
+ return (pa_ace_access_mask(context, mask, returnstat, flag));
+ }
+
+ int
+ pa_wsid(pr_context_t *context, int status, int flag)
+ {
+ int returnstat;
+ short length;
+ char *sid;
+ uval_t uval;
+ char *name = NULL;
+
+ if (status < 0)
+ return (status);
+ if ((returnstat = open_tag(context, TAG_WSID)) != 0)
+ return (returnstat);
+
+ if ((returnstat = pr_adr_short(context, &length, 1)) != 0)
+ return (returnstat);
+ if ((sid = (char *)malloc(length + 1)) == NULL)
+ return (-1);
+ if ((returnstat = pr_adr_char(context, sid, length)) != 0) {
+ free(sid);
+ return (returnstat);
+ }
+
+ uval.uvaltype = PRA_STRING;
+ uval.string_val = sid;
+ if ((context->format & PRF_RAWM) == 0) {
+ int rc;
+ int flag = IDMAP_REQ_FLG_USE_CACHE;
+ rc = idmap_getwinnamebysid(sid, flag, &name);
+ if (rc == IDMAP_SUCCESS)
+ uval.string_val = name;
+ else
+ (void) fprintf(stderr,
+ gettext("praudit: failed to map sid to name "
+ "rc=%d\n"), rc);
+ }
+ returnstat = pa_print(context, &uval, flag);
+ free(sid);
+ if (name != NULL)
+ free(name);
+ if (returnstat == 0)
+ returnstat = close_tag(context, TAG_WSID);
+ return (returnstat);
}