static int create_labeled_file(char *filename, const char *labeltext) { mac_t mac = NULL; int fd = -1, err; int ret = 0; fd = open(filename, O_RDWR | O_CREAT, 0777); failure("Could not create test file?!"); if (!assert(fd >= 0)) goto done; failure("Couldn't convert MAC label"); if (!assert(mac_from_text(&mac, labeltext) == 0)) goto done; errno = 0; err = mac_set_fd(fd, mac); failure("mac_set_fd(): errno=%d (%s)", errno, strerror(errno)); if (assert(err == 0)) ret = 1; /* success */ done: if (mac) mac_free(mac); if (fd >= 0) close(fd); return ret; }
int main(int argc, char *argv[]) { mac_t exl; if (argc < 3) usage(); if (mac_prepare(&exl, "sebsd")) err(1, "sebsd"); if (mac_from_text(&exl, argv[1])) err(1, argv[1]); argv += 2; if (mac_execve(argv[0], argv, NULL, exl)) perror(argv[0]); exit(1); }
int setfilecon_raw(const char *path, security_context_t context) { mac_t mac; char tmp[strlen(context) + strlen("sebsd/0")]; int r; if (mac_prepare(&mac, "sebsd")) return -1; strcpy(tmp, "sebsd/"); strcat(tmp, context); if (mac_from_text(&mac, tmp)) { mac_free(mac); return -1; } r = mac_set_file(path, mac); mac_free(mac); return r; }
static void setifmaclabel(const char *val, int d, int s, const struct afswtch *rafp) { struct ifreq ifr; mac_t label; int error; if (mac_from_text(&label, val) == -1) { perror(val); return; } memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_ifru.ifru_data = (void *)label; error = ioctl(s, SIOCSIFMAC, &ifr); mac_free(label); if (error == -1) perror("setifmac"); }
int main(int argc, char *argv[]) { const char *shell; mac_t label; int error; if (argc < 3) usage(); error = mac_from_text(&label, argv[1]); if (error != 0) { perror("mac_from_text"); return (-1); } error = mac_set_proc(label); if (error != 0) { perror(argv[1]); return (-1); } mac_free(label); if (argc >= 3) { execvp(argv[2], argv + 2); err(1, "%s", argv[2]); } else { if (!(shell = getenv("SHELL"))) shell = _PATH_BSHELL; execlp(shell, shell, "-i", (char *)NULL); err(1, "%s", shell); } /* NOTREACHED */ }
int setusercontext(login_cap_t *lc, const struct passwd *pwd, uid_t uid, unsigned int flags) { quad_t p; mode_t mymask; login_cap_t *llc = NULL; struct sigaction sa, prevsa; struct rtprio rtp; int error; if (lc == NULL) { if (pwd != NULL && (lc = login_getpwclass(pwd)) != NULL) llc = lc; /* free this when we're done */ } if (flags & LOGIN_SETPATH) pathvars[0].def = uid ? _PATH_DEFPATH : _PATH_STDPATH; /* we need a passwd entry to set these */ if (pwd == NULL) flags &= ~(LOGIN_SETGROUP | LOGIN_SETLOGIN | LOGIN_SETMAC); /* Set the process priority */ if (flags & LOGIN_SETPRIORITY) { p = login_getcapnum(lc, "priority", LOGIN_DEFPRI, LOGIN_DEFPRI); if (p > PRIO_MAX) { rtp.type = RTP_PRIO_IDLE; rtp.prio = p - PRIO_MAX - 1; p = (rtp.prio > RTP_PRIO_MAX) ? 31 : p; if (rtprio(RTP_SET, 0, &rtp)) syslog(LOG_WARNING, "rtprio '%s' (%s): %m", pwd ? pwd->pw_name : "-", lc ? lc->lc_class : LOGIN_DEFCLASS); } else if (p < PRIO_MIN) { rtp.type = RTP_PRIO_REALTIME; rtp.prio = abs(p - PRIO_MIN + RTP_PRIO_MAX); p = (rtp.prio > RTP_PRIO_MAX) ? 1 : p; if (rtprio(RTP_SET, 0, &rtp)) syslog(LOG_WARNING, "rtprio '%s' (%s): %m", pwd ? pwd->pw_name : "-", lc ? lc->lc_class : LOGIN_DEFCLASS); } else { if (setpriority(PRIO_PROCESS, 0, (int)p) != 0) syslog(LOG_WARNING, "setpriority '%s' (%s): %m", pwd ? pwd->pw_name : "-", lc ? lc->lc_class : LOGIN_DEFCLASS); } } /* Setup the user's group permissions */ if (flags & LOGIN_SETGROUP) { if (setgid(pwd->pw_gid) != 0) { syslog(LOG_ERR, "setgid(%lu): %m", (u_long)pwd->pw_gid); login_close(llc); return (-1); } if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) { syslog(LOG_ERR, "initgroups(%s,%lu): %m", pwd->pw_name, (u_long)pwd->pw_gid); login_close(llc); return (-1); } } /* Set up the user's MAC label. */ if ((flags & LOGIN_SETMAC) && mac_is_present(NULL) == 1) { const char *label_string; mac_t label; label_string = login_getcapstr(lc, "label", NULL, NULL); if (label_string != NULL) { if (mac_from_text(&label, label_string) == -1) { syslog(LOG_ERR, "mac_from_text('%s') for %s: %m", pwd->pw_name, label_string); return (-1); } if (mac_set_proc(label) == -1) error = errno; else error = 0; mac_free(label); if (error != 0) { syslog(LOG_ERR, "mac_set_proc('%s') for %s: %s", label_string, pwd->pw_name, strerror(error)); return (-1); } } } /* Set the sessions login */ if ((flags & LOGIN_SETLOGIN) && setlogin(pwd->pw_name) != 0) { syslog(LOG_ERR, "setlogin(%s): %m", pwd->pw_name); login_close(llc); return (-1); } /* Inform the kernel about current login class */ if (lc != NULL && lc->lc_class != NULL && (flags & LOGIN_SETLOGINCLASS)) { /* * XXX: This is a workaround to fail gracefully in case the kernel * does not support setloginclass(2). */ bzero(&sa, sizeof(sa)); sa.sa_handler = SIG_IGN; sigfillset(&sa.sa_mask); sigaction(SIGSYS, &sa, &prevsa); error = setloginclass(lc->lc_class); sigaction(SIGSYS, &prevsa, NULL); if (error != 0) { syslog(LOG_ERR, "setloginclass(%s): %m", lc->lc_class); #ifdef notyet login_close(llc); return (-1); #endif } } mymask = (flags & LOGIN_SETUMASK) ? umask(LOGIN_DEFUMASK) : 0; mymask = setlogincontext(lc, pwd, mymask, flags); login_close(llc); /* This needs to be done after anything that needs root privs */ if ((flags & LOGIN_SETUSER) && setuid(uid) != 0) { syslog(LOG_ERR, "setuid(%lu): %m", (u_long)uid); return (-1); /* Paranoia again */ } /* * Now, we repeat some of the above for the user's private entries */ if (getuid() == uid && (lc = login_getuserclass(pwd)) != NULL) { mymask = setlogincontext(lc, pwd, mymask, flags); login_close(lc); } /* Finally, set any umask we've found */ if (flags & LOGIN_SETUMASK) umask(mymask); return (0); }
/***************************************************************************** * * NAME * check_file - Make sure the specified file exists as specified. * * SYNOPSIS * check_file_retval = check_file( file, own, grp, mode ); * * file r The name of the file to be verified, changed * or created. * own r The file's owner. * grp r The file's group. * mode r The file's mode. * * DESCRIPTION * This routine determines whether <file> exists -and- is a regular file. * If the file doesn't exist, this routine will create it. * * In either case, the file's owner will be set to <own>, group will be * set to <grp>, mode will be set to <mode>, and MAC label will be set * to dbadmin (for Trusted IRIX only). * * NOTES: If the owner cannot be changed to <own> because the executing * user does NOT have permission, the error is ignored and this * routine will return a successful indication. * * Only the -low order- 9 bits of <mode> are expected to be used. * * All file descriptors opened by the processing contained in * this routine are closed -before- control is returned. * * If an error occurs and the file was NOT created, this routine * attempts to put the file back to the way it existed upon entry * to this routine. * * If an error occurs and the file was created by this routine, * it is removed -before- control is returned to the caller. * * RETURNS * 0 - If the file exists as requested. * 1 - If <own> is NOT a valid user name. * 2 - If <grp> is NOT a valid group name. * 3 - If <mode> has more than the -low order- 9 bits set. * 4 - If the file could NOT be creat()'d. * 5 - If the stat() system call failed. * 6 - If the file's mode could NOT be set as requested. * 7 - If the file's group could NOT be set as requested. * 8 - If the file's owner could NOT be set as requested. * 9 - If <file> exists -and- is NOT a regular file. * 10 - If we cannot get the mac_t structure for dbadmin. * 11 - If the file's MAC label could NOT be set as requested. * *****************************************************************************/ check_file_retval check_file( char *file, char *own, char *grp, mode_t mode ) { uid_t uid; gid_t gid; #ifdef HAVE_MAC_H mac_t mac_label; #endif /* HAVE_MAC_H */ int we_created_it = 0; check_file_retval rc = CHK_SUCCESS; int fd; struct stat stbuf; if ( ( mode & ~0777 ) != 0 ) return( CHK_BAD_MODE ); uid = name_to_uid( own ); if ( uid < 0 ) return( CHK_BAD_OWNER ); gid = name_to_gid( grp ); if ( gid < 0 ) return( CHK_BAD_GROUP ); if ( stat( file, &stbuf ) < 0 ) { if ( ( fd = creat( file, mode ) ) < 0 ) return( CHK_NOT_CREATED ); (void) close( fd ); we_created_it = 1; if ( stat( file, &stbuf ) < 0 ) rc = CHK_STAT_FAILED; } if ( rc == CHK_SUCCESS && ! ( stbuf.st_mode & S_IFREG ) ) rc = CHK_FILE_NOT_REGULAR; if ( rc == CHK_SUCCESS && stbuf.st_gid != gid ) { if ( chown( file, stbuf.st_uid, gid ) < 0 ) rc = CHK_CANNOT_SET_GROUP; } if ( rc == CHK_SUCCESS && ( stbuf.st_mode & 0777 ) != mode ) { if ( chmod( file, mode ) < 0 ) rc = CHK_CANNOT_SET_MODE; } if ( rc == CHK_SUCCESS && stbuf.st_uid != uid ) { if ( chown( file, uid, gid ) < 0 ) { if ( errno != EPERM ) rc = CHK_CANNOT_SET_OWNER; } } #ifdef HAVE_MAC_H if ( rc == CHK_SUCCESS && sysconf(_SC_MAC) ) { /* * Set the MAC label of the accounting file to dbadmin. */ if (( mac_label = mac_from_text( "dbadmin" ) ) == NULL) rc = CHK_CANNOT_GET_MAC; else if ( mac_set_file( file, mac_label ) < 0 ) rc = CHK_CANNOT_SET_MAC; mac_free( mac_label ); } #endif /* HAVE_MAC_H */ if ( rc != CHK_SUCCESS ) { if ( we_created_it == 1 ) (void) unlink( file ); else { (void) chown( file, stbuf.st_uid, stbuf.st_gid ); (void) chmod( file, ( stbuf.st_mode & 0777 ) ); } } return( rc ); }