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.
41 #include <arpa/inet.h>
43 #include <bsm/audit.h>
44 #include <bsm/audit_record.h>
45 #include <bsm/libbsm.h>
46 #include <security/pam_appl.h>
48 #include <sys/inttypes.h>
49 #include <sys/mkdev.h>
50 #include <sys/types.h>
55 #include "adt_xlate.h"
57 static void convertascii(char *p
, char *c
, int size
);
58 static int convertbinary(char *p
, char *c
, int size
);
59 static void eventmodifier2string(au_emod_t emodifier
, char *modstring
,
61 static int do_mtime32(pr_context_t
*context
, int status
, int flag
,
63 static int do_mtime64(pr_context_t
*context
, int status
, int flag
,
67 * ------------------------------------------------------
68 * field widths for arbitrary data token type
69 * ------------------------------------------------------
78 /* character data type, 8 bits */
79 AUR_CHAR
, AUP_BINARY
, 12,
84 AUR_BYTE
, AUP_BINARY
, 12,
89 AUR_SHORT
, AUP_BINARY
, 20,
94 AUR_INT32
, AUP_BINARY
, 36,
99 AUR_INT64
, AUP_BINARY
, 68,
106 static int numwidthentries
= sizeof (fwidth
)
107 / sizeof (struct fw
);
111 * -----------------------------------------------------------------------
113 * Print a newline, if needed according to various formatting
115 * return codes : 0 - success
117 * -----------------------------------------------------------------------
120 do_newline(pr_context_t
*context
, int flag
)
124 if (!(context
->format
& PRF_ONELINE
) && (flag
== 1))
125 retstat
= pr_putchar(context
, '\n');
126 else if (!(context
->format
& PRF_XMLM
))
127 retstat
= pr_printf(context
, "%s", context
->SEPARATOR
);
133 open_tag(pr_context_t
*context
, int tagnum
)
138 /* no-op if not doing XML format */
139 if (!(context
->format
& PRF_XMLM
))
142 tag
= &tokentable
[tagnum
];
145 * First if needed do an implicit finish of a pending open for an
146 * extended tag. I.e., for the extended tag xxx:
147 * <xxx a=".." b=".."> ... </xxx>
148 * -- insert a close bracket after the last attribute
149 * (in other words, when the 1st non-attribute is opened while
150 * this is pending). Note that only one tag could be pending at
151 * a given time -- it couldn't be nested.
153 if (context
->pending_flag
&& (tag
->t_type
!= T_ATTRIBUTE
)) {
154 /* complete pending extended open */
155 err
= pr_putchar(context
, '>');
158 context
->pending_flag
= 0;
161 if (is_header_token(tagnum
) || is_file_token(tagnum
)) {
162 /* File token or new record on new line */
163 err
= pr_putchar(context
, '\n');
164 } else if (is_token(tagnum
)) {
165 /* Each token on new line if possible */
166 err
= do_newline(context
, 1);
171 switch (tag
->t_type
) {
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
);
182 err
= pr_printf(context
, "<%s", tag
->t_tagname
);
184 context
->pending_flag
= tagnum
;
190 if (is_header_token(tagnum
) && (err
== 0))
191 context
->current_rec
= tagnum
; /* set start of new record */
197 * Do an implicit close of a record when needed.
200 check_close_rec(pr_context_t
*context
, int tagnum
)
204 /* no-op if not doing XML format */
205 if (!(context
->format
& PRF_XMLM
))
209 * If we're opening a header or the file token (i.e., starting a new
210 * record), if there's a current record in progress do an implicit
213 if ((is_header_token(tagnum
) || is_file_token(tagnum
)) &&
214 context
->current_rec
) {
215 err
= do_newline(context
, 1);
217 err
= close_tag(context
, context
->current_rec
);
224 * explicit finish of a pending open for an extended tag.
227 finish_open_tag(pr_context_t
*context
)
231 /* no-op if not doing XML format */
232 if (!(context
->format
& PRF_XMLM
))
235 if (context
->pending_flag
) {
236 /* complete pending extended open */
237 err
= pr_putchar(context
, '>');
239 context
->pending_flag
= 0;
245 close_tag(pr_context_t
*context
, int tagnum
)
250 /* no-op if not doing XML format */
251 if (!(context
->format
& PRF_XMLM
))
254 tag
= &tokentable
[tagnum
];
256 switch (tag
->t_type
) {
258 err
= pr_putchar(context
, '\"');
261 err
= pr_printf(context
, "</%s>", tag
->t_tagname
);
264 err
= pr_printf(context
, "/>");
267 err
= pr_printf(context
, "</%s>", tag
->t_tagname
);
273 if (is_header_token(tagnum
) && (err
== 0))
274 context
->current_rec
= 0; /* closing rec; none current */
280 * -----------------------------------------------------------------------
282 * Calls the routine corresponding to the tag
283 * Note that to use this mechanism, all such routines must
284 * take 2 ints for their parameters; the first of these is
285 * the current status.
287 * flag = 1 for newline / delimiter, else 0
288 * return codes : -1 - error
290 * -----------------------------------------------------------------------
293 process_tag(pr_context_t
*context
, int tagnum
, int status
, int flag
)
302 if ((tagnum
> 0) && (tagnum
<= MAXTAG
) &&
303 (tokentable
[tagnum
].func
!= NOFUNC
)) {
304 retstat
= open_tag(context
, tagnum
);
306 retstat
= (*tokentable
[tagnum
].func
)(context
, status
,
309 retstat
= close_tag(context
, tagnum
);
312 /* here if token id is not in table */
313 (void) fprintf(stderr
, gettext("praudit: No code associated with "
314 "tag id %d\n"), tagnum
);
319 get_Hname(uint32_t addr
, char *buf
, size_t buflen
)
321 extern char *inet_ntoa(const struct in_addr
);
325 phe
= gethostbyaddr((const char *)&addr
, 4, AF_INET
);
326 if (phe
== (struct hostent
*)0) {
328 (void) snprintf(buf
, buflen
, "%s", inet_ntoa(ia
));
332 (void) snprintf(buf
, buflen
, "%s", phe
->h_name
);
336 get_Hname_ex(uint32_t *addr
, char *buf
, size_t buflen
)
341 phe
= getipnodebyaddr((const void *)addr
, 16, AF_INET6
, &err
);
343 if (phe
== (struct hostent
*)0) {
344 (void) inet_ntop(AF_INET6
, (void *)addr
, buf
, buflen
);
346 (void) snprintf(buf
, buflen
, "%s", phe
->h_name
);
353 pa_hostname(pr_context_t
*context
, int status
, int flag
)
364 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
367 uval
.uvaltype
= PRA_STRING
;
369 if (!(context
->format
& PRF_RAWM
)) {
370 uval
.string_val
= buf
;
371 get_Hname(ip_addr
, buf
, sizeof (buf
));
372 returnstat
= pa_print(context
, &uval
, flag
);
375 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
377 returnstat
= pa_print(context
, &uval
, flag
);
383 pa_hostname_ex(pr_context_t
*context
, int status
, int flag
)
396 if ((returnstat
= pr_adr_int32(context
, (int32_t *)&ip_type
, 1)) != 0)
399 /* only IPv4 and IPv6 addresses are legal */
400 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
404 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
407 if ((returnstat
= open_tag(context
, TAG_HOSTID
)) != 0)
410 uval
.uvaltype
= PRA_STRING
;
411 if (ip_type
== AU_IPv4
) { /* ipv4 address */
412 if (!(context
->format
& PRF_RAWM
)) {
413 uval
.string_val
= buf
;
414 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
415 returnstat
= pa_print(context
, &uval
, flag
);
417 ia
.s_addr
= ip_addr
[0];
418 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
420 returnstat
= pa_print(context
, &uval
, flag
);
422 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
423 if (!(context
->format
& PRF_RAWM
)) {
424 uval
.string_val
= buf
;
425 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
426 returnstat
= pa_print(context
, &uval
, flag
);
428 uval
.string_val
= (char *)buf
;
429 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
431 returnstat
= pa_print(context
, &uval
, flag
);
437 return (close_tag(context
, TAG_HOSTID
));
441 pa_hostname_so(pr_context_t
*context
, int status
, int flag
)
455 if ((returnstat
= pr_adr_short(context
, &ip_type
, 1)) != 0)
458 /* only IPv4 and IPv6 addresses are legal */
459 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
462 /* get local ip port */
463 if ((returnstat
= pr_adr_u_short(context
, &ip_port
, 1)) != 0)
466 if ((returnstat
= open_tag(context
, TAG_SOCKEXLPORT
)) != 0)
469 uval
.uvaltype
= PRA_STRING
;
470 uval
.string_val
= hexconvert((char *)&ip_port
, sizeof (ip_port
),
472 if (uval
.string_val
) {
473 returnstat
= pa_print(context
, &uval
, 0);
474 free(uval
.string_val
);
480 if ((returnstat
= close_tag(context
, TAG_SOCKEXLPORT
)) != 0)
483 /* get local ip address */
484 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
487 if ((returnstat
= open_tag(context
, TAG_SOCKEXLADDR
)) != 0)
490 if (ip_type
== AU_IPv4
) { /* ipv4 address */
492 if (!(context
->format
& PRF_RAWM
)) {
493 uval
.string_val
= buf
;
494 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
495 returnstat
= pa_print(context
, &uval
, 0);
497 ia
.s_addr
= ip_addr
[0];
498 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
500 returnstat
= pa_print(context
, &uval
, 0);
503 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
505 if (!(context
->format
& PRF_RAWM
)) {
506 uval
.string_val
= buf
;
507 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
508 returnstat
= pa_print(context
, &uval
, 0);
510 uval
.string_val
= (char *)buf
;
511 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
513 returnstat
= pa_print(context
, &uval
, 0);
521 if ((returnstat
= close_tag(context
, TAG_SOCKEXLADDR
)) != 0)
524 /* get foreign ip port */
525 if ((returnstat
= pr_adr_u_short(context
, &ip_port
, 1)) != 0)
528 if ((returnstat
= open_tag(context
, TAG_SOCKEXFPORT
)) != 0)
531 uval
.string_val
= hexconvert((char *)&ip_port
, sizeof (ip_port
),
533 if (uval
.string_val
) {
534 returnstat
= pa_print(context
, &uval
, 0);
535 free(uval
.string_val
);
542 if ((returnstat
= close_tag(context
, TAG_SOCKEXFPORT
)) != 0)
545 /* get foreign ip address */
546 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
549 if ((returnstat
= open_tag(context
, TAG_SOCKEXFADDR
)) != 0)
552 if (ip_type
== AU_IPv4
) { /* ipv4 address */
554 if (!(context
->format
& PRF_RAWM
)) {
555 uval
.string_val
= buf
;
556 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
557 returnstat
= pa_print(context
, &uval
, flag
);
559 ia
.s_addr
= ip_addr
[0];
560 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
562 returnstat
= pa_print(context
, &uval
, flag
);
565 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
567 if (!(context
->format
& PRF_RAWM
)) {
568 uval
.string_val
= buf
;
569 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
570 returnstat
= pa_print(context
, &uval
, flag
);
572 uval
.string_val
= (char *)buf
;
573 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
575 returnstat
= pa_print(context
, &uval
, flag
);
583 if ((returnstat
= close_tag(context
, TAG_SOCKEXFADDR
)) != 0)
590 #define NBITSMAJOR64 32 /* # of major device bits in 64-bit Solaris */
591 #define NBITSMINOR64 32 /* # of minor device bits in 64-bit Solaris */
592 #define MAXMAJ64 0xfffffffful /* max major value */
593 #define MAXMIN64 0xfffffffful /* max minor value */
595 #define NBITSMAJOR32 14 /* # of SVR4 major device bits */
596 #define NBITSMINOR32 18 /* # of SVR4 minor device bits */
597 #define NMAXMAJ32 0x3fff /* SVR4 max major value */
598 #define NMAXMIN32 0x3ffff /* MAX minor for 3b2 software drivers. */
602 minor_64(uint64_t dev
)
608 return (int32_t)(dev
& MAXMIN64
);
612 major_64(uint64_t dev
)
616 maj
= (uint32_t)(dev
>> NBITSMINOR64
);
618 if (dev
== NODEV
|| maj
> MAXMAJ64
) {
622 return (int32_t)(maj
);
626 minor_32(uint32_t dev
)
632 return (int32_t)(dev
& MAXMIN32
);
636 major_32(uint32_t dev
)
640 maj
= (uint32_t)(dev
>> NBITSMINOR32
);
642 if (dev
== NODEV
|| maj
> MAXMAJ32
) {
646 return (int32_t)(maj
);
651 * -----------------------------------------------------------------------
652 * pa_tid() : Process terminal id and display contents
653 * return codes : -1 - error
656 * terminal id port adr_int32
657 * terminal id machine adr_int32
658 * -----------------------------------------------------------------------
661 pa_tid32(pr_context_t
*context
, int status
, int flag
)
674 if ((returnstat
= pr_adr_int32(context
, &dev_maj_min
, 1)) != 0)
677 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
680 uval
.uvaltype
= PRA_STRING
;
681 uval
.string_val
= buf
;
683 if (!(context
->format
& PRF_RAWM
)) {
686 get_Hname(ip_addr
, hostname
, sizeof (hostname
));
687 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
688 major_32(dev_maj_min
),
689 minor_32(dev_maj_min
),
691 return (pa_print(context
, &uval
, flag
));
695 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
698 (void) snprintf(buf
, sizeof (buf
), "%d %d %s", major_32(dev_maj_min
),
699 minor_32(dev_maj_min
),
702 return (pa_print(context
, &uval
, flag
));
706 pa_tid32_ex(pr_context_t
*context
, int status
, int flag
)
710 uint32_t ip_addr
[16];
723 if ((returnstat
= pr_adr_int32(context
, &dev_maj_min
, 1)) != 0)
726 /* get address type */
727 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
730 /* legal address types are either AU_IPv4 or AU_IPv6 only */
731 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
734 /* get address (4/16) */
735 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
738 uval
.uvaltype
= PRA_STRING
;
739 if (ip_type
== AU_IPv4
) {
740 uval
.string_val
= buf
;
742 if (!(context
->format
& PRF_RAWM
)) {
743 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
744 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
745 major_32(dev_maj_min
), minor_32(dev_maj_min
),
747 return (pa_print(context
, &uval
, flag
));
750 ia
.s_addr
= ip_addr
[0];
751 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
754 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
755 major_32(dev_maj_min
), minor_32(dev_maj_min
), ipstring
);
757 return (pa_print(context
, &uval
, flag
));
759 uval
.string_val
= buf
;
761 if (!(context
->format
& PRF_RAWM
)) {
762 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
763 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
764 major_32(dev_maj_min
), minor_32(dev_maj_min
),
766 return (pa_print(context
, &uval
, flag
));
769 (void) inet_ntop(AF_INET6
, (void *) ip_addr
, tbuf
,
772 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
773 major_32(dev_maj_min
), minor_32(dev_maj_min
), tbuf
);
775 return (pa_print(context
, &uval
, flag
));
780 pa_ip_addr(pr_context_t
*context
, int status
, int flag
)
795 /* get address type */
796 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
799 /* legal address type is AU_IPv4 or AU_IPv6 */
800 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
803 /* get address (4/16) */
804 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
807 uval
.uvaltype
= PRA_STRING
;
808 if (ip_type
== AU_IPv4
) {
809 uval
.string_val
= buf
;
811 if (!(context
->format
& PRF_RAWM
)) {
812 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
813 (void) snprintf(buf
, sizeof (buf
), "%s", hostname
);
814 return (pa_print(context
, &uval
, flag
));
817 ia
.s_addr
= ip_addr
[0];
818 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
821 (void) snprintf(buf
, sizeof (buf
), "%s", ipstring
);
823 return (pa_print(context
, &uval
, flag
));
825 uval
.string_val
= buf
;
827 if (!(context
->format
& PRF_RAWM
)) {
828 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
829 (void) snprintf(buf
, sizeof (buf
), "%s",
831 return (pa_print(context
, &uval
, flag
));
834 (void) inet_ntop(AF_INET6
, (void *) ip_addr
, tbuf
,
837 (void) snprintf(buf
, sizeof (buf
), "%s", tbuf
);
839 return (pa_print(context
, &uval
, flag
));
845 pa_tid64(pr_context_t
*context
, int status
, int flag
)
858 if ((returnstat
= pr_adr_int64(context
, &dev_maj_min
, 1)) != 0)
861 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
864 uval
.uvaltype
= PRA_STRING
;
865 uval
.string_val
= buf
;
867 if (!(context
->format
& PRF_RAWM
)) {
870 get_Hname(ip_addr
, hostname
, sizeof (hostname
));
871 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
872 major_64(dev_maj_min
), minor_64(dev_maj_min
), hostname
);
873 return (pa_print(context
, &uval
, flag
));
877 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
880 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
881 major_64(dev_maj_min
), minor_64(dev_maj_min
), ipstring
);
883 return (pa_print(context
, &uval
, flag
));
887 pa_tid64_ex(pr_context_t
*context
, int status
, int flag
)
904 if ((returnstat
= pr_adr_int64(context
, &dev_maj_min
, 1)) != 0)
907 /* get address type */
908 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
911 /* legal address types are either AU_IPv4 or AU_IPv6 only */
912 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
915 /* get address (4/16) */
916 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, ip_type
)) != 0)
919 uval
.uvaltype
= PRA_STRING
;
920 if (ip_type
== AU_IPv4
) {
921 uval
.string_val
= buf
;
923 if (!(context
->format
& PRF_RAWM
)) {
924 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
925 uval
.string_val
= buf
;
926 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
927 major_64(dev_maj_min
), minor_64(dev_maj_min
),
929 return (pa_print(context
, &uval
, flag
));
932 ia
.s_addr
= ip_addr
[0];
933 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
936 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
937 major_64(dev_maj_min
), minor_64(dev_maj_min
), ipstring
);
939 return (pa_print(context
, &uval
, flag
));
941 uval
.string_val
= buf
;
943 if (!(context
->format
& PRF_RAWM
)) {
944 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
945 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
946 major_64(dev_maj_min
), minor_64(dev_maj_min
),
948 return (pa_print(context
, &uval
, flag
));
951 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, tbuf
,
954 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
955 major_64(dev_maj_min
), minor_64(dev_maj_min
), tbuf
);
957 return (pa_print(context
, &uval
, flag
));
963 * ----------------------------------------------------------------
965 * Returns the field width based on the basic unit and print mode.
966 * This routine is called to determine the field width for the
967 * data items in the arbitrary data token where the tokens are
968 * to be printed in more than one line. The field width can be
969 * found in the fwidth structure.
972 * basicunit Can be one of AUR_CHAR, AUR_BYTE, AUR_SHORT,
973 * AUR_INT32, or AUR_INT64
974 * howtoprint Print mode. Can be one of AUP_BINARY, AUP_OCTAL,
975 * AUP_DECIMAL, or AUP_HEX.
976 * ----------------------------------------------------------------
979 findfieldwidth(char basicunit
, char howtoprint
)
983 for (i
= 0; i
< numwidthentries
; i
++) {
984 if (fwidth
[i
].basic_unit
== basicunit
) {
985 for (j
= 0; j
<= 4; j
++) {
986 if (fwidth
[i
].pwidth
[j
].print_base
==
989 fwidth
[i
].pwidth
[j
].field_width
);
993 * if we got here, then we didn't get what we were after
998 /* if we got here, we didn't get what we wanted either */
1004 * -----------------------------------------------------------------------
1005 * pa_cmd: Retrieves the cmd item from the input stream.
1006 * return codes : -1 - error
1008 * -----------------------------------------------------------------------
1011 pa_cmd(pr_context_t
*context
, int status
, int flag
)
1013 char *cmd
; /* cmd */
1019 * We need to know how much space to allocate for our string, so
1020 * read the length first, then call pr_adr_char to read those bytes.
1023 if (pr_adr_short(context
, &length
, 1) == 0) {
1024 if ((cmd
= (char *)malloc(length
+ 1)) == NULL
)
1026 if (pr_adr_char(context
, cmd
, length
) == 0) {
1027 uval
.uvaltype
= PRA_STRING
;
1028 uval
.string_val
= cmd
;
1029 returnstat
= pa_print(context
, &uval
, flag
);
1034 return (returnstat
);
1044 * -----------------------------------------------------------------------
1045 * pa_adr_byte : Issues pr_adr_char to retrieve the next ADR item from
1046 * the input stream pointed to by audit_adr, and prints it
1047 * as an integer if status >= 0
1048 * return codes : -1 - error
1050 * -----------------------------------------------------------------------
1053 pa_adr_byte(pr_context_t
*context
, int status
, int flag
)
1059 if (pr_adr_char(context
, &c
, 1) == 0) {
1060 uval
.uvaltype
= PRA_BYTE
;
1062 return (pa_print(context
, &uval
, flag
));
1070 * -----------------------------------------------------------------------
1071 * pa_adr_charhex: Issues pr_adr_char to retrieve the next ADR item from
1072 * the input stream pointed to by audit_adr, and prints it
1073 * in hexadecimal if status >= 0
1074 * return codes : -1 - error
1076 * -----------------------------------------------------------------------
1079 pa_adr_charhex(pr_context_t
*context
, int status
, int flag
)
1088 if ((returnstat
= pr_adr_char(context
, p
, 1)) == 0) {
1089 uval
.uvaltype
= PRA_STRING
;
1090 uval
.string_val
= hexconvert(p
, sizeof (char),
1092 if (uval
.string_val
) {
1093 returnstat
= pa_print(context
, &uval
, flag
);
1094 free(uval
.string_val
);
1097 return (returnstat
);
1103 * -----------------------------------------------------------------------
1104 * pa_adr_int32 : Issues pr_adr_int32 to retrieve the next ADR item from the
1105 * input stream pointed to by audit_adr, and prints it
1107 * return codes : -1 - error
1109 * -----------------------------------------------------------------------
1112 pa_adr_int32(pr_context_t
*context
, int status
, int flag
)
1118 if (pr_adr_int32(context
, &c
, 1) == 0) {
1119 uval
.uvaltype
= PRA_INT32
;
1121 return (pa_print(context
, &uval
, flag
));
1132 * -----------------------------------------------------------------------
1133 * pa_adr_int64 : Issues pr_adr_int64 to retrieve the next ADR item from the
1134 * input stream pointed to by audit_adr, and prints it
1136 * return codes : -1 - error
1138 * -----------------------------------------------------------------------
1141 pa_adr_int64(pr_context_t
*context
, int status
, int flag
)
1147 if (pr_adr_int64(context
, &c
, 1) == 0) {
1148 uval
.uvaltype
= PRA_INT64
;
1150 return (pa_print(context
, &uval
, flag
));
1158 * -----------------------------------------------------------------------
1159 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1160 * input stream pointed to by audit_adr, and prints it
1161 * in hexadecimal if status >= 0
1162 * return codes : -1 - error
1164 * -----------------------------------------------------------------------
1167 pa_adr_int32hex(pr_context_t
*context
, int status
, int flag
)
1174 if ((returnstat
= pr_adr_int32(context
, &l
, 1)) == 0) {
1175 uval
.uvaltype
= PRA_HEX32
;
1177 returnstat
= pa_print(context
, &uval
, flag
);
1179 return (returnstat
);
1185 * -----------------------------------------------------------------------
1186 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1187 * input stream pointed to by audit_adr, and prints it
1188 * in hexadecimal if status >= 0
1189 * return codes : -1 - error
1191 * -----------------------------------------------------------------------
1194 pa_adr_int64hex(pr_context_t
*context
, int status
, int flag
)
1201 if ((returnstat
= pr_adr_int64(context
, &l
, 1)) == 0) {
1202 uval
.uvaltype
= PRA_HEX64
;
1204 returnstat
= pa_print(context
, &uval
, flag
);
1206 return (returnstat
);
1213 * -------------------------------------------------------------------
1214 * bu2string: Maps a print basic unit type to a string.
1215 * returns : The string mapping or "unknown basic unit type".
1216 * -------------------------------------------------------------------
1219 bu2string(char basic_unit
)
1230 * These names are data units when displaying the arbitrary data
1234 static struct bu_map_ent bu_map
[] = {
1235 { AUR_BYTE
, "byte" },
1236 { AUR_CHAR
, "char" },
1237 { AUR_SHORT
, "short" },
1238 { AUR_INT32
, "int32" },
1239 { AUR_INT64
, "int64" } };
1241 for (i
= 0; i
< sizeof (bu_map
) / sizeof (struct bu_map_ent
); i
++)
1242 if (basic_unit
== bu_map
[i
].basic_unit
)
1243 return (gettext(bu_map
[i
].string
));
1245 return (gettext("unknown basic unit type"));
1250 * -------------------------------------------------------------------
1251 * eventmodifier2string: Maps event modifier flags to a readable string.
1252 * returns: The string mapping or "none".
1253 * -------------------------------------------------------------------
1256 eventmodifier2string(au_emod_t emodifier
, char *modstring
, size_t modlen
)
1267 * These abbreviations represent the event modifier field of the
1268 * header token. To gain a better understanding of each modifier,
1270 * System Administration Guide: Security Services >> Solaris Auditing
1271 * at http://docs.sun.com.
1274 static struct em_map_ent em_map
[] = {
1275 { (int)PAD_READ
, "rd" }, /* data read from object */
1276 { (int)PAD_WRITE
, "wr" }, /* data written to object */
1277 { (int)PAD_SPRIVUSE
, "sp" }, /* successfully used priv */
1278 { (int)PAD_FPRIVUSE
, "fp" }, /* failed use of priv */
1279 { (int)PAD_NONATTR
, "na" }, /* non-attributable event */
1280 { (int)PAD_FAILURE
, "fe" } /* fail audit event */
1283 modstring
[0] = '\0';
1285 for (i
= 0, j
= 0; i
< sizeof (em_map
) / sizeof (struct em_map_ent
);
1287 if ((int)emodifier
& em_map
[i
].mask
) {
1289 (void) strlcat(modstring
, ":", modlen
);
1290 (void) strlcat(modstring
, em_map
[i
].string
, modlen
);
1297 * ---------------------------------------------------------
1298 * convert_char_to_string:
1299 * Converts a byte to string depending on the print mode
1300 * input : printmode, which may be one of AUP_BINARY,
1301 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1302 * c, which is the byte to convert
1303 * output : p, which is a pointer to the location where
1304 * the resulting string is to be stored
1305 * ----------------------------------------------------------
1309 convert_char_to_string(char printmode
, char c
, char *p
)
1319 if (printmode
== AUP_BINARY
)
1320 (void) convertbinary(p
, &c
, sizeof (char));
1321 else if (printmode
== AUP_OCTAL
)
1322 (void) sprintf(p
, "%o", (int)dat
.c2
);
1323 else if (printmode
== AUP_DECIMAL
)
1324 (void) sprintf(p
, "%d", c
);
1325 else if (printmode
== AUP_HEX
)
1326 (void) sprintf(p
, "0x%x", (int)dat
.c2
);
1327 else if (printmode
== AUP_STRING
)
1328 convertascii(p
, &c
, sizeof (char));
1333 * --------------------------------------------------------------
1334 * convert_short_to_string:
1335 * Converts a short integer to string depending on the print mode
1336 * input : printmode, which may be one of AUP_BINARY,
1337 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1338 * c, which is the short integer to convert
1339 * output : p, which is a pointer to the location where
1340 * the resulting string is to be stored
1341 * ---------------------------------------------------------------
1344 convert_short_to_string(char printmode
, short c
, char *p
)
1354 if (printmode
== AUP_BINARY
)
1355 (void) convertbinary(p
, (char *)&c
, sizeof (short));
1356 else if (printmode
== AUP_OCTAL
)
1357 (void) sprintf(p
, "%o", (int)dat
.c2
);
1358 else if (printmode
== AUP_DECIMAL
)
1359 (void) sprintf(p
, "%hd", c
);
1360 else if (printmode
== AUP_HEX
)
1361 (void) sprintf(p
, "0x%x", (int)dat
.c2
);
1362 else if (printmode
== AUP_STRING
)
1363 convertascii(p
, (char *)&c
, sizeof (short));
1368 * ---------------------------------------------------------
1369 * convert_int32_to_string:
1370 * Converts a integer to string depending on the print mode
1371 * input : printmode, which may be one of AUP_BINARY,
1372 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1373 * c, which is the integer to convert
1374 * output : p, which is a pointer to the location where
1375 * the resulting string is to be stored
1376 * ----------------------------------------------------------
1379 convert_int32_to_string(char printmode
, int32_t c
, char *p
)
1381 if (printmode
== AUP_BINARY
)
1382 (void) convertbinary(p
, (char *)&c
, sizeof (int32_t));
1383 else if (printmode
== AUP_OCTAL
)
1384 (void) sprintf(p
, "%o", c
);
1385 else if (printmode
== AUP_DECIMAL
)
1386 (void) sprintf(p
, "%d", c
);
1387 else if (printmode
== AUP_HEX
)
1388 (void) sprintf(p
, "0x%x", c
);
1389 else if (printmode
== AUP_STRING
)
1390 convertascii(p
, (char *)&c
, sizeof (int));
1395 * ---------------------------------------------------------
1396 * convert_int64_to_string:
1397 * Converts a integer to string depending on the print mode
1398 * input : printmode, which may be one of AUP_BINARY,
1399 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1400 * c, which is the integer to convert
1401 * output : p, which is a pointer to the location where
1402 * the resulting string is to be stored
1403 * ----------------------------------------------------------
1406 convert_int64_to_string(char printmode
, int64_t c
, char *p
)
1408 if (printmode
== AUP_BINARY
)
1409 (void) convertbinary(p
, (char *)&c
, sizeof (int64_t));
1410 else if (printmode
== AUP_OCTAL
)
1411 (void) sprintf(p
, "%"PRIo64
, c
);
1412 else if (printmode
== AUP_DECIMAL
)
1413 (void) sprintf(p
, "%"PRId64
, c
);
1414 else if (printmode
== AUP_HEX
)
1415 (void) sprintf(p
, "0x%"PRIx64
, c
);
1416 else if (printmode
== AUP_STRING
)
1417 convertascii(p
, (char *)&c
, sizeof (int64_t));
1423 * -----------------------------------------------------------
1425 * Converts a unit c of 'size' bytes long into a binary string
1426 * and returns it into the position pointed to by p
1427 * ------------------------------------------------------------
1430 convertbinary(char *p
, char *c
, int size
)
1435 if ((s
= (char *)malloc(8 * size
+ 1)) == NULL
)
1440 /* first convert to binary */
1442 for (i
= 0; i
< size
; i
++) {
1443 for (j
= 0; j
< 8; j
++)
1444 (void) sprintf(t
++, "%d", ((*c
>> (7 - j
)) & (0x01)));
1449 /* now string leading zero's if any */
1451 for (i
= 0; i
< j
; i
++) {
1458 /* now copy the contents of s to p */
1460 for (i
= 0; i
< (8 * size
+ 1); i
++) {
1473 static char hex
[] = "0123456789abcdef";
1475 * -------------------------------------------------------------------
1476 * hexconvert : Converts a string of (size) bytes to hexadecimal, and
1477 * returns the hexadecimal string.
1478 * returns : - NULL if memory cannot be allocated for the string, or
1479 * - pointer to the hexadecimal string if successful
1480 * -------------------------------------------------------------------
1483 hexconvert(char *c
, int size
, int chunk
)
1485 register char *s
, *t
;
1486 register int i
, j
, k
;
1493 if ((s
= (char *)malloc((size
* 5) + 1)) == NULL
)
1496 if (chunk
> size
|| chunk
<= 0)
1499 numchunks
= size
/ chunk
;
1500 leftovers
= size
% chunk
;
1503 for (i
= j
= 0; i
< numchunks
; i
++) {
1509 for (k
= 0; k
< chunk
; k
++) {
1510 *t
++ = hex
[(uint_t
)((uchar_t
)*c
>> 4)];
1511 *t
++ = hex
[(uint_t
)((uchar_t
)*c
& 0xF)];
1520 for (i
= 0; i
< leftovers
; i
++) {
1521 *t
++ = hex
[(uint_t
)((uchar_t
)*c
>> 4)];
1522 *t
++ = hex
[(uint_t
)((uchar_t
)*c
& 0xF)];
1533 * -------------------------------------------------------------------
1534 * htp2string: Maps a print suggestion to a string.
1535 * returns : The string mapping or "unknown print suggestion".
1536 * -------------------------------------------------------------------
1539 htp2string(char print_sugg
)
1543 struct htp_map_ent
{
1550 * These names are data types when displaying the arbitrary data
1554 static struct htp_map_ent htp_map
[] = {
1555 { AUP_BINARY
, "binary" },
1556 { AUP_OCTAL
, "octal" },
1557 { AUP_DECIMAL
, "decimal" },
1558 { AUP_HEX
, "hexadecimal" },
1559 { AUP_STRING
, "string" } };
1561 for (i
= 0; i
< sizeof (htp_map
) / sizeof (struct htp_map_ent
); i
++)
1562 if (print_sugg
== htp_map
[i
].print_sugg
)
1563 return (gettext(htp_map
[i
].print_string
));
1565 return (gettext("unknown print suggestion"));
1569 * ----------------------------------------------------------------------
1570 * pa_adr_short: Issues pr_adr_short to retrieve the next ADR item from the
1571 * input stream pointed to by audit_adr, and prints it
1573 * return codes: -1 - error
1575 * ----------------------------------------------------------------------
1578 pa_adr_short(pr_context_t
*context
, int status
, int flag
)
1584 if (pr_adr_short(context
, &c
, 1) == 0) {
1585 uval
.uvaltype
= PRA_SHORT
;
1587 return (pa_print(context
, &uval
, flag
));
1595 * -----------------------------------------------------------------------
1596 * pa_adr_shorthex: Issues pr_adr_short to retrieve the next ADR item from the
1597 * input stream pointed to by audit_adr, and prints it
1598 * in hexadecimal if status >= 0
1599 * return codes : -1 - error
1601 * -----------------------------------------------------------------------
1604 pa_adr_shorthex(pr_context_t
*context
, int status
, int flag
)
1611 if ((returnstat
= pr_adr_short(context
, &s
, 1)) == 0) {
1612 uval
.uvaltype
= PRA_STRING
;
1613 uval
.string_val
= hexconvert((char *)&s
, sizeof (s
),
1615 if (uval
.string_val
) {
1616 returnstat
= pa_print(context
, &uval
, flag
);
1617 free(uval
.string_val
);
1620 return (returnstat
);
1627 * -----------------------------------------------------------------------
1628 * pa_adr_string: Retrieves a string from the input stream and prints it
1630 * return codes : -1 - error
1632 * -----------------------------------------------------------------------
1635 pa_adr_string(pr_context_t
*context
, int status
, int flag
)
1643 * We need to know how much space to allocate for our string, so
1644 * read the length first, then call pr_adr_char to read those bytes.
1649 if ((returnstat
= pr_adr_short(context
, &length
, 1)) != 0)
1650 return (returnstat
);
1651 if ((c
= (char *)malloc(length
+ 1)) == NULL
)
1653 if ((returnstat
= pr_adr_char(context
, c
, length
)) != 0) {
1655 return (returnstat
);
1658 uval
.uvaltype
= PRA_STRING
;
1659 uval
.string_val
= c
;
1660 returnstat
= pa_print(context
, &uval
, flag
);
1662 return (returnstat
);
1666 * -----------------------------------------------------------------------
1667 * pa_file_string: Retrieves a file string from the input stream and prints it
1669 * return codes : -1 - error
1671 * -----------------------------------------------------------------------
1674 pa_file_string(pr_context_t
*context
, int status
, int flag
)
1683 * We need to know how much space to allocate for our string, so
1684 * read the length first, then call pr_adr_char to read those bytes.
1689 if ((returnstat
= pr_adr_short(context
, &length
, 1)) != 0)
1690 return (returnstat
);
1691 if ((c
= (char *)malloc(length
+ 1)) == NULL
)
1693 if ((p
= (char *)malloc((length
* 4) + 1)) == NULL
) {
1697 if ((returnstat
= pr_adr_char(context
, c
, length
)) != 0) {
1700 return (returnstat
);
1703 if (is_file_token(context
->tokenid
))
1704 context
->audit_rec_len
+= length
;
1706 convertascii(p
, c
, length
- 1);
1707 uval
.uvaltype
= PRA_STRING
;
1708 uval
.string_val
= p
;
1710 if (returnstat
== 0)
1711 returnstat
= finish_open_tag(context
);
1713 if (returnstat
== 0)
1714 returnstat
= pa_print(context
, &uval
, flag
);
1718 return (returnstat
);
1722 pa_putstr_xml(pr_context_t
*context
, int printable
, char *str
, size_t len
)
1728 * Unprintable chars should always be converted to the
1729 * visible form. If there are unprintable characters which
1730 * require special treatment in xml, those should be
1734 err
= pr_printf(context
, "\\%03o",
1735 (unsigned char)*str
++);
1736 } while (err
== 0 && --len
!= 0);
1739 /* printable characters */
1742 * check for the special chars only when char size was 1
1743 * ie, ignore special chars appear in the middle of multibyte
1747 /* Escape for XML */
1750 err
= pr_printf(context
, "%s", "&");
1754 err
= pr_printf(context
, "%s", "<");
1758 err
= pr_printf(context
, "%s", ">");
1762 err
= pr_printf(context
, "%s", """);
1766 err
= pr_printf(context
, "%s", "'");
1770 err
= pr_putchar(context
, *str
);
1776 err
= pr_putchar(context
, *str
++);
1777 } while (err
== 0 && --len
!= 0);
1782 pa_putstr(pr_context_t
*context
, int printable
, char *str
, size_t len
)
1786 if (context
->format
& PRF_XMLM
)
1787 return (pa_putstr_xml(context
, printable
, str
, len
));
1791 err
= pr_printf(context
, "\\%03o",
1792 (unsigned char)*str
++);
1793 } while (err
== 0 && --len
!= 0);
1797 err
= pr_putchar(context
, *str
++);
1798 } while (err
== 0 && --len
!= 0);
1803 pa_string(pr_context_t
*context
, int status
, int flag
)
1806 int i
, printable
, eos
;
1808 int mbmax
= MB_CUR_MAX
;
1810 char mbuf
[MB_LEN_MAX
+ 1];
1819 while (wstat
== 0) {
1820 if ((rstat
= pr_adr_char(context
, &c
, 1)) < 0)
1824 printable
= isprint((unsigned char)c
);
1825 wstat
= pa_putstr(context
, printable
, &c
, 1);
1831 while (wstat
== 0) {
1835 rstat
= pr_adr_char(context
, &c
, 1);
1836 if (rstat
!= 0 || c
== '\0')
1841 rlen
= mbtowc(&wc
, mbuf
, mlen
);
1842 } while (!eos
&& mlen
< mbmax
&& rlen
<= 0);
1845 break; /* end of string */
1847 if (rlen
<= 0) { /* no good sequence */
1851 printable
= iswprint(wc
);
1853 wstat
= pa_putstr(context
, printable
, mbuf
, rlen
);
1856 for (i
= 0; i
< mlen
; i
++)
1857 mbuf
[i
] = mbuf
[rlen
+ i
];
1863 wstat
= do_newline(context
, flag
);
1865 if (wstat
== 0 && context
->data_mode
== FILEMODE
)
1866 (void) fflush(stdout
);
1868 return ((rstat
!= 0 || wstat
!= 0) ? -1 : 0);
1872 * -----------------------------------------------------------------------
1873 * pa_adr_u_int32: Issues pr_adr_u_int32 to retrieve the next ADR item from
1874 * the input stream pointed to by audit_adr, and prints it
1876 * return codes : -1 - error
1878 * -----------------------------------------------------------------------
1883 pa_adr_u_int32(pr_context_t
*context
, int status
, int flag
)
1889 if (pr_adr_u_int32(context
, &c
, 1) == 0) {
1890 uval
.uvaltype
= PRA_UINT32
;
1891 uval
.uint32_val
= c
;
1892 return (pa_print(context
, &uval
, flag
));
1902 * -----------------------------------------------------------------------
1903 * pa_adr_u_int64: Issues pr_adr_u_int64 to retrieve the next ADR item from the
1904 * input stream pointed to by audit_adr, and prints it
1906 * return codes : -1 - error
1908 * -----------------------------------------------------------------------
1911 pa_adr_u_int64(pr_context_t
*context
, int status
, int flag
)
1917 if (pr_adr_u_int64(context
, &c
, 1) == 0) {
1918 uval
.uvaltype
= PRA_UINT64
;
1919 uval
.uint64_val
= c
;
1920 return (pa_print(context
, &uval
, flag
));
1929 * -----------------------------------------------------------------------
1930 * pa_adr_u_short: Issues pr_adr_u_short to retrieve the next ADR item from
1931 * the input stream pointed to by audit_adr, and prints it
1933 * return codes : -1 - error
1935 * -----------------------------------------------------------------------
1938 pa_adr_u_short(pr_context_t
*context
, int status
, int flag
)
1944 if (pr_adr_u_short(context
, &c
, 1) == 0) {
1945 uval
.uvaltype
= PRA_USHORT
;
1946 uval
.ushort_val
= c
;
1947 return (pa_print(context
, &uval
, flag
));
1955 * -----------------------------------------------------------------------
1956 * pa_reclen: Issues pr_adr_u_long to retrieve the length of the record
1957 * from the input stream pointed to by audit_adr,
1958 * and prints it (unless format is XML) if status = 0
1959 * return codes : -1 - error
1961 * -----------------------------------------------------------------------
1964 pa_reclen(pr_context_t
*context
, int status
)
1970 if ((int)pr_adr_u_int32(context
, &c
, 1) == 0) {
1971 context
->audit_rec_len
= c
;
1973 /* Don't print this for XML format */
1974 if (context
->format
& PRF_XMLM
) {
1977 uval
.uvaltype
= PRA_UINT32
;
1978 uval
.uint32_val
= c
;
1979 return (pa_print(context
, &uval
, 0));
1988 * -----------------------------------------------------------------------
1989 * pa_mode : Issues pr_adr_u_short to retrieve the next ADR item from
1990 * the input stream pointed to by audit_adr, and prints it
1991 * in octal if status = 0
1992 * return codes : -1 - error
1994 * -----------------------------------------------------------------------
1997 pa_mode(pr_context_t
*context
, int status
, int flag
)
2003 if (pr_adr_u_int32(context
, &c
, 1) == 0) {
2004 uval
.uvaltype
= PRA_LOCT
;
2005 uval
.uint32_val
= c
;
2006 return (pa_print(context
, &uval
, flag
));
2014 pa_print_uid(pr_context_t
*context
, uid_t uid
, int status
, int flag
)
2023 if (!(context
->format
& PRF_RAWM
)) {
2024 /* get password file entry */
2025 if ((pw
= getpwuid(uid
)) == NULL
) {
2028 /* print in ASCII form */
2029 uval
.uvaltype
= PRA_STRING
;
2030 uval
.string_val
= pw
->pw_name
;
2031 returnstat
= pa_print(context
, &uval
, flag
);
2034 /* print in integer form */
2035 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
2036 uval
.uvaltype
= PRA_INT32
;
2037 uval
.int32_val
= uid
;
2038 returnstat
= pa_print(context
, &uval
, flag
);
2040 return (returnstat
);
2045 * -----------------------------------------------------------------------
2046 * pa_pw_uid() : Issues pr_adr_u_int32 to reads uid from input stream
2047 * pointed to by audit_adr, and displays it in either
2048 * raw form or its ASCII representation, if status >= 0.
2049 * return codes : -1 - error
2050 * : 1 - warning, passwd entry not found
2052 * -----------------------------------------------------------------------
2055 pa_pw_uid(pr_context_t
*context
, int status
, int flag
)
2062 if (pr_adr_u_int32(context
, &uid
, 1) != 0)
2063 /* cannot retrieve uid */
2066 return (pa_print_uid(context
, uid
, status
, flag
));
2070 pa_print_gid(pr_context_t
*context
, gid_t gid
, int status
, int flag
)
2079 if (!(context
->format
& PRF_RAWM
)) {
2080 /* get group file entry */
2081 if ((gr
= getgrgid(gid
)) == NULL
) {
2084 /* print in ASCII form */
2085 uval
.uvaltype
= PRA_STRING
;
2086 uval
.string_val
= gr
->gr_name
;
2087 returnstat
= pa_print(context
, &uval
, flag
);
2090 /* print in integer form */
2091 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
2092 uval
.uvaltype
= PRA_INT32
;
2093 uval
.int32_val
= gid
;
2094 returnstat
= pa_print(context
, &uval
, flag
);
2096 return (returnstat
);
2101 * -----------------------------------------------------------------------
2102 * pa_gr_uid() : Issues pr_adr_u_int32 to reads group uid from input stream
2103 * pointed to by audit_adr, and displays it in either
2104 * raw form or its ASCII representation, if status >= 0.
2105 * return codes : -1 - error
2106 * : 1 - warning, passwd entry not found
2108 * -----------------------------------------------------------------------
2111 pa_gr_uid(pr_context_t
*context
, int status
, int flag
)
2118 if (pr_adr_u_int32(context
, &gid
, 1) != 0)
2119 /* cannot retrieve gid */
2122 return (pa_print_gid(context
, gid
, status
, flag
));
2127 * -----------------------------------------------------------------------
2128 * pa_pw_uid_gr_gid() : Issues pr_adr_u_int32 to reads uid or group uid
2130 * pointed to by audit_adr, and displays it in either
2131 * raw form or its ASCII representation, if status >= 0.
2132 * return codes : -1 - error
2133 * : 1 - warning, passwd entry not found
2135 * -----------------------------------------------------------------------
2138 pa_pw_uid_gr_gid(pr_context_t
*context
, int status
, int flag
)
2147 /* get value of a_type */
2148 if ((returnstat
= pr_adr_u_int32(context
, &value
, 1)) != 0)
2149 return (returnstat
);
2151 if ((returnstat
= open_tag(context
, TAG_ACLTYPE
)) != 0)
2152 return (returnstat
);
2154 uval
.uvaltype
= PRA_UINT32
;
2155 uval
.uint32_val
= value
;
2156 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
2157 return (returnstat
);
2159 if ((returnstat
= close_tag(context
, TAG_ACLTYPE
)) != 0)
2160 return (returnstat
);
2162 if ((returnstat
= open_tag(context
, TAG_ACLVAL
)) != 0)
2163 return (returnstat
);
2166 * The "mask" and "other" strings refer to the class mask
2167 * and other (or world) entries in an ACL.
2168 * The "unrecognized" string refers to an unrecognized ACL
2174 returnstat
= pa_pw_uid(context
, returnstat
, flag
);
2178 returnstat
= pa_gr_uid(context
, returnstat
, flag
);
2181 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2182 if (returnstat
!= 0)
2183 return (returnstat
);
2185 if (!(context
->format
& PRF_RAWM
)) {
2186 uval
.uvaltype
= PRA_STRING
;
2187 uval
.string_val
= gettext("mask");
2188 returnstat
= pa_print(context
, &uval
, flag
);
2190 uval
.uvaltype
= PRA_UINT32
;
2191 uval
.uint32_val
= value
;
2193 pa_print(context
, &uval
, flag
)) != 0) {
2194 return (returnstat
);
2199 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2200 if (returnstat
!= 0)
2201 return (returnstat
);
2203 if (!(context
->format
& PRF_RAWM
)) {
2204 uval
.uvaltype
= PRA_STRING
;
2205 uval
.string_val
= gettext("other");
2206 returnstat
= pa_print(context
, &uval
, flag
);
2208 uval
.uvaltype
= PRA_UINT32
;
2209 uval
.uint32_val
= value
;
2211 pa_print(context
, &uval
, flag
)) != 0) {
2212 return (returnstat
);
2217 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2218 if (returnstat
!= 0)
2219 return (returnstat
);
2221 if (!(context
->format
& PRF_RAWM
)) {
2222 uval
.uvaltype
= PRA_STRING
;
2223 uval
.string_val
= gettext("unrecognized");
2224 returnstat
= pa_print(context
, &uval
, flag
);
2226 uval
.uvaltype
= PRA_UINT32
;
2227 uval
.uint32_val
= value
;
2229 pa_print(context
, &uval
, flag
)) != 0) {
2230 return (returnstat
);
2235 if ((returnstat
= close_tag(context
, TAG_ACLVAL
)) != 0)
2236 return (returnstat
);
2238 return (returnstat
);
2243 * -----------------------------------------------------------------------
2244 * pa_event_modifier(): Issues pr_adr_u_short to retrieve the next ADR item from
2245 * the input stream pointed to by audit_adr. This is the
2246 * event type, and is displayed in hex;
2247 * return codes : -1 - error
2249 * -----------------------------------------------------------------------
2252 pa_event_modifier(pr_context_t
*context
, int status
, int flag
)
2255 au_emod_t emodifier
;
2262 if ((returnstat
= pr_adr_u_short(context
, &emodifier
, 1)) != 0)
2263 return (returnstat
);
2265 /* For XML, only print when modifier is non-zero */
2266 if (!(context
->format
& PRF_XMLM
) || (emodifier
!= 0)) {
2267 uval
.uvaltype
= PRA_STRING
;
2269 returnstat
= open_tag(context
, TAG_EVMOD
);
2271 if (returnstat
>= 0) {
2272 if (!(context
->format
& PRF_RAWM
)) {
2273 eventmodifier2string(emodifier
, modstring
,
2274 sizeof (modstring
));
2275 uval
.string_val
= modstring
;
2276 returnstat
= pa_print(context
, &uval
, flag
);
2278 uval
.string_val
= hexconvert((char *)&emodifier
,
2279 sizeof (emodifier
), sizeof (emodifier
));
2280 if (uval
.string_val
) {
2281 returnstat
= pa_print(context
, &uval
,
2283 free(uval
.string_val
);
2287 if (returnstat
>= 0)
2288 returnstat
= close_tag(context
, TAG_EVMOD
);
2291 return (returnstat
);
2296 * -----------------------------------------------------------------------
2297 * pa_event_type(): Issues pr_adr_u_short to retrieve the next ADR item from
2298 * the input stream pointed to by audit_adr. This is the
2299 * event type, and is displayed in either raw or
2300 * ASCII form as appropriate
2301 * return codes : -1 - error
2303 * -----------------------------------------------------------------------
2306 pa_event_type(pr_context_t
*context
, int status
, int flag
)
2310 au_event_ent_t
*p_event
= NULL
;
2314 if ((returnstat
= pr_adr_u_short(context
, &etype
, 1)) == 0) {
2315 if (!(context
->format
& PRF_RAWM
)) {
2316 uval
.uvaltype
= PRA_STRING
;
2317 if (context
->format
& PRF_NOCACHE
) {
2318 p_event
= getauevnum(etype
);
2320 (void) cacheauevent(&p_event
, etype
);
2322 if (p_event
!= NULL
) {
2323 if (context
->format
& PRF_SHORTM
)
2331 gettext("invalid event number");
2333 returnstat
= pa_print(context
, &uval
, flag
);
2335 uval
.uvaltype
= PRA_USHORT
;
2336 uval
.ushort_val
= etype
;
2337 returnstat
= pa_print(context
, &uval
, flag
);
2340 return (returnstat
);
2348 * Print time from struct timeval to millisecond resolution.
2350 * typedef long time_t; time of day in seconds
2351 * typedef long useconds_t; signed # of microseconds
2354 * time_t tv_sec; seconds
2355 * suseconds_t tv_usec; and microseconds
2360 pa_utime32(pr_context_t
*context
, int status
, int flag
)
2362 uint32_t scale
= 1000; /* usec to msec */
2364 return (do_mtime32(context
, status
, flag
, scale
));
2368 * Print time from timestruc_t to millisecond resolution.
2370 * typedef struct timespec timestruct_t;
2372 * time_t tv_sec; seconds
2373 * long tv_nsec; and nanoseconds
2377 pa_ntime32(pr_context_t
*context
, int status
, int flag
)
2379 uint32_t scale
= 1000000; /* nsec to msec */
2381 return (do_mtime32(context
, status
, flag
, scale
));
2385 * Format the timezone +/- HH:MM and terminate the string
2386 * Note tm and tv_sec are the same time.
2387 * Too bad strftime won't produce an ISO 8601 time zone numeric
2390 #define MINS (24L * 60)
2392 tzone(struct tm
*tm
, time_t *tv_sec
, char *p
)
2397 gmt
= gmtime(tv_sec
);
2399 min_off
= ((tm
->tm_hour
- gmt
->tm_hour
) * 60) +
2400 (tm
->tm_min
- gmt
->tm_min
);
2402 if (tm
->tm_year
< gmt
->tm_year
) /* cross new year */
2404 else if (tm
->tm_year
> gmt
->tm_year
)
2406 else if (tm
->tm_yday
< gmt
->tm_yday
) /* cross dateline */
2408 else if (tm
->tm_yday
> gmt
->tm_yday
)
2418 *p
++ = min_off
/ 600 + '0'; /* 10s of hours */
2419 min_off
= min_off
- min_off
/ 600 * 600;
2420 *p
++ = min_off
/ 60 % 10 + '0'; /* hours */
2421 min_off
= min_off
- min_off
/ 60 * 60;
2423 *p
++ = min_off
/ 10 + '0'; /* 10s of minutes */
2424 *p
++ = min_off
% 10 + '0'; /* minutes */
2429 * Format the milliseconds in place in the string.
2430 * Borrowed from strftime.c:itoa()
2433 msec32(uint32_t msec
, char *p
)
2435 *p
++ = msec
/ 100 + '0';
2436 msec
= msec
- msec
/ 100 * 100;
2437 *p
++ = msec
/ 10 + '0';
2438 *p
++ = msec
% 10 +'0';
2442 * Format time and print relative to scale factor from micro/nano seconds.
2445 do_mtime32(pr_context_t
*context
, int status
, int flag
, uint32_t scale
)
2450 char time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2457 if ((returnstat
= open_tag(context
, TAG_ISO
)) != 0)
2458 return (returnstat
);
2460 if ((returnstat
= pr_adr_u_int32(context
,
2461 (uint32_t *)&tv_sec
, 1)) != 0)
2462 return (returnstat
);
2463 if ((returnstat
= pr_adr_u_int32(context
, &t32
, 1)) == 0) {
2464 if (!(context
->format
& PRF_RAWM
)) {
2465 (void) localtime_r(&tv_sec
, &tm
);
2466 (void) strftime(time_created
,
2467 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2468 "%Y-%m-%d %H:%M:%S.xxx ", &tm
);
2470 &time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2473 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2474 uval
.uvaltype
= PRA_STRING
;
2475 uval
.string_val
= time_created
;
2477 uval
.uvaltype
= PRA_UINT32
;
2478 uval
.uint32_val
= (uint32_t)tv_sec
;
2479 (void) pa_print(context
, &uval
, 0);
2480 if (context
->format
& PRF_XMLM
) {
2481 uval
.uvaltype
= PRA_CHAR
;
2482 uval
.char_val
= '.';
2483 (void) pa_print(context
, &uval
, 0);
2485 uval
.uvaltype
= PRA_UINT32
;
2486 uval
.uint32_val
= t32
;
2488 returnstat
= pa_print(context
, &uval
, flag
);
2491 if (returnstat
== 0)
2492 return (close_tag(context
, TAG_ISO
));
2494 return (returnstat
);
2498 * Print time from struct timeval to millisecond resolution.
2500 * typedef long time_t; time of day in seconds
2501 * typedef long useconds_t; signed # of microseconds
2504 * time_t tv_sec; seconds
2505 * suseconds_t tv_usec; and microseconds
2510 pa_utime64(pr_context_t
*context
, int status
, int flag
)
2512 uint64_t scale
= 1000; /* usec to msec */
2514 return (do_mtime64(context
, status
, flag
, scale
));
2518 * Print time from timestruc_t to millisecond resolution.
2520 * typedef struct timespec timestruct_t;
2522 * time_t tv_sec; seconds
2523 * long tv_nsec; and nanoseconds
2527 pa_ntime64(pr_context_t
*context
, int status
, int flag
)
2529 uint64_t scale
= 1000000; /* nsec to msec */
2531 return (do_mtime64(context
, status
, flag
, scale
));
2535 * Format the milliseconds in place in the string.
2536 * Borrowed from strftime.c:itoa()
2539 msec64(uint64_t msec
, char *p
)
2541 *p
++ = msec
/ 100 + '0';
2542 msec
= msec
- msec
/ 100 * 100;
2543 *p
++ = msec
/ 10 + '0';
2544 *p
++ = msec
% 10 +'0';
2548 * Format time and print relative to scale factor from micro/nano seconds.
2551 do_mtime64(pr_context_t
*context
, int status
, int flag
, uint64_t scale
)
2557 char time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2564 if ((returnstat
= open_tag(context
, TAG_ISO
)) != 0)
2565 return (returnstat
);
2567 if ((returnstat
= pr_adr_u_int64(context
, &t64_sec
, 1)) != 0)
2568 return (returnstat
);
2569 if ((returnstat
= pr_adr_u_int64(context
, &t64_msec
, 1)) == 0) {
2570 if (!(context
->format
& PRF_RAWM
)) {
2574 * This fails for years from 2038
2575 * The Y2K+38 problem
2578 tv_sec
= (time_t)t64_sec
;
2579 (void) localtime_r(&tv_sec
, &tm
);
2580 (void) strftime(time_created
,
2581 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2582 "%Y-%m-%d %H:%M:%S.xxx ", &tm
);
2583 msec64(t64_msec
/scale
,
2584 &time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2587 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2588 uval
.uvaltype
= PRA_STRING
;
2589 uval
.string_val
= time_created
;
2591 uval
.uvaltype
= PRA_UINT64
;
2592 uval
.uint64_val
= t64_sec
;
2593 (void) pa_print(context
, &uval
, 0);
2594 if (context
->format
& PRF_XMLM
) {
2595 uval
.uvaltype
= PRA_CHAR
;
2596 uval
.char_val
= '.';
2597 (void) pa_print(context
, &uval
, 0);
2599 uval
.uvaltype
= PRA_UINT64
;
2600 uval
.uint64_val
= t64_msec
;
2602 returnstat
= pa_print(context
, &uval
, flag
);
2606 return (returnstat
);
2608 return (close_tag(context
, TAG_ISO
));
2612 * -----------------------------------------------------------------------
2613 * pa_error() : convert the return token error code.
2615 * output : buf string representing return token error code.
2617 * -----------------------------------------------------------------------
2620 pa_error(const uchar_t err
, char *buf
, size_t buflen
)
2622 if (err
== ADT_SUCCESS
) {
2623 (void) strlcpy(buf
, gettext("success"), buflen
);
2624 } else if ((char)err
== ADT_FAILURE
) {
2625 (void) strlcpy(buf
, gettext("failure"), buflen
);
2627 char *emsg
= strerror(err
);
2630 (void) strlcpy(buf
, gettext("failure: "), buflen
);
2631 (void) strlcat(buf
, emsg
, buflen
);
2633 (void) snprintf(buf
, buflen
, "%s%d",
2634 gettext("failure: "), err
);
2640 * -----------------------------------------------------------------------
2641 * pa_retval() : convert the return token return value code.
2643 * input : err, for kernel success 0, or
2644 * failure errno: 0 > & < sys_nerr.
2645 * for userland success ADT_SUCCESS (0) or
2646 * failure ADT_FAILURE (-1).
2647 * pa_error() above has already converted err.
2649 * : retval, for kernel arbitrary return value for success, or
2652 * >= ADT_FAIL_VALUE < ADT_FAIL_PAM, an adt message code;
2653 * >= ADT_FAIL_PAM, a pam_strerror value;
2654 * < ADT_FAIL_VALUE, supposed to be an errno.
2656 * output : buf string representing return token error code.
2658 * -----------------------------------------------------------------------
2661 pa_retval(const uchar_t err
, const int32_t retval
, char *buf
, size_t buflen
)
2663 struct msg_text
*msglist
;
2666 /* success or kernel failure */
2667 if (((char)err
== ADT_SUCCESS
) ||
2670 (void) snprintf(buf
, buflen
, "%d", retval
);
2674 /* userland failure */
2675 msglist
= &adt_msg_text
[ADT_LIST_FAIL_VALUE
];
2677 if ((retval
+ msglist
->ml_offset
>= msglist
->ml_min_index
) &&
2678 (retval
+ msglist
->ml_offset
<= msglist
->ml_max_index
)) {
2681 gettext(msglist
->ml_msg_list
[retval
+ msglist
->ml_offset
]),
2683 } else if ((retval
>= ADT_FAIL_PAM
) &&
2684 (retval
< ADT_FAIL_PAM
+ PAM_TOTAL_ERRNUM
)) {
2686 (void) strlcpy(buf
, pam_strerror(NULL
, retval
- ADT_FAIL_PAM
),
2688 } else if ((emsg
= strerror(retval
)) != NULL
) {
2690 (void) strlcpy(buf
, emsg
, buflen
);
2693 (void) snprintf(buf
, buflen
, "%d", retval
);
2698 * -----------------------------------------------------------------------
2699 * pa_printstr() : print a given string, translating unprintables
2703 pa_printstr(pr_context_t
*context
, char *str
)
2707 int mbmax
= MB_CUR_MAX
;
2713 while (err
== 0 && *str
!= '\0') {
2715 printable
= isprint((unsigned char)c
);
2716 err
= pa_putstr(context
, printable
, &c
, 1);
2720 while (err
== 0 && *str
!= '\0') {
2721 len
= mbtowc(&wc
, str
, mbmax
);
2726 printable
= iswprint(wc
);
2728 err
= pa_putstr(context
, printable
, str
, len
);
2735 * -----------------------------------------------------------------------
2736 * pa_print() : print as one str or formatted for easy reading.
2737 * : flag - indicates whether to output a new line for
2738 * : multi-line output.
2739 * : = 0; no new line
2740 * : = 1; new line if regular output
2741 * output : The audit record information is displayed in the
2742 * type specified by uvaltype and value specified in
2743 * uval. The printing of the delimiter or newline is
2744 * determined by PRF_ONELINE, and the flag value,
2746 * +--------+------+------+-----------------+
2747 * |ONELINE | flag | last | Action |
2748 * +--------+------+------+-----------------+
2749 * | Y | Y | T | print new line |
2750 * | Y | Y | F | print delimiter |
2751 * | Y | N | T | print new line |
2752 * | Y | N | F | print delimiter |
2753 * | N | Y | T | print new line |
2754 * | N | Y | F | print new line |
2755 * | N | N | T | print new line |
2756 * | N | N | F | print delimiter |
2757 * +--------+------+------+-----------------+
2759 * return codes : -1 - error
2761 * -----------------------------------------------------------------------
2764 pa_print(pr_context_t
*context
, uval_t
*uval
, int flag
)
2769 switch (uval
->uvaltype
) {
2771 returnstat
= pr_printf(context
, "%d", uval
->int32_val
);
2774 returnstat
= pr_printf(context
, "%u", uval
->uint32_val
);
2777 returnstat
= pr_printf(context
, "%"PRId64
, uval
->int64_val
);
2780 returnstat
= pr_printf(context
, "%"PRIu64
, uval
->uint64_val
);
2783 returnstat
= pr_printf(context
, "%hd", uval
->short_val
);
2786 returnstat
= pr_printf(context
, "%hu", uval
->ushort_val
);
2789 returnstat
= pr_printf(context
, "%c", uval
->char_val
);
2792 returnstat
= pr_printf(context
, "%d", uval
->char_val
);
2795 returnstat
= pa_printstr(context
, uval
->string_val
);
2798 returnstat
= pr_printf(context
, "0x%x", uval
->int32_val
);
2801 returnstat
= pr_printf(context
, "0x%"PRIx64
, uval
->int64_val
);
2804 returnstat
= pr_printf(context
, "0x%hx", uval
->short_val
);
2807 returnstat
= pr_printf(context
, "%ho", uval
->ushort_val
);
2810 returnstat
= pr_printf(context
, "%o", (int)uval
->uint32_val
);
2813 (void) fprintf(stderr
, gettext("praudit: Unknown type.\n"));
2818 return (returnstat
);
2820 last
= (context
->audit_adr
->adr_now
==
2821 (context
->audit_rec_start
+ context
->audit_rec_len
));
2823 if (!(context
->format
& PRF_XMLM
)) {
2824 if (!(context
->format
& PRF_ONELINE
)) {
2825 if ((flag
== 1) || last
)
2826 returnstat
= pr_putchar(context
, '\n');
2828 returnstat
= pr_printf(context
, "%s",
2829 context
->SEPARATOR
);
2832 returnstat
= pr_printf(context
, "%s",
2833 context
->SEPARATOR
);
2835 returnstat
= pr_putchar(context
, '\n');
2838 if ((returnstat
== 0) && (context
->data_mode
== FILEMODE
))
2839 (void) fflush(stdout
);
2841 return (returnstat
);
2844 static struct cntrl_mapping
{
2858 static int cntrl_map_entries
= sizeof (cntrl_map
)
2859 / sizeof (struct cntrl_mapping
);
2862 * Convert binary data to ASCII for printing.
2865 convertascii(char *p
, char *c
, int size
)
2869 for (i
= 0; i
< size
; i
++) {
2870 uc
= (unsigned char)*(c
+ i
);
2873 for (j
= 0; j
< cntrl_map_entries
; j
++) {
2874 if (cntrl_map
[j
].from
== uc
) {
2876 *p
++ = cntrl_map
[j
].to
;
2880 if (j
== cntrl_map_entries
) {
2882 *p
++ = (char)(uc
^ 0100);
2888 p
+= sprintf(p
, "\\%03o", uc
);
2895 * -----------------------------------------------------------------------
2896 * pa_xgeneric: Process Xobject token and display contents
2897 * This routine will handle many of the attribute
2898 * types introduced in TS 2.x, such as:
2900 * AUT_XCOLORMAP, AUT_XCURSOR, AUT_XFONT,
2901 * AUT_XGC, AUT_XPIXMAP, AUT_XWINDOW
2903 * NOTE: At the time of call, the token id has been retrieved
2905 * return codes : -1 - error
2907 * NOTE: At the time of call, the xatom token id has been retrieved
2910 * text token id adr_char
2912 * creator uid adr_pw_uid
2913 * -----------------------------------------------------------------------
2916 pa_xgeneric(pr_context_t
*context
)
2920 returnstat
= process_tag(context
, TAG_XID
, 0, 0);
2921 return (process_tag(context
, TAG_XCUID
, returnstat
, 1));
2926 * ------------------------------------------------------------------------
2927 * pa_liaison : Issues pr_adr_char to retrieve the next ADR item from the
2928 * input stream pointed to by audit_adr, and prints it
2929 * if status >= 0 either in ASCII or raw form
2930 * return codes : -1 - error
2932 * : 1 - warning, unknown label type
2933 * -----------------------------------------------------------------------
2936 pa_liaison(pr_context_t
*context
, int status
, int flag
)
2943 if ((returnstat
= pr_adr_int32(context
, &li
, 1)) != 0) {
2944 return (returnstat
);
2946 if (!(context
->format
& PRF_RAWM
)) {
2947 uval
.uvaltype
= PRA_UINT32
;
2948 uval
.uint32_val
= li
;
2949 returnstat
= pa_print(context
, &uval
, flag
);
2951 /* print in hexadecimal form */
2952 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
2953 uval
.uvaltype
= PRA_HEX32
;
2954 uval
.uint32_val
= li
;
2955 returnstat
= pa_print(context
, &uval
, flag
);
2957 return (returnstat
);
2963 * ------------------------------------------------------------------------
2964 * pa_xid : Issues pr_adr_int32 to retrieve the XID from the input
2965 * stream pointed to by audit_adr, and prints it if
2966 * status >= 0 either in ASCII or raw form
2967 * return codes : -1 - error
2969 * : 1 - warning, unknown label type
2970 * ------------------------------------------------------------------------
2974 pa_xid(pr_context_t
*context
, int status
, int flag
)
2983 /* get XID from stream */
2984 if ((returnstat
= pr_adr_int32(context
, (int32_t *)&xid
, 1)) != 0)
2985 return (returnstat
);
2987 if (!(context
->format
& PRF_RAWM
)) {
2988 uval
.uvaltype
= PRA_STRING
;
2989 uval
.string_val
= hexconvert((char *)&xid
, sizeof (xid
),
2991 if (uval
.string_val
) {
2992 returnstat
= pa_print(context
, &uval
, flag
);
2993 free(uval
.string_val
);
2996 uval
.uvaltype
= PRA_INT32
;
2997 uval
.int32_val
= xid
;
2998 returnstat
= pa_print(context
, &uval
, flag
);
3001 return (returnstat
);
3005 pa_ace_flags(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3015 * ace->a_flags refers to access flags of ZFS/NFSv4 ACL entry.
3017 if ((returnstat
= open_tag(context
, TAG_ACEFLAGS
)) != 0)
3018 return (returnstat
);
3019 if (!(context
->format
& PRF_RAWM
)) {
3020 uval
.uvaltype
= PRA_STRING
;
3021 switch (ace
->a_flags
& ACE_TYPE_FLAGS
) {
3023 uval
.string_val
= gettext(OWNERAT_TXT
);
3025 case ACE_GROUP
| ACE_IDENTIFIER_GROUP
:
3026 uval
.string_val
= gettext(GROUPAT_TXT
);
3028 case ACE_IDENTIFIER_GROUP
:
3029 uval
.string_val
= gettext(GROUP_TXT
);
3032 uval
.string_val
= gettext(EVERYONEAT_TXT
);
3035 uval
.string_val
= gettext(USER_TXT
);
3038 uval
.uvaltype
= PRA_USHORT
;
3039 uval
.uint32_val
= ace
->a_flags
;
3042 uval
.uvaltype
= PRA_USHORT
;
3043 uval
.uint32_val
= ace
->a_flags
;
3045 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
3046 return (returnstat
);
3047 return (close_tag(context
, TAG_ACEFLAGS
));
3051 pa_ace_who(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3060 * ace->a_who refers to user id or group id of ZFS/NFSv4 ACL entry.
3062 if ((returnstat
= open_tag(context
, TAG_ACEID
)) != 0)
3063 return (returnstat
);
3064 switch (ace
->a_flags
& ACE_TYPE_FLAGS
) {
3065 case ACE_IDENTIFIER_GROUP
: /* group id */
3066 returnstat
= pa_print_gid(context
, ace
->a_who
, returnstat
,
3069 default: /* user id */
3070 returnstat
= pa_print_uid(context
, ace
->a_who
, returnstat
,
3075 return (returnstat
);
3076 return (close_tag(context
, TAG_ACEID
));
3080 * Appends what to str, (re)allocating str if necessary.
3082 #define INITIAL_ALLOC 256
3084 strappend(char **str
, char *what
, size_t *alloc
)
3092 s
= malloc(INITIAL_ALLOC
);
3097 *alloc
= INITIAL_ALLOC
;
3102 needed
= strlen(s
) + strlen(what
) + 1;
3103 if (*alloc
< needed
) {
3104 newstr
= realloc(s
, needed
);
3111 (void) strlcat(s
, what
, *alloc
);
3117 pa_ace_access_mask(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3121 char *permstr
= NULL
;
3122 size_t permstr_alloc
= 0;
3129 * ace->a_access_mask refers to access mask of ZFS/NFSv4 ACL entry.
3131 if ((returnstat
= open_tag(context
, TAG_ACEMASK
)) != 0)
3132 return (returnstat
);
3133 if (context
->format
& PRF_SHORTM
&&
3134 ((permstr
= malloc(15)) != NULL
)) {
3135 for (i
= 0; i
< 14; i
++)
3138 if (ace
->a_access_mask
& ACE_READ_DATA
)
3140 if (ace
->a_access_mask
& ACE_WRITE_DATA
)
3142 if (ace
->a_access_mask
& ACE_EXECUTE
)
3144 if (ace
->a_access_mask
& ACE_APPEND_DATA
)
3146 if (ace
->a_access_mask
& ACE_DELETE
)
3148 if (ace
->a_access_mask
& ACE_DELETE_CHILD
)
3150 if (ace
->a_access_mask
& ACE_READ_ATTRIBUTES
)
3152 if (ace
->a_access_mask
& ACE_WRITE_ATTRIBUTES
)
3154 if (ace
->a_access_mask
& ACE_READ_NAMED_ATTRS
)
3156 if (ace
->a_access_mask
& ACE_WRITE_NAMED_ATTRS
)
3158 if (ace
->a_access_mask
& ACE_READ_ACL
)
3160 if (ace
->a_access_mask
& ACE_WRITE_ACL
)
3162 if (ace
->a_access_mask
& ACE_WRITE_OWNER
)
3164 if (ace
->a_access_mask
& ACE_SYNCHRONIZE
)
3167 uval
.uvaltype
= PRA_STRING
;
3168 uval
.string_val
= permstr
;
3169 } else if (!(context
->format
& PRF_RAWM
)) {
3172 * Note this differs from acltext.c:ace_perm_txt()
3173 * because we don't know if the acl belongs to a file
3174 * or directory. ace mask value are the same
3175 * nonetheless, see sys/acl.h
3177 if (ace
->a_access_mask
& ACE_LIST_DIRECTORY
) {
3178 returnstat
= strappend(&permstr
, gettext(READ_DIR_TXT
),
3181 if (ace
->a_access_mask
& ACE_ADD_FILE
) {
3182 returnstat
= strappend(&permstr
, gettext(ADD_FILE_TXT
),
3185 if (ace
->a_access_mask
& ACE_ADD_SUBDIRECTORY
) {
3186 returnstat
= strappend(&permstr
, gettext(ADD_DIR_TXT
),
3189 if (ace
->a_access_mask
& ACE_READ_NAMED_ATTRS
) {
3190 returnstat
= strappend(&permstr
,
3191 gettext(READ_XATTR_TXT
), &permstr_alloc
);
3193 if (ace
->a_access_mask
& ACE_WRITE_NAMED_ATTRS
) {
3194 returnstat
= strappend(&permstr
,
3195 gettext(WRITE_XATTR_TXT
), &permstr_alloc
);
3197 if (ace
->a_access_mask
& ACE_EXECUTE
) {
3198 returnstat
= strappend(&permstr
,
3199 gettext(EXECUTE_TXT
), &permstr_alloc
);
3201 if (ace
->a_access_mask
& ACE_DELETE_CHILD
) {
3202 returnstat
= strappend(&permstr
,
3203 gettext(DELETE_CHILD_TXT
), &permstr_alloc
);
3205 if (ace
->a_access_mask
& ACE_READ_ATTRIBUTES
) {
3206 returnstat
= strappend(&permstr
,
3207 gettext(READ_ATTRIBUTES_TXT
), &permstr_alloc
);
3209 if (ace
->a_access_mask
& ACE_WRITE_ATTRIBUTES
) {
3210 returnstat
= strappend(&permstr
,
3211 gettext(WRITE_ATTRIBUTES_TXT
), &permstr_alloc
);
3213 if (ace
->a_access_mask
& ACE_DELETE
) {
3214 returnstat
= strappend(&permstr
, gettext(DELETE_TXT
),
3217 if (ace
->a_access_mask
& ACE_READ_ACL
) {
3218 returnstat
= strappend(&permstr
, gettext(READ_ACL_TXT
),
3221 if (ace
->a_access_mask
& ACE_WRITE_ACL
) {
3222 returnstat
= strappend(&permstr
, gettext(WRITE_ACL_TXT
),
3225 if (ace
->a_access_mask
& ACE_WRITE_OWNER
) {
3226 returnstat
= strappend(&permstr
,
3227 gettext(WRITE_OWNER_TXT
), &permstr_alloc
);
3229 if (ace
->a_access_mask
& ACE_SYNCHRONIZE
) {
3230 returnstat
= strappend(&permstr
,
3231 gettext(SYNCHRONIZE_TXT
), &permstr_alloc
);
3233 if (permstr
[strlen(permstr
) - 1] == '/')
3234 permstr
[strlen(permstr
) - 1] = '\0';
3235 uval
.uvaltype
= PRA_STRING
;
3236 uval
.string_val
= permstr
;
3238 if ((permstr
== NULL
) || (returnstat
!= 0) ||
3239 (context
->format
& PRF_RAWM
)) {
3240 uval
.uvaltype
= PRA_UINT32
;
3241 uval
.uint32_val
= ace
->a_access_mask
;
3243 returnstat
= pa_print(context
, &uval
, flag
);
3245 if (permstr
!= NULL
)
3247 if (returnstat
!= 0)
3248 return (returnstat
);
3249 return (close_tag(context
, TAG_ACEMASK
));
3253 pa_ace_type(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3263 * ace->a_type refers to access type of ZFS/NFSv4 ACL entry.
3265 if ((returnstat
= open_tag(context
, TAG_ACETYPE
)) != 0)
3266 return (returnstat
);
3267 if (!(context
->format
& PRF_RAWM
)) {
3268 uval
.uvaltype
= PRA_STRING
;
3269 switch (ace
->a_type
) {
3270 case ACE_ACCESS_ALLOWED_ACE_TYPE
:
3271 uval
.string_val
= gettext(ALLOW_TXT
);
3273 case ACE_ACCESS_DENIED_ACE_TYPE
:
3274 uval
.string_val
= gettext(DENY_TXT
);
3276 case ACE_SYSTEM_AUDIT_ACE_TYPE
:
3277 uval
.string_val
= gettext(AUDIT_TXT
);
3279 case ACE_SYSTEM_ALARM_ACE_TYPE
:
3280 uval
.string_val
= gettext(ALARM_TXT
);
3283 uval
.string_val
= gettext(UNKNOWN_TXT
);
3286 uval
.uvaltype
= PRA_USHORT
;
3287 uval
.uint32_val
= ace
->a_type
;
3289 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
3290 return (returnstat
);
3291 return (close_tag(context
, TAG_ACETYPE
));
3295 pa_ace(pr_context_t
*context
, int status
, int flag
)
3303 if ((returnstat
= pr_adr_u_int32(context
, &ace
.a_who
, 1)) != 0)
3304 return (returnstat
);
3305 if ((returnstat
= pr_adr_u_int32(context
, &ace
.a_access_mask
, 1)) != 0)
3306 return (returnstat
);
3307 if ((returnstat
= pr_adr_u_short(context
, &ace
.a_flags
, 1)) != 0)
3308 return (returnstat
);
3309 if ((returnstat
= pr_adr_u_short(context
, &ace
.a_type
, 1)) != 0)
3310 return (returnstat
);
3312 if ((returnstat
= pa_ace_flags(context
, &ace
, returnstat
, 0)) != 0)
3313 return (returnstat
);
3314 /* pa_ace_who can returns 1 if uid/gid is not found */
3315 if ((returnstat
= pa_ace_who(context
, &ace
, returnstat
, 0)) < 0)
3316 return (returnstat
);
3317 if ((returnstat
= pa_ace_access_mask(context
, &ace
,
3318 returnstat
, 0)) != 0)
3319 return (returnstat
);
3320 return (pa_ace_type(context
, &ace
, returnstat
, flag
));