/* Copyright (c) Chris Wright * GPL v2 * Drop uid/gid and caps and read syslog */ #include #include #include #include #include #include #include #include static void usage(void) { printf("Usage: read_syslog options\n"); printf("-u uid\n -p {use /proc/kmsg (default)}\n -s {use syslog(2)}\n"); } static void dumpcred(void) { uid_t ruid, euid, suid; gid_t rgid, egid, sgid; cap_t caps = cap_get_proc(); getresuid(&ruid, &euid, &suid); getresgid(&rgid, &egid, &sgid); printf(" Real Eff Saved\n"); printf("User %-8d%-8d%-8d\n", ruid, euid, suid); printf("Group %-8d%-8d%-8d\n", rgid, egid, sgid); if (caps) { char *p = cap_to_text(caps, NULL); if (p) { printf("Caps: %s\n\n", p); cap_free(p); } cap_free(caps); } } static int usecap(const char *caps) { int rc = -1; cap_t capset = cap_from_text(caps); if (capset) { rc = cap_set_proc(capset); if (rc) { perror("cap_set_proc"); } cap_free(capset); } return rc; } static int drop_privs(uid_t uid, gid_t gid, const char *caps) { int rc; dumpcred(); prctl(PR_SET_KEEPCAPS, 1); rc = setresgid(gid, gid, gid); if (rc == -1) { perror("setresgid"); goto out; } rc = setresuid(uid, uid, uid); if (rc == -1) { perror("setresuid"); goto out; } rc = usecap(caps); if (rc == -1) { perror("usecap"); goto out; } out: dumpcred(); return rc; } main(int argc, char *argv[]) { uid_t new_uid = 500; gid_t new_gid = 500; int c, fd, rc, use_proc = 1; char *caps = "cap_dac_read_search,cap_sys_admin=ep"; char buf[1024]; while ((c = getopt(argc, argv, "u:g:ps")) != -1) { switch(c) { case 'u': new_uid = atoi(optarg); break; case 'g': new_gid = atoi(optarg); break; case 'p': /* default */ break; case 's': use_proc = 0; caps = "cap_sys_admin=ep"; break; default: usage(); exit(1); break; } } memset(buf, 0, sizeof(buf)); if (drop_privs(new_uid, new_gid, caps) == -1) { exit(1); } if (use_proc) { fd = open("/proc/kmsg", O_RDONLY); if (fd == -1) { perror("open"); exit(1); } rc = read(fd, buf, sizeof(buf)); if (rc == -1) { perror("read"); exit(1); } } else { rc = syslog(2, buf, sizeof(buf)); if (rc == -1) { perror("syslog"); exit(1); } } printf("%s\n", buf); }