static int smb_init_daemon_priv(int flags, uid_t uid, gid_t gid) { priv_set_t *perm = NULL; int ret = -1; char buf[1024]; /* * This is not a significant failure: it allows us to start programs * with sufficient privileges and with the proper uid. We don't * care enough about the extra groups in that case. */ if (flags & PU_RESETGROUPS) (void) setgroups(0, NULL); if (gid != (gid_t)-1 && setgid(gid) != 0) goto end; perm = priv_allocset(); if (perm == NULL) goto end; /* E = P */ (void) getppriv(PRIV_PERMITTED, perm); (void) setppriv(PRIV_SET, PRIV_EFFECTIVE, perm); /* Now reset suid and euid */ if (uid != (uid_t)-1 && setreuid(uid, uid) != 0) goto end; /* I = 0 */ priv_emptyset(perm); ret = setppriv(PRIV_SET, PRIV_INHERITABLE, perm); end: priv_freeset(perm); if (core_get_process_path(buf, sizeof (buf), getpid()) == 0 && strcmp(buf, "core") == 0) { if ((uid == (uid_t)-1 ? geteuid() : uid) == 0) { (void) core_set_process_path(root_cp, sizeof (root_cp), getpid()); } else { (void) core_set_process_path(daemon_cp, sizeof (daemon_cp), getpid()); } } (void) setpflags(__PROC_PROTECT, 0); return (ret); }
static void privupdate_self(void) { int set; if (mac_aware) { if (setpflags(NET_MAC_AWARE, 1) != 0) fatal("setpflags(NET_MAC_AWARE)"); if (setpflags(NET_MAC_AWARE_INHERIT, 1) != 0) fatal("setpflags(NET_MAC_AWARE_INHERIT)"); } if (pfexec) { if (setpflags(PRIV_PFEXEC, 1) != 0) fatal("setpflags(PRIV_PFEXEC)"); } if (sets != NULL) { priv_set_t *target = priv_allocset(); if (target == NULL) fatal("priv_allocet"); set = priv_getsetbyname(PRIV_INHERITABLE); if (rem[set] != NULL || add[set] != NULL || assign[set] != NULL) { (void) getppriv(PRIV_INHERITABLE, target); if (rem[set] != NULL) priv_intersect(rem[set], target); if (add[set] != NULL) priv_union(add[set], target); if (assign[set] != NULL) priv_copyset(assign[set], target); if (setppriv(PRIV_SET, PRIV_INHERITABLE, target) != 0) fatal("setppriv(Inheritable)"); } set = priv_getsetbyname(PRIV_LIMIT); if (rem[set] != NULL || add[set] != NULL || assign[set] != NULL) { (void) getppriv(PRIV_LIMIT, target); if (rem[set] != NULL) priv_intersect(rem[set], target); if (add[set] != NULL) priv_union(add[set], target); if (assign[set] != NULL) priv_copyset(assign[set], target); if (setppriv(PRIV_SET, PRIV_LIMIT, target) != 0) fatal("setppriv(Limit)"); } priv_freeset(target); } if (Doff || Don) (void) setpflags(PRIV_DEBUG, Don ? 1 : 0); if (xpol) (void) setpflags(PRIV_XPOLICY, 1); if (pfexec) (void) setpflags(PRIV_PFEXEC, 1); }
void smb_credinit(struct smb_cred *scred, cred_t *cr) { /* cr arg is optional */ if (cr == NULL) cr = ddi_get_cred(); if (is_system_labeled()) { cr = crdup(cr); (void) setpflags(NET_MAC_AWARE, 1, cr); } else { crhold(cr); } scred->scr_cred = cr; }
/* * Privilege system call entry point */ int privsys(int code, priv_op_t op, priv_ptype_t type, void *buf, size_t bufsize, int itype) { int retv; extern int issetugid(void); switch (code) { case PRIVSYS_SETPPRIV: if (bufsize < sizeof (priv_set_t)) return (set_errno(ENOMEM)); return (setppriv(op, type, buf)); case PRIVSYS_GETPPRIV: if (bufsize < sizeof (priv_set_t)) return (set_errno(ENOMEM)); return (getppriv(type, buf)); case PRIVSYS_GETIMPLINFO: return (getprivimplinfo(buf, bufsize)); case PRIVSYS_SETPFLAGS: retv = setpflags((uint_t)op, (uint_t)type, NULL); return (retv != 0 ? set_errno(retv) : 0); case PRIVSYS_GETPFLAGS: retv = (int)getpflags((uint_t)op, CRED()); return (retv == -1 ? set_errno(EINVAL) : retv); case PRIVSYS_ISSETUGID: return (issetugid()); case PRIVSYS_KLPD_REG: if (bufsize < sizeof (priv_set_t)) return (set_errno(ENOMEM)); return ((int)klpd_reg((int)op, (idtype_t)itype, (id_t)type, buf)); case PRIVSYS_KLPD_UNREG: return ((int)klpd_unreg((int)op, (idtype_t)itype, (id_t)type)); case PRIVSYS_PFEXEC_REG: return ((int)pfexec_reg((int)op)); case PRIVSYS_PFEXEC_UNREG: return ((int)pfexec_unreg((int)op)); } return (set_errno(EINVAL)); }
void set_gssd_uid(uid_t uid) { /* Initialize */ if (lowprivs == NULL) { /* L, P & I shall not change in gssd; we manipulate P though */ if ((highprivs = priv_allocset()) == NULL || (lowprivs = priv_str_to_set(LOWPRIVS, ",", NULL)) == NULL) { printf(gettext( "fatal: can't allocate privilege set (%s)\n"), strerror(ENOMEM)); syslog(LOG_ERR, "Fatal: can't allocate privilege " "set (%s)"), strerror(ENOMEM); exit(1); } /* P has the privs we need when we need privs */ (void) getppriv(PRIV_PERMITTED, highprivs); /* * In case "basic" grows privs not excluded in LOWPRIVS * but excluded in the service's method_context */ priv_intersect(highprivs, lowprivs); (void) setpflags(PRIV_AWARE, 1); } printf(gettext("set_gssd_uid called with uid = %d\n"), uid); /* * nfsd runs as UID 1, so upcalls triggered by nfsd will cause uid to * 1 here, but nfsd's upcalls need to run as root with privs here. */ if (uid == 1) uid = 0; /* * Set the value of krb5_cc_uid, so it can be retrieved when * app_krb5_user_uid() is called by the underlying mechanism * libraries. This should go away soon. */ krb5_cc_uid = uid; /* Claw privs back */ (void) setppriv(PRIV_SET, PRIV_EFFECTIVE, highprivs); /* * Switch uid and set the saved set-uid to 0 so setuid(0) will work * later. */ if (setuid(0) != 0 || (uid != 0 && setreuid(uid, -1) != 0) || (uid != 0 && seteuid(uid) != 0)) { /* Not enough privs, so bail! */ printf(gettext( "fatal: gssd is running with insufficient privilege\n")); syslog(LOG_ERR, "Fatal: gssd is running with insufficient " "privilege."); exit(1); } /* Temporarily drop privs, but only if uid != 0 */ if (uid != 0) (void) setppriv(PRIV_SET, PRIV_EFFECTIVE, lowprivs); }
int main(int argc, char **argv) { char *cmd; char *pset = NULL; char pathbuf[MAXPATHLEN]; int c; priv_set_t *wanted; int oflag; oflag = getpflags(PRIV_PFEXEC); if (setpflags(PRIV_PFEXEC, 1) != 0) { perror("setpflags(PRIV_PFEXEC)"); exit(1); } if (*argv[0] == '-') cmd = argv[0] + 1; else cmd = argv[0]; /* Strip "pf" from argv[0], it confuses some shells. */ if (strncmp(cmd, "pf", 2) == 0) { argv[0] += 2; /* argv[0] will need to start with '-' again. */ if (argv[0][-2] == '-') *argv[0] = '-'; } /* If this fails, we just continue with plan B */ if (shellname(getexecname(), pathbuf) == RES_OK) (void) execv(pathbuf, argv); switch (shellname(cmd, pathbuf)) { case RES_OK: (void) execv(pathbuf, argv); perror(pathbuf); return (1); case RES_PFEXEC: case RES_FAILURE: while ((c = getopt(argc, argv, "P:")) != EOF) { switch (c) { case 'P': if (pset == NULL) { pset = optarg; break; } /* FALLTHROUGH */ default: usage(); } } argc -= optind; argv += optind; if (argc < 1) usage(); if (pset != NULL) { wanted = priv_str_to_set(pset, ",", NULL); if (setppriv(PRIV_ON, PRIV_INHERITABLE, wanted) != 0) { (void) fprintf(stderr, gettext("setppriv(): %s\n"), strerror(errno)); exit(EXIT_FAILURE); } (void) setpflags(PRIV_PFEXEC, oflag); } (void) execvp(argv[0], argv); perror(argv[0]); return (1); } return (1); }