コード例 #1
0
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;
	}
}
コード例 #2
0
ファイル: SELinux.c プロジェクト: ArashAll/klee
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;
}
コード例 #3
0
ファイル: copy_file.c プロジェクト: kjokinie/busybox
/* 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;
}
コード例 #4
0
ファイル: selinux.c プロジェクト: arnoo/coreutils_magic
/*
  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);
}
コード例 #6
0
ファイル: passverify.c プロジェクト: GNA-SERVICES-INC/MoNGate
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;
    }
}
コード例 #7
0
ファイル: passverify.c プロジェクト: GNA-SERVICES-INC/MoNGate
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;
    }
}
コード例 #8
0
ファイル: passverify.c プロジェクト: GNA-SERVICES-INC/MoNGate
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;
    }
}
コード例 #9
0
ファイル: rpmsx-js.c プロジェクト: cmjonze/rpm5_tarballs
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;
}