summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/ptools/pfiles/pfiles.c79
-rw-r--r--usr/src/lib/libproc/common/libproc.h2
-rw-r--r--usr/src/lib/libproc/common/mapfile-vers1
-rw-r--r--usr/src/lib/libproc/common/pr_getsockname.c60
4 files changed, 130 insertions, 12 deletions
diff --git a/usr/src/cmd/ptools/pfiles/pfiles.c b/usr/src/cmd/ptools/pfiles/pfiles.c
index b41ea95f85..cd5ee360d8 100644
--- a/usr/src/cmd/ptools/pfiles/pfiles.c
+++ b/usr/src/cmd/ptools/pfiles/pfiles.c
@@ -44,6 +44,8 @@
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
+#include <ucred.h>
+#include <zone.h>
#define copyflock(dst, src) \
(dst).l_type = (src).l_type; \
@@ -61,6 +63,7 @@ static boolean_t nflag = B_FALSE;
static void intr(int);
static void dofcntl(struct ps_prochandle *, int, int, int);
static void dosocket(struct ps_prochandle *, int);
+static void dofifo(struct ps_prochandle *, int);
static void dotli(struct ps_prochandle *, int);
static void show_files(struct ps_prochandle *);
static void show_fileflags(int);
@@ -301,6 +304,8 @@ show_files(struct ps_prochandle *Pr)
if ((statb.st_mode & S_IFMT) == S_IFSOCK)
dosocket(Pr, fd);
+ else if ((statb.st_mode & S_IFMT) == S_IFIFO)
+ dofifo(Pr, fd);
(void) sprintf(pname, "/proc/%d/path/%d", (int)pid, fd);
@@ -470,25 +475,29 @@ show_fileflags(int flags)
(void) printf("%s", str);
}
+/* show process on the other end of a door, socket or fifo */
+static void
+show_peer_process(pid_t ppid)
+{
+ psinfo_t psinfo;
+
+ if (proc_get_psinfo(ppid, &psinfo) == 0)
+ (void) printf(" %s[%d]", psinfo.pr_fname, (int)ppid);
+ else
+ (void) printf(" pid %d", (int)ppid);
+}
+
/* show door info */
static void
show_door(struct ps_prochandle *Pr, int fd)
{
door_info_t door_info;
- psinfo_t psinfo;
if (pr_door_info(Pr, fd, &door_info) != 0)
return;
- if (proc_get_psinfo(door_info.di_target, &psinfo) != 0)
- psinfo.pr_fname[0] = '\0';
-
- (void) printf(" door to ");
- if (psinfo.pr_fname[0] != '\0')
- (void) printf("%s[%d]", psinfo.pr_fname,
- (int)door_info.di_target);
- else
- (void) printf("pid %d", (int)door_info.di_target);
+ (void) printf(" door to");
+ show_peer_process(door_info.di_target);
}
/*
@@ -555,6 +564,35 @@ show_sockaddr(const char *str, struct sockaddr *sa, socklen_t len)
(void) printf("\t%s: %s\n", str, p);
}
+/*
+ * Print out the process information for the other end of local sockets
+ * and fifos
+ */
+static void
+show_ucred(const char *str, ucred_t *cred)
+{
+ pid_t upid = ucred_getpid(cred);
+ zoneid_t uzid = ucred_getzoneid(cred);
+ char zonename[ZONENAME_MAX];
+
+ if ((upid != -1) || (uzid != -1)) {
+ (void) printf("\t%s:", str);
+ if (upid != -1) {
+ show_peer_process(upid);
+ }
+ if (uzid != -1) {
+ if (getzonenamebyid(uzid, zonename, sizeof (zonename))
+ != -1) {
+ (void) printf(" zone: %s[%d]", zonename,
+ (int)uzid);
+ } else {
+ (void) printf(" zoneid: %d", (int)uzid);
+ }
+ }
+ (void) printf("\n");
+ }
+}
+
static void
show_socktype(uint_t type)
{
@@ -709,6 +747,18 @@ show_sockfilters(struct ps_prochandle *Pr, int fd)
free(fi);
}
+/* print peer credentials for sockets and named pipes */
+static void
+dopeerucred(struct ps_prochandle *Pr, int fd)
+{
+ ucred_t *peercred = NULL; /* allocated by getpeerucred */
+
+ if (pr_getpeerucred(Pr, fd, &peercred) == 0) {
+ show_ucred("peer", peercred);
+ ucred_free(peercred);
+ }
+}
+
/* the file is a socket */
static void
dosocket(struct ps_prochandle *Pr, int fd)
@@ -734,6 +784,15 @@ dosocket(struct ps_prochandle *Pr, int fd)
len = sizeof (buf);
if (pr_getpeername(Pr, fd, sa, &len) == 0)
show_sockaddr("peername", sa, len);
+
+ dopeerucred(Pr, fd);
+}
+
+/* the file is a fifo (aka "named pipe") */
+static void
+dofifo(struct ps_prochandle *Pr, int fd)
+{
+ dopeerucred(Pr, fd);
}
/* the file is a TLI endpoint */
diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h
index 8f3730c3a0..b4374324a1 100644
--- a/usr/src/lib/libproc/common/libproc.h
+++ b/usr/src/lib/libproc/common/libproc.h
@@ -53,6 +53,7 @@
#include <proc_service.h>
#include <rtld_db.h>
#include <procfs.h>
+#include <ucred.h>
#include <rctl.h>
#include <libctf.h>
#include <sys/stat.h>
@@ -347,6 +348,7 @@ extern offset_t pr_llseek(struct ps_prochandle *, int, offset_t, int);
extern int pr_rename(struct ps_prochandle *, const char *, const char *);
extern int pr_link(struct ps_prochandle *, const char *, const char *);
extern int pr_unlink(struct ps_prochandle *, const char *);
+extern int pr_getpeerucred(struct ps_prochandle *, int, ucred_t **);
extern int pr_getpeername(struct ps_prochandle *,
int, struct sockaddr *, socklen_t *);
extern int pr_getsockname(struct ps_prochandle *,
diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers
index 9143637cf2..c3e2eb2e8a 100644
--- a/usr/src/lib/libproc/common/mapfile-vers
+++ b/usr/src/lib/libproc/common/mapfile-vers
@@ -170,6 +170,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
pr_fstatvfs;
pr_getitimer;
pr_getpeername;
+ pr_getpeerucred;
pr_getprojid;
pr_getrctl;
pr_getrlimit;
diff --git a/usr/src/lib/libproc/common/pr_getsockname.c b/usr/src/lib/libproc/common/pr_getsockname.c
index ce29c9bdca..ce86b11468 100644
--- a/usr/src/lib/libproc/common/pr_getsockname.c
+++ b/usr/src/lib/libproc/common/pr_getsockname.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
@@ -33,6 +31,9 @@
#include <sys/stream.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
+#include <procfs.h>
+#include <ucred.h>
+#include <sys/ucred.h>
#include "libproc.h"
static int
@@ -167,3 +168,58 @@ pr_getsockopt(struct ps_prochandle *Pr,
}
return (0);
}
+
+/*
+ * getpeerucred() system call -- executed by subject process
+ */
+int
+pr_getpeerucred(struct ps_prochandle *Pr, int fd, ucred_t **ucp)
+{
+ sysret_t rval; /* return value from getpeerucred() */
+ argdes_t argd[3]; /* arg descriptors for getpeerucred() */
+ argdes_t *adp;
+ int error;
+ ucred_t *uc = *ucp;
+
+ if (Pr == NULL) /* no subject process */
+ return (getpeerucred(fd, ucp));
+
+ if (uc == NULL) {
+ uc = _ucred_alloc();
+ if (uc == NULL)
+ return (-1);
+ }
+
+ adp = &argd[0]; /* code argument */
+ adp->arg_value = UCREDSYS_GETPEERUCRED;
+ adp->arg_object = NULL;
+ adp->arg_type = AT_BYVAL;
+ adp->arg_inout = AI_INPUT;
+ adp->arg_size = 0;
+
+ adp++; /* fd argument */
+ adp->arg_value = fd;
+ adp->arg_object = NULL;
+ adp->arg_type = AT_BYVAL;
+ adp->arg_inout = AI_INPUT;
+ adp->arg_size = 0;
+
+ adp++; /* ucred argument */
+ adp->arg_value = 0;
+ adp->arg_object = uc;
+ adp->arg_type = AT_BYREF;
+ adp->arg_inout = AI_OUTPUT;
+ adp->arg_size = ucred_size();
+
+ error = Psyscall(Pr, &rval, SYS_ucredsys, 3, &argd[0]);
+
+ if (error) {
+ errno = (error > 0)? error : ENOSYS;
+ if (*ucp == NULL)
+ ucred_free(uc);
+
+ return (-1);
+ }
+ *ucp = uc;
+ return (0);
+}