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); }