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
,
66 static uid_t lastuid
= (uid_t
)-1;
67 static gid_t lastgid
= (gid_t
)-1;
68 static char *lastuname
= NULL
;
69 static char *lastgname
= NULL
;
70 static char *getname(uid_t
);
71 static char *getgroup(gid_t
);
72 static struct cachenode
*findincache(struct cachenode
**, long);
77 #define NMAX (sizeof (utmp.ut_name))
78 #define SCPYN(a, b) (void) strncpy(a, b, NMAX)
80 struct cachenode
{ /* this struct must be zeroed before using */
81 struct cachenode
*lesschild
; /* subtree whose entries < val */
82 struct cachenode
*grtrchild
; /* subtree whose entries > val */
83 long val
; /* the uid or gid of this entry */
84 int initted
; /* name has been filled in */
85 char name
[NMAX
+1]; /* the string that val maps to */
87 static struct cachenode
*names
, *groups
;
89 static struct cachenode
*
90 findincache(struct cachenode
**head
, long val
)
92 struct cachenode
**parent
= head
;
93 struct cachenode
*c
= *parent
;
99 } else if (val
< c
->val
) {
100 parent
= &c
->lesschild
;
103 parent
= &c
->grtrchild
;
108 /* not in the cache, make a new entry for it */
109 c
= calloc(1, sizeof (struct cachenode
));
120 * get name from cache, or passwd file for a given uid;
121 * lastuid is set to uid.
126 struct passwd
*pwent
;
129 if ((uid
== lastuid
) && lastuname
)
132 c
= findincache(&names
, uid
);
133 if (c
->initted
== 0) {
134 if ((pwent
= getpwuid(uid
)) != NULL
) {
135 SCPYN(&c
->name
[0], pwent
->pw_name
);
137 (void) sprintf(&c
->name
[0], "%u", (int)uid
);
142 lastuname
= &c
->name
[0];
147 * get name from cache, or group file for a given gid;
148 * lastgid is set to gid.
156 if ((gid
== lastgid
) && lastgname
)
159 c
= findincache(&groups
, gid
);
160 if (c
->initted
== 0) {
161 if ((grent
= getgrgid(gid
)) != NULL
) {
162 SCPYN(&c
->name
[0], grent
->gr_name
);
164 (void) sprintf(&c
->name
[0], "%u", (int)gid
);
169 lastgname
= &c
->name
[0];
174 * ------------------------------------------------------
175 * field widths for arbitrary data token type
176 * ------------------------------------------------------
185 /* character data type, 8 bits */
186 AUR_CHAR
, AUP_BINARY
, 12,
191 AUR_BYTE
, AUP_BINARY
, 12,
196 AUR_SHORT
, AUP_BINARY
, 20,
201 AUR_INT32
, AUP_BINARY
, 36,
206 AUR_INT64
, AUP_BINARY
, 68,
213 static int numwidthentries
= sizeof (fwidth
)
214 / sizeof (struct fw
);
218 * -----------------------------------------------------------------------
220 * Print a newline, if needed according to various formatting
222 * return codes : 0 - success
224 * -----------------------------------------------------------------------
227 do_newline(pr_context_t
*context
, int flag
)
231 if (!(context
->format
& PRF_ONELINE
) && (flag
== 1))
232 retstat
= pr_putchar(context
, '\n');
233 else if (!(context
->format
& PRF_XMLM
))
234 retstat
= pr_printf(context
, "%s", context
->SEPARATOR
);
240 open_tag(pr_context_t
*context
, int tagnum
)
245 /* no-op if not doing XML format */
246 if (!(context
->format
& PRF_XMLM
))
249 tag
= &tokentable
[tagnum
];
252 * First if needed do an implicit finish of a pending open for an
253 * extended tag. I.e., for the extended tag xxx:
254 * <xxx a=".." b=".."> ... </xxx>
255 * -- insert a close bracket after the last attribute
256 * (in other words, when the 1st non-attribute is opened while
257 * this is pending). Note that only one tag could be pending at
258 * a given time -- it couldn't be nested.
260 if (context
->pending_flag
&& (tag
->t_type
!= T_ATTRIBUTE
)) {
261 /* complete pending extended open */
262 err
= pr_putchar(context
, '>');
265 context
->pending_flag
= 0;
268 if (is_header_token(tagnum
) || is_file_token(tagnum
)) {
269 /* File token or new record on new line */
270 err
= pr_putchar(context
, '\n');
271 } else if (is_token(tagnum
)) {
272 /* Each token on new line if possible */
273 err
= do_newline(context
, 1);
278 switch (tag
->t_type
) {
280 err
= pr_printf(context
, " %s=\"", tag
->t_tagname
);
283 err
= pr_printf(context
, "<%s>", tag
->t_tagname
);
286 err
= pr_printf(context
, "<%s", tag
->t_tagname
);
289 err
= pr_printf(context
, "<%s", tag
->t_tagname
);
291 context
->pending_flag
= tagnum
;
297 if (is_header_token(tagnum
) && (err
== 0))
298 context
->current_rec
= tagnum
; /* set start of new record */
304 * Do an implicit close of a record when needed.
307 check_close_rec(pr_context_t
*context
, int tagnum
)
311 /* no-op if not doing XML format */
312 if (!(context
->format
& PRF_XMLM
))
316 * If we're opening a header or the file token (i.e., starting a new
317 * record), if there's a current record in progress do an implicit
320 if ((is_header_token(tagnum
) || is_file_token(tagnum
)) &&
321 context
->current_rec
) {
322 err
= do_newline(context
, 1);
324 err
= close_tag(context
, context
->current_rec
);
331 * explicit finish of a pending open for an extended tag.
334 finish_open_tag(pr_context_t
*context
)
338 /* no-op if not doing XML format */
339 if (!(context
->format
& PRF_XMLM
))
342 if (context
->pending_flag
) {
343 /* complete pending extended open */
344 err
= pr_putchar(context
, '>');
346 context
->pending_flag
= 0;
352 close_tag(pr_context_t
*context
, int tagnum
)
357 /* no-op if not doing XML format */
358 if (!(context
->format
& PRF_XMLM
))
361 tag
= &tokentable
[tagnum
];
363 switch (tag
->t_type
) {
365 err
= pr_putchar(context
, '\"');
368 err
= pr_printf(context
, "</%s>", tag
->t_tagname
);
371 err
= pr_printf(context
, "/>");
374 err
= pr_printf(context
, "</%s>", tag
->t_tagname
);
380 if (is_header_token(tagnum
) && (err
== 0))
381 context
->current_rec
= 0; /* closing rec; none current */
387 * -----------------------------------------------------------------------
389 * Calls the routine corresponding to the tag
390 * Note that to use this mechanism, all such routines must
391 * take 2 ints for their parameters; the first of these is
392 * the current status.
394 * flag = 1 for newline / delimiter, else 0
395 * return codes : -1 - error
397 * -----------------------------------------------------------------------
400 process_tag(pr_context_t
*context
, int tagnum
, int status
, int flag
)
409 if ((tagnum
> 0) && (tagnum
<= MAXTAG
) &&
410 (tokentable
[tagnum
].func
!= NOFUNC
)) {
411 retstat
= open_tag(context
, tagnum
);
413 retstat
= (*tokentable
[tagnum
].func
)(context
, status
,
416 retstat
= close_tag(context
, tagnum
);
419 /* here if token id is not in table */
420 (void) fprintf(stderr
, gettext("praudit: No code associated with "
421 "tag id %d\n"), tagnum
);
426 get_Hname(uint32_t addr
, char *buf
, size_t buflen
)
428 extern char *inet_ntoa(const struct in_addr
);
432 phe
= gethostbyaddr((const char *)&addr
, 4, AF_INET
);
435 (void) snprintf(buf
, buflen
, "%s", inet_ntoa(ia
));
439 (void) snprintf(buf
, buflen
, "%s", phe
->h_name
);
443 get_Hname_ex(uint32_t *addr
, char *buf
, size_t buflen
)
448 phe
= getipnodebyaddr((const void *)addr
, 16, AF_INET6
, &err
);
451 (void) inet_ntop(AF_INET6
, (void *)addr
, buf
, buflen
);
453 (void) snprintf(buf
, buflen
, "%s", phe
->h_name
);
460 pa_hostname(pr_context_t
*context
, int status
, int flag
)
471 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
474 uval
.uvaltype
= PRA_STRING
;
476 if (!(context
->format
& PRF_RAWM
)) {
477 uval
.string_val
= buf
;
478 get_Hname(ip_addr
, buf
, sizeof (buf
));
479 returnstat
= pa_print(context
, &uval
, flag
);
482 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
484 returnstat
= pa_print(context
, &uval
, flag
);
490 pa_hostname_ex(pr_context_t
*context
, int status
, int flag
)
503 if ((returnstat
= pr_adr_int32(context
, (int32_t *)&ip_type
, 1)) != 0)
506 /* only IPv4 and IPv6 addresses are legal */
507 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
511 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
514 if ((returnstat
= open_tag(context
, TAG_HOSTID
)) != 0)
517 uval
.uvaltype
= PRA_STRING
;
518 if (ip_type
== AU_IPv4
) { /* ipv4 address */
519 if (!(context
->format
& PRF_RAWM
)) {
520 uval
.string_val
= buf
;
521 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
522 returnstat
= pa_print(context
, &uval
, flag
);
524 ia
.s_addr
= ip_addr
[0];
525 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
527 returnstat
= pa_print(context
, &uval
, flag
);
529 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
530 if (!(context
->format
& PRF_RAWM
)) {
531 uval
.string_val
= buf
;
532 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
533 returnstat
= pa_print(context
, &uval
, flag
);
535 uval
.string_val
= (char *)buf
;
536 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
538 returnstat
= pa_print(context
, &uval
, flag
);
544 return (close_tag(context
, TAG_HOSTID
));
548 pa_hostname_so(pr_context_t
*context
, int status
, int flag
)
562 if ((returnstat
= pr_adr_short(context
, &ip_type
, 1)) != 0)
565 /* only IPv4 and IPv6 addresses are legal */
566 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
569 /* get local ip port */
570 if ((returnstat
= pr_adr_u_short(context
, &ip_port
, 1)) != 0)
573 if ((returnstat
= open_tag(context
, TAG_SOCKEXLPORT
)) != 0)
576 uval
.uvaltype
= PRA_STRING
;
577 uval
.string_val
= hexconvert((char *)&ip_port
, sizeof (ip_port
),
579 if (uval
.string_val
) {
580 returnstat
= pa_print(context
, &uval
, 0);
581 free(uval
.string_val
);
587 if ((returnstat
= close_tag(context
, TAG_SOCKEXLPORT
)) != 0)
590 /* get local ip address */
591 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
594 if ((returnstat
= open_tag(context
, TAG_SOCKEXLADDR
)) != 0)
597 if (ip_type
== AU_IPv4
) { /* ipv4 address */
599 if (!(context
->format
& PRF_RAWM
)) {
600 uval
.string_val
= buf
;
601 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
602 returnstat
= pa_print(context
, &uval
, 0);
604 ia
.s_addr
= ip_addr
[0];
605 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
607 returnstat
= pa_print(context
, &uval
, 0);
610 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
612 if (!(context
->format
& PRF_RAWM
)) {
613 uval
.string_val
= buf
;
614 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
615 returnstat
= pa_print(context
, &uval
, 0);
617 uval
.string_val
= (char *)buf
;
618 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
620 returnstat
= pa_print(context
, &uval
, 0);
628 if ((returnstat
= close_tag(context
, TAG_SOCKEXLADDR
)) != 0)
631 /* get foreign ip port */
632 if ((returnstat
= pr_adr_u_short(context
, &ip_port
, 1)) != 0)
635 if ((returnstat
= open_tag(context
, TAG_SOCKEXFPORT
)) != 0)
638 uval
.string_val
= hexconvert((char *)&ip_port
, sizeof (ip_port
),
640 if (uval
.string_val
) {
641 returnstat
= pa_print(context
, &uval
, 0);
642 free(uval
.string_val
);
649 if ((returnstat
= close_tag(context
, TAG_SOCKEXFPORT
)) != 0)
652 /* get foreign ip address */
653 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
656 if ((returnstat
= open_tag(context
, TAG_SOCKEXFADDR
)) != 0)
659 if (ip_type
== AU_IPv4
) { /* ipv4 address */
661 if (!(context
->format
& PRF_RAWM
)) {
662 uval
.string_val
= buf
;
663 get_Hname(ip_addr
[0], buf
, sizeof (buf
));
664 returnstat
= pa_print(context
, &uval
, flag
);
666 ia
.s_addr
= ip_addr
[0];
667 if ((uval
.string_val
= inet_ntoa(ia
)) == NULL
)
669 returnstat
= pa_print(context
, &uval
, flag
);
672 } else if (ip_type
== AU_IPv6
) { /* IPv6 addresss (128 bits) */
674 if (!(context
->format
& PRF_RAWM
)) {
675 uval
.string_val
= buf
;
676 get_Hname_ex(ip_addr
, buf
, sizeof (buf
));
677 returnstat
= pa_print(context
, &uval
, flag
);
679 uval
.string_val
= (char *)buf
;
680 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, buf
,
682 returnstat
= pa_print(context
, &uval
, flag
);
690 if ((returnstat
= close_tag(context
, TAG_SOCKEXFADDR
)) != 0)
697 #define NBITSMAJOR64 32 /* # of major device bits in 64-bit Solaris */
698 #define NBITSMINOR64 32 /* # of minor device bits in 64-bit Solaris */
699 #define MAXMAJ64 0xfffffffful /* max major value */
700 #define MAXMIN64 0xfffffffful /* max minor value */
702 #define NBITSMAJOR32 14 /* # of SVR4 major device bits */
703 #define NBITSMINOR32 18 /* # of SVR4 minor device bits */
704 #define NMAXMAJ32 0x3fff /* SVR4 max major value */
705 #define NMAXMIN32 0x3ffff /* MAX minor for 3b2 software drivers. */
709 minor_64(uint64_t dev
)
715 return (int32_t)(dev
& MAXMIN64
);
719 major_64(uint64_t dev
)
723 maj
= (uint32_t)(dev
>> NBITSMINOR64
);
725 if (dev
== NODEV
|| maj
> MAXMAJ64
) {
729 return (int32_t)(maj
);
733 minor_32(uint32_t dev
)
739 return (int32_t)(dev
& MAXMIN32
);
743 major_32(uint32_t dev
)
747 maj
= (uint32_t)(dev
>> NBITSMINOR32
);
749 if (dev
== NODEV
|| maj
> MAXMAJ32
) {
753 return (int32_t)(maj
);
758 * -----------------------------------------------------------------------
759 * pa_tid() : Process terminal id and display contents
760 * return codes : -1 - error
763 * terminal id port adr_int32
764 * terminal id machine adr_int32
765 * -----------------------------------------------------------------------
768 pa_tid32(pr_context_t
*context
, int status
, int flag
)
781 if ((returnstat
= pr_adr_int32(context
, &dev_maj_min
, 1)) != 0)
784 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
787 uval
.uvaltype
= PRA_STRING
;
788 uval
.string_val
= buf
;
790 if (!(context
->format
& PRF_RAWM
)) {
793 get_Hname(ip_addr
, hostname
, sizeof (hostname
));
794 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
795 major_32(dev_maj_min
),
796 minor_32(dev_maj_min
),
798 return (pa_print(context
, &uval
, flag
));
802 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
805 (void) snprintf(buf
, sizeof (buf
), "%d %d %s", major_32(dev_maj_min
),
806 minor_32(dev_maj_min
),
809 return (pa_print(context
, &uval
, flag
));
813 pa_tid32_ex(pr_context_t
*context
, int status
, int flag
)
817 uint32_t ip_addr
[16];
830 if ((returnstat
= pr_adr_int32(context
, &dev_maj_min
, 1)) != 0)
833 /* get address type */
834 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
837 /* legal address types are either AU_IPv4 or AU_IPv6 only */
838 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
841 /* get address (4/16) */
842 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
845 uval
.uvaltype
= PRA_STRING
;
846 if (ip_type
== AU_IPv4
) {
847 uval
.string_val
= buf
;
849 if (!(context
->format
& PRF_RAWM
)) {
850 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
851 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
852 major_32(dev_maj_min
), minor_32(dev_maj_min
),
854 return (pa_print(context
, &uval
, flag
));
857 ia
.s_addr
= ip_addr
[0];
858 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
861 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
862 major_32(dev_maj_min
), minor_32(dev_maj_min
), ipstring
);
864 return (pa_print(context
, &uval
, flag
));
866 uval
.string_val
= buf
;
868 if (!(context
->format
& PRF_RAWM
)) {
869 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
870 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
871 major_32(dev_maj_min
), minor_32(dev_maj_min
),
873 return (pa_print(context
, &uval
, flag
));
876 (void) inet_ntop(AF_INET6
, (void *) ip_addr
, tbuf
,
879 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
880 major_32(dev_maj_min
), minor_32(dev_maj_min
), tbuf
);
882 return (pa_print(context
, &uval
, flag
));
887 pa_ip_addr(pr_context_t
*context
, int status
, int flag
)
902 /* get address type */
903 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
906 /* legal address type is AU_IPv4 or AU_IPv6 */
907 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
910 /* get address (4/16) */
911 if ((returnstat
= pr_adr_char(context
, (char *)ip_addr
, ip_type
)) != 0)
914 uval
.uvaltype
= PRA_STRING
;
915 if (ip_type
== AU_IPv4
) {
916 uval
.string_val
= buf
;
918 if (!(context
->format
& PRF_RAWM
)) {
919 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
920 (void) snprintf(buf
, sizeof (buf
), "%s", hostname
);
921 return (pa_print(context
, &uval
, flag
));
924 ia
.s_addr
= ip_addr
[0];
925 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
928 (void) snprintf(buf
, sizeof (buf
), "%s", ipstring
);
930 return (pa_print(context
, &uval
, flag
));
932 uval
.string_val
= buf
;
934 if (!(context
->format
& PRF_RAWM
)) {
935 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
936 (void) snprintf(buf
, sizeof (buf
), "%s",
938 return (pa_print(context
, &uval
, flag
));
941 (void) inet_ntop(AF_INET6
, (void *) ip_addr
, tbuf
,
944 (void) snprintf(buf
, sizeof (buf
), "%s", tbuf
);
946 return (pa_print(context
, &uval
, flag
));
952 pa_tid64(pr_context_t
*context
, int status
, int flag
)
965 if ((returnstat
= pr_adr_int64(context
, &dev_maj_min
, 1)) != 0)
968 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, 4)) != 0)
971 uval
.uvaltype
= PRA_STRING
;
972 uval
.string_val
= buf
;
974 if (!(context
->format
& PRF_RAWM
)) {
977 get_Hname(ip_addr
, hostname
, sizeof (hostname
));
978 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
979 major_64(dev_maj_min
), minor_64(dev_maj_min
), hostname
);
980 return (pa_print(context
, &uval
, flag
));
984 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
987 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
988 major_64(dev_maj_min
), minor_64(dev_maj_min
), ipstring
);
990 return (pa_print(context
, &uval
, flag
));
994 pa_tid64_ex(pr_context_t
*context
, int status
, int flag
)
1011 if ((returnstat
= pr_adr_int64(context
, &dev_maj_min
, 1)) != 0)
1012 return (returnstat
);
1014 /* get address type */
1015 if ((returnstat
= pr_adr_u_int32(context
, &ip_type
, 1)) != 0)
1016 return (returnstat
);
1018 /* legal address types are either AU_IPv4 or AU_IPv6 only */
1019 if ((ip_type
!= AU_IPv4
) && (ip_type
!= AU_IPv6
))
1022 /* get address (4/16) */
1023 if ((returnstat
= pr_adr_char(context
, (char *)&ip_addr
, ip_type
)) != 0)
1024 return (returnstat
);
1026 uval
.uvaltype
= PRA_STRING
;
1027 if (ip_type
== AU_IPv4
) {
1028 uval
.string_val
= buf
;
1030 if (!(context
->format
& PRF_RAWM
)) {
1031 get_Hname(ip_addr
[0], hostname
, sizeof (hostname
));
1032 uval
.string_val
= buf
;
1033 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
1034 major_64(dev_maj_min
), minor_64(dev_maj_min
),
1036 return (pa_print(context
, &uval
, flag
));
1039 ia
.s_addr
= ip_addr
[0];
1040 if ((ipstring
= inet_ntoa(ia
)) == NULL
)
1043 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
1044 major_64(dev_maj_min
), minor_64(dev_maj_min
), ipstring
);
1046 return (pa_print(context
, &uval
, flag
));
1048 uval
.string_val
= buf
;
1050 if (!(context
->format
& PRF_RAWM
)) {
1051 get_Hname_ex(ip_addr
, hostname
, sizeof (hostname
));
1052 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
1053 major_64(dev_maj_min
), minor_64(dev_maj_min
),
1055 return (pa_print(context
, &uval
, flag
));
1058 (void) inet_ntop(AF_INET6
, (void *)ip_addr
, tbuf
,
1061 (void) snprintf(buf
, sizeof (buf
), "%d %d %s",
1062 major_64(dev_maj_min
), minor_64(dev_maj_min
), tbuf
);
1064 return (pa_print(context
, &uval
, flag
));
1070 * ----------------------------------------------------------------
1072 * Returns the field width based on the basic unit and print mode.
1073 * This routine is called to determine the field width for the
1074 * data items in the arbitrary data token where the tokens are
1075 * to be printed in more than one line. The field width can be
1076 * found in the fwidth structure.
1079 * basicunit Can be one of AUR_CHAR, AUR_BYTE, AUR_SHORT,
1080 * AUR_INT32, or AUR_INT64
1081 * howtoprint Print mode. Can be one of AUP_BINARY, AUP_OCTAL,
1082 * AUP_DECIMAL, or AUP_HEX.
1083 * ----------------------------------------------------------------
1086 findfieldwidth(char basicunit
, char howtoprint
)
1090 for (i
= 0; i
< numwidthentries
; i
++) {
1091 if (fwidth
[i
].basic_unit
== basicunit
) {
1092 for (j
= 0; j
<= 4; j
++) {
1093 if (fwidth
[i
].pwidth
[j
].print_base
==
1096 fwidth
[i
].pwidth
[j
].field_width
);
1100 * if we got here, then we didn't get what we were after
1105 /* if we got here, we didn't get what we wanted either */
1111 * -----------------------------------------------------------------------
1112 * pa_cmd: Retrieves the cmd item from the input stream.
1113 * return codes : -1 - error
1115 * -----------------------------------------------------------------------
1118 pa_cmd(pr_context_t
*context
, int status
, int flag
)
1120 char *cmd
; /* cmd */
1126 * We need to know how much space to allocate for our string, so
1127 * read the length first, then call pr_adr_char to read those bytes.
1130 if (pr_adr_short(context
, &length
, 1) == 0) {
1131 if ((cmd
= (char *)malloc(length
+ 1)) == NULL
)
1133 if (pr_adr_char(context
, cmd
, length
) == 0) {
1134 uval
.uvaltype
= PRA_STRING
;
1135 uval
.string_val
= cmd
;
1136 returnstat
= pa_print(context
, &uval
, flag
);
1141 return (returnstat
);
1151 * -----------------------------------------------------------------------
1152 * pa_adr_byte : Issues pr_adr_char to retrieve the next ADR item from
1153 * the input stream pointed to by audit_adr, and prints it
1154 * as an integer if status >= 0
1155 * return codes : -1 - error
1157 * -----------------------------------------------------------------------
1160 pa_adr_byte(pr_context_t
*context
, int status
, int flag
)
1166 if (pr_adr_char(context
, &c
, 1) == 0) {
1167 uval
.uvaltype
= PRA_BYTE
;
1169 return (pa_print(context
, &uval
, flag
));
1177 * -----------------------------------------------------------------------
1178 * pa_adr_charhex: Issues pr_adr_char to retrieve the next ADR item from
1179 * the input stream pointed to by audit_adr, and prints it
1180 * in hexadecimal if status >= 0
1181 * return codes : -1 - error
1183 * -----------------------------------------------------------------------
1186 pa_adr_charhex(pr_context_t
*context
, int status
, int flag
)
1195 if ((returnstat
= pr_adr_char(context
, p
, 1)) == 0) {
1196 uval
.uvaltype
= PRA_STRING
;
1197 uval
.string_val
= hexconvert(p
, sizeof (char),
1199 if (uval
.string_val
) {
1200 returnstat
= pa_print(context
, &uval
, flag
);
1201 free(uval
.string_val
);
1204 return (returnstat
);
1210 * -----------------------------------------------------------------------
1211 * pa_adr_int32 : Issues pr_adr_int32 to retrieve the next ADR item from the
1212 * input stream pointed to by audit_adr, and prints it
1214 * return codes : -1 - error
1216 * -----------------------------------------------------------------------
1219 pa_adr_int32(pr_context_t
*context
, int status
, int flag
)
1225 if (pr_adr_int32(context
, &c
, 1) == 0) {
1226 uval
.uvaltype
= PRA_INT32
;
1228 return (pa_print(context
, &uval
, flag
));
1239 * -----------------------------------------------------------------------
1240 * pa_adr_int64 : Issues pr_adr_int64 to retrieve the next ADR item from the
1241 * input stream pointed to by audit_adr, and prints it
1243 * return codes : -1 - error
1245 * -----------------------------------------------------------------------
1248 pa_adr_int64(pr_context_t
*context
, int status
, int flag
)
1254 if (pr_adr_int64(context
, &c
, 1) == 0) {
1255 uval
.uvaltype
= PRA_INT64
;
1257 return (pa_print(context
, &uval
, flag
));
1265 * -----------------------------------------------------------------------
1266 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1267 * input stream pointed to by audit_adr, and prints it
1268 * in hexadecimal if status >= 0
1269 * return codes : -1 - error
1271 * -----------------------------------------------------------------------
1274 pa_adr_int32hex(pr_context_t
*context
, int status
, int flag
)
1281 if ((returnstat
= pr_adr_int32(context
, &l
, 1)) == 0) {
1282 uval
.uvaltype
= PRA_HEX32
;
1284 returnstat
= pa_print(context
, &uval
, flag
);
1286 return (returnstat
);
1292 * -----------------------------------------------------------------------
1293 * pa_adr_int64hex: Issues pr_adr_int64 to retrieve the next ADR item from the
1294 * input stream pointed to by audit_adr, and prints it
1295 * in hexadecimal if status >= 0
1296 * return codes : -1 - error
1298 * -----------------------------------------------------------------------
1301 pa_adr_int64hex(pr_context_t
*context
, int status
, int flag
)
1308 if ((returnstat
= pr_adr_int64(context
, &l
, 1)) == 0) {
1309 uval
.uvaltype
= PRA_HEX64
;
1311 returnstat
= pa_print(context
, &uval
, flag
);
1313 return (returnstat
);
1320 * -------------------------------------------------------------------
1321 * bu2string: Maps a print basic unit type to a string.
1322 * returns : The string mapping or "unknown basic unit type".
1323 * -------------------------------------------------------------------
1326 bu2string(char basic_unit
)
1337 * These names are data units when displaying the arbitrary data
1341 static struct bu_map_ent bu_map
[] = {
1342 { AUR_BYTE
, "byte" },
1343 { AUR_CHAR
, "char" },
1344 { AUR_SHORT
, "short" },
1345 { AUR_INT32
, "int32" },
1346 { AUR_INT64
, "int64" } };
1348 for (i
= 0; i
< sizeof (bu_map
) / sizeof (struct bu_map_ent
); i
++)
1349 if (basic_unit
== bu_map
[i
].basic_unit
)
1350 return (gettext(bu_map
[i
].string
));
1352 return (gettext("unknown basic unit type"));
1357 * -------------------------------------------------------------------
1358 * eventmodifier2string: Maps event modifier flags to a readable string.
1359 * returns: The string mapping or "none".
1360 * -------------------------------------------------------------------
1363 eventmodifier2string(au_emod_t emodifier
, char *modstring
, size_t modlen
)
1374 * These abbreviations represent the event modifier field of the
1375 * header token. To gain a better understanding of each modifier,
1377 * System Administration Guide: Security Services >> Solaris Auditing
1378 * at http://docs.sun.com.
1381 static struct em_map_ent em_map
[] = {
1382 { (int)PAD_READ
, "rd" }, /* data read from object */
1383 { (int)PAD_WRITE
, "wr" }, /* data written to object */
1384 { (int)PAD_SPRIVUSE
, "sp" }, /* successfully used priv */
1385 { (int)PAD_FPRIVUSE
, "fp" }, /* failed use of priv */
1386 { (int)PAD_NONATTR
, "na" }, /* non-attributable event */
1387 { (int)PAD_FAILURE
, "fe" } /* fail audit event */
1390 modstring
[0] = '\0';
1392 for (i
= 0, j
= 0; i
< sizeof (em_map
) / sizeof (struct em_map_ent
);
1394 if ((int)emodifier
& em_map
[i
].mask
) {
1396 (void) strlcat(modstring
, ":", modlen
);
1397 (void) strlcat(modstring
, em_map
[i
].string
, modlen
);
1404 * ---------------------------------------------------------
1405 * convert_char_to_string:
1406 * Converts a byte to string depending on the print mode
1407 * input : printmode, which may be one of AUP_BINARY,
1408 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1409 * c, which is the byte to convert
1410 * output : p, which is a pointer to the location where
1411 * the resulting string is to be stored
1412 * ----------------------------------------------------------
1416 convert_char_to_string(char printmode
, char c
, char *p
)
1426 if (printmode
== AUP_BINARY
)
1427 (void) convertbinary(p
, &c
, sizeof (char));
1428 else if (printmode
== AUP_OCTAL
)
1429 (void) sprintf(p
, "%o", (int)dat
.c2
);
1430 else if (printmode
== AUP_DECIMAL
)
1431 (void) sprintf(p
, "%d", c
);
1432 else if (printmode
== AUP_HEX
)
1433 (void) sprintf(p
, "0x%x", (int)dat
.c2
);
1434 else if (printmode
== AUP_STRING
)
1435 convertascii(p
, &c
, sizeof (char));
1440 * --------------------------------------------------------------
1441 * convert_short_to_string:
1442 * Converts a short integer to string depending on the print mode
1443 * input : printmode, which may be one of AUP_BINARY,
1444 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1445 * c, which is the short integer to convert
1446 * output : p, which is a pointer to the location where
1447 * the resulting string is to be stored
1448 * ---------------------------------------------------------------
1451 convert_short_to_string(char printmode
, short c
, char *p
)
1461 if (printmode
== AUP_BINARY
)
1462 (void) convertbinary(p
, (char *)&c
, sizeof (short));
1463 else if (printmode
== AUP_OCTAL
)
1464 (void) sprintf(p
, "%o", (int)dat
.c2
);
1465 else if (printmode
== AUP_DECIMAL
)
1466 (void) sprintf(p
, "%hd", c
);
1467 else if (printmode
== AUP_HEX
)
1468 (void) sprintf(p
, "0x%x", (int)dat
.c2
);
1469 else if (printmode
== AUP_STRING
)
1470 convertascii(p
, (char *)&c
, sizeof (short));
1475 * ---------------------------------------------------------
1476 * convert_int32_to_string:
1477 * Converts a integer to string depending on the print mode
1478 * input : printmode, which may be one of AUP_BINARY,
1479 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1480 * c, which is the integer to convert
1481 * output : p, which is a pointer to the location where
1482 * the resulting string is to be stored
1483 * ----------------------------------------------------------
1486 convert_int32_to_string(char printmode
, int32_t c
, char *p
)
1488 if (printmode
== AUP_BINARY
)
1489 (void) convertbinary(p
, (char *)&c
, sizeof (int32_t));
1490 else if (printmode
== AUP_OCTAL
)
1491 (void) sprintf(p
, "%o", c
);
1492 else if (printmode
== AUP_DECIMAL
)
1493 (void) sprintf(p
, "%d", c
);
1494 else if (printmode
== AUP_HEX
)
1495 (void) sprintf(p
, "0x%x", c
);
1496 else if (printmode
== AUP_STRING
)
1497 convertascii(p
, (char *)&c
, sizeof (int));
1502 * ---------------------------------------------------------
1503 * convert_int64_to_string:
1504 * Converts a integer to string depending on the print mode
1505 * input : printmode, which may be one of AUP_BINARY,
1506 * AUP_OCTAL, AUP_DECIMAL, and AUP_HEX
1507 * c, which is the integer to convert
1508 * output : p, which is a pointer to the location where
1509 * the resulting string is to be stored
1510 * ----------------------------------------------------------
1513 convert_int64_to_string(char printmode
, int64_t c
, char *p
)
1515 if (printmode
== AUP_BINARY
)
1516 (void) convertbinary(p
, (char *)&c
, sizeof (int64_t));
1517 else if (printmode
== AUP_OCTAL
)
1518 (void) sprintf(p
, "%"PRIo64
, c
);
1519 else if (printmode
== AUP_DECIMAL
)
1520 (void) sprintf(p
, "%"PRId64
, c
);
1521 else if (printmode
== AUP_HEX
)
1522 (void) sprintf(p
, "0x%"PRIx64
, c
);
1523 else if (printmode
== AUP_STRING
)
1524 convertascii(p
, (char *)&c
, sizeof (int64_t));
1530 * -----------------------------------------------------------
1532 * Converts a unit c of 'size' bytes long into a binary string
1533 * and returns it into the position pointed to by p
1534 * ------------------------------------------------------------
1537 convertbinary(char *p
, char *c
, int size
)
1542 if ((s
= (char *)malloc(8 * size
+ 1)) == NULL
)
1547 /* first convert to binary */
1549 for (i
= 0; i
< size
; i
++) {
1550 for (j
= 0; j
< 8; j
++)
1551 (void) sprintf(t
++, "%d", ((*c
>> (7 - j
)) & (0x01)));
1556 /* now string leading zero's if any */
1558 for (i
= 0; i
< j
; i
++) {
1565 /* now copy the contents of s to p */
1567 for (i
= 0; i
< (8 * size
+ 1); i
++) {
1580 static char hex
[] = "0123456789abcdef";
1582 * -------------------------------------------------------------------
1583 * hexconvert : Converts a string of (size) bytes to hexadecimal, and
1584 * returns the hexadecimal string.
1585 * returns : - NULL if memory cannot be allocated for the string, or
1586 * - pointer to the hexadecimal string if successful
1587 * -------------------------------------------------------------------
1590 hexconvert(char *c
, int size
, int chunk
)
1592 register char *s
, *t
;
1593 register int i
, j
, k
;
1600 if ((s
= (char *)malloc((size
* 5) + 1)) == NULL
)
1603 if (chunk
> size
|| chunk
<= 0)
1606 numchunks
= size
/ chunk
;
1607 leftovers
= size
% chunk
;
1610 for (i
= j
= 0; i
< numchunks
; i
++) {
1616 for (k
= 0; k
< chunk
; k
++) {
1617 *t
++ = hex
[(uint_t
)((uchar_t
)*c
>> 4)];
1618 *t
++ = hex
[(uint_t
)((uchar_t
)*c
& 0xF)];
1627 for (i
= 0; i
< leftovers
; i
++) {
1628 *t
++ = hex
[(uint_t
)((uchar_t
)*c
>> 4)];
1629 *t
++ = hex
[(uint_t
)((uchar_t
)*c
& 0xF)];
1640 * -------------------------------------------------------------------
1641 * htp2string: Maps a print suggestion to a string.
1642 * returns : The string mapping or "unknown print suggestion".
1643 * -------------------------------------------------------------------
1646 htp2string(char print_sugg
)
1650 struct htp_map_ent
{
1657 * These names are data types when displaying the arbitrary data
1661 static struct htp_map_ent htp_map
[] = {
1662 { AUP_BINARY
, "binary" },
1663 { AUP_OCTAL
, "octal" },
1664 { AUP_DECIMAL
, "decimal" },
1665 { AUP_HEX
, "hexadecimal" },
1666 { AUP_STRING
, "string" } };
1668 for (i
= 0; i
< sizeof (htp_map
) / sizeof (struct htp_map_ent
); i
++)
1669 if (print_sugg
== htp_map
[i
].print_sugg
)
1670 return (gettext(htp_map
[i
].print_string
));
1672 return (gettext("unknown print suggestion"));
1676 * ----------------------------------------------------------------------
1677 * pa_adr_short: Issues pr_adr_short to retrieve the next ADR item from the
1678 * input stream pointed to by audit_adr, and prints it
1680 * return codes: -1 - error
1682 * ----------------------------------------------------------------------
1685 pa_adr_short(pr_context_t
*context
, int status
, int flag
)
1691 if (pr_adr_short(context
, &c
, 1) == 0) {
1692 uval
.uvaltype
= PRA_SHORT
;
1694 return (pa_print(context
, &uval
, flag
));
1702 * -----------------------------------------------------------------------
1703 * pa_adr_shorthex: Issues pr_adr_short to retrieve the next ADR item from the
1704 * input stream pointed to by audit_adr, and prints it
1705 * in hexadecimal if status >= 0
1706 * return codes : -1 - error
1708 * -----------------------------------------------------------------------
1711 pa_adr_shorthex(pr_context_t
*context
, int status
, int flag
)
1718 if ((returnstat
= pr_adr_short(context
, &s
, 1)) == 0) {
1719 uval
.uvaltype
= PRA_STRING
;
1720 uval
.string_val
= hexconvert((char *)&s
, sizeof (s
),
1722 if (uval
.string_val
) {
1723 returnstat
= pa_print(context
, &uval
, flag
);
1724 free(uval
.string_val
);
1727 return (returnstat
);
1734 * -----------------------------------------------------------------------
1735 * pa_adr_string: Retrieves a string from the input stream and prints it
1737 * return codes : -1 - error
1739 * -----------------------------------------------------------------------
1742 pa_adr_string(pr_context_t
*context
, int status
, int flag
)
1750 * We need to know how much space to allocate for our string, so
1751 * read the length first, then call pr_adr_char to read those bytes.
1756 if ((returnstat
= pr_adr_short(context
, &length
, 1)) != 0)
1757 return (returnstat
);
1758 if ((c
= (char *)malloc(length
+ 1)) == NULL
)
1760 if ((returnstat
= pr_adr_char(context
, c
, length
)) != 0) {
1762 return (returnstat
);
1765 uval
.uvaltype
= PRA_STRING
;
1766 uval
.string_val
= c
;
1767 returnstat
= pa_print(context
, &uval
, flag
);
1769 return (returnstat
);
1773 * -----------------------------------------------------------------------
1774 * pa_file_string: Retrieves a file string from the input stream and prints it
1776 * return codes : -1 - error
1778 * -----------------------------------------------------------------------
1781 pa_file_string(pr_context_t
*context
, int status
, int flag
)
1790 * We need to know how much space to allocate for our string, so
1791 * read the length first, then call pr_adr_char to read those bytes.
1796 if ((returnstat
= pr_adr_short(context
, &length
, 1)) != 0)
1797 return (returnstat
);
1798 if ((c
= (char *)malloc(length
+ 1)) == NULL
)
1800 if ((p
= (char *)malloc((length
* 4) + 1)) == NULL
) {
1804 if ((returnstat
= pr_adr_char(context
, c
, length
)) != 0) {
1807 return (returnstat
);
1810 if (is_file_token(context
->tokenid
))
1811 context
->audit_rec_len
+= length
;
1813 convertascii(p
, c
, length
- 1);
1814 uval
.uvaltype
= PRA_STRING
;
1815 uval
.string_val
= p
;
1817 if (returnstat
== 0)
1818 returnstat
= finish_open_tag(context
);
1820 if (returnstat
== 0)
1821 returnstat
= pa_print(context
, &uval
, flag
);
1825 return (returnstat
);
1829 pa_putstr_xml(pr_context_t
*context
, int printable
, char *str
, size_t len
)
1835 * Unprintable chars should always be converted to the
1836 * visible form. If there are unprintable characters which
1837 * require special treatment in xml, those should be
1841 err
= pr_printf(context
, "\\%03o",
1842 (unsigned char)*str
++);
1843 } while (err
== 0 && --len
!= 0);
1846 /* printable characters */
1849 * check for the special chars only when char size was 1
1850 * ie, ignore special chars appear in the middle of multibyte
1854 /* Escape for XML */
1857 err
= pr_printf(context
, "%s", "&");
1861 err
= pr_printf(context
, "%s", "<");
1865 err
= pr_printf(context
, "%s", ">");
1869 err
= pr_printf(context
, "%s", """);
1873 err
= pr_printf(context
, "%s", "'");
1877 err
= pr_putchar(context
, *str
);
1883 err
= pr_putchar(context
, *str
++);
1884 } while (err
== 0 && --len
!= 0);
1889 pa_putstr(pr_context_t
*context
, int printable
, char *str
, size_t len
)
1893 if (context
->format
& PRF_XMLM
)
1894 return (pa_putstr_xml(context
, printable
, str
, len
));
1898 err
= pr_printf(context
, "\\%03o",
1899 (unsigned char)*str
++);
1900 } while (err
== 0 && --len
!= 0);
1904 err
= pr_putchar(context
, *str
++);
1905 } while (err
== 0 && --len
!= 0);
1910 pa_string(pr_context_t
*context
, int status
, int flag
)
1913 int i
, printable
, eos
;
1915 int mbmax
= MB_CUR_MAX
;
1917 char mbuf
[MB_LEN_MAX
+ 1];
1926 while (wstat
== 0) {
1927 if ((rstat
= pr_adr_char(context
, &c
, 1)) < 0)
1931 printable
= isprint((unsigned char)c
);
1932 wstat
= pa_putstr(context
, printable
, &c
, 1);
1938 while (wstat
== 0) {
1942 rstat
= pr_adr_char(context
, &c
, 1);
1943 if (rstat
!= 0 || c
== '\0')
1948 rlen
= mbtowc(&wc
, mbuf
, mlen
);
1949 } while (!eos
&& mlen
< mbmax
&& rlen
<= 0);
1952 break; /* end of string */
1954 if (rlen
<= 0) { /* no good sequence */
1958 printable
= iswprint(wc
);
1960 wstat
= pa_putstr(context
, printable
, mbuf
, rlen
);
1963 for (i
= 0; i
< mlen
; i
++)
1964 mbuf
[i
] = mbuf
[rlen
+ i
];
1970 wstat
= do_newline(context
, flag
);
1972 return ((rstat
!= 0 || wstat
!= 0) ? -1 : 0);
1976 * -----------------------------------------------------------------------
1977 * pa_adr_u_int32: Issues pr_adr_u_int32 to retrieve the next ADR item from
1978 * the input stream pointed to by audit_adr, and prints it
1980 * return codes : -1 - error
1982 * -----------------------------------------------------------------------
1987 pa_adr_u_int32(pr_context_t
*context
, int status
, int flag
)
1993 if (pr_adr_u_int32(context
, &c
, 1) == 0) {
1994 uval
.uvaltype
= PRA_UINT32
;
1995 uval
.uint32_val
= c
;
1996 return (pa_print(context
, &uval
, flag
));
2006 * -----------------------------------------------------------------------
2007 * pa_adr_u_int64: Issues pr_adr_u_int64 to retrieve the next ADR item from the
2008 * input stream pointed to by audit_adr, and prints it
2010 * return codes : -1 - error
2012 * -----------------------------------------------------------------------
2015 pa_adr_u_int64(pr_context_t
*context
, int status
, int flag
)
2021 if (pr_adr_u_int64(context
, &c
, 1) == 0) {
2022 uval
.uvaltype
= PRA_UINT64
;
2023 uval
.uint64_val
= c
;
2024 return (pa_print(context
, &uval
, flag
));
2033 * -----------------------------------------------------------------------
2034 * pa_adr_u_short: Issues pr_adr_u_short to retrieve the next ADR item from
2035 * the input stream pointed to by audit_adr, and prints it
2037 * return codes : -1 - error
2039 * -----------------------------------------------------------------------
2042 pa_adr_u_short(pr_context_t
*context
, int status
, int flag
)
2048 if (pr_adr_u_short(context
, &c
, 1) == 0) {
2049 uval
.uvaltype
= PRA_USHORT
;
2050 uval
.ushort_val
= c
;
2051 return (pa_print(context
, &uval
, flag
));
2059 * -----------------------------------------------------------------------
2060 * pa_reclen: Issues pr_adr_u_long to retrieve the length of the record
2061 * from the input stream pointed to by audit_adr,
2062 * and prints it (unless format is XML) if status = 0
2063 * return codes : -1 - error
2065 * -----------------------------------------------------------------------
2068 pa_reclen(pr_context_t
*context
, int status
)
2074 if ((int)pr_adr_u_int32(context
, &c
, 1) == 0) {
2075 context
->audit_rec_len
= c
;
2077 /* Don't print this for XML format */
2078 if (context
->format
& PRF_XMLM
) {
2081 uval
.uvaltype
= PRA_UINT32
;
2082 uval
.uint32_val
= c
;
2083 return (pa_print(context
, &uval
, 0));
2092 * -----------------------------------------------------------------------
2093 * pa_mode : Issues pr_adr_u_short to retrieve the next ADR item from
2094 * the input stream pointed to by audit_adr, and prints it
2095 * in octal if status = 0
2096 * return codes : -1 - error
2098 * -----------------------------------------------------------------------
2101 pa_mode(pr_context_t
*context
, int status
, int flag
)
2107 if (pr_adr_u_int32(context
, &c
, 1) == 0) {
2108 uval
.uvaltype
= PRA_LOCT
;
2109 uval
.uint32_val
= c
;
2110 return (pa_print(context
, &uval
, flag
));
2118 pa_print_uid(pr_context_t
*context
, uid_t uid
, int status
, int flag
)
2126 if (context
->format
& PRF_RAWM
) {
2127 /* print in integer form */
2128 uval
.uvaltype
= PRA_INT32
;
2129 uval
.int32_val
= uid
;
2130 returnstat
= pa_print(context
, &uval
, flag
);
2132 /* print in ASCII form */
2133 uval
.uvaltype
= PRA_STRING
;
2134 uval
.string_val
= getname(uid
);
2135 returnstat
= pa_print(context
, &uval
, flag
);
2137 return (returnstat
);
2142 * -----------------------------------------------------------------------
2143 * pa_pw_uid() : Issues pr_adr_u_int32 to reads uid from input stream
2144 * pointed to by audit_adr, and displays it in either
2145 * raw form or its ASCII representation, if status >= 0.
2146 * return codes : -1 - error
2147 * : 1 - warning, passwd entry not found
2149 * -----------------------------------------------------------------------
2152 pa_pw_uid(pr_context_t
*context
, int status
, int flag
)
2159 if (pr_adr_u_int32(context
, &uid
, 1) != 0)
2160 /* cannot retrieve uid */
2163 return (pa_print_uid(context
, uid
, status
, flag
));
2167 pa_print_gid(pr_context_t
*context
, gid_t gid
, int status
, int flag
)
2175 if (context
->format
& PRF_RAWM
) {
2176 /* print in integer form */
2177 uval
.uvaltype
= PRA_INT32
;
2178 uval
.int32_val
= gid
;
2179 returnstat
= pa_print(context
, &uval
, flag
);
2181 /* print in ASCII form */
2182 uval
.uvaltype
= PRA_STRING
;
2183 uval
.string_val
= getgroup(gid
);
2184 returnstat
= pa_print(context
, &uval
, flag
);
2186 return (returnstat
);
2191 * -----------------------------------------------------------------------
2192 * pa_gr_uid() : Issues pr_adr_u_int32 to reads group uid from input stream
2193 * pointed to by audit_adr, and displays it in either
2194 * raw form or its ASCII representation, if status >= 0.
2195 * return codes : -1 - error
2196 * : 1 - warning, passwd entry not found
2198 * -----------------------------------------------------------------------
2201 pa_gr_uid(pr_context_t
*context
, int status
, int flag
)
2208 if (pr_adr_u_int32(context
, &gid
, 1) != 0)
2209 /* cannot retrieve gid */
2212 return (pa_print_gid(context
, gid
, status
, flag
));
2217 * -----------------------------------------------------------------------
2218 * pa_pw_uid_gr_gid() : Issues pr_adr_u_int32 to reads uid or group uid
2220 * pointed to by audit_adr, and displays it in either
2221 * raw form or its ASCII representation, if status >= 0.
2222 * return codes : -1 - error
2223 * : 1 - warning, passwd entry not found
2225 * -----------------------------------------------------------------------
2228 pa_pw_uid_gr_gid(pr_context_t
*context
, int status
, int flag
)
2237 /* get value of a_type */
2238 if ((returnstat
= pr_adr_u_int32(context
, &value
, 1)) != 0)
2239 return (returnstat
);
2241 if ((returnstat
= open_tag(context
, TAG_ACLTYPE
)) != 0)
2242 return (returnstat
);
2244 uval
.uvaltype
= PRA_UINT32
;
2245 uval
.uint32_val
= value
;
2246 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
2247 return (returnstat
);
2249 if ((returnstat
= close_tag(context
, TAG_ACLTYPE
)) != 0)
2250 return (returnstat
);
2252 if ((returnstat
= open_tag(context
, TAG_ACLVAL
)) != 0)
2253 return (returnstat
);
2256 * The "mask" and "other" strings refer to the class mask
2257 * and other (or world) entries in an ACL.
2258 * The "unrecognized" string refers to an unrecognized ACL
2264 returnstat
= pa_pw_uid(context
, returnstat
, flag
);
2268 returnstat
= pa_gr_uid(context
, returnstat
, flag
);
2271 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2272 if (returnstat
!= 0)
2273 return (returnstat
);
2275 if (!(context
->format
& PRF_RAWM
)) {
2276 uval
.uvaltype
= PRA_STRING
;
2277 uval
.string_val
= gettext("mask");
2278 returnstat
= pa_print(context
, &uval
, flag
);
2280 uval
.uvaltype
= PRA_UINT32
;
2281 uval
.uint32_val
= value
;
2283 pa_print(context
, &uval
, flag
)) != 0) {
2284 return (returnstat
);
2289 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2290 if (returnstat
!= 0)
2291 return (returnstat
);
2293 if (!(context
->format
& PRF_RAWM
)) {
2294 uval
.uvaltype
= PRA_STRING
;
2295 uval
.string_val
= gettext("other");
2296 returnstat
= pa_print(context
, &uval
, flag
);
2298 uval
.uvaltype
= PRA_UINT32
;
2299 uval
.uint32_val
= value
;
2301 pa_print(context
, &uval
, flag
)) != 0) {
2302 return (returnstat
);
2307 returnstat
= pr_adr_u_int32(context
, &value
, 1);
2308 if (returnstat
!= 0)
2309 return (returnstat
);
2311 if (!(context
->format
& PRF_RAWM
)) {
2312 uval
.uvaltype
= PRA_STRING
;
2313 uval
.string_val
= gettext("unrecognized");
2314 returnstat
= pa_print(context
, &uval
, flag
);
2316 uval
.uvaltype
= PRA_UINT32
;
2317 uval
.uint32_val
= value
;
2319 pa_print(context
, &uval
, flag
)) != 0) {
2320 return (returnstat
);
2325 if ((returnstat
= close_tag(context
, TAG_ACLVAL
)) != 0)
2326 return (returnstat
);
2328 return (returnstat
);
2333 * -----------------------------------------------------------------------
2334 * pa_event_modifier(): Issues pr_adr_u_short to retrieve the next ADR item from
2335 * the input stream pointed to by audit_adr. This is the
2336 * event type, and is displayed in hex;
2337 * return codes : -1 - error
2339 * -----------------------------------------------------------------------
2342 pa_event_modifier(pr_context_t
*context
, int status
, int flag
)
2345 au_emod_t emodifier
;
2352 if ((returnstat
= pr_adr_u_short(context
, &emodifier
, 1)) != 0)
2353 return (returnstat
);
2355 /* For XML, only print when modifier is non-zero */
2356 if (!(context
->format
& PRF_XMLM
) || (emodifier
!= 0)) {
2357 uval
.uvaltype
= PRA_STRING
;
2359 returnstat
= open_tag(context
, TAG_EVMOD
);
2361 if (returnstat
>= 0) {
2362 if (!(context
->format
& PRF_RAWM
)) {
2363 eventmodifier2string(emodifier
, modstring
,
2364 sizeof (modstring
));
2365 uval
.string_val
= modstring
;
2366 returnstat
= pa_print(context
, &uval
, flag
);
2368 uval
.string_val
= hexconvert((char *)&emodifier
,
2369 sizeof (emodifier
), sizeof (emodifier
));
2370 if (uval
.string_val
) {
2371 returnstat
= pa_print(context
, &uval
,
2373 free(uval
.string_val
);
2377 if (returnstat
>= 0)
2378 returnstat
= close_tag(context
, TAG_EVMOD
);
2381 return (returnstat
);
2386 * -----------------------------------------------------------------------
2387 * pa_event_type(): Issues pr_adr_u_short to retrieve the next ADR item from
2388 * the input stream pointed to by audit_adr. This is the
2389 * event type, and is displayed in either raw or
2390 * ASCII form as appropriate
2391 * return codes : -1 - error
2393 * -----------------------------------------------------------------------
2396 pa_event_type(pr_context_t
*context
, int status
, int flag
)
2400 au_event_ent_t
*p_event
= NULL
;
2404 if ((returnstat
= pr_adr_u_short(context
, &etype
, 1)) == 0) {
2405 if (!(context
->format
& PRF_RAWM
)) {
2406 uval
.uvaltype
= PRA_STRING
;
2407 if (context
->format
& PRF_NOCACHE
) {
2408 p_event
= getauevnum(etype
);
2410 (void) cacheauevent(&p_event
, etype
);
2412 if (p_event
!= NULL
) {
2413 if (context
->format
& PRF_SHORTM
)
2421 gettext("invalid event number");
2423 returnstat
= pa_print(context
, &uval
, flag
);
2425 uval
.uvaltype
= PRA_USHORT
;
2426 uval
.ushort_val
= etype
;
2427 returnstat
= pa_print(context
, &uval
, flag
);
2430 return (returnstat
);
2438 * Print time from struct timeval to millisecond resolution.
2440 * typedef long time_t; time of day in seconds
2441 * typedef long useconds_t; signed # of microseconds
2444 * time_t tv_sec; seconds
2445 * suseconds_t tv_usec; and microseconds
2450 pa_utime32(pr_context_t
*context
, int status
, int flag
)
2452 uint32_t scale
= 1000; /* usec to msec */
2454 return (do_mtime32(context
, status
, flag
, scale
));
2458 * Print time from timestruc_t to millisecond resolution.
2460 * typedef struct timespec timestruct_t;
2462 * time_t tv_sec; seconds
2463 * long tv_nsec; and nanoseconds
2467 pa_ntime32(pr_context_t
*context
, int status
, int flag
)
2469 uint32_t scale
= 1000000; /* nsec to msec */
2471 return (do_mtime32(context
, status
, flag
, scale
));
2475 * Format the timezone +/- HH:MM and terminate the string
2476 * Note tm and tv_sec are the same time.
2477 * Too bad strftime won't produce an ISO 8601 time zone numeric
2480 #define MINS (24L * 60)
2482 tzone(struct tm
*tm
, time_t *tv_sec
, char *p
)
2487 gmt
= gmtime(tv_sec
);
2489 min_off
= ((tm
->tm_hour
- gmt
->tm_hour
) * 60) +
2490 (tm
->tm_min
- gmt
->tm_min
);
2492 if (tm
->tm_year
< gmt
->tm_year
) /* cross new year */
2494 else if (tm
->tm_year
> gmt
->tm_year
)
2496 else if (tm
->tm_yday
< gmt
->tm_yday
) /* cross dateline */
2498 else if (tm
->tm_yday
> gmt
->tm_yday
)
2508 *p
++ = min_off
/ 600 + '0'; /* 10s of hours */
2509 min_off
= min_off
- min_off
/ 600 * 600;
2510 *p
++ = min_off
/ 60 % 10 + '0'; /* hours */
2511 min_off
= min_off
- min_off
/ 60 * 60;
2513 *p
++ = min_off
/ 10 + '0'; /* 10s of minutes */
2514 *p
++ = min_off
% 10 + '0'; /* minutes */
2519 * Format the milliseconds in place in the string.
2520 * Borrowed from strftime.c:itoa()
2523 msec32(uint32_t msec
, char *p
)
2525 *p
++ = msec
/ 100 + '0';
2526 msec
= msec
- msec
/ 100 * 100;
2527 *p
++ = msec
/ 10 + '0';
2528 *p
++ = msec
% 10 +'0';
2532 * Format time and print relative to scale factor from micro/nano seconds.
2535 do_mtime32(pr_context_t
*context
, int status
, int flag
, uint32_t scale
)
2540 char time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2547 if ((returnstat
= open_tag(context
, TAG_ISO
)) != 0)
2548 return (returnstat
);
2550 if ((returnstat
= pr_adr_u_int32(context
,
2551 (uint32_t *)&tv_sec
, 1)) != 0)
2552 return (returnstat
);
2553 if ((returnstat
= pr_adr_u_int32(context
, &t32
, 1)) == 0) {
2554 if (!(context
->format
& PRF_RAWM
)) {
2555 (void) localtime_r(&tv_sec
, &tm
);
2556 (void) strftime(time_created
,
2557 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2558 "%Y-%m-%d %H:%M:%S.xxx ", &tm
);
2560 &time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2563 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2564 uval
.uvaltype
= PRA_STRING
;
2565 uval
.string_val
= time_created
;
2567 uval
.uvaltype
= PRA_UINT32
;
2568 uval
.uint32_val
= (uint32_t)tv_sec
;
2569 (void) pa_print(context
, &uval
, 0);
2570 if (context
->format
& PRF_XMLM
) {
2571 uval
.uvaltype
= PRA_CHAR
;
2572 uval
.char_val
= '.';
2573 (void) pa_print(context
, &uval
, 0);
2575 uval
.uvaltype
= PRA_UINT32
;
2576 uval
.uint32_val
= t32
;
2578 returnstat
= pa_print(context
, &uval
, flag
);
2581 if (returnstat
== 0)
2582 return (close_tag(context
, TAG_ISO
));
2584 return (returnstat
);
2588 * Print time from struct timeval to millisecond resolution.
2590 * typedef long time_t; time of day in seconds
2591 * typedef long useconds_t; signed # of microseconds
2594 * time_t tv_sec; seconds
2595 * suseconds_t tv_usec; and microseconds
2600 pa_utime64(pr_context_t
*context
, int status
, int flag
)
2602 uint64_t scale
= 1000; /* usec to msec */
2604 return (do_mtime64(context
, status
, flag
, scale
));
2608 * Print time from timestruc_t to millisecond resolution.
2610 * typedef struct timespec timestruct_t;
2612 * time_t tv_sec; seconds
2613 * long tv_nsec; and nanoseconds
2617 pa_ntime64(pr_context_t
*context
, int status
, int flag
)
2619 uint64_t scale
= 1000000; /* nsec to msec */
2621 return (do_mtime64(context
, status
, flag
, scale
));
2625 * Format the milliseconds in place in the string.
2626 * Borrowed from strftime.c:itoa()
2629 msec64(uint64_t msec
, char *p
)
2631 *p
++ = msec
/ 100 + '0';
2632 msec
= msec
- msec
/ 100 * 100;
2633 *p
++ = msec
/ 10 + '0';
2634 *p
++ = msec
% 10 +'0';
2638 * Format time and print relative to scale factor from micro/nano seconds.
2641 do_mtime64(pr_context_t
*context
, int status
, int flag
, uint64_t scale
)
2647 char time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.sss -HH:MM")];
2654 if ((returnstat
= open_tag(context
, TAG_ISO
)) != 0)
2655 return (returnstat
);
2657 if ((returnstat
= pr_adr_u_int64(context
, &t64_sec
, 1)) != 0)
2658 return (returnstat
);
2659 if ((returnstat
= pr_adr_u_int64(context
, &t64_msec
, 1)) == 0) {
2660 if (!(context
->format
& PRF_RAWM
)) {
2664 * This fails for years from 2038
2665 * The Y2K+38 problem
2668 tv_sec
= (time_t)t64_sec
;
2669 (void) localtime_r(&tv_sec
, &tm
);
2670 (void) strftime(time_created
,
2671 sizeof ("YYYY-MM-DD HH:MM:SS.xxx "),
2672 "%Y-%m-%d %H:%M:%S.xxx ", &tm
);
2673 msec64(t64_msec
/scale
,
2674 &time_created
[sizeof ("YYYY-MM-DD HH:MM:SS.")-1]);
2677 sizeof ("YYYY-MM-DD HH:MM:SS.xxx ")-1]);
2678 uval
.uvaltype
= PRA_STRING
;
2679 uval
.string_val
= time_created
;
2681 uval
.uvaltype
= PRA_UINT64
;
2682 uval
.uint64_val
= t64_sec
;
2683 (void) pa_print(context
, &uval
, 0);
2684 if (context
->format
& PRF_XMLM
) {
2685 uval
.uvaltype
= PRA_CHAR
;
2686 uval
.char_val
= '.';
2687 (void) pa_print(context
, &uval
, 0);
2689 uval
.uvaltype
= PRA_UINT64
;
2690 uval
.uint64_val
= t64_msec
;
2692 returnstat
= pa_print(context
, &uval
, flag
);
2696 return (returnstat
);
2698 return (close_tag(context
, TAG_ISO
));
2702 * -----------------------------------------------------------------------
2703 * pa_error() : convert the return token error code.
2705 * output : buf string representing return token error code.
2707 * -----------------------------------------------------------------------
2710 pa_error(const uchar_t err
, char *buf
, size_t buflen
)
2712 if (err
== ADT_SUCCESS
) {
2713 (void) strlcpy(buf
, gettext("success"), buflen
);
2714 } else if ((char)err
== ADT_FAILURE
) {
2715 (void) strlcpy(buf
, gettext("failure"), buflen
);
2717 char *emsg
= strerror(err
);
2720 (void) strlcpy(buf
, gettext("failure: "), buflen
);
2721 (void) strlcat(buf
, emsg
, buflen
);
2723 (void) snprintf(buf
, buflen
, "%s%d",
2724 gettext("failure: "), err
);
2730 * -----------------------------------------------------------------------
2731 * pa_retval() : convert the return token return value code.
2733 * input : err, for kernel success 0, or
2734 * failure errno: 0 > & < sys_nerr.
2735 * for userland success ADT_SUCCESS (0) or
2736 * failure ADT_FAILURE (-1).
2737 * pa_error() above has already converted err.
2739 * : retval, for kernel arbitrary return value for success, or
2742 * >= ADT_FAIL_VALUE < ADT_FAIL_PAM, an adt message code;
2743 * >= ADT_FAIL_PAM, a pam_strerror value;
2744 * < ADT_FAIL_VALUE, supposed to be an errno.
2746 * output : buf string representing return token error code.
2748 * -----------------------------------------------------------------------
2751 pa_retval(const uchar_t err
, const int32_t retval
, char *buf
, size_t buflen
)
2753 struct msg_text
*msglist
;
2756 /* success or kernel failure */
2757 if (((char)err
== ADT_SUCCESS
) ||
2760 (void) snprintf(buf
, buflen
, "%d", retval
);
2764 /* userland failure */
2765 msglist
= &adt_msg_text
[ADT_LIST_FAIL_VALUE
];
2767 if ((retval
+ msglist
->ml_offset
>= msglist
->ml_min_index
) &&
2768 (retval
+ msglist
->ml_offset
<= msglist
->ml_max_index
)) {
2771 gettext(msglist
->ml_msg_list
[retval
+ msglist
->ml_offset
]),
2773 } else if ((retval
>= ADT_FAIL_PAM
) &&
2774 (retval
< ADT_FAIL_PAM
+ PAM_TOTAL_ERRNUM
)) {
2776 (void) strlcpy(buf
, pam_strerror(NULL
, retval
- ADT_FAIL_PAM
),
2778 } else if ((emsg
= strerror(retval
)) != NULL
) {
2780 (void) strlcpy(buf
, emsg
, buflen
);
2783 (void) snprintf(buf
, buflen
, "%d", retval
);
2788 * -----------------------------------------------------------------------
2789 * pa_printstr() : print a given string, translating unprintables
2793 pa_printstr(pr_context_t
*context
, char *str
)
2797 int mbmax
= MB_CUR_MAX
;
2803 while (err
== 0 && *str
!= '\0') {
2805 printable
= isprint((unsigned char)c
);
2806 err
= pa_putstr(context
, printable
, &c
, 1);
2810 while (err
== 0 && *str
!= '\0') {
2811 len
= mbtowc(&wc
, str
, mbmax
);
2816 printable
= iswprint(wc
);
2818 err
= pa_putstr(context
, printable
, str
, len
);
2825 * -----------------------------------------------------------------------
2826 * pa_print() : print as one str or formatted for easy reading.
2827 * : flag - indicates whether to output a new line for
2828 * : multi-line output.
2829 * : = 0; no new line
2830 * : = 1; new line if regular output
2831 * output : The audit record information is displayed in the
2832 * type specified by uvaltype and value specified in
2833 * uval. The printing of the delimiter or newline is
2834 * determined by PRF_ONELINE, and the flag value,
2836 * +--------+------+------+-----------------+
2837 * |ONELINE | flag | last | Action |
2838 * +--------+------+------+-----------------+
2839 * | Y | Y | T | print new line |
2840 * | Y | Y | F | print delimiter |
2841 * | Y | N | T | print new line |
2842 * | Y | N | F | print delimiter |
2843 * | N | Y | T | print new line |
2844 * | N | Y | F | print new line |
2845 * | N | N | T | print new line |
2846 * | N | N | F | print delimiter |
2847 * +--------+------+------+-----------------+
2849 * return codes : -1 - error
2851 * -----------------------------------------------------------------------
2854 pa_print(pr_context_t
*context
, uval_t
*uval
, int flag
)
2859 switch (uval
->uvaltype
) {
2861 returnstat
= pr_printf(context
, "%d", uval
->int32_val
);
2864 returnstat
= pr_printf(context
, "%u", uval
->uint32_val
);
2867 returnstat
= pr_printf(context
, "%"PRId64
, uval
->int64_val
);
2870 returnstat
= pr_printf(context
, "%"PRIu64
, uval
->uint64_val
);
2873 returnstat
= pr_printf(context
, "%hd", uval
->short_val
);
2876 returnstat
= pr_printf(context
, "%hu", uval
->ushort_val
);
2879 returnstat
= pr_printf(context
, "%c", uval
->char_val
);
2882 returnstat
= pr_printf(context
, "%d", uval
->char_val
);
2885 returnstat
= pa_printstr(context
, uval
->string_val
);
2888 returnstat
= pr_printf(context
, "0x%x", uval
->int32_val
);
2891 returnstat
= pr_printf(context
, "0x%"PRIx64
, uval
->int64_val
);
2894 returnstat
= pr_printf(context
, "0x%hx", uval
->short_val
);
2897 returnstat
= pr_printf(context
, "%ho", uval
->ushort_val
);
2900 returnstat
= pr_printf(context
, "%o", (int)uval
->uint32_val
);
2903 (void) fprintf(stderr
, gettext("praudit: Unknown type.\n"));
2908 return (returnstat
);
2910 last
= (context
->audit_adr
->adr_now
==
2911 (context
->audit_rec_start
+ context
->audit_rec_len
));
2913 if (!(context
->format
& PRF_XMLM
)) {
2914 if (!(context
->format
& PRF_ONELINE
)) {
2915 if ((flag
== 1) || last
)
2916 returnstat
= pr_putchar(context
, '\n');
2918 returnstat
= pr_printf(context
, "%s",
2919 context
->SEPARATOR
);
2922 returnstat
= pr_printf(context
, "%s",
2923 context
->SEPARATOR
);
2925 returnstat
= pr_putchar(context
, '\n');
2928 return (returnstat
);
2931 static struct cntrl_mapping
{
2945 static int cntrl_map_entries
= sizeof (cntrl_map
)
2946 / sizeof (struct cntrl_mapping
);
2949 * Convert binary data to ASCII for printing.
2952 convertascii(char *p
, char *c
, int size
)
2956 for (i
= 0; i
< size
; i
++) {
2957 uc
= (unsigned char)*(c
+ i
);
2960 for (j
= 0; j
< cntrl_map_entries
; j
++) {
2961 if (cntrl_map
[j
].from
== uc
) {
2963 *p
++ = cntrl_map
[j
].to
;
2967 if (j
== cntrl_map_entries
) {
2969 *p
++ = (char)(uc
^ 0100);
2975 p
+= sprintf(p
, "\\%03o", uc
);
2982 * -----------------------------------------------------------------------
2983 * pa_xgeneric: Process Xobject token and display contents
2984 * This routine will handle many of the attribute
2985 * types introduced in TS 2.x, such as:
2987 * AUT_XCOLORMAP, AUT_XCURSOR, AUT_XFONT,
2988 * AUT_XGC, AUT_XPIXMAP, AUT_XWINDOW
2990 * NOTE: At the time of call, the token id has been retrieved
2992 * return codes : -1 - error
2994 * NOTE: At the time of call, the xatom token id has been retrieved
2997 * text token id adr_char
2999 * creator uid adr_pw_uid
3000 * -----------------------------------------------------------------------
3003 pa_xgeneric(pr_context_t
*context
)
3007 returnstat
= process_tag(context
, TAG_XID
, 0, 0);
3008 return (process_tag(context
, TAG_XCUID
, returnstat
, 1));
3013 * ------------------------------------------------------------------------
3014 * pa_liaison : Issues pr_adr_char to retrieve the next ADR item from the
3015 * input stream pointed to by audit_adr, and prints it
3016 * if status >= 0 either in ASCII or raw form
3017 * return codes : -1 - error
3019 * : 1 - warning, unknown label type
3020 * -----------------------------------------------------------------------
3023 pa_liaison(pr_context_t
*context
, int status
, int flag
)
3030 if ((returnstat
= pr_adr_int32(context
, &li
, 1)) != 0) {
3031 return (returnstat
);
3033 if (!(context
->format
& PRF_RAWM
)) {
3034 uval
.uvaltype
= PRA_UINT32
;
3035 uval
.uint32_val
= li
;
3036 returnstat
= pa_print(context
, &uval
, flag
);
3038 /* print in hexadecimal form */
3039 if ((context
->format
& PRF_RAWM
) || (returnstat
== 1)) {
3040 uval
.uvaltype
= PRA_HEX32
;
3041 uval
.uint32_val
= li
;
3042 returnstat
= pa_print(context
, &uval
, flag
);
3044 return (returnstat
);
3050 * ------------------------------------------------------------------------
3051 * pa_xid : Issues pr_adr_int32 to retrieve the XID from the input
3052 * stream pointed to by audit_adr, and prints it if
3053 * status >= 0 either in ASCII or raw form
3054 * return codes : -1 - error
3056 * : 1 - warning, unknown label type
3057 * ------------------------------------------------------------------------
3061 pa_xid(pr_context_t
*context
, int status
, int flag
)
3070 /* get XID from stream */
3071 if ((returnstat
= pr_adr_int32(context
, (int32_t *)&xid
, 1)) != 0)
3072 return (returnstat
);
3074 if (!(context
->format
& PRF_RAWM
)) {
3075 uval
.uvaltype
= PRA_STRING
;
3076 uval
.string_val
= hexconvert((char *)&xid
, sizeof (xid
),
3078 if (uval
.string_val
) {
3079 returnstat
= pa_print(context
, &uval
, flag
);
3080 free(uval
.string_val
);
3083 uval
.uvaltype
= PRA_INT32
;
3084 uval
.int32_val
= xid
;
3085 returnstat
= pa_print(context
, &uval
, flag
);
3088 return (returnstat
);
3092 pa_ace_flags(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3102 * ace->a_flags refers to access flags of ZFS/NFSv4 ACL entry.
3104 if ((returnstat
= open_tag(context
, TAG_ACEFLAGS
)) != 0)
3105 return (returnstat
);
3106 if (!(context
->format
& PRF_RAWM
)) {
3107 uval
.uvaltype
= PRA_STRING
;
3108 switch (ace
->a_flags
& ACE_TYPE_FLAGS
) {
3110 uval
.string_val
= gettext(OWNERAT_TXT
);
3112 case ACE_GROUP
| ACE_IDENTIFIER_GROUP
:
3113 uval
.string_val
= gettext(GROUPAT_TXT
);
3115 case ACE_IDENTIFIER_GROUP
:
3116 uval
.string_val
= gettext(GROUP_TXT
);
3119 uval
.string_val
= gettext(EVERYONEAT_TXT
);
3122 uval
.string_val
= gettext(USER_TXT
);
3125 uval
.uvaltype
= PRA_USHORT
;
3126 uval
.uint32_val
= ace
->a_flags
;
3129 uval
.uvaltype
= PRA_USHORT
;
3130 uval
.uint32_val
= ace
->a_flags
;
3132 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
3133 return (returnstat
);
3134 return (close_tag(context
, TAG_ACEFLAGS
));
3138 pa_ace_who(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3147 * ace->a_who refers to user id or group id of ZFS/NFSv4 ACL entry.
3149 if ((returnstat
= open_tag(context
, TAG_ACEID
)) != 0)
3150 return (returnstat
);
3151 switch (ace
->a_flags
& ACE_TYPE_FLAGS
) {
3152 case ACE_IDENTIFIER_GROUP
: /* group id */
3153 returnstat
= pa_print_gid(context
, ace
->a_who
, returnstat
,
3156 default: /* user id */
3157 returnstat
= pa_print_uid(context
, ace
->a_who
, returnstat
,
3162 return (returnstat
);
3163 return (close_tag(context
, TAG_ACEID
));
3167 * Appends what to str, (re)allocating str if necessary.
3169 #define INITIAL_ALLOC 256
3171 strappend(char **str
, char *what
, size_t *alloc
)
3179 s
= malloc(INITIAL_ALLOC
);
3184 *alloc
= INITIAL_ALLOC
;
3189 needed
= strlen(s
) + strlen(what
) + 1;
3190 if (*alloc
< needed
) {
3191 newstr
= realloc(s
, needed
);
3198 (void) strlcat(s
, what
, *alloc
);
3204 pa_ace_access_mask(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3208 char *permstr
= NULL
;
3209 size_t permstr_alloc
= 0;
3216 * ace->a_access_mask refers to access mask of ZFS/NFSv4 ACL entry.
3218 if ((returnstat
= open_tag(context
, TAG_ACEMASK
)) != 0)
3219 return (returnstat
);
3220 if (context
->format
& PRF_SHORTM
&&
3221 ((permstr
= malloc(15)) != NULL
)) {
3222 for (i
= 0; i
< 14; i
++)
3225 if (ace
->a_access_mask
& ACE_READ_DATA
)
3227 if (ace
->a_access_mask
& ACE_WRITE_DATA
)
3229 if (ace
->a_access_mask
& ACE_EXECUTE
)
3231 if (ace
->a_access_mask
& ACE_APPEND_DATA
)
3233 if (ace
->a_access_mask
& ACE_DELETE
)
3235 if (ace
->a_access_mask
& ACE_DELETE_CHILD
)
3237 if (ace
->a_access_mask
& ACE_READ_ATTRIBUTES
)
3239 if (ace
->a_access_mask
& ACE_WRITE_ATTRIBUTES
)
3241 if (ace
->a_access_mask
& ACE_READ_NAMED_ATTRS
)
3243 if (ace
->a_access_mask
& ACE_WRITE_NAMED_ATTRS
)
3245 if (ace
->a_access_mask
& ACE_READ_ACL
)
3247 if (ace
->a_access_mask
& ACE_WRITE_ACL
)
3249 if (ace
->a_access_mask
& ACE_WRITE_OWNER
)
3251 if (ace
->a_access_mask
& ACE_SYNCHRONIZE
)
3254 uval
.uvaltype
= PRA_STRING
;
3255 uval
.string_val
= permstr
;
3256 } else if (!(context
->format
& PRF_RAWM
)) {
3259 * Note this differs from acltext.c:ace_perm_txt()
3260 * because we don't know if the acl belongs to a file
3261 * or directory. ace mask value are the same
3262 * nonetheless, see sys/acl.h
3264 if (ace
->a_access_mask
& ACE_LIST_DIRECTORY
) {
3265 returnstat
= strappend(&permstr
, gettext(READ_DIR_TXT
),
3268 if (ace
->a_access_mask
& ACE_ADD_FILE
) {
3269 returnstat
= strappend(&permstr
, gettext(ADD_FILE_TXT
),
3272 if (ace
->a_access_mask
& ACE_ADD_SUBDIRECTORY
) {
3273 returnstat
= strappend(&permstr
, gettext(ADD_DIR_TXT
),
3276 if (ace
->a_access_mask
& ACE_READ_NAMED_ATTRS
) {
3277 returnstat
= strappend(&permstr
,
3278 gettext(READ_XATTR_TXT
), &permstr_alloc
);
3280 if (ace
->a_access_mask
& ACE_WRITE_NAMED_ATTRS
) {
3281 returnstat
= strappend(&permstr
,
3282 gettext(WRITE_XATTR_TXT
), &permstr_alloc
);
3284 if (ace
->a_access_mask
& ACE_EXECUTE
) {
3285 returnstat
= strappend(&permstr
,
3286 gettext(EXECUTE_TXT
), &permstr_alloc
);
3288 if (ace
->a_access_mask
& ACE_DELETE_CHILD
) {
3289 returnstat
= strappend(&permstr
,
3290 gettext(DELETE_CHILD_TXT
), &permstr_alloc
);
3292 if (ace
->a_access_mask
& ACE_READ_ATTRIBUTES
) {
3293 returnstat
= strappend(&permstr
,
3294 gettext(READ_ATTRIBUTES_TXT
), &permstr_alloc
);
3296 if (ace
->a_access_mask
& ACE_WRITE_ATTRIBUTES
) {
3297 returnstat
= strappend(&permstr
,
3298 gettext(WRITE_ATTRIBUTES_TXT
), &permstr_alloc
);
3300 if (ace
->a_access_mask
& ACE_DELETE
) {
3301 returnstat
= strappend(&permstr
, gettext(DELETE_TXT
),
3304 if (ace
->a_access_mask
& ACE_READ_ACL
) {
3305 returnstat
= strappend(&permstr
, gettext(READ_ACL_TXT
),
3308 if (ace
->a_access_mask
& ACE_WRITE_ACL
) {
3309 returnstat
= strappend(&permstr
, gettext(WRITE_ACL_TXT
),
3312 if (ace
->a_access_mask
& ACE_WRITE_OWNER
) {
3313 returnstat
= strappend(&permstr
,
3314 gettext(WRITE_OWNER_TXT
), &permstr_alloc
);
3316 if (ace
->a_access_mask
& ACE_SYNCHRONIZE
) {
3317 returnstat
= strappend(&permstr
,
3318 gettext(SYNCHRONIZE_TXT
), &permstr_alloc
);
3320 if (permstr
[strlen(permstr
) - 1] == '/')
3321 permstr
[strlen(permstr
) - 1] = '\0';
3322 uval
.uvaltype
= PRA_STRING
;
3323 uval
.string_val
= permstr
;
3325 if ((permstr
== NULL
) || (returnstat
!= 0) ||
3326 (context
->format
& PRF_RAWM
)) {
3327 uval
.uvaltype
= PRA_UINT32
;
3328 uval
.uint32_val
= ace
->a_access_mask
;
3330 returnstat
= pa_print(context
, &uval
, flag
);
3333 if (returnstat
!= 0)
3334 return (returnstat
);
3335 return (close_tag(context
, TAG_ACEMASK
));
3339 pa_ace_type(pr_context_t
*context
, ace_t
*ace
, int status
, int flag
)
3349 * ace->a_type refers to access type of ZFS/NFSv4 ACL entry.
3351 if ((returnstat
= open_tag(context
, TAG_ACETYPE
)) != 0)
3352 return (returnstat
);
3353 if (!(context
->format
& PRF_RAWM
)) {
3354 uval
.uvaltype
= PRA_STRING
;
3355 switch (ace
->a_type
) {
3356 case ACE_ACCESS_ALLOWED_ACE_TYPE
:
3357 uval
.string_val
= gettext(ALLOW_TXT
);
3359 case ACE_ACCESS_DENIED_ACE_TYPE
:
3360 uval
.string_val
= gettext(DENY_TXT
);
3362 case ACE_SYSTEM_AUDIT_ACE_TYPE
:
3363 uval
.string_val
= gettext(AUDIT_TXT
);
3365 case ACE_SYSTEM_ALARM_ACE_TYPE
:
3366 uval
.string_val
= gettext(ALARM_TXT
);
3369 uval
.string_val
= gettext(UNKNOWN_TXT
);
3372 uval
.uvaltype
= PRA_USHORT
;
3373 uval
.uint32_val
= ace
->a_type
;
3375 if ((returnstat
= pa_print(context
, &uval
, flag
)) != 0)
3376 return (returnstat
);
3377 return (close_tag(context
, TAG_ACETYPE
));
3381 pa_ace(pr_context_t
*context
, int status
, int flag
)
3389 if ((returnstat
= pr_adr_u_int32(context
, &ace
.a_who
, 1)) != 0)
3390 return (returnstat
);
3391 if ((returnstat
= pr_adr_u_int32(context
, &ace
.a_access_mask
, 1)) != 0)
3392 return (returnstat
);
3393 if ((returnstat
= pr_adr_u_short(context
, &ace
.a_flags
, 1)) != 0)
3394 return (returnstat
);
3395 if ((returnstat
= pr_adr_u_short(context
, &ace
.a_type
, 1)) != 0)
3396 return (returnstat
);
3398 if ((returnstat
= pa_ace_flags(context
, &ace
, returnstat
, 0)) != 0)
3399 return (returnstat
);
3400 /* pa_ace_who can returns 1 if uid/gid is not found */
3401 if ((returnstat
= pa_ace_who(context
, &ace
, returnstat
, 0)) < 0)
3402 return (returnstat
);
3403 if ((returnstat
= pa_ace_access_mask(context
, &ace
,
3404 returnstat
, 0)) != 0)
3405 return (returnstat
);
3406 return (pa_ace_type(context
, &ace
, returnstat
, flag
));