static void change_user_set_privs(void) { priv_set_t *priv_set; priv_set = priv_allocset(); if (getppriv(PRIV_PERMITTED, priv_set) == -1) { dprintf("getppriv %s", strerror(errno)); } else { char *p; p = priv_set_to_str(priv_set, ',', 0); dprintf("started with privs %s", p != NULL ? p : "Unknown"); free(p); } priv_freeset(priv_set); /* always start with the basic set */ priv_set = priv_str_to_set("basic", ",", NULL); if (priv_set == NULL) { syslog(LOG_ERR, "converting basic privilege set: %m"); exit(EXIT_FAILURE); } (void) priv_addset(priv_set, PRIV_FILE_CHOWN_SELF); (void) priv_addset(priv_set, PRIV_FILE_DAC_READ); (void) priv_addset(priv_set, PRIV_FILE_DAC_WRITE); (void) priv_addset(priv_set, PRIV_NET_PRIVADDR); (void) priv_addset(priv_set, PRIV_NET_RAWACCESS); (void) priv_addset(priv_set, PRIV_PROC_AUDIT); (void) priv_addset(priv_set, PRIV_PROC_OWNER); (void) priv_addset(priv_set, PRIV_PROC_SETID); (void) priv_addset(priv_set, PRIV_SYS_CONFIG); (void) priv_addset(priv_set, PRIV_SYS_IP_CONFIG); (void) priv_addset(priv_set, PRIV_SYS_IPC_CONFIG); (void) priv_addset(priv_set, PRIV_SYS_NET_CONFIG); (void) priv_addset(priv_set, PRIV_SYS_RES_CONFIG); (void) priv_addset(priv_set, PRIV_SYS_RESOURCE); if (setppriv(PRIV_SET, PRIV_INHERITABLE, priv_set) == -1) { syslog(LOG_ERR, "setppriv inheritable: %m"); priv_freeset(priv_set); exit(EXIT_FAILURE); } if (setppriv(PRIV_SET, PRIV_PERMITTED, priv_set) == -1) { syslog(LOG_ERR, "setppriv permitted: %m"); priv_freeset(priv_set); exit(EXIT_FAILURE); } if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) == -1) { syslog(LOG_ERR, "setppriv effective: %m"); priv_freeset(priv_set); exit(EXIT_FAILURE); } priv_freeset(priv_set); }
int mtev_security_setcaps(mtev_security_captype_t type, const char *capstring) { #ifndef CAP_SUPPORTED mtevL(mtev_error, "Capabilities not supported on this platform.\n"); return -1; #endif #ifdef HAVE_SETPPRIV int rv; const char *endptr; char *str; priv_set_t *set, *old; priv_ptype_t ptype = "Permitted"; set = priv_str_to_set(capstring, ",", &endptr); if(!set) { mtevL(mtev_error, "Cannot translate '%s' to privilege set.\n", capstring); return -1; } switch(type) { case MTEV_SECURITY_CAP_PERMITTED: ptype = "Permitted"; break; case MTEV_SECURITY_CAP_EFFECTIVE: ptype = "Effective"; break; case MTEV_SECURITY_CAP_INHERITABLE: ptype = "Inheritable"; break; } old = priv_allocset(); getppriv(ptype, old); str = priv_set_to_str(old, ',', PRIV_STR_PORT); mtevL(mtev_debug, "Old privs(%s) -> %s\n", ptype, str); priv_freeset(old); free(str); rv = setppriv(PRIV_SET, ptype, set); str = priv_set_to_str(set, ',', PRIV_STR_PORT); mtevL(mtev_debug, "%s privs(%s) -> %s\n", (rv == 0) ? "Changed to" : "Failed to change to", ptype, str); free(str); priv_freeset(set); return rv; #else return -1; #endif }
void checkAsRoot() { #ifndef __CYGWIN__ #ifdef SOLAR_PRIV priv_set_t *privset; char *p; /* Get the basic set */ privset = priv_str_to_set("basic", ",", NULL); if (privset == NULL) { die("ERROR: Could not get basic privset from priv_str_to_set()."); } else { p = priv_set_to_str(privset, ',', 0); SPINE_LOG_DEBUG(("DEBUG: Basic privset is: '%s'.", p != NULL ? p : "Unknown")); } /* Add priviledge to send/receive ICMP packets */ if (priv_addset(privset, PRIV_NET_ICMPACCESS) < 0 ) { SPINE_LOG_DEBUG(("Warning: Addition of PRIV_NET_ICMPACCESS to privset failed: '%s'.", strerror(errno))); } /* Compute the set of privileges that are never needed */ priv_inverse(privset); /* Remove the set of unneeded privs from Permitted (and by * implication from Effective) */ if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) < 0) { SPINE_LOG_DEBUG(("Warning: Dropping privileges from PRIV_PERMITTED failed: '%s'.", strerror(errno))); } /* Remove unneeded priv set from Limit to be safe */ if (setppriv(PRIV_OFF, PRIV_LIMIT, privset) < 0) { SPINE_LOG_DEBUG(("Warning: Dropping privileges from PRIV_LIMIT failed: '%s'.", strerror(errno))); } boolean_t pe = priv_ineffect(PRIV_NET_ICMPACCESS); SPINE_LOG_DEBUG(("DEBUG: Privilege PRIV_NET_ICMPACCESS is: '%s'.", pe != 0 ? "Enabled" : "Disabled")); set.icmp_avail = pe; /* Free the privset */ priv_freeset(privset); free(p); #else if (hasCaps() != TRUE) { seteuid(0); if (geteuid() != 0) { SPINE_LOG_DEBUG(("WARNING: Spine NOT running asroot. This is required if using ICMP. Please run \"chmod +s;chown root:root spine\" to resolve.")); set.icmp_avail = FALSE; }else{ SPINE_LOG_DEBUG(("DEBUG: Spine is running asroot.")); set.icmp_avail = TRUE; seteuid(getuid()); } } else { SPINE_LOG_DEBUG(("DEBUG: Spine has cap_net_raw capability.")); set.icmp_avail = TRUE; } #endif #endif }
static int look(char *arg) { struct ps_prochandle *Pr; int gcode; size_t sz; void *pdata; char *x; int i; boolean_t nodata; prpriv_t *ppriv; procname = arg; /* for perr() */ if ((Pr = proc_arg_grab(arg, set ? PR_ARG_PIDS : PR_ARG_ANY, PGRAB_RETAIN | PGRAB_FORCE | (set ? 0 : PGRAB_RDONLY) | PGRAB_NOSTOP, &gcode)) == NULL) { (void) fprintf(stderr, "%s: cannot examine %s: %s\n", command, arg, Pgrab_error(gcode)); return (1); } if (Ppriv(Pr, &ppriv) == -1) { perr(command); Prelease(Pr, 0); return (1); } sz = PRIV_PRPRIV_SIZE(ppriv); /* * The ppriv fields are unsigned and may overflow, so check them * separately. Size must be word aligned, so check that too. * Make sure size is "smallish" too. */ if ((sz & 3) || ppriv->pr_nsets == 0 || sz / ppriv->pr_nsets < ppriv->pr_setsize || ppriv->pr_infosize > sz || sz > 1024 * 1024) { (void) fprintf(stderr, "%s: %s: bad PRNOTES section, size = %lx\n", command, arg, (long)sz); Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (1); } if (set) { privupdate(ppriv, arg); if (Psetpriv(Pr, ppriv) != 0) { perr(command); Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (1); } Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (0); } if (Pstate(Pr) == PS_DEAD) { (void) printf("core '%s' of %d:\t%.70s\n", arg, (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs); pdata = Pprivinfo(Pr); nodata = Pstate(Pr) == PS_DEAD && pdata == NULL; } else { (void) printf("%d:\t%.70s\n", (int)Ppsinfo(Pr)->pr_pid, Ppsinfo(Pr)->pr_psargs); pdata = NULL; nodata = B_FALSE; } x = (char *)ppriv + sz - ppriv->pr_infosize; while (x < (char *)ppriv + sz) { /* LINTED: alignment */ priv_info_t *pi = (priv_info_t *)x; priv_info_uint_t *pii; switch (pi->priv_info_type) { case PRIV_INFO_FLAGS: /* LINTED: alignment */ pii = (priv_info_uint_t *)x; (void) printf("flags ="); flags2str(pii->val); (void) putchar('\n'); break; default: (void) fprintf(stderr, "%s: unknown priv_info: %d\n", arg, pi->priv_info_type); break; } if (pi->priv_info_size > ppriv->pr_infosize || pi->priv_info_size <= sizeof (priv_info_t) || (pi->priv_info_size & 3) != 0) { (void) fprintf(stderr, "%s: bad priv_info_size: %u\n", arg, pi->priv_info_size); break; } x += pi->priv_info_size; } for (i = 0; i < ppriv->pr_nsets; i++) { extern const char *__priv_getsetbynum(const void *, int); const char *setnm = pdata ? __priv_getsetbynum(pdata, i) : priv_getsetbynum(i); priv_chunk_t *pc = (priv_chunk_t *)&ppriv->pr_sets[ppriv->pr_setsize * i]; (void) printf("\t%c: ", setnm && !nodata ? *setnm : '?'); if (!nodata) { extern char *__priv_set_to_str(void *, const priv_set_t *, char, int); priv_set_t *pset = (priv_set_t *)pc; char *s; if (pdata) s = __priv_set_to_str(pdata, pset, ',', mode); else s = priv_set_to_str(pset, ',', mode); (void) puts(s); free(s); } else { int j; for (j = 0; j < ppriv->pr_setsize; j++) (void) printf("%08x", pc[j]); (void) putchar('\n'); } } Prelease(Pr, 0); Ppriv_free(Pr, ppriv); return (0); }