void udev_selinux_init(struct udev *udev) { /* record the present security context */ selinux_enabled = (is_selinux_enabled() > 0); info(udev, "selinux=%i\n", selinux_enabled); if (!selinux_enabled) return; matchpathcon_init_prefix(NULL, udev_get_dev_path(udev)); if (getfscreatecon(&selinux_prev_scontext) < 0) { err(udev, "getfscreatecon failed\n"); selinux_prev_scontext = NULL; } }
int main(int argc, char** argv) { security_context_t con; assert(argc == 2); int selinux = is_selinux_enabled(); printf("selinux enabled = %d\n", selinux); if (setfscreatecon(argv[1]) < 0) printf("Error: set\n"); else printf("Success: set\n"); if (getfscreatecon(&con) < 0) printf("Error: get\n"); else printf("Success: get\n"); printf("create_con = %s\n", con); return 0; }
/* Return: * -1 error, copy not made * 0 copy is made or user answered "no" in interactive mode * (failures to preserve mode/owner/times are not reported in exit code) */ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) { /* This is a recursive function, try to minimize stack usage */ /* NB: each struct stat is ~100 bytes */ struct stat source_stat; struct stat dest_stat; smallint retval = 0; smallint dest_exists = 0; smallint ovr; /* Inverse of cp -d ("cp without -d") */ #define FLAGS_DEREF (flags & (FILEUTILS_DEREFERENCE + FILEUTILS_DEREFERENCE_L0)) if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) { /* This may be a dangling symlink. * Making [sym]links to dangling symlinks works, so... */ if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) goto make_links; bb_perror_msg("can't stat '%s'", source); return -1; } if (lstat(dest, &dest_stat) < 0) { if (errno != ENOENT) { bb_perror_msg("can't stat '%s'", dest); return -1; } } else { if (source_stat.st_dev == dest_stat.st_dev && source_stat.st_ino == dest_stat.st_ino ) { bb_error_msg("'%s' and '%s' are the same file", source, dest); return -1; } dest_exists = 1; } #if ENABLE_SELINUX if ((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) && is_selinux_enabled() > 0) { security_context_t con; if (lgetfilecon(source, &con) >= 0) { if (setfscreatecon(con) < 0) { bb_perror_msg("can't set setfscreatecon %s", con); freecon(con); return -1; } } else if (errno == ENOTSUP || errno == ENODATA) { setfscreatecon_or_die(NULL); } else { bb_perror_msg("can't lgetfilecon %s", source); return -1; } } #endif if (S_ISDIR(source_stat.st_mode)) { DIR *dp; const char *tp; struct dirent *d; mode_t saved_umask = 0; if (!(flags & FILEUTILS_RECUR)) { bb_error_msg("omitting directory '%s'", source); return -1; } /* Did we ever create source ourself before? */ tp = is_in_ino_dev_hashtable(&source_stat); if (tp) { /* We did! it's a recursion! man the lifeboats... */ bb_error_msg("recursion detected, omitting directory '%s'", source); return -1; } if (dest_exists) { if (!S_ISDIR(dest_stat.st_mode)) { bb_error_msg("target '%s' is not a directory", dest); return -1; } /* race here: user can substitute a symlink between * this check and actual creation of files inside dest */ } else { /* Create DEST */ mode_t mode; saved_umask = umask(0); mode = source_stat.st_mode; if (!(flags & FILEUTILS_PRESERVE_STATUS)) mode = source_stat.st_mode & ~saved_umask; /* Allow owner to access new dir (at least for now) */ mode |= S_IRWXU; if (mkdir(dest, mode) < 0) { umask(saved_umask); bb_perror_msg("can't create directory '%s'", dest); return -1; } umask(saved_umask); /* need stat info for add_to_ino_dev_hashtable */ if (lstat(dest, &dest_stat) < 0) { bb_perror_msg("can't stat '%s'", dest); return -1; } } /* remember (dev,inode) of each created dir. * NULL: name is not remembered */ add_to_ino_dev_hashtable(&dest_stat, NULL); /* Recursively copy files in SOURCE */ dp = opendir(source); if (dp == NULL) { retval = -1; goto preserve_mode_ugid_time; } while ((d = readdir(dp)) != NULL) { char *new_source, *new_dest; new_source = concat_subpath_file(source, d->d_name); if (new_source == NULL) continue; new_dest = concat_path_file(dest, d->d_name); if (copy_file(new_source, new_dest, flags & ~FILEUTILS_DEREFERENCE_L0) < 0) retval = -1; free(new_source); free(new_dest); } closedir(dp); if (!dest_exists && chmod(dest, source_stat.st_mode & ~saved_umask) < 0 ) { bb_perror_msg("can't preserve %s of '%s'", "permissions", dest); /* retval = -1; - WRONG! copy *WAS* made */ } goto preserve_mode_ugid_time; } if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { int (*lf)(const char *oldpath, const char *newpath); make_links: /* Hmm... maybe * if (DEREF && MAKE_SOFTLINK) source = realpath(source) ? * (but realpath returns NULL on dangling symlinks...) */ lf = (flags & FILEUTILS_MAKE_SOFTLINK) ? symlink : link; if (lf(source, dest) < 0) { ovr = ask_and_unlink(dest, flags); if (ovr <= 0) return ovr; if (lf(source, dest) < 0) { bb_perror_msg("can't create link '%s'", dest); return -1; } } /* _Not_ jumping to preserve_mode_ugid_time: * (sym)links don't have those */ return 0; } if (/* "cp thing1 thing2" without -R: just open and read() from thing1 */ !(flags & FILEUTILS_RECUR) /* "cp [-opts] regular_file thing2" */ || S_ISREG(source_stat.st_mode) /* DEREF uses stat, which never returns S_ISLNK() == true. * So the below is never true: */ /* || (FLAGS_DEREF && S_ISLNK(source_stat.st_mode)) */ ) { int src_fd; int dst_fd; mode_t new_mode; if (!FLAGS_DEREF && S_ISLNK(source_stat.st_mode)) { /* "cp -d symlink dst": create a link */ goto dont_cat; } if (ENABLE_FEATURE_PRESERVE_HARDLINKS && !FLAGS_DEREF) { const char *link_target; link_target = is_in_ino_dev_hashtable(&source_stat); if (link_target) { if (link(link_target, dest) < 0) { ovr = ask_and_unlink(dest, flags); if (ovr <= 0) return ovr; if (link(link_target, dest) < 0) { bb_perror_msg("can't create link '%s'", dest); return -1; } } return 0; } add_to_ino_dev_hashtable(&source_stat, dest); } src_fd = open_or_warn(source, O_RDONLY); if (src_fd < 0) return -1; /* Do not try to open with weird mode fields */ new_mode = source_stat.st_mode; if (!S_ISREG(source_stat.st_mode)) new_mode = 0666; // POSIX way is a security problem versus (sym)link attacks if (!ENABLE_FEATURE_NON_POSIX_CP) { dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, new_mode); } else { /* safe way: */ dst_fd = open(dest, O_WRONLY|O_CREAT|O_EXCL, new_mode); } if (dst_fd == -1) { ovr = ask_and_unlink(dest, flags); if (ovr <= 0) { close(src_fd); return ovr; } /* It shouldn't exist. If it exists, do not open (symlink attack?) */ dst_fd = open3_or_warn(dest, O_WRONLY|O_CREAT|O_EXCL, new_mode); if (dst_fd < 0) { close(src_fd); return -1; } } #if ENABLE_SELINUX if ((flags & (FILEUTILS_PRESERVE_SECURITY_CONTEXT|FILEUTILS_SET_SECURITY_CONTEXT)) && is_selinux_enabled() > 0 ) { security_context_t con; if (getfscreatecon(&con) == -1) { bb_perror_msg("getfscreatecon"); return -1; } if (con) { if (setfilecon(dest, con) == -1) { bb_perror_msg("setfilecon:%s,%s", dest, con); freecon(con); return -1; } freecon(con); } } #endif if (bb_copyfd_eof(src_fd, dst_fd) == -1) retval = -1; /* Careful with writing... */ if (close(dst_fd) < 0) { bb_perror_msg("error writing to '%s'", dest); retval = -1; } /* ...but read size is already checked by bb_copyfd_eof */ close(src_fd); /* "cp /dev/something new_file" should not * copy mode of /dev/something */ if (!S_ISREG(source_stat.st_mode)) return retval; goto preserve_mode_ugid_time; } dont_cat: /* Source is a symlink or a special file */ /* We are lazy here, a bit lax with races... */ if (dest_exists) { errno = EEXIST; ovr = ask_and_unlink(dest, flags); if (ovr <= 0) return ovr; } if (S_ISLNK(source_stat.st_mode)) { char *lpath = xmalloc_readlink_or_warn(source); if (lpath) { int r = symlink(lpath, dest); free(lpath); if (r < 0) { bb_perror_msg("can't create symlink '%s'", dest); return -1; } if (flags & FILEUTILS_PRESERVE_STATUS) if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) bb_perror_msg("can't preserve %s of '%s'", "ownership", dest); } /* _Not_ jumping to preserve_mode_ugid_time: * symlinks don't have those */ return 0; } if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) ) { if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { bb_perror_msg("can't create '%s'", dest); return -1; } } else { bb_error_msg("unrecognized file '%s' with mode %x", source, source_stat.st_mode); return -1; } preserve_mode_ugid_time: if (flags & FILEUTILS_PRESERVE_STATUS /* Cannot happen: */ /* && !(flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) */ ) { struct timeval times[2]; times[1].tv_sec = times[0].tv_sec = source_stat.st_mtime; times[1].tv_usec = times[0].tv_usec = 0; /* BTW, utimes sets usec-precision time - just FYI */ if (utimes(dest, times) < 0) bb_perror_msg("can't preserve %s of '%s'", "times", dest); if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { source_stat.st_mode &= ~(S_ISUID | S_ISGID); bb_perror_msg("can't preserve %s of '%s'", "ownership", dest); } #if ENABLE_XATTR /* Preserve extended attributes. We must copy it after chown() * because it resets capabilities. */ if (copy_file_attr(source, dest) == -1) bb_perror_msg("can't preserve %s of '%s'", "extended attributes", dest); #endif if (chmod(dest, source_stat.st_mode) < 0) bb_perror_msg("can't preserve %s of '%s'", "permissions", dest); } return retval; }
/* This function takes a PATH of an existing file system object, and a LOCAL boolean that indicates whether the function should set the object's label to the default for the local process, or one using system wide settings. If LOCAL == true, it will ask the SELinux Kernel what the default label for all objects created should be and then sets the label on the object. Otherwise it calls matchpathcon on the object to ask the system what the default label should be, extracts the type field and then modifies the file system object. Note only the type field is updated, thus preserving MLS levels and user identity etc. of the PATH. Returns -1 on failure. errno will be set appropriately. */ static int restorecon_private (char const *path, bool local) { int rc = -1; struct stat sb; char *scon = NULL; char *tcon = NULL; context_t scontext = 0, tcontext = 0; const char *contype; char *constr; int fd; if (local) { if (getfscreatecon (&tcon) < 0) return rc; if (!tcon) { errno = ENODATA; return rc; } rc = lsetfilecon (path, tcon); freecon (tcon); return rc; } fd = open (path, O_RDONLY | O_NOFOLLOW); if (fd == -1 && (errno != ELOOP)) goto quit; if (fd != -1) { if (fstat (fd, &sb) < 0) goto quit; } else { if (lstat (path, &sb) < 0) goto quit; } if (matchpathcon (path, sb.st_mode, &scon) < 0) { /* "No such file or directory" is a confusing error, when processing files, when in fact it was the associated default context that was not found. Therefore map the error to something more appropriate to the context in which we're using matchpathcon(). */ if (errno == ENOENT) errno = ENODATA; goto quit; } if (!(scontext = context_new (scon))) goto quit; if (fd != -1) { if (fgetfilecon (fd, &tcon) < 0) goto quit; } else { if (lgetfilecon (path, &tcon) < 0) goto quit; } if (!(tcontext = context_new (tcon))) goto quit; if (!(contype = context_type_get (scontext))) goto quit; if (context_type_set (tcontext, contype)) goto quit; if (!(constr = context_str (tcontext))) goto quit; if (fd != -1) rc = fsetfilecon (fd, constr); else rc = lsetfilecon (path, constr); quit: if (fd != -1) close (fd); context_free (scontext); context_free (tcontext); freecon (scon); freecon (tcon); return rc; }
static gboolean plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); shvarFile *network; char *hostname_eol; gboolean ret; #if HAVE_SELINUX security_context_t se_ctx_prev = NULL, se_ctx = NULL; struct stat file_stat = { .st_mode = 0 }; mode_t st_mode = 0; /* Get default context for HOSTNAME_FILE and set it for fscreate */ if (stat (HOSTNAME_FILE, &file_stat) == 0) st_mode = file_stat.st_mode; matchpathcon (HOSTNAME_FILE, st_mode, &se_ctx); matchpathcon_fini (); getfscreatecon (&se_ctx_prev); setfscreatecon (se_ctx); #endif hostname_eol = g_strdup_printf ("%s\n", hostname); ret = g_file_set_contents (HOSTNAME_FILE, hostname_eol, -1, NULL); #if HAVE_SELINUX /* Restore previous context and cleanup */ setfscreatecon (se_ctx_prev); freecon (se_ctx); freecon (se_ctx_prev); #endif if (!ret) { _LOGW ("Could not save hostname: failed to create/open " HOSTNAME_FILE); g_free (hostname_eol); return FALSE; } g_free (priv->hostname); priv->hostname = g_strdup (hostname); g_free (hostname_eol); /* Remove "HOSTNAME" from SC_NETWORK_FILE, if present */ network = svOpenFile (SC_NETWORK_FILE, NULL); if (network) { svSetValue (network, "HOSTNAME", NULL, FALSE); svWriteFile (network, 0644, NULL); svCloseFile (network); } return TRUE; } static void hostname_maybe_changed (SCPluginIfcfg *plugin) { SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); char *new_hostname; new_hostname = plugin_get_hostname (plugin); if ( (new_hostname && !priv->hostname) || (!new_hostname && priv->hostname) || (priv->hostname && new_hostname && strcmp (priv->hostname, new_hostname))) { g_free (priv->hostname); priv->hostname = new_hostname; g_object_notify (G_OBJECT (plugin), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME); } else g_free (new_hostname); }
PAMH_ARG_DECL(int unix_update_shadow, const char *forwho, char *towhat) { struct spwd spwdent, *stmpent = NULL; struct stat st; FILE *pwfile, *opwfile; int err = 0; int oldmask; int wroteentry = 0; #ifdef WITH_SELINUX security_context_t prev_context=NULL; #endif oldmask = umask(077); #ifdef WITH_SELINUX if (SELINUX_ENABLED) { security_context_t shadow_context=NULL; if (getfilecon("/etc/shadow",&shadow_context)<0) { return PAM_AUTHTOK_ERR; }; if (getfscreatecon(&prev_context)<0) { freecon(shadow_context); return PAM_AUTHTOK_ERR; } if (setfscreatecon(shadow_context)) { freecon(shadow_context); freecon(prev_context); return PAM_AUTHTOK_ERR; } freecon(shadow_context); } #endif pwfile = fopen(SH_TMPFILE, "w"); umask(oldmask); if (pwfile == NULL) { err = 1; goto done; } opwfile = fopen("/etc/shadow", "r"); if (opwfile == NULL) { fclose(pwfile); err = 1; goto done; } if (fstat(fileno(opwfile), &st) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } if (fchmod(fileno(pwfile), st.st_mode) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } stmpent = fgetspent(opwfile); while (stmpent) { if (!strcmp(stmpent->sp_namp, forwho)) { stmpent->sp_pwdp = towhat; stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24); if (stmpent->sp_lstchg == 0) stmpent->sp_lstchg = -1; /* Don't request passwort change only because time isn't set yet. */ wroteentry = 1; D(("Set password %s for %s", stmpent->sp_pwdp, forwho)); } if (putspent(stmpent, pwfile)) { D(("error writing entry to shadow file: %m")); err = 1; break; } stmpent = fgetspent(opwfile); } fclose(opwfile); if (!wroteentry && !err) { spwdent.sp_namp = forwho; spwdent.sp_pwdp = towhat; spwdent.sp_lstchg = time(NULL) / (60 * 60 * 24); if (spwdent.sp_lstchg == 0) spwdent.sp_lstchg = -1; /* Don't request passwort change only because time isn't set yet. */ spwdent.sp_min = spwdent.sp_max = spwdent.sp_warn = spwdent.sp_inact = spwdent.sp_expire = -1; spwdent.sp_flag = (unsigned long)-1l; if (putspent(&spwdent, pwfile)) { D(("error writing entry to shadow file: %m")); err = 1; } } if (fflush(pwfile) || fsync(fileno(pwfile))) { D(("fflush or fsync error writing entries to shadow file: %m")); err = 1; } if (fclose(pwfile)) { D(("fclose error writing entries to shadow file: %m")); err = 1; } done: if (!err) { if (!rename(SH_TMPFILE, "/etc/shadow")) pam_syslog(pamh, LOG_NOTICE, "password changed for %s", forwho); else err = 1; } #ifdef WITH_SELINUX if (SELINUX_ENABLED) { if (setfscreatecon(prev_context)) { err = 1; } if (prev_context) freecon(prev_context); prev_context=NULL; } #endif if (!err) { return PAM_SUCCESS; } else { unlink(SH_TMPFILE); return PAM_AUTHTOK_ERR; } }
PAMH_ARG_DECL(int unix_update_passwd, const char *forwho, const char *towhat) { struct passwd *tmpent = NULL; struct stat st; FILE *pwfile, *opwfile; int err = 1; int oldmask; #ifdef WITH_SELINUX security_context_t prev_context=NULL; #endif oldmask = umask(077); #ifdef WITH_SELINUX if (SELINUX_ENABLED) { security_context_t passwd_context=NULL; if (getfilecon("/etc/passwd",&passwd_context)<0) { return PAM_AUTHTOK_ERR; }; if (getfscreatecon(&prev_context)<0) { freecon(passwd_context); return PAM_AUTHTOK_ERR; } if (setfscreatecon(passwd_context)) { freecon(passwd_context); freecon(prev_context); return PAM_AUTHTOK_ERR; } freecon(passwd_context); } #endif pwfile = fopen(PW_TMPFILE, "w"); umask(oldmask); if (pwfile == NULL) { err = 1; goto done; } opwfile = fopen("/etc/passwd", "r"); if (opwfile == NULL) { fclose(pwfile); err = 1; goto done; } if (fstat(fileno(opwfile), &st) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } if (fchmod(fileno(pwfile), st.st_mode) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } tmpent = fgetpwent(opwfile); while (tmpent) { if (!strcmp(tmpent->pw_name, forwho)) { /* To shut gcc up */ union { const char *const_charp; char *charp; } assigned_passwd; assigned_passwd.const_charp = towhat; tmpent->pw_passwd = assigned_passwd.charp; err = 0; } if (putpwent(tmpent, pwfile)) { D(("error writing entry to password file: %m")); err = 1; break; } tmpent = fgetpwent(opwfile); } fclose(opwfile); if (fflush(pwfile) || fsync(fileno(pwfile))) { D(("fflush or fsync error writing entries to password file: %m")); err = 1; } if (fclose(pwfile)) { D(("fclose error writing entries to password file: %m")); err = 1; } done: if (!err) { if (!rename(PW_TMPFILE, "/etc/passwd")) pam_syslog(pamh, LOG_NOTICE, "password changed for %s", forwho); else err = 1; } #ifdef WITH_SELINUX if (SELINUX_ENABLED) { if (setfscreatecon(prev_context)) { err = 1; } if (prev_context) freecon(prev_context); prev_context=NULL; } #endif if (!err) { return PAM_SUCCESS; } else { unlink(PW_TMPFILE); return PAM_AUTHTOK_ERR; } }
int save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass, int howmany) #endif { static char buf[16384]; static char nbuf[16384]; char *s_luser, *s_uid, *s_npas, *s_pas, *pass; int npas; FILE *pwfile, *opwfile; int err = 0; int oldmask; int found = 0; struct passwd *pwd = NULL; struct stat st; #ifdef WITH_SELINUX security_context_t prev_context=NULL; #endif if (howmany < 0) { return PAM_SUCCESS; } if (oldpass == NULL) { return PAM_SUCCESS; } oldmask = umask(077); #ifdef WITH_SELINUX if (SELINUX_ENABLED) { security_context_t passwd_context=NULL; if (getfilecon("/etc/passwd",&passwd_context)<0) { return PAM_AUTHTOK_ERR; }; if (getfscreatecon(&prev_context)<0) { freecon(passwd_context); return PAM_AUTHTOK_ERR; } if (setfscreatecon(passwd_context)) { freecon(passwd_context); freecon(prev_context); return PAM_AUTHTOK_ERR; } freecon(passwd_context); } #endif pwfile = fopen(OPW_TMPFILE, "w"); umask(oldmask); if (pwfile == NULL) { err = 1; goto done; } opwfile = fopen(OLD_PASSWORDS_FILE, "r"); if (opwfile == NULL) { fclose(pwfile); err = 1; goto done; } if (fstat(fileno(opwfile), &st) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } if (fchmod(fileno(pwfile), st.st_mode) == -1) { fclose(opwfile); fclose(pwfile); err = 1; goto done; } while (fgets(buf, 16380, opwfile)) { if (!strncmp(buf, forwho, strlen(forwho))) { char *sptr = NULL; found = 1; if (howmany == 0) continue; buf[strlen(buf) - 1] = '\0'; s_luser = strtok_r(buf, ":", &sptr); s_uid = strtok_r(NULL, ":", &sptr); s_npas = strtok_r(NULL, ":", &sptr); s_pas = strtok_r(NULL, ":", &sptr); npas = strtol(s_npas, NULL, 10) + 1; while (npas > howmany) { s_pas = strpbrk(s_pas, ","); if (s_pas != NULL) s_pas++; npas--; } pass = crypt_md5_wrapper(oldpass); if (s_pas == NULL) snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s\n", s_luser, s_uid, npas, pass); else snprintf(nbuf, sizeof(nbuf),"%s:%s:%d:%s,%s\n", s_luser, s_uid, npas, s_pas, pass); _pam_delete(pass); if (fputs(nbuf, pwfile) < 0) { err = 1; break; } } else if (fputs(buf, pwfile) < 0) { err = 1; break; } } fclose(opwfile); if (!found) { pwd = pam_modutil_getpwnam(pamh, forwho); if (pwd == NULL) { err = 1; } else { pass = crypt_md5_wrapper(oldpass); snprintf(nbuf, sizeof(nbuf), "%s:%lu:1:%s\n", forwho, (unsigned long)pwd->pw_uid, pass); _pam_delete(pass); if (fputs(nbuf, pwfile) < 0) { err = 1; } } } if (fflush(pwfile) || fsync(fileno(pwfile))) { D(("fflush or fsync error writing entries to old passwords file: %m")); err = 1; } if (fclose(pwfile)) { D(("fclose error writing entries to old passwords file: %m")); err = 1; } done: if (!err) { if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE)) err = 1; } #ifdef WITH_SELINUX if (SELINUX_ENABLED) { if (setfscreatecon(prev_context)) { err = 1; } if (prev_context) freecon(prev_context); prev_context=NULL; } #endif if (!err) { return PAM_SUCCESS; } else { unlink(OPW_TMPFILE); return PAM_AUTHTOK_ERR; } }
static JSBool rpmsx_getprop(JSContext *cx, JSObject *obj, jsid id, jsval *vp) { void * ptr = JS_GetInstancePrivate(cx, obj, &rpmsxClass, NULL); jsint tiny = JSVAL_TO_INT(id); #if defined(WITH_SELINUX) security_context_t con = NULL; #endif /* XXX the class has ptr == NULL, instances have ptr != NULL. */ if (ptr == NULL) return JS_TRUE; switch (tiny) { case _DEBUG: *vp = INT_TO_JSVAL(_debug); break; #if defined(WITH_SELINUX) case _CURRENT: *vp = _GET_CON(!getcon(&con)); break; case _PID: *vp = _GET_CON(!getpidcon(getpid(), &con)); break; case _PPID: *vp = _GET_CON(!getpidcon(getppid(), &con)); break; case _PREV: *vp = _GET_CON(!getprevcon(&con)); break; case _EXEC: *vp = _GET_CON(!getexeccon(&con)); break; case _FSCREATE: *vp = _GET_CON(!getfscreatecon(&con)); break; case _KEYCREATE: *vp = _GET_CON(!getkeycreatecon(&con)); break; case _SOCKCREATE: *vp = _GET_CON(!getsockcreatecon(&con)); break; case _ENFORCE: *vp = INT_TO_JSVAL(security_getenforce()); break; case _DENY: *vp = INT_TO_JSVAL(security_deny_unknown()); break; case _POLICYVERS: *vp = INT_TO_JSVAL(security_policyvers()); break; case _ENABLED: *vp = INT_TO_JSVAL(is_selinux_enabled()); break; case _MLSENABLED: *vp = INT_TO_JSVAL(is_selinux_mls_enabled()); break; #ifdef NOTYET case _BOOLS: *vp = ; break; #endif case _ROOT: *vp = _GET_STR(selinux_policy_root()); break; case _BINARY: *vp = _GET_STR(selinux_binary_policy_path()); break; case _FAILSAFE: *vp = _GET_STR(selinux_failsafe_context_path());break; case _REMOVABLE: *vp = _GET_STR(selinux_removable_context_path());break; case _DEFAULT: *vp = _GET_STR(selinux_default_context_path()); break; case _USER: *vp = _GET_STR(selinux_user_contexts_path()); break; case _FCON: *vp = _GET_STR(selinux_file_context_path()); break; case _FCONHOME: *vp = _GET_STR(selinux_file_context_homedir_path());break; case _FCONLOCAL: *vp = _GET_STR(selinux_file_context_local_path());break; case _FCONSUBS: *vp = _GET_STR(selinux_file_context_subs_path());break; case _HOMEDIR: *vp = _GET_STR(selinux_homedir_context_path()); break; case _MEDIA: *vp = _GET_STR(selinux_media_context_path()); break; case _VIRTDOMAIN: *vp = _GET_STR(selinux_virtual_domain_context_path());break; case _VIRTIMAGE: *vp = _GET_STR(selinux_virtual_image_context_path());break; case _X: *vp = _GET_STR(selinux_x_context_path()); break; case _CONTEXTS: *vp = _GET_STR(selinux_contexts_path()); break; case _SECURETTY: *vp = _GET_STR(selinux_securetty_types_path()); break; case _BOOLEANS: *vp = _GET_STR(selinux_booleans_path()); break; case _CUSTOMTYPES: *vp = _GET_STR(selinux_customizable_types_path());break; case _USERS: *vp = _GET_STR(selinux_users_path()); break; case _USERSCONF: *vp = _GET_STR(selinux_usersconf_path()); break; case _XLATIONS: *vp = _GET_STR(selinux_translations_path()); break; case _COLORS: *vp = _GET_STR(selinux_colors_path()); break; case _NETFILTER: *vp = _GET_STR(selinux_netfilter_context_path());break; case _PATH: *vp = _GET_STR(selinux_path()); break; #endif default: break; } #if defined(WITH_SELINUX) if (con) { freecon(con); con = NULL; } #endif return JS_TRUE; }