diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/ptools/pfiles/pfiles.c | 79 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/libproc.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/mapfile-vers | 1 | ||||
-rw-r--r-- | usr/src/lib/libproc/common/pr_getsockname.c | 60 |
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); +} |