1 /*- 2 * Copyright (c) 2007-2008 Robert N. M. Watson 3 * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #include <sys/param.h> 31 #include <sys/sysctl.h> 32 #include <sys/user.h> 33 34 #include <err.h> 35 #include <libprocstat.h> 36 #include <stdlib.h> 37 #include <stdio.h> 38 #include <unistd.h> 39 40 #include "procstat.h" 41 42 static const char *get_umask(struct procstat *procstat, 43 struct kinfo_proc *kipp); 44 45 void 46 procstat_cred(struct procstat *procstat, struct kinfo_proc *kipp) 47 { 48 unsigned int i, ngroups; 49 gid_t *groups; 50 51 if (!hflag) 52 xo_emit("{T:/%5s %-16s %5s %5s %5s %5s %5s %5s %5s %5s %-15s}\n", 53 "PID", "COMM", "EUID", "RUID", "SVUID", "EGID", "RGID", 54 "SVGID", "UMASK", "FLAGS", "GROUPS"); 55 56 xo_emit("{k:process_id/%5d/%d} ", kipp->ki_pid); 57 xo_emit("{:command/%-16s/%s} ", kipp->ki_comm); 58 xo_emit("{:uid/%5d} ", kipp->ki_uid); 59 xo_emit("{:ruid/%5d} ", kipp->ki_ruid); 60 xo_emit("{:svuid/%5d} ", kipp->ki_svuid); 61 xo_emit("{:group/%5d} ", kipp->ki_groups[0]); 62 xo_emit("{:rgid/%5d} ", kipp->ki_rgid); 63 xo_emit("{:svgid/%5d} ", kipp->ki_svgid); 64 xo_emit("{:umask/%5s} ", get_umask(procstat, kipp)); 65 xo_emit("{:cr_flags/%s}", kipp->ki_cr_flags & CRED_FLAG_CAPMODE ? 66 "C" : "-"); 67 xo_emit("{P: }"); 68 69 groups = NULL; 70 /* 71 * We may have too many groups to fit in kinfo_proc's statically 72 * sized storage. If that occurs, attempt to retrieve them using 73 * libprocstat. 74 */ 75 if (kipp->ki_cr_flags & KI_CRF_GRP_OVERFLOW) 76 groups = procstat_getgroups(procstat, kipp, &ngroups); 77 if (groups == NULL) { 78 ngroups = kipp->ki_ngroups; 79 groups = kipp->ki_groups; 80 } 81 xo_open_list("groups"); 82 for (i = 0; i < ngroups; i++) 83 xo_emit("{D:/%s}{l:groups/%d}", (i > 0) ? "," : "", groups[i]); 84 if (groups != kipp->ki_groups) 85 procstat_freegroups(procstat, groups); 86 87 xo_close_list("groups"); 88 xo_emit("\n"); 89 } 90 91 static const char * 92 get_umask(struct procstat *procstat, struct kinfo_proc *kipp) 93 { 94 u_short fd_cmask; 95 static char umask[4]; 96 97 if (procstat_getumask(procstat, kipp, &fd_cmask) == 0) { 98 snprintf(umask, 4, "%03o", fd_cmask); 99 return (umask); 100 } else { 101 return ("-"); 102 } 103 } 104