4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
38 #include <arpa/inet.h>
40 #include <bsm/audit.h>
41 #include <bsm/audit_record.h>
42 #include <bsm/libbsm.h>
43 #include <security/pam_appl.h>
45 #include <sys/inttypes.h>
46 #include <sys/mkdev.h>
47 #include <sys/types.h>
52 #include "adt_xlate.h"
54 static void convertascii(char *p
, char *c
, int size
);
55 static int convertbinary(char *p
, char *c
, int size
);
56 static void eventmodifier2string(au_emod_t emodifier
, char *modstring
,
58 static int do_mtime32(pr_context_t
*context
, int status
, int flag
,
60 static int do_mtime64(pr_context_t
*context
, int status
, int flag
,
64 * ------------------------------------------------------
65 * field widths for arbitrary data token type
66 * ------------------------------------------------------
75 /* character data type, 8 bits */
76 AUR_CHAR
, AUP_BINARY
, 12,
81 AUR_BYTE
, AUP_BINARY
, 12,
86 AUR_SHORT
, AUP_BINARY
, 20,
91 AUR_INT32
, AUP_BINARY
, 36,
96 AUR_INT64
, AUP_BINARY
, 68,
103 static int numwidthentries
= sizeof (fwidth
)
104 / sizeof (struct fw
);
108 * -----------------------------------------------------------------------
110 * Print a newline, if needed according to various formatting
112 * return codes : 0 - success
114 * -----------------------------------------------------------------------
117 do_newline(pr_context_t
*context
, int flag
)
121 if (!(context
->format
& PRF_ONELINE
) && (flag
== 1))
122 retstat
= pr_putchar(context
, '\n');
123 else if (!(context
->format
& PRF_XMLM
))
124 retstat
= pr_printf(context
, "%s", context
->SEPARATOR
);
130 open_tag(pr_context_t
*context
, int tagnum
)
135 /* no-op if not doing XML format */
136 if (!(context
->format
& PRF_XMLM
))
139 tag
= &tokentable
[tagnum
];
142 * First if needed do an implicit finish of a pending open for an
143 * extended tag. I.e., for the extended tag xxx:
144 * <xxx a=".." b=".."> ... </xxx>
145 * -- insert a close bracket after the last attribute
146 * (in other words, when the 1st non-attribute is opened while
147 * this is pending). Note that only one tag could be pending at
148 * a given time -- it couldn't be nested.
150 if (context
->pending_flag
&& (tag
->t_type
!= T_ATTRIBUTE
)) {
151 /* complete pending extended open */
152 err
= pr_putchar(context
, '>');
155 context
->pending_flag
= 0;
158 if (is_header_token(tagnum
) || is_file_token(tagnum
)) {
159 /* File token or new record on new line */
160 err
= pr_putchar(context
, '\n');
161 } else if (is_token(tagnum
)) {
162 /* Each token on new line if possible */
163 err
= do_newline(context
, 1);
168 switch (tag
->t_type
) {
170 err
= pr_printf(context
, " %s=\"", tag
->t_tagname
);
173 err
= pr_printf(context
, "<%s>", tag
->t_tagname
);
176 err
= pr_printf(context
, "<%s", tag
->t_tagname
);
179 err
= pr_printf(context
, "<%s", tag
->t_tagname
);
181 context
->pending_flag
= tagnum
;
187 if (is_header_token(tagnum
) && (err
== 0))
188 context
->current_rec
= tagnum
; /* set start of new record */
194 * Do an implicit close of a record when needed.
197 check_close_rec(pr_context_t
*context
, int tagnum
)
201 /* no-op if not doing XML format */
202 if (!(context
->format
& PRF_XMLM
))
206 * If we're opening a header or the file token (i.e., starting a new
207 * record), if there's a current record in progress do an implicit
210 if ((is_header_token(tagnum
) || is_file_token(tagnum
)) &&
211 context
->current_rec
) {
212 err
= do_newline(context
, 1);
214 err
= close_tag(context
, context
->current_rec
);
221 * explicit finish of a pending open for an extended tag.
224 finish_open_tag(pr_context_t
*context
)
228 /* no-op if not doing XML format */
229 if (!(context
->format
& PRF_XMLM
))
232 if (context
->pending_flag
) {
233 /* complete pending extended open */
234 err
= pr_putchar(context
, '>');
236 context
->pending_flag
= 0;
242 close_tag(pr_context_t
*context
, int tagnum
)
247 /* no-op if not doing XML format */
248 if (!(context
->format
& PRF_XMLM
))
251 tag
= &tokentable
[tagnum
];
253 switch (tag
->t_type
) {
255 err
= pr_putchar(context
, '\"');
258 err
= pr_printf(context
, "</%s>", tag
->t_tagname
);
261 err
= pr_printf(context
, "/>");
264 err
= pr_printf(context
, "</%s>", tag
->t_tagname
);
270 if (is_header_token(tagnum
) && (err
== 0))
271 context
->current_rec
= 0; /* closing rec; none current */
277 * -----------------------------------------------------------------------
279 * Calls the routine corresponding to the tag
280 * Note that to use this mechanism, all such routines must
281 * take 2 ints for their parameters; the first of these is
282 * the current status.
284 * flag = 1 for newline / delimiter, else 0
285 * return codes : -1 - error
287 * -----------------------------------------------------------------------
290 process_tag(pr_context_t
*context
, int tagnum
, int status
, int flag
)
299 if ((tagnum
> 0) && (tagnum
<= MAXTAG
) &&
300 (tokentable
[tagnum
].func
!= NOFUNC
)) {
301 retstat
= open_tag(context
, tagnum
);
303 retstat
= (*tokentable
[tagnum
].func
)(context
, status
,
306 retstat
= close_tag(context
, tagnum
);
309 /* here if token id is not in table */
310 (void) fprintf(stderr
, gettext("praudit: No code associated with "
311 "tag id %d\n"), tagnum
);
316 get_Hname(uint32_t addr
, char *buf
, size_t buflen
)
318 extern char *inet_ntoa(const struct in_addr
);
322 phe
= gethostbyaddr((const char *)&addr
, 4, AF_INET
);
325 (void) snprintf(buf
, buflen
, "%s", inet_ntoa(ia
));
329 (void) snprintf(buf
, buflen
, "%s", phe
->h_name
);
333 get_Hname_ex(uint32_t *addr
, char *buf
, size_t buflen
)
338 phe
= getipnodebyaddr((const void *)addr
, 16, AF_INET6
, &err
);
341 (void) inet_ntop(AF_INET6
, (void *)addr
, buf
, buflen
);
343 (void) snprintf(buf
, buflen
, "%s", phe
->h_name
);
350 pa_hostname(pr_context_t
*context
, int status
, int flag
)
361 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
364 uval
.uvaltype
= PRA_STRING
;
366 if (!(context
->format
& PRF_RAWM
)) {
367 uval
.string_val
= buf
;
368 get_Hname(ip_addr
, buf
, sizeof (buf
));
369 returnstat
= pa_print(context
, &uval
, flag
);
372 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
374 returnstat
= pa_print(context
, &uval
, flag
);
380 pa_hostname_ex(pr_context_t
*context
, int status
, int flag
)
393 if ((returnstat
= pr_adr_int32(context
, (int32_t *)&ip_type
, 1)) != 0)
396 /* only IPv4 and IPv6 addresses are legal */
397 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
401 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
404 if ((returnstat
= open_tag(context
, TAG_HOSTID
)) != 0)
407 uval
.uvaltype
= PRA_STRING
;
408 if (ip_type
== AU_IPv4
) { /* ipv4 address */
409 if (!(context
->format
& PRF_RAWM
)) {
410 uval
.string_val
= buf
;
411 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
412 returnstat
= pa_print(context
, &uval
, flag
);
414 ia
.s_addr
= ip_addr
[0];
415 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
417 returnstat
= pa_print(context
, &uval
, flag
);
419 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
420 if (!(context
->format
& PRF_RAWM
)) {
421 uval
.string_val
= buf
;
422 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
423 returnstat
= pa_print(context
, &uval
, flag
);
425 uval
.string_val
= (char *)buf
;
426 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
428 returnstat
= pa_print(context
, &uval
, flag
);
434 return (close_tag(context
, TAG_HOSTID
));
438 pa_hostname_so(pr_context_t
*context
, int status
, int flag
)
452 if ((returnstat
= pr_adr_short(context
, &ip_type
, 1)) != 0)
455 /* only IPv4 and IPv6 addresses are legal */
456 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
459 /* get local ip port */
460 if ((returnstat
= pr_adr_u_short(context
, &ip_port
, 1)) != 0)
463 if ((returnstat
= open_tag(context
, TAG_SOCKEXLPORT
)) != 0)
466 uval
.uvaltype
= PRA_STRING
;
467 uval
.string_val
= hexconvert((char *)&ip_port
, sizeof (ip_port
),
469 if (uval
.string_val
) {
470 returnstat
= pa_print(context
, &uval
, 0);
471 free(uval
.string_val
);
477 if ((returnstat
= close_tag(context
, TAG_SOCKEXLPORT
)) != 0)
480 /* get local ip address */
481 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
484 if ((returnstat
= open_tag(context
, TAG_SOCKEXLADDR
)) != 0)
487 if (ip_type
== AU_IPv4
) { /* ipv4 address */
489 if (!(context
->format
& PRF_RAWM
)) {
490 uval
.string_val
= buf
;
491 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
492 returnstat
= pa_print(context
, &uval
, 0);
494 ia
.s_addr
= ip_addr
[0];
495 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
497 returnstat
= pa_print(context
, &uval
, 0);
500 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
502 if (!(context
->format
& PRF_RAWM
)) {
503 uval
.string_val
= buf
;
504 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
505 returnstat
= pa_print(context
, &uval
, 0);
507 uval
.string_val
= (char *)buf
;
508 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
510 returnstat
= pa_print(context
, &uval
, 0);
518 if ((returnstat
= close_tag(context
, TAG_SOCKEXLADDR
)) != 0)
521 /* get foreign ip port */
522 if ((returnstat
= pr_adr_u_short(context
, &ip_port
, 1)) != 0)
525 if ((returnstat
= open_tag(context
, TAG_SOCKEXFPORT
)) != 0)
528 uval
.string_val
= hexconvert((char *)&ip_port
, sizeof (ip_port
),
530 if (uval
.string_val
) {
531 returnstat
= pa_print(context
, &uval
, 0);
532 free(uval
.string_val
);
539 if ((returnstat
= close_tag(context
, TAG_SOCKEXFPORT
)) != 0)
542 /* get foreign ip address */
543 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
546 if ((returnstat
= open_tag(context
, TAG_SOCKEXFADDR
)) != 0)
549 if (ip_type
== AU_IPv4
) { /* ipv4 address */
551 if (!(context
->format
& PRF_RAWM
)) {
552 uval
.string_val
= buf
;
553 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
554 returnstat
= pa_print(context
, &uval
, flag
);
556 ia
.s_addr
= ip_addr
[0];
557 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
559 returnstat
= pa_print(context
, &uval
, flag
);
562 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
564 if (!(context
->format
& PRF_RAWM
)) {
565 uval
.string_val
= buf
;
566 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
567 returnstat
= pa_print(context
, &uval
, flag
);
569 uval
.string_val
= (char *)buf
;
570 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
572 returnstat
= pa_print(context
, &uval
, flag
);
580 if ((returnstat
= close_tag(context
, TAG_SOCKEXFADDR
)) != 0)
587 #define NBITSMAJOR64 32 /* # of major device bits in 64-bit Solaris */
588 #define NBITSMINOR64 32 /* # of minor device bits in 64-bit Solaris */
589 #define MAXMAJ64 0xfffffffful /* max major value */
590 #define MAXMIN64 0xfffffffful /* max minor value */
592 #define NBITSMAJOR32 14 /* # of SVR4 major device bits */
593 #define NBITSMINOR32 18 /* # of SVR4 minor device bits */
594 #define NMAXMAJ32 0x3fff /* SVR4 max major value */
595 #define NMAXMIN32 0x3ffff /* MAX minor for 3b2 software drivers. */
599 minor_64(uint64_t dev
)
605 return (int32_t)(dev
& MAXMIN64
);
609 major_64(uint64_t dev
)
613 maj
= (uint32_t)(dev
>> NBITSMINOR64
);
615 if (dev
== NODEV
|| maj
> MAXMAJ64
) {
619 return (int32_t)(maj
);
623 minor_32(uint32_t dev
)
629 return (int32_t)(dev
& MAXMIN32
);
633 major_32(uint32_t dev
)
637 maj
= (uint32_t)(dev
>> NBITSMINOR32
);
639 if (dev
== NODEV
|| maj
> MAXMAJ32
) {
643 return (int32_t)(maj
);
648 * -----------------------------------------------------------------------
649 * pa_tid() : Process terminal id and display contents
650 * return codes : -1 - error
653 * terminal id port adr_int32
654 * terminal id machine adr_int32
655 * -----------------------------------------------------------------------
658 pa_tid32(pr_context_t
*context
, int status
, int flag
)
671 if ((returnstat
= pr_adr_int32(context
, &dev_maj_min
, 1)) != 0)
674 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
677 uval
.uvaltype
= PRA_STRING
;
678 uval
.string_val
= buf
;
680 if (!(context
->format
& PRF_RAWM
)) {
683 get_Hname(ip_addr
, hostname
, sizeof (hostname
));
684 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
685 major_32(dev_maj_min
),
686 minor_32(dev_maj_min
),
688 return (pa_print(context
, &uval
, flag
));
692 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
695 (void) snprintf(buf
, sizeof (buf
), "%d %d %s", major_32(dev_maj_min
),
696 minor_32(dev_maj_min
),
699 return (pa_print(context
, &uval
, flag
));
703 pa_tid32_ex(pr_context_t
*context
, int status
, int flag
)
707 uint32_t ip_addr
[16];
720 if ((returnstat
= pr_adr_int32(context
, &dev_maj_min
, 1)) != 0)
723 /* get address type */
724 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
727 /* legal address types are either AU_IPv4 or AU_IPv6 only */
728 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
731 /* get address (4/16) */
732 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
735 uval
.uvaltype
= PRA_STRING
;
736 if (ip_type
== AU_IPv4
) {
737 uval
.string_val
= buf
;
739 if (!(context
->format
& PRF_RAWM
)) {
740 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
741 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
742 major_32(dev_maj_min
), minor_32(dev_maj_min
),
744 return (pa_print(context
, &uval
, flag
));
747 ia
.s_addr
= ip_addr
[0];
748 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
751 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
752 major_32(dev_maj_min
), minor_32(dev_maj_min
), ipstring
);
754 return (pa_print(context
, &uval
, flag
));
756 uval
.string_val
= buf
;
758 if (!(context
->format
& PRF_RAWM
)) {
759 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
760 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
761 major_32(dev_maj_min
), minor_32(dev_maj_min
),
763 return (pa_print(context
, &uval
, flag
));
766 (void) inet_ntop(AF_INET6
, (void *) ip_addr
, tbuf
,
769 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
770 major_32(dev_maj_min
), minor_32(dev_maj_min
), tbuf
);
772 return (pa_print(context
, &uval
, flag
));
777 pa_ip_addr(pr_context_t
*context
, int status
, int flag
)
792 /* get address type */
793 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
796 /* legal address type is AU_IPv4 or AU_IPv6 */
797 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
800 /* get address (4/16) */
801 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
804 uval
.uvaltype
= PRA_STRING
;
805 if (ip_type
== AU_IPv4
) {
806 uval
.string_val
= buf
;
808 if (!(context
->format
& PRF_RAWM
)) {
809 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
810 (void) snprintf(buf
, sizeof (buf
), "%s", hostname
);
811 return (pa_print(context
, &uval
, flag
));
814 ia
.s_addr
= ip_addr
[0];
815 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
818 (void) snprintf(buf
, sizeof (buf
), "%s", ipstring
);
820 return (pa_print(context
, &uval
, flag
));
822 uval
.string_val
= buf
;
824 if (!(context
->format
& PRF_RAWM
)) {
825 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
826 (void) snprintf(buf
, sizeof (buf
), "%s",
828 return (pa_print(context
, &uval
, flag
));
831 (void) inet_ntop(AF_INET6
, (void *) ip_addr
, tbuf
,
834 (void) snprintf(buf
, sizeof (buf
), "%s", tbuf
);
836 return (pa_print(context
, &uval
, flag
));
842 pa_tid64(pr_context_t
*context
, int status
, int flag
)
855 if ((returnstat
= pr_adr_int64(context
, &dev_maj_min
, 1)) != 0)
858 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
861 uval
.uvaltype
= PRA_STRING
;
862 uval
.string_val
= buf
;
864 if (!(context
->format
& PRF_RAWM
)) {
867 get_Hname(ip_addr
, hostname
, sizeof (hostname
));
868 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
869 major_64(dev_maj_min
), minor_64(dev_maj_min
), hostname
);
870 return (pa_print(context
, &uval
, flag
));
874 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
877 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
878 major_64(dev_maj_min
), minor_64(dev_maj_min
), ipstring
);
880 return (pa_print(context
, &uval
, flag
));
884 pa_tid64_ex(pr_context_t
*context
, int status
, int flag
)
901 if ((returnstat
= pr_adr_int64(context
, &dev_maj_min
, 1)) != 0)
904 /* get address type */
905 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
908 /* legal address types are either AU_IPv4 or AU_IPv6 only */
909 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
912 /* get address (4/16) */
913 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, ip_type
)) != 0)
916 uval
.uvaltype
= PRA_STRING
;
917 if (ip_type
== AU_IPv4
) {
918 uval
.string_val
= buf
;
920 if (!(context
->format
& PRF_RAWM
)) {
921 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
922 uval
.string_val
= buf
;
923 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
924 major_64(dev_maj_min
), minor_64(dev_maj_min
),
926 return (pa_print(context
, &uval
, flag
));
929 ia
.s_addr
= ip_addr
[0];
930 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
933 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
934 major_64(dev_maj_min
), minor_64(dev_maj_min
), ipstring
);
936 return (pa_print(context
, &uval
, flag
));
938 uval
.string_val
= buf
;
940 if (!(context
->format
& PRF_RAWM
)) {
941 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
942 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
943 major_64(dev_maj_min
), minor_64(dev_maj_min
),
945 return (pa_print(context
, &uval
, flag
));
948 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, tbuf
,
951 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
952 major_64(dev_maj_min
), minor_64(dev_maj_min
), tbuf
);
954 return (pa_print(context
, &uval
, flag
));
960 * ----------------------------------------------------------------
962 * Returns the field width based on the basic unit and print mode.
963 * This routine is called to determine the field width for the
964 * data items in the arbitrary data token where the tokens are
965 * to be printed in more than one line. The field width can be
966 * found in the fwidth structure.
969 * basicunit Can be one of AUR_CHAR, AUR_BYTE, AUR_SHORT,
970 * AUR_INT32, or AUR_INT64
971 * howtoprint Print mode. Can be one of AUP_BINARY, AUP_OCTAL,
972 * AUP_DECIMAL, or AUP_HEX.
973 * ----------------------------------------------------------------
976 findfieldwidth(char basicunit
, char howtoprint
)
980 for (i
= 0; i
< numwidthentries
; i
++) {
981 if (fwidth
[i
].basic_unit
== basicunit
) {
982 for (j
= 0; j
<= 4; j
++) {
983 if (fwidth
[i
].pwidth
[j
].print_base
==
986 fwidth
[i
].pwidth
[j
].field_width
);
990 * if we got here, then we didn't get what we were after
995 /* if we got here, we didn't get what we wanted either */
1001 * -----------------------------------------------------------------------
1002 * pa_cmd: Retrieves the cmd item from the input stream.
1003 * return codes : -1 - error
1005 * -----------------------------------------------------------------------
1008 pa_cmd(pr_context_t
*context
, int status
, int flag
)
1010 char *cmd
; /* cmd */
1016 * We need to know how much space to allocate for our string, so
1017 * read the length first, then call pr_adr_char to read those bytes.
1020 if (pr_adr_short(context
, &length
, 1) == 0) {
1021 if ((cmd
= (char *)malloc(length
+ 1)) == NULL
)
1023 if (pr_adr_char(context
, cmd
, length
) == 0) {
1024 uval
.uvaltype
= PRA_STRING
;
1025 uval
.string_val
= cmd
;
1026 returnstat
= pa_print(context
, &uval
, flag
);
1031 return (returnstat
);
1041 * -----------------------------------------------------------------------
1042 * pa_adr_byte : Issues pr_adr_char to retrieve the next ADR item from
1043 * the input stream pointed to by audit_adr, and prints it
1044 * as an integer if status >= 0
1045 * return codes : -1 - error
1047 * -----------------------------------------------------------------------
1050 pa_adr_byte(pr_context_t
*context
, int status
, int flag
)
1056 if (pr_adr_char(context
, &c
, 1) == 0) {
1057 uval
.uvaltype
= PRA_BYTE
;
1059 return (pa_print(context
, &uval
, flag
));
1067 * -----------------------------------------------------------------------
1068 * pa_adr_charhex: Issues pr_adr_char to retrieve the next ADR item from
1069 * the input stream pointed to by audit_adr, and prints it
1070 * in hexadecimal if status >= 0
1071 * return codes : -1 - error
1073 * -----------------------------------------------------------------------
1076 pa_adr_charhex(pr_context_t
*context
, int status
, int flag
)
1085 if ((returnstat
= pr_adr_char(context
, p
, 1)) == 0) {
1086 uval
.uvaltype
= PRA_STRING
;
1087 uval
.string_val
= hexconvert(p
, sizeof (char),
1089 if (uval
.string_val
) {
1090 returnstat
= pa_print(context
, &uval
, flag
);
1091 free(uval
.string_val
);
1094 return (returnstat
);
1100 * -----------------------------------------------------------------------
1101 * pa_adr_int32 : Issues pr_adr_int32 to retrieve the next ADR item from the
1102 * input stream pointed to by audit_adr, and prints it
1104 * return codes : -1 - error
1106 * -----------------------------------------------------------------------
1109 pa_adr_int32(pr_context_t
*context
, int status
, int flag
)
1115 if (pr_adr_int32(context
, &c
, 1) == 0) {
1116 uval
.uvaltype
= PRA_INT32
;
1118 return (pa_print(context
, &uval
, flag
));
1129 * -----------------------------------------------------------------------
1130 * pa_adr_int64 : Issues pr_adr_int64 to retrieve the next ADR item from the
1131 * input stream pointed to by audit_adr, and prints it
1133 * return codes : -1 - error
1135 * -----------------------------------------------------------------------
1138 pa_adr_int64(pr_context_t
*context
, int status
, int flag
)
1144 if (pr_adr_int64(context
, &c
, 1) == 0) {
1145 uval
.uvaltype
= PRA_INT64
;
1147 return (pa_print(context
, &uval
, flag
));
1155 * -----------------------------------------------------------------------
1156 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1157 * input stream pointed to by audit_adr, and prints it
1158 * in hexadecimal if status >= 0
1159 * return codes : -1 - error
1161 * -----------------------------------------------------------------------
1164 pa_adr_int32hex(pr_context_t
*context
, int status
, int flag
)
1171 if ((returnstat
= pr_adr_int32(context
, &l
, 1)) == 0) {
1172 uval
.uvaltype
= PRA_HEX32
;
1174 returnstat
= pa_print(context
, &uval
, flag
);
1176 return (returnstat
);
1182 * -----------------------------------------------------------------------
1183 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1184 * input stream pointed to by audit_adr, and prints it
1185 * in hexadecimal if status >= 0
1186 * return codes : -1 - error
1188 * -----------------------------------------------------------------------
1191 pa_adr_int64hex(pr_context_t
*context
, int status
, int flag
)
1198 if ((returnstat
= pr_adr_int64(context
, &l
, 1)) == 0) {
1199 uval
.uvaltype
= PRA_HEX64
;
1201 returnstat
= pa_print(context
, &uval
, flag
);
1203 return (returnstat
);
1210 * -------------------------------------------------------------------
1211 * bu2string: Maps a print basic unit type to a string.
1212 * returns : The string mapping or "unknown basic unit type".
1213 * -------------------------------------------------------------------
1216 bu2string(char basic_unit
)
1227 * These names are data units when displaying the arbitrary data
1231 static struct bu_map_ent bu_map
[] = {
1232 { AUR_BYTE
, "byte" },
1233 { AUR_CHAR
, "char" },
1234 { AUR_SHORT
, "short" },
1235 { AUR_INT32
, "int32" },
1236 { AUR_INT64
, "int64" } };
1238 for (i
= 0; i
< sizeof (bu_map
) / sizeof (struct bu_map_ent
); i
++)
1239 if (basic_unit
== bu_map
[i
].basic_unit
)
1240 return (gettext(bu_map
[i
].string
));
1242 return (gettext("unknown basic unit type"));
1247 * -------------------------------------------------------------------
1248 * eventmodifier2string: Maps event modifier flags to a readable string.
1249 * returns: The string mapping or "none".
1250 * -------------------------------------------------------------------
1253 eventmodifier2string(au_emod_t emodifier
, char *modstring
, size_t modlen
)
1264 * These abbreviations represent the event modifier field of the
1265 * header token. To gain a better understanding of each modifier,
1267 * System Administration Guide: Security Services >> Solaris Auditing
1268 * at http://docs.sun.com.
1271 static struct em_map_ent em_map
[] = {
1272 { (int)PAD_READ
, "rd" }, /* data read from object */
1273 { (int)PAD_WRITE
, "wr" }, /* data written to object */
1274 { (int)PAD_SPRIVUSE
, "sp" }, /* successfully used priv */
1275 { (int)PAD_FPRIVUSE
, "fp" }, /* failed use of priv */
1276 { (int)PAD_NONATTR
, "na" }, /* non-attributable event */
1277 { (int)PAD_FAILURE
, "fe" } /* fail audit event */
1280 modstring
[0] = '\0';
1282 for (i
= 0, j
= 0; i
< sizeof (em_map
) / sizeof (struct em_map_ent
);
1284 if ((int)emodifier
& em_map
[i
].mask
) {
1286 (void) strlcat(modstring
, ":", modlen
);
1287 (void) strlcat(modstring
, em_map
[i
].string
, modlen
);
1294 * ---------------------------------------------------------
1295 * convert_char_to_string:
1296 * Converts a byte to string depending on the print mode
1297 * input : printmode, which may be one of AUP_BINARY,
1298 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1299 * c, which is the byte to convert
1300 * output : p, which is a pointer to the location where
1301 * the resulting string is to be stored
1302 * ----------------------------------------------------------
1306 convert_char_to_string(char printmode
, char c
, char *p
)
1316 if (printmode
== AUP_BINARY
)
1317 (void) convertbinary(p
, &c
, sizeof (char));
1318 else if (printmode
== AUP_OCTAL
)
1319 (void) sprintf(p
, "%o", (int)dat
.c2
);
1320 else if (printmode
== AUP_DECIMAL
)
1321 (void) sprintf(p
, "%d", c
);
1322 else if (printmode
== AUP_HEX
)
1323 (void) sprintf(p
, "0x%x", (int)dat
.c2
);
1324 else if (printmode
== AUP_STRING
)
1325 convertascii(p
, &c
, sizeof (char));
1330 * --------------------------------------------------------------
1331 * convert_short_to_string:
1332 * Converts a short integer to string depending on the print mode
1333 * input : printmode, which may be one of AUP_BINARY,
1334 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1335 * c, which is the short integer to convert
1336 * output : p, which is a pointer to the location where
1337 * the resulting string is to be stored
1338 * ---------------------------------------------------------------
1341 convert_short_to_string(char printmode
, short c
, char *p
)
1351 if (printmode
== AUP_BINARY
)
1352 (void) convertbinary(p
, (char *)&c
, sizeof (short));
1353 else if (printmode
== AUP_OCTAL
)
1354 (void) sprintf(p
, "%o", (int)dat
.c2
);
1355 else if (printmode
== AUP_DECIMAL
)
1356 (void) sprintf(p
, "%hd", c
);
1357 else if (printmode
== AUP_HEX
)
1358 (void) sprintf(p
, "0x%x", (int)dat
.c2
);
1359 else if (printmode
== AUP_STRING
)
1360 convertascii(p
, (char *)&c
, sizeof (short));
1365 * ---------------------------------------------------------
1366 * convert_int32_to_string:
1367 * Converts a integer to string depending on the print mode
1368 * input : printmode, which may be one of AUP_BINARY,
1369 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1370 * c, which is the integer to convert
1371 * output : p, which is a pointer to the location where
1372 * the resulting string is to be stored
1373 * ----------------------------------------------------------
1376 convert_int32_to_string(char printmode
, int32_t c
, char *p
)
1378 if (printmode
== AUP_BINARY
)
1379 (void) convertbinary(p
, (char *)&c
, sizeof (int32_t));
1380 else if (printmode
== AUP_OCTAL
)
1381 (void) sprintf(p
, "%o", c
);
1382 else if (printmode
== AUP_DECIMAL
)
1383 (void) sprintf(p
, "%d", c
);
1384 else if (printmode
== AUP_HEX
)
1385 (void) sprintf(p
, "0x%x", c
);
1386 else if (printmode
== AUP_STRING
)
1387 convertascii(p
, (char *)&c
, sizeof (int));
1392 * ---------------------------------------------------------
1393 * convert_int64_to_string:
1394 * Converts a integer to string depending on the print mode
1395 * input : printmode, which may be one of AUP_BINARY,
1396 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1397 * c, which is the integer to convert
1398 * output : p, which is a pointer to the location where
1399 * the resulting string is to be stored
1400 * ----------------------------------------------------------
1403 convert_int64_to_string(char printmode
, int64_t c
, char *p
)
1405 if (printmode
== AUP_BINARY
)
1406 (void) convertbinary(p
, (char *)&c
, sizeof (int64_t));
1407 else if (printmode
== AUP_OCTAL
)
1408 (void) sprintf(p
, "%"PRIo64
, c
);
1409 else if (printmode
== AUP_DECIMAL
)
1410 (void) sprintf(p
, "%"PRId64
, c
);
1411 else if (printmode
== AUP_HEX
)
1412 (void) sprintf(p
, "0x%"PRIx64
, c
);
1413 else if (printmode
== AUP_STRING
)
1414 convertascii(p
, (char *)&c
, sizeof (int64_t));
1420 * -----------------------------------------------------------
1422 * Converts a unit c of 'size' bytes long into a binary string
1423 * and returns it into the position pointed to by p
1424 * ------------------------------------------------------------
1427 convertbinary(char *p
, char *c
, int size
)
1432 if ((s
= (char *)malloc(8 * size
+ 1)) == NULL
)
1437 /* first convert to binary */
1439 for (i
= 0; i
< size
; i
++) {
1440 for (j
= 0; j
< 8; j
++)
1441 (void) sprintf(t
++, "%d", ((*c
>> (7 - j
)) & (0x01)));
1446 /* now string leading zero's if any */
1448 for (i
= 0; i
< j
; i
++) {
1455 /* now copy the contents of s to p */
1457 for (i
= 0; i
< (8 * size
+ 1); i
++) {
1470 static char hex
[] = "0123456789abcdef";
1472 * -------------------------------------------------------------------
1473 * hexconvert : Converts a string of (size) bytes to hexadecimal, and
1474 * returns the hexadecimal string.
1475 * returns : - NULL if memory cannot be allocated for the string, or
1476 * - pointer to the hexadecimal string if successful
1477 * -------------------------------------------------------------------
1480 hexconvert(char *c
, int size
, int chunk
)
1482 register char *s
, *t
;
1483 register int i
, j
, k
;
1490 if ((s
= (char *)malloc((size
* 5) + 1)) == NULL
)
1493 if (chunk
> size
|| chunk
<= 0)
1496 numchunks
= size
/ chunk
;
1497 leftovers
= size
% chunk
;
1500 for (i
= j
= 0; i
< numchunks
; i
++) {
1506 for (k
= 0; k
< chunk
; k
++) {
1507 *t
++ = hex
[(uint_t
)((uchar_t
)*c
>> 4)];
1508 *t
++ = hex
[(uint_t
)((uchar_t
)*c
& 0xF)];
1517 for (i
= 0; i
< leftovers
; i
++) {
1518 *t
++ = hex
[(uint_t
)((uchar_t
)*c
>> 4)];
1519 *t
++ = hex
[(uint_t
)((uchar_t
)*c
& 0xF)];
1530 * -------------------------------------------------------------------
1531 * htp2string: Maps a print suggestion to a string.
1532 * returns : The string mapping or "unknown print suggestion".
1533 * -------------------------------------------------------------------
1536 htp2string(char print_sugg
)
1540 struct htp_map_ent
{
1547 * These names are data types when displaying the arbitrary data
1551 static struct htp_map_ent htp_map
[] = {
1552 { AUP_BINARY
, "binary" },
1553 { AUP_OCTAL
, "octal" },
1554 { AUP_DECIMAL
, "decimal" },
1555 { AUP_HEX
, "hexadecimal" },
1556 { AUP_STRING
, "string" } };
1558 for (i
= 0; i
< sizeof (htp_map
) / sizeof (struct htp_map_ent
); i
++)
1559 if (print_sugg
== htp_map
[i
].print_sugg
)
1560 return (gettext(htp_map
[i
].print_string
));
1562 return (gettext("unknown print suggestion"));
1566 * ----------------------------------------------------------------------
1567 * pa_adr_short: Issues pr_adr_short to retrieve the next ADR item from the
1568 * input stream pointed to by audit_adr, and prints it
1570 * return codes: -1 - error
1572 * ----------------------------------------------------------------------
1575 pa_adr_short(pr_context_t
*context
, int status
, int flag
)
1581 if (pr_adr_short(context
, &c
, 1) == 0) {
1582 uval
.uvaltype
= PRA_SHORT
;
1584 return (pa_print(context
, &uval
, flag
));
1592 * -----------------------------------------------------------------------
1593 * pa_adr_shorthex: Issues pr_adr_short to retrieve the next ADR item from the
1594 * input stream pointed to by audit_adr, and prints it
1595 * in hexadecimal if status >= 0
1596 * return codes : -1 - error
1598 * -----------------------------------------------------------------------
1601 pa_adr_shorthex(pr_context_t
*context
, int status
, int flag
)
1608 if ((returnstat
= pr_adr_short(context
, &s
, 1)) == 0) {
1609 uval
.uvaltype
= PRA_STRING
;
1610 uval
.string_val
= hexconvert((char *)&s
, sizeof (s
),
1612 if (uval
.string_val
) {
1613 returnstat
= pa_print(context
, &uval
, flag
);
1614 free(uval
.string_val
);
1617 return (returnstat
);
1624 * -----------------------------------------------------------------------
1625 * pa_adr_string: Retrieves a string from the input stream and prints it
1627 * return codes : -1 - error
1629 * -----------------------------------------------------------------------
1632 pa_adr_string(pr_context_t
*context
, int status
, int flag
)
1640 * We need to know how much space to allocate for our string, so
1641 * read the length first, then call pr_adr_char to read those bytes.
1646 if ((returnstat
= pr_adr_short(context
, &length
, 1)) != 0)
1647 return (returnstat
);
1648 if ((c
= (char *)malloc(length
+ 1)) == NULL
)
1650 if ((returnstat
= pr_adr_char(context
, c
, length
)) != 0) {
1652 return (returnstat
);
1655 uval
.uvaltype
= PRA_STRING
;
1656 uval
.string_val
= c
;
1657 returnstat
= pa_print(context
, &uval
, flag
);
1659 return (returnstat
);
1663 * -----------------------------------------------------------------------
1664 * pa_file_string: Retrieves a file string from the input stream and prints it
1666 * return codes : -1 - error
1668 * -----------------------------------------------------------------------
1671 pa_file_string(pr_context_t
*context
, int status
, int flag
)
1680 * We need to know how much space to allocate for our string, so
1681 * read the length first, then call pr_adr_char to read those bytes.
1686 if ((returnstat
= pr_adr_short(context
, &length
, 1)) != 0)
1687 return (returnstat
);
1688 if ((c
= (char *)malloc(length
+ 1)) == NULL
)
1690 if ((p
= (char *)malloc((length
* 4) + 1)) == NULL
) {
1694 if ((returnstat
= pr_adr_char(context
, c
, length
)) != 0) {
1697 return (returnstat
);
1700 if (is_file_token(context
->tokenid
))
1701 context
->audit_rec_len
+= length
;
1703 convertascii(p
, c
, length
- 1);
1704 uval
.uvaltype
= PRA_STRING
;
1705 uval
.string_val
= p
;
1707 if (returnstat
== 0)
1708 returnstat
= finish_open_tag(context
);
1710 if (returnstat
== 0)
1711 returnstat
= pa_print(context
, &uval
, flag
);
1715 return (returnstat
);
1719 pa_putstr_xml(pr_context_t
*context
, int printable
, char *str
, size_t len
)
1725 * Unprintable chars should always be converted to the
1726 * visible form. If there are unprintable characters which
1727 * require special treatment in xml, those should be
1731 err
= pr_printf(context
, "\\%03o",
1732 (unsigned char)*str
++);
1733 } while (err
== 0 && --len
!= 0);
1736 /* printable characters */
1739 * check for the special chars only when char size was 1
1740 * ie, ignore special chars appear in the middle of multibyte
1744 /* Escape for XML */
1747 err
= pr_printf(context
, "%s", "&");
1751 err
= pr_printf(context
, "%s", "<");
1755 err
= pr_printf(context
, "%s", ">");
1759 err
= pr_printf(context
, "%s", """);
1763 err
= pr_printf(context
, "%s", "'");
1767 err
= pr_putchar(context
, *str
);
1773 err
= pr_putchar(context
, *str
++);
1774 } while (err
== 0 && --len
!= 0);
1779 pa_putstr(pr_context_t
*context
, int printable
, char *str
, size_t len
)
1783 if (context
->format
& PRF_XMLM
)
1784 return (pa_putstr_xml(context
, printable
, str
, len
));
1788 err
= pr_printf(context
, "\\%03o",
1789 (unsigned char)*str
++);
1790 } while (err
== 0 && --len
!= 0);
1794 err
= pr_putchar(context
, *str
++);
1795 } while (err
== 0 && --len
!= 0);
1800 pa_string(pr_context_t
*context
, int status
, int flag
)
1803 int i
, printable
, eos
;
1805 int mbmax
= MB_CUR_MAX
;
1807 char mbuf
[MB_LEN_MAX
+ 1];
1816 while (wstat
== 0) {
1817 if ((rstat
= pr_adr_char(context
, &c
, 1)) < 0)
1821 printable
= isprint((unsigned char)c
);
1822 wstat
= pa_putstr(context
, printable
, &c
, 1);
1828 while (wstat
== 0) {
1832 rstat
= pr_adr_char(context
, &c
, 1);
1833 if (rstat
!= 0 || c
== '\0')
1838 rlen
= mbtowc(&wc
, mbuf
, mlen
);
1839 } while (!eos
&& mlen
< mbmax
&& rlen
<= 0);
1842 break; /* end of string */
1844 if (rlen
<= 0) { /* no good sequence */
1848 printable
= iswprint(wc
);
1850 wstat
= pa_putstr(context
, printable
, mbuf
, rlen
);
1853 for (i
= 0; i
< mlen
; i
++)
1854 mbuf
[i
] = mbuf
[rlen
+ i
];
1860 wstat
= do_newline(context
, flag
);
1862 if (wstat
== 0 && context
->data_mode
== FILEMODE
)
1863 (void) fflush(stdout
);
1865 return ((rstat
!= 0 || wstat
!= 0) ? -1 : 0);
1869 * -----------------------------------------------------------------------
1870 * pa_adr_u_int32: Issues pr_adr_u_int32 to retrieve the next ADR item from
1871 * the input stream pointed to by audit_adr, and prints it
1873 * return codes : -1 - error
1875 * -----------------------------------------------------------------------
1880 pa_adr_u_int32(pr_context_t
*context
, int status
, int flag
)
1886 if (pr_adr_u_int32(context
, &c
, 1) == 0) {
1887 uval
.uvaltype
= PRA_UINT32
;
1888 uval
.uint32_val
= c
;
1889 return (pa_print(context
, &uval
, flag
));
1899 * -----------------------------------------------------------------------
1900 * pa_adr_u_int64: Issues pr_adr_u_int64 to retrieve the next ADR item from the
1901 * input stream pointed to by audit_adr, and prints it
1903 * return codes : -1 - error
1905 * -----------------------------------------------------------------------
1908 pa_adr_u_int64(pr_context_t
*context
, int status
, int flag
)
1914 if (pr_adr_u_int64(context
, &c
, 1) == 0) {
1915 uval
.uvaltype
= PRA_UINT64
;
1916 uval
.uint64_val
= c
;
1917 return (pa_print(context
, &uval
, flag
));
1926 * -----------------------------------------------------------------------
1927 * pa_adr_u_short: Issues pr_adr_u_short to retrieve the next ADR item from
1928 * the input stream pointed to by audit_adr, and prints it
1930 * return codes : -1 - error
1932 * -----------------------------------------------------------------------
1935 pa_adr_u_short(pr_context_t
*context
, int status
, int flag
)
1941 if (pr_adr_u_short(context
, &c
, 1) == 0) {
1942 uval
.uvaltype
= PRA_USHORT
;
1943 uval
.ushort_val
= c
;
1944 return (pa_print(context
, &uval
, flag
));
1952 * -----------------------------------------------------------------------
1953 * pa_reclen: Issues pr_adr_u_long to retrieve the length of the record
1954 * from the input stream pointed to by audit_adr,
1955 * and prints it (unless format is XML) if status = 0
1956 * return codes : -1 - error
1958 * -----------------------------------------------------------------------
1961 pa_reclen(pr_context_t
*context
, int status
)
1967 if ((int)pr_adr_u_int32(context
, &c
, 1) == 0) {
1968 context
->audit_rec_len
= c
;
1970 /* Don't print this for XML format */
1971 if (context
->format
& PRF_XMLM
) {
1974 uval
.uvaltype
= PRA_UINT32
;
1975 uval
.uint32_val
= c
;
1976 return (pa_print(context
, &uval
, 0));
1985 * -----------------------------------------------------------------------
1986 * pa_mode : Issues pr_adr_u_short to retrieve the next ADR item from
1987 * the input stream pointed to by audit_adr, and prints it
1988 * in octal if status = 0
1989 * return codes : -1 - error
1991 * -----------------------------------------------------------------------
1994 pa_mode(pr_context_t
*context
, int status
, int flag
)
2000 if (pr_adr_u_int32(context
, &c
, 1) == 0) {
2001 uval
.uvaltype
= PRA_LOCT
;
2002 uval
.uint32_val
= c
;
2003 return (pa_print(context
, &uval
, flag
));
2011 pa_print_uid(pr_context_t
*context
, uid_t uid
, int status
, int flag
)
2020 if (!(context
->format
& PRF_RAWM
)) {
2021 /* get password file entry */
2022 if ((pw
= getpwuid(uid
)) == NULL
) {
2025 /* print in ASCII form */
2026 uval
.uvaltype
= PRA_STRING
;
2027 uval
.string_val
= pw
->pw_name
;
2028 returnstat
= pa_print(context
, &uval
, flag
);
2031 /* print in integer form */
2032 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
2033 uval
.uvaltype
= PRA_INT32
;
2034 uval
.int32_val
= uid
;
2035 returnstat
= pa_print(context
, &uval
, flag
);
2037 return (returnstat
);
2042 * -----------------------------------------------------------------------
2043 * pa_pw_uid() : Issues pr_adr_u_int32 to reads uid from input stream
2044 * pointed to by audit_adr, and displays it in either
2045 * raw form or its ASCII representation, if status >= 0.
2046 * return codes : -1 - error
2047 * : 1 - warning, passwd entry not found
2049 * -----------------------------------------------------------------------
2052 pa_pw_uid(pr_context_t
*context
, int status
, int flag
)
2059 if (pr_adr_u_int32(context
, &uid
, 1) != 0)
2060 /* cannot retrieve uid */
2063 return (pa_print_uid(context
, uid
, status
, flag
));
2067 pa_print_gid(pr_context_t
*context
, gid_t gid
, int status
, int flag
)
2076 if (!(context
->format
& PRF_RAWM
)) {
2077 /* get group file entry */
2078 if ((gr
= getgrgid(gid
)) == NULL
) {
2081 /* print in ASCII form */
2082 uval
.uvaltype
= PRA_STRING
;
2083 uval
.string_val
= gr
->gr_name
;
2084 returnstat
= pa_print(context
, &uval
, flag
);
2087 /* print in integer form */
2088 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
2089 uval
.uvaltype
= PRA_INT32
;
2090 uval
.int32_val
= gid
;
2091 returnstat
= pa_print(context
, &uval
, flag
);
2093 return (returnstat
);
2098 * -----------------------------------------------------------------------
2099 * pa_gr_uid() : Issues pr_adr_u_int32 to reads group uid from input stream
2100 * pointed to by audit_adr, and displays it in either
2101 * raw form or its ASCII representation, if status >= 0.
2102 * return codes : -1 - error
2103 * : 1 - warning, passwd entry not found
2105 * -----------------------------------------------------------------------
2108 pa_gr_uid(pr_context_t
*context
, int status
, int flag
)
2115 if (pr_adr_u_int32(context
, &gid
, 1) != 0)
2116 /* cannot retrieve gid */
2119 return (pa_print_gid(context
, gid
, status
, flag
));
2124 * -----------------------------------------------------------------------
2125 * pa_pw_uid_gr_gid() : Issues pr_adr_u_int32 to reads uid or group uid
2127 * pointed to by audit_adr, and displays it in either
2128 * raw form or its ASCII representation, if status >= 0.
2129 * return codes : -1 - error
2130 * : 1 - warning, passwd entry not found
2132 * -----------------------------------------------------------------------
2135 pa_pw_uid_gr_gid(pr_context_t
*context
, int status
, int flag
)
2144 /* get value of a_type */
2145 if ((returnstat
= pr_adr_u_int32(context
, &value
, 1)) != 0)
2146 return (returnstat
);
2148 if ((returnstat
= open_tag(context
, TAG_ACLTYPE
)) != 0)
2149 return (returnstat
);
2151 uval
.uvaltype
= PRA_UINT32
;
2152 uval
.uint32_val
= value
;
2153 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
2154 return (returnstat
);
2156 if ((returnstat
= close_tag(context
, TAG_ACLTYPE
)) != 0)
2157 return (returnstat
);
2159 if ((returnstat
= open_tag(context
, TAG_ACLVAL
)) != 0)
2160 return (returnstat
);
2163 * The "mask" and "other" strings refer to the class mask
2164 * and other (or world) entries in an ACL.
2165 * The "unrecognized" string refers to an unrecognized ACL
2171 returnstat
= pa_pw_uid(context
, returnstat
, flag
);
2175 returnstat
= pa_gr_uid(context
, returnstat
, flag
);
2178 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2179 if (returnstat
!= 0)
2180 return (returnstat
);
2182 if (!(context
->format
& PRF_RAWM
)) {
2183 uval
.uvaltype
= PRA_STRING
;
2184 uval
.string_val
= gettext("mask");
2185 returnstat
= pa_print(context
, &uval
, flag
);
2187 uval
.uvaltype
= PRA_UINT32
;
2188 uval
.uint32_val
= value
;
2190 pa_print(context
, &uval
, flag
)) != 0) {
2191 return (returnstat
);
2196 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2197 if (returnstat
!= 0)
2198 return (returnstat
);
2200 if (!(context
->format
& PRF_RAWM
)) {
2201 uval
.uvaltype
= PRA_STRING
;
2202 uval
.string_val
= gettext("other");
2203 returnstat
= pa_print(context
, &uval
, flag
);
2205 uval
.uvaltype
= PRA_UINT32
;
2206 uval
.uint32_val
= value
;
2208 pa_print(context
, &uval
, flag
)) != 0) {
2209 return (returnstat
);
2214 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2215 if (returnstat
!= 0)
2216 return (returnstat
);
2218 if (!(context
->format
& PRF_RAWM
)) {
2219 uval
.uvaltype
= PRA_STRING
;
2220 uval
.string_val
= gettext("unrecognized");
2221 returnstat
= pa_print(context
, &uval
, flag
);
2223 uval
.uvaltype
= PRA_UINT32
;
2224 uval
.uint32_val
= value
;
2226 pa_print(context
, &uval
, flag
)) != 0) {
2227 return (returnstat
);
2232 if ((returnstat
= close_tag(context
, TAG_ACLVAL
)) != 0)
2233 return (returnstat
);
2235 return (returnstat
);
2240 * -----------------------------------------------------------------------
2241 * pa_event_modifier(): Issues pr_adr_u_short to retrieve the next ADR item from
2242 * the input stream pointed to by audit_adr. This is the
2243 * event type, and is displayed in hex;
2244 * return codes : -1 - error
2246 * -----------------------------------------------------------------------
2249 pa_event_modifier(pr_context_t
*context
, int status
, int flag
)
2252 au_emod_t emodifier
;
2259 if ((returnstat
= pr_adr_u_short(context
, &emodifier
, 1)) != 0)
2260 return (returnstat
);
2262 /* For XML, only print when modifier is non-zero */
2263 if (!(context
->format
& PRF_XMLM
) || (emodifier
!= 0)) {
2264 uval
.uvaltype
= PRA_STRING
;
2266 returnstat
= open_tag(context
, TAG_EVMOD
);
2268 if (returnstat
>= 0) {
2269 if (!(context
->format
& PRF_RAWM
)) {
2270 eventmodifier2string(emodifier
, modstring
,
2271 sizeof (modstring
));
2272 uval
.string_val
= modstring
;
2273 returnstat
= pa_print(context
, &uval
, flag
);
2275 uval
.string_val
= hexconvert((char *)&emodifier
,
2276 sizeof (emodifier
), sizeof (emodifier
));
2277 if (uval
.string_val
) {
2278 returnstat
= pa_print(context
, &uval
,
2280 free(uval
.string_val
);
2284 if (returnstat
>= 0)
2285 returnstat
= close_tag(context
, TAG_EVMOD
);
2288 return (returnstat
);
2293 * -----------------------------------------------------------------------
2294 * pa_event_type(): Issues pr_adr_u_short to retrieve the next ADR item from
2295 * the input stream pointed to by audit_adr. This is the
2296 * event type, and is displayed in either raw or
2297 * ASCII form as appropriate
2298 * return codes : -1 - error
2300 * -----------------------------------------------------------------------
2303 pa_event_type(pr_context_t
*context
, int status
, int flag
)
2307 au_event_ent_t
*p_event
= NULL
;
2311 if ((returnstat
= pr_adr_u_short(context
, &etype
, 1)) == 0) {
2312 if (!(context
->format
& PRF_RAWM
)) {
2313 uval
.uvaltype
= PRA_STRING
;
2314 if (context
->format
& PRF_NOCACHE
) {
2315 p_event
= getauevnum(etype
);
2317 (void) cacheauevent(&p_event
, etype
);
2319 if (p_event
!= NULL
) {
2320 if (context
->format
& PRF_SHORTM
)
2328 gettext("invalid event number");
2330 returnstat
= pa_print(context
, &uval
, flag
);
2332 uval
.uvaltype
= PRA_USHORT
;
2333 uval
.ushort_val
= etype
;
2334 returnstat
= pa_print(context
, &uval
, flag
);
2337 return (returnstat
);
2345 * Print time from struct timeval to millisecond resolution.
2347 * typedef long time_t; time of day in seconds
2348 * typedef long useconds_t; signed # of microseconds
2351 * time_t tv_sec; seconds
2352 * suseconds_t tv_usec; and microseconds
2357 pa_utime32(pr_context_t
*context
, int status
, int flag
)
2359 uint32_t scale
= 1000; /* usec to msec */
2361 return (do_mtime32(context
, status
, flag
, scale
));
2365 * Print time from timestruc_t to millisecond resolution.
2367 * typedef struct timespec timestruct_t;
2369 * time_t tv_sec; seconds
2370 * long tv_nsec; and nanoseconds
2374 pa_ntime32(pr_context_t
*context
, int status
, int flag
)
2376 uint32_t scale
= 1000000; /* nsec to msec */
2378 return (do_mtime32(context
, status
, flag
, scale
));
2382 * Format the timezone +/- HH:MM and terminate the string
2383 * Note tm and tv_sec are the same time.
2384 * Too bad strftime won't produce an ISO 8601 time zone numeric
2387 #define MINS (24L * 60)
2389 tzone(struct tm
*tm
, time_t *tv_sec
, char *p
)
2394 gmt
= gmtime(tv_sec
);
2396 min_off
= ((tm
->tm_hour
- gmt
->tm_hour
) * 60) +
2397 (tm
->tm_min
- gmt
->tm_min
);
2399 if (tm
->tm_year
< gmt
->tm_year
) /* cross new year */
2401 else if (tm
->tm_year
> gmt
->tm_year
)
2403 else if (tm
->tm_yday
< gmt
->tm_yday
) /* cross dateline */
2405 else if (tm
->tm_yday
> gmt
->tm_yday
)
2415 *p
++ = min_off
/ 600 + '0'; /* 10s of hours */
2416 min_off
= min_off
- min_off
/ 600 * 600;
2417 *p
++ = min_off
/ 60 % 10 + '0'; /* hours */
2418 min_off
= min_off
- min_off
/ 60 * 60;
2420 *p
++ = min_off
/ 10 + '0'; /* 10s of minutes */
2421 *p
++ = min_off
% 10 + '0'; /* minutes */
2426 * Format the milliseconds in place in the string.
2427 * Borrowed from strftime.c:itoa()
2430 msec32(uint32_t msec
, char *p
)
2432 *p
++ = msec
/ 100 + '0';
2433 msec
= msec
- msec
/ 100 * 100;
2434 *p
++ = msec
/ 10 + '0';
2435 *p
++ = msec
% 10 +'0';
2439 * Format time and print relative to scale factor from micro/nano seconds.
2442 do_mtime32(pr_context_t
*context
, int status
, int flag
, uint32_t scale
)
2447 char time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2454 if ((returnstat
= open_tag(context
, TAG_ISO
)) != 0)
2455 return (returnstat
);
2457 if ((returnstat
= pr_adr_u_int32(context
,
2458 (uint32_t *)&tv_sec
, 1)) != 0)
2459 return (returnstat
);
2460 if ((returnstat
= pr_adr_u_int32(context
, &t32
, 1)) == 0) {
2461 if (!(context
->format
& PRF_RAWM
)) {
2462 (void) localtime_r(&tv_sec
, &tm
);
2463 (void) strftime(time_created
,
2464 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2465 "%Y-%m-%d %H:%M:%S.xxx ", &tm
);
2467 &time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2470 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2471 uval
.uvaltype
= PRA_STRING
;
2472 uval
.string_val
= time_created
;
2474 uval
.uvaltype
= PRA_UINT32
;
2475 uval
.uint32_val
= (uint32_t)tv_sec
;
2476 (void) pa_print(context
, &uval
, 0);
2477 if (context
->format
& PRF_XMLM
) {
2478 uval
.uvaltype
= PRA_CHAR
;
2479 uval
.char_val
= '.';
2480 (void) pa_print(context
, &uval
, 0);
2482 uval
.uvaltype
= PRA_UINT32
;
2483 uval
.uint32_val
= t32
;
2485 returnstat
= pa_print(context
, &uval
, flag
);
2488 if (returnstat
== 0)
2489 return (close_tag(context
, TAG_ISO
));
2491 return (returnstat
);
2495 * Print time from struct timeval to millisecond resolution.
2497 * typedef long time_t; time of day in seconds
2498 * typedef long useconds_t; signed # of microseconds
2501 * time_t tv_sec; seconds
2502 * suseconds_t tv_usec; and microseconds
2507 pa_utime64(pr_context_t
*context
, int status
, int flag
)
2509 uint64_t scale
= 1000; /* usec to msec */
2511 return (do_mtime64(context
, status
, flag
, scale
));
2515 * Print time from timestruc_t to millisecond resolution.
2517 * typedef struct timespec timestruct_t;
2519 * time_t tv_sec; seconds
2520 * long tv_nsec; and nanoseconds
2524 pa_ntime64(pr_context_t
*context
, int status
, int flag
)
2526 uint64_t scale
= 1000000; /* nsec to msec */
2528 return (do_mtime64(context
, status
, flag
, scale
));
2532 * Format the milliseconds in place in the string.
2533 * Borrowed from strftime.c:itoa()
2536 msec64(uint64_t msec
, char *p
)
2538 *p
++ = msec
/ 100 + '0';
2539 msec
= msec
- msec
/ 100 * 100;
2540 *p
++ = msec
/ 10 + '0';
2541 *p
++ = msec
% 10 +'0';
2545 * Format time and print relative to scale factor from micro/nano seconds.
2548 do_mtime64(pr_context_t
*context
, int status
, int flag
, uint64_t scale
)
2554 char time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2561 if ((returnstat
= open_tag(context
, TAG_ISO
)) != 0)
2562 return (returnstat
);
2564 if ((returnstat
= pr_adr_u_int64(context
, &t64_sec
, 1)) != 0)
2565 return (returnstat
);
2566 if ((returnstat
= pr_adr_u_int64(context
, &t64_msec
, 1)) == 0) {
2567 if (!(context
->format
& PRF_RAWM
)) {
2571 * This fails for years from 2038
2572 * The Y2K+38 problem
2575 tv_sec
= (time_t)t64_sec
;
2576 (void) localtime_r(&tv_sec
, &tm
);
2577 (void) strftime(time_created
,
2578 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2579 "%Y-%m-%d %H:%M:%S.xxx ", &tm
);
2580 msec64(t64_msec
/scale
,
2581 &time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2584 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2585 uval
.uvaltype
= PRA_STRING
;
2586 uval
.string_val
= time_created
;
2588 uval
.uvaltype
= PRA_UINT64
;
2589 uval
.uint64_val
= t64_sec
;
2590 (void) pa_print(context
, &uval
, 0);
2591 if (context
->format
& PRF_XMLM
) {
2592 uval
.uvaltype
= PRA_CHAR
;
2593 uval
.char_val
= '.';
2594 (void) pa_print(context
, &uval
, 0);
2596 uval
.uvaltype
= PRA_UINT64
;
2597 uval
.uint64_val
= t64_msec
;
2599 returnstat
= pa_print(context
, &uval
, flag
);
2603 return (returnstat
);
2605 return (close_tag(context
, TAG_ISO
));
2609 * -----------------------------------------------------------------------
2610 * pa_error() : convert the return token error code.
2612 * output : buf string representing return token error code.
2614 * -----------------------------------------------------------------------
2617 pa_error(const uchar_t err
, char *buf
, size_t buflen
)
2619 if (err
== ADT_SUCCESS
) {
2620 (void) strlcpy(buf
, gettext("success"), buflen
);
2621 } else if ((char)err
== ADT_FAILURE
) {
2622 (void) strlcpy(buf
, gettext("failure"), buflen
);
2624 char *emsg
= strerror(err
);
2627 (void) strlcpy(buf
, gettext("failure: "), buflen
);
2628 (void) strlcat(buf
, emsg
, buflen
);
2630 (void) snprintf(buf
, buflen
, "%s%d",
2631 gettext("failure: "), err
);
2637 * -----------------------------------------------------------------------
2638 * pa_retval() : convert the return token return value code.
2640 * input : err, for kernel success 0, or
2641 * failure errno: 0 > & < sys_nerr.
2642 * for userland success ADT_SUCCESS (0) or
2643 * failure ADT_FAILURE (-1).
2644 * pa_error() above has already converted err.
2646 * : retval, for kernel arbitrary return value for success, or
2649 * >= ADT_FAIL_VALUE < ADT_FAIL_PAM, an adt message code;
2650 * >= ADT_FAIL_PAM, a pam_strerror value;
2651 * < ADT_FAIL_VALUE, supposed to be an errno.
2653 * output : buf string representing return token error code.
2655 * -----------------------------------------------------------------------
2658 pa_retval(const uchar_t err
, const int32_t retval
, char *buf
, size_t buflen
)
2660 struct msg_text
*msglist
;
2663 /* success or kernel failure */
2664 if (((char)err
== ADT_SUCCESS
) ||
2667 (void) snprintf(buf
, buflen
, "%d", retval
);
2671 /* userland failure */
2672 msglist
= &adt_msg_text
[ADT_LIST_FAIL_VALUE
];
2674 if ((retval
+ msglist
->ml_offset
>= msglist
->ml_min_index
) &&
2675 (retval
+ msglist
->ml_offset
<= msglist
->ml_max_index
)) {
2678 gettext(msglist
->ml_msg_list
[retval
+ msglist
->ml_offset
]),
2680 } else if ((retval
>= ADT_FAIL_PAM
) &&
2681 (retval
< ADT_FAIL_PAM
+ PAM_TOTAL_ERRNUM
)) {
2683 (void) strlcpy(buf
, pam_strerror(NULL
, retval
- ADT_FAIL_PAM
),
2685 } else if ((emsg
= strerror(retval
)) != NULL
) {
2687 (void) strlcpy(buf
, emsg
, buflen
);
2690 (void) snprintf(buf
, buflen
, "%d", retval
);
2695 * -----------------------------------------------------------------------
2696 * pa_printstr() : print a given string, translating unprintables
2700 pa_printstr(pr_context_t
*context
, char *str
)
2704 int mbmax
= MB_CUR_MAX
;
2710 while (err
== 0 && *str
!= '\0') {
2712 printable
= isprint((unsigned char)c
);
2713 err
= pa_putstr(context
, printable
, &c
, 1);
2717 while (err
== 0 && *str
!= '\0') {
2718 len
= mbtowc(&wc
, str
, mbmax
);
2723 printable
= iswprint(wc
);
2725 err
= pa_putstr(context
, printable
, str
, len
);
2732 * -----------------------------------------------------------------------
2733 * pa_print() : print as one str or formatted for easy reading.
2734 * : flag - indicates whether to output a new line for
2735 * : multi-line output.
2736 * : = 0; no new line
2737 * : = 1; new line if regular output
2738 * output : The audit record information is displayed in the
2739 * type specified by uvaltype and value specified in
2740 * uval. The printing of the delimiter or newline is
2741 * determined by PRF_ONELINE, and the flag value,
2743 * +--------+------+------+-----------------+
2744 * |ONELINE | flag | last | Action |
2745 * +--------+------+------+-----------------+
2746 * | Y | Y | T | print new line |
2747 * | Y | Y | F | print delimiter |
2748 * | Y | N | T | print new line |
2749 * | Y | N | F | print delimiter |
2750 * | N | Y | T | print new line |
2751 * | N | Y | F | print new line |
2752 * | N | N | T | print new line |
2753 * | N | N | F | print delimiter |
2754 * +--------+------+------+-----------------+
2756 * return codes : -1 - error
2758 * -----------------------------------------------------------------------
2761 pa_print(pr_context_t
*context
, uval_t
*uval
, int flag
)
2766 switch (uval
->uvaltype
) {
2768 returnstat
= pr_printf(context
, "%d", uval
->int32_val
);
2771 returnstat
= pr_printf(context
, "%u", uval
->uint32_val
);
2774 returnstat
= pr_printf(context
, "%"PRId64
, uval
->int64_val
);
2777 returnstat
= pr_printf(context
, "%"PRIu64
, uval
->uint64_val
);
2780 returnstat
= pr_printf(context
, "%hd", uval
->short_val
);
2783 returnstat
= pr_printf(context
, "%hu", uval
->ushort_val
);
2786 returnstat
= pr_printf(context
, "%c", uval
->char_val
);
2789 returnstat
= pr_printf(context
, "%d", uval
->char_val
);
2792 returnstat
= pa_printstr(context
, uval
->string_val
);
2795 returnstat
= pr_printf(context
, "0x%x", uval
->int32_val
);
2798 returnstat
= pr_printf(context
, "0x%"PRIx64
, uval
->int64_val
);
2801 returnstat
= pr_printf(context
, "0x%hx", uval
->short_val
);
2804 returnstat
= pr_printf(context
, "%ho", uval
->ushort_val
);
2807 returnstat
= pr_printf(context
, "%o", (int)uval
->uint32_val
);
2810 (void) fprintf(stderr
, gettext("praudit: Unknown type.\n"));
2815 return (returnstat
);
2817 last
= (context
->audit_adr
->adr_now
==
2818 (context
->audit_rec_start
+ context
->audit_rec_len
));
2820 if (!(context
->format
& PRF_XMLM
)) {
2821 if (!(context
->format
& PRF_ONELINE
)) {
2822 if ((flag
== 1) || last
)
2823 returnstat
= pr_putchar(context
, '\n');
2825 returnstat
= pr_printf(context
, "%s",
2826 context
->SEPARATOR
);
2829 returnstat
= pr_printf(context
, "%s",
2830 context
->SEPARATOR
);
2832 returnstat
= pr_putchar(context
, '\n');
2835 if ((returnstat
== 0) && (context
->data_mode
== FILEMODE
))
2836 (void) fflush(stdout
);
2838 return (returnstat
);
2841 static struct cntrl_mapping
{
2855 static int cntrl_map_entries
= sizeof (cntrl_map
)
2856 / sizeof (struct cntrl_mapping
);
2859 * Convert binary data to ASCII for printing.
2862 convertascii(char *p
, char *c
, int size
)
2866 for (i
= 0; i
< size
; i
++) {
2867 uc
= (unsigned char)*(c
+ i
);
2870 for (j
= 0; j
< cntrl_map_entries
; j
++) {
2871 if (cntrl_map
[j
].from
== uc
) {
2873 *p
++ = cntrl_map
[j
].to
;
2877 if (j
== cntrl_map_entries
) {
2879 *p
++ = (char)(uc
^ 0100);
2885 p
+= sprintf(p
, "\\%03o", uc
);
2892 * -----------------------------------------------------------------------
2893 * pa_xgeneric: Process Xobject token and display contents
2894 * This routine will handle many of the attribute
2895 * types introduced in TS 2.x, such as:
2897 * AUT_XCOLORMAP, AUT_XCURSOR, AUT_XFONT,
2898 * AUT_XGC, AUT_XPIXMAP, AUT_XWINDOW
2900 * NOTE: At the time of call, the token id has been retrieved
2902 * return codes : -1 - error
2904 * NOTE: At the time of call, the xatom token id has been retrieved
2907 * text token id adr_char
2909 * creator uid adr_pw_uid
2910 * -----------------------------------------------------------------------
2913 pa_xgeneric(pr_context_t
*context
)
2917 returnstat
= process_tag(context
, TAG_XID
, 0, 0);
2918 return (process_tag(context
, TAG_XCUID
, returnstat
, 1));
2923 * ------------------------------------------------------------------------
2924 * pa_liaison : Issues pr_adr_char to retrieve the next ADR item from the
2925 * input stream pointed to by audit_adr, and prints it
2926 * if status >= 0 either in ASCII or raw form
2927 * return codes : -1 - error
2929 * : 1 - warning, unknown label type
2930 * -----------------------------------------------------------------------
2933 pa_liaison(pr_context_t
*context
, int status
, int flag
)
2940 if ((returnstat
= pr_adr_int32(context
, &li
, 1)) != 0) {
2941 return (returnstat
);
2943 if (!(context
->format
& PRF_RAWM
)) {
2944 uval
.uvaltype
= PRA_UINT32
;
2945 uval
.uint32_val
= li
;
2946 returnstat
= pa_print(context
, &uval
, flag
);
2948 /* print in hexadecimal form */
2949 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
2950 uval
.uvaltype
= PRA_HEX32
;
2951 uval
.uint32_val
= li
;
2952 returnstat
= pa_print(context
, &uval
, flag
);
2954 return (returnstat
);
2960 * ------------------------------------------------------------------------
2961 * pa_xid : Issues pr_adr_int32 to retrieve the XID from the input
2962 * stream pointed to by audit_adr, and prints it if
2963 * status >= 0 either in ASCII or raw form
2964 * return codes : -1 - error
2966 * : 1 - warning, unknown label type
2967 * ------------------------------------------------------------------------
2971 pa_xid(pr_context_t
*context
, int status
, int flag
)
2980 /* get XID from stream */
2981 if ((returnstat
= pr_adr_int32(context
, (int32_t *)&xid
, 1)) != 0)
2982 return (returnstat
);
2984 if (!(context
->format
& PRF_RAWM
)) {
2985 uval
.uvaltype
= PRA_STRING
;
2986 uval
.string_val
= hexconvert((char *)&xid
, sizeof (xid
),
2988 if (uval
.string_val
) {
2989 returnstat
= pa_print(context
, &uval
, flag
);
2990 free(uval
.string_val
);
2993 uval
.uvaltype
= PRA_INT32
;
2994 uval
.int32_val
= xid
;
2995 returnstat
= pa_print(context
, &uval
, flag
);
2998 return (returnstat
);
3002 pa_ace_flags(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3012 * ace->a_flags refers to access flags of ZFS/NFSv4 ACL entry.
3014 if ((returnstat
= open_tag(context
, TAG_ACEFLAGS
)) != 0)
3015 return (returnstat
);
3016 if (!(context
->format
& PRF_RAWM
)) {
3017 uval
.uvaltype
= PRA_STRING
;
3018 switch (ace
->a_flags
& ACE_TYPE_FLAGS
) {
3020 uval
.string_val
= gettext(OWNERAT_TXT
);
3022 case ACE_GROUP
| ACE_IDENTIFIER_GROUP
:
3023 uval
.string_val
= gettext(GROUPAT_TXT
);
3025 case ACE_IDENTIFIER_GROUP
:
3026 uval
.string_val
= gettext(GROUP_TXT
);
3029 uval
.string_val
= gettext(EVERYONEAT_TXT
);
3032 uval
.string_val
= gettext(USER_TXT
);
3035 uval
.uvaltype
= PRA_USHORT
;
3036 uval
.uint32_val
= ace
->a_flags
;
3039 uval
.uvaltype
= PRA_USHORT
;
3040 uval
.uint32_val
= ace
->a_flags
;
3042 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
3043 return (returnstat
);
3044 return (close_tag(context
, TAG_ACEFLAGS
));
3048 pa_ace_who(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3057 * ace->a_who refers to user id or group id of ZFS/NFSv4 ACL entry.
3059 if ((returnstat
= open_tag(context
, TAG_ACEID
)) != 0)
3060 return (returnstat
);
3061 switch (ace
->a_flags
& ACE_TYPE_FLAGS
) {
3062 case ACE_IDENTIFIER_GROUP
: /* group id */
3063 returnstat
= pa_print_gid(context
, ace
->a_who
, returnstat
,
3066 default: /* user id */
3067 returnstat
= pa_print_uid(context
, ace
->a_who
, returnstat
,
3072 return (returnstat
);
3073 return (close_tag(context
, TAG_ACEID
));
3077 * Appends what to str, (re)allocating str if necessary.
3079 #define INITIAL_ALLOC 256
3081 strappend(char **str
, char *what
, size_t *alloc
)
3089 s
= malloc(INITIAL_ALLOC
);
3094 *alloc
= INITIAL_ALLOC
;
3099 needed
= strlen(s
) + strlen(what
) + 1;
3100 if (*alloc
< needed
) {
3101 newstr
= realloc(s
, needed
);
3108 (void) strlcat(s
, what
, *alloc
);
3114 pa_ace_access_mask(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3118 char *permstr
= NULL
;
3119 size_t permstr_alloc
= 0;
3126 * ace->a_access_mask refers to access mask of ZFS/NFSv4 ACL entry.
3128 if ((returnstat
= open_tag(context
, TAG_ACEMASK
)) != 0)
3129 return (returnstat
);
3130 if (context
->format
& PRF_SHORTM
&&
3131 ((permstr
= malloc(15)) != NULL
)) {
3132 for (i
= 0; i
< 14; i
++)
3135 if (ace
->a_access_mask
& ACE_READ_DATA
)
3137 if (ace
->a_access_mask
& ACE_WRITE_DATA
)
3139 if (ace
->a_access_mask
& ACE_EXECUTE
)
3141 if (ace
->a_access_mask
& ACE_APPEND_DATA
)
3143 if (ace
->a_access_mask
& ACE_DELETE
)
3145 if (ace
->a_access_mask
& ACE_DELETE_CHILD
)
3147 if (ace
->a_access_mask
& ACE_READ_ATTRIBUTES
)
3149 if (ace
->a_access_mask
& ACE_WRITE_ATTRIBUTES
)
3151 if (ace
->a_access_mask
& ACE_READ_NAMED_ATTRS
)
3153 if (ace
->a_access_mask
& ACE_WRITE_NAMED_ATTRS
)
3155 if (ace
->a_access_mask
& ACE_READ_ACL
)
3157 if (ace
->a_access_mask
& ACE_WRITE_ACL
)
3159 if (ace
->a_access_mask
& ACE_WRITE_OWNER
)
3161 if (ace
->a_access_mask
& ACE_SYNCHRONIZE
)
3164 uval
.uvaltype
= PRA_STRING
;
3165 uval
.string_val
= permstr
;
3166 } else if (!(context
->format
& PRF_RAWM
)) {
3169 * Note this differs from acltext.c:ace_perm_txt()
3170 * because we don't know if the acl belongs to a file
3171 * or directory. ace mask value are the same
3172 * nonetheless, see sys/acl.h
3174 if (ace
->a_access_mask
& ACE_LIST_DIRECTORY
) {
3175 returnstat
= strappend(&permstr
, gettext(READ_DIR_TXT
),
3178 if (ace
->a_access_mask
& ACE_ADD_FILE
) {
3179 returnstat
= strappend(&permstr
, gettext(ADD_FILE_TXT
),
3182 if (ace
->a_access_mask
& ACE_ADD_SUBDIRECTORY
) {
3183 returnstat
= strappend(&permstr
, gettext(ADD_DIR_TXT
),
3186 if (ace
->a_access_mask
& ACE_READ_NAMED_ATTRS
) {
3187 returnstat
= strappend(&permstr
,
3188 gettext(READ_XATTR_TXT
), &permstr_alloc
);
3190 if (ace
->a_access_mask
& ACE_WRITE_NAMED_ATTRS
) {
3191 returnstat
= strappend(&permstr
,
3192 gettext(WRITE_XATTR_TXT
), &permstr_alloc
);
3194 if (ace
->a_access_mask
& ACE_EXECUTE
) {
3195 returnstat
= strappend(&permstr
,
3196 gettext(EXECUTE_TXT
), &permstr_alloc
);
3198 if (ace
->a_access_mask
& ACE_DELETE_CHILD
) {
3199 returnstat
= strappend(&permstr
,
3200 gettext(DELETE_CHILD_TXT
), &permstr_alloc
);
3202 if (ace
->a_access_mask
& ACE_READ_ATTRIBUTES
) {
3203 returnstat
= strappend(&permstr
,
3204 gettext(READ_ATTRIBUTES_TXT
), &permstr_alloc
);
3206 if (ace
->a_access_mask
& ACE_WRITE_ATTRIBUTES
) {
3207 returnstat
= strappend(&permstr
,
3208 gettext(WRITE_ATTRIBUTES_TXT
), &permstr_alloc
);
3210 if (ace
->a_access_mask
& ACE_DELETE
) {
3211 returnstat
= strappend(&permstr
, gettext(DELETE_TXT
),
3214 if (ace
->a_access_mask
& ACE_READ_ACL
) {
3215 returnstat
= strappend(&permstr
, gettext(READ_ACL_TXT
),
3218 if (ace
->a_access_mask
& ACE_WRITE_ACL
) {
3219 returnstat
= strappend(&permstr
, gettext(WRITE_ACL_TXT
),
3222 if (ace
->a_access_mask
& ACE_WRITE_OWNER
) {
3223 returnstat
= strappend(&permstr
,
3224 gettext(WRITE_OWNER_TXT
), &permstr_alloc
);
3226 if (ace
->a_access_mask
& ACE_SYNCHRONIZE
) {
3227 returnstat
= strappend(&permstr
,
3228 gettext(SYNCHRONIZE_TXT
), &permstr_alloc
);
3230 if (permstr
[strlen(permstr
) - 1] == '/')
3231 permstr
[strlen(permstr
) - 1] = '\0';
3232 uval
.uvaltype
= PRA_STRING
;
3233 uval
.string_val
= permstr
;
3235 if ((permstr
== NULL
) || (returnstat
!= 0) ||
3236 (context
->format
& PRF_RAWM
)) {
3237 uval
.uvaltype
= PRA_UINT32
;
3238 uval
.uint32_val
= ace
->a_access_mask
;
3240 returnstat
= pa_print(context
, &uval
, flag
);
3243 if (returnstat
!= 0)
3244 return (returnstat
);
3245 return (close_tag(context
, TAG_ACEMASK
));
3249 pa_ace_type(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3259 * ace->a_type refers to access type of ZFS/NFSv4 ACL entry.
3261 if ((returnstat
= open_tag(context
, TAG_ACETYPE
)) != 0)
3262 return (returnstat
);
3263 if (!(context
->format
& PRF_RAWM
)) {
3264 uval
.uvaltype
= PRA_STRING
;
3265 switch (ace
->a_type
) {
3266 case ACE_ACCESS_ALLOWED_ACE_TYPE
:
3267 uval
.string_val
= gettext(ALLOW_TXT
);
3269 case ACE_ACCESS_DENIED_ACE_TYPE
:
3270 uval
.string_val
= gettext(DENY_TXT
);
3272 case ACE_SYSTEM_AUDIT_ACE_TYPE
:
3273 uval
.string_val
= gettext(AUDIT_TXT
);
3275 case ACE_SYSTEM_ALARM_ACE_TYPE
:
3276 uval
.string_val
= gettext(ALARM_TXT
);
3279 uval
.string_val
= gettext(UNKNOWN_TXT
);
3282 uval
.uvaltype
= PRA_USHORT
;
3283 uval
.uint32_val
= ace
->a_type
;
3285 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
3286 return (returnstat
);
3287 return (close_tag(context
, TAG_ACETYPE
));
3291 pa_ace(pr_context_t
*context
, int status
, int flag
)
3299 if ((returnstat
= pr_adr_u_int32(context
, &ace
.a_who
, 1)) != 0)
3300 return (returnstat
);
3301 if ((returnstat
= pr_adr_u_int32(context
, &ace
.a_access_mask
, 1)) != 0)
3302 return (returnstat
);
3303 if ((returnstat
= pr_adr_u_short(context
, &ace
.a_flags
, 1)) != 0)
3304 return (returnstat
);
3305 if ((returnstat
= pr_adr_u_short(context
, &ace
.a_type
, 1)) != 0)
3306 return (returnstat
);
3308 if ((returnstat
= pa_ace_flags(context
, &ace
, returnstat
, 0)) != 0)
3309 return (returnstat
);
3310 /* pa_ace_who can returns 1 if uid/gid is not found */
3311 if ((returnstat
= pa_ace_who(context
, &ace
, returnstat
, 0)) < 0)
3312 return (returnstat
);
3313 if ((returnstat
= pa_ace_access_mask(context
, &ace
,
3314 returnstat
, 0)) != 0)
3315 return (returnstat
);
3316 return (pa_ace_type(context
, &ace
, returnstat
, flag
));