コード例 #1
0
ファイル: copydir.c プロジェクト: justinc1985/IntelRangeley
/*
 * selinux_file_context - Set the security context before any file or
 *                        directory creation.
 *
 *	selinux_file_context () should be called before any creation of file,
 *	symlink, directory, ...
 *
 *	Callers may have to Reset SELinux to create files with default
 *	contexts:
 *		setfscreatecon (NULL);
 */
int selinux_file_context (const char *dst_name)
{
	static bool selinux_checked = false;
	static bool selinux_enabled;
	security_context_t scontext = NULL;

	if (!selinux_checked) {
		selinux_enabled = is_selinux_enabled () > 0;
		selinux_checked = true;
	}

	if (selinux_enabled) {
		/* Get the default security context for this file */
		if (matchpathcon (dst_name, 0, &scontext) < 0) {
			if (security_getenforce () != 0) {
				return 1;
			}
		}
		/* Set the security context for the next created file */
		if (setfscreatecon (scontext) < 0) {
			if (security_getenforce () != 0) {
				return 1;
			}
		}
		freecon (scontext);
	}
	return 0;
}
コード例 #2
0
ファイル: install.c プロジェクト: 593141477/Learning-Linux
static void setdefaultfilecon(const char *path)
{
	struct stat s;
	security_context_t scontext = NULL;

	if (!is_selinux_enabled()) {
		return;
	}
	if (lstat(path, &s) != 0) {
		return;
	}

	if (matchpathcon(path, s.st_mode, &scontext) < 0) {
		goto out;
	}
	if (strcmp(scontext, "<<none>>") == 0) {
		goto out;
	}

	if (lsetfilecon(path, scontext) < 0) {
		if (errno != ENOTSUP) {
			bb_perror_msg("warning: can't change context"
					" of %s to %s", path, scontext);
		}
	}

 out:
	freecon(scontext);
}
コード例 #3
0
ファイル: selinux.c プロジェクト: arnoo/coreutils_magic
/*
  This function takes a path and a mode, it calls computecon to get the
  label of the path object if the current process created it, then it calls
  matchpathcon to get the default type for the object.  It substitutes the
  default type into label.  It tells the SELinux Kernel to label all new file
  system objects created by the current process with this label.

  Returns -1 on failure.  errno will be set appropriately.
*/
int
defaultcon (char const *path, mode_t mode)
{
  int rc = -1;
  char *scon = NULL;
  char *tcon = NULL;
  context_t scontext = 0, tcontext = 0;
  const char *contype;
  char *constr;
  char *newpath = NULL;

  if (! IS_ABSOLUTE_FILE_NAME (path))
    {
      /* Generate absolute path as required by subsequent matchpathcon(),
         with libselinux < 2.1.5 2011-0826.  */
      newpath = canonicalize_filename_mode (path, CAN_MISSING);
      if (! newpath)
        error (EXIT_FAILURE, errno, _("error canonicalizing %s"),
               quote (path));
      path = newpath;
    }

  if (matchpathcon (path, 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 (computecon (path, mode, &tcon) < 0)
    goto quit;
  if (!(scontext = context_new (scon)))
    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;

  rc = setfscreatecon (constr);

quit:
  context_free (scontext);
  context_free (tcontext);
  freecon (scon);
  freecon (tcon);
  free (newpath);
  return rc;
}
コード例 #4
0
VALUE Selinux_matchpathcon(VALUE self, VALUE path, VALUE mode)
{
	char *_path = StringValuePtr(path);
	mode_t _mode = FIX2INT(mode);
	security_context_t _con = NULL;
	int _result = matchpathcon(_path, _mode, &_con);
	VALUE result = rb_ary_new3(2, INT2FIX(_result), _result == -1 ? Qnil : rb_str_new2(_con));
	freecon(_con);
	return result;
}
コード例 #5
0
void
ssh_selinux_setfscreatecon(const char *path)
{
		security_context_t context;

		if (path == NULL) {
			setfscreatecon(NULL);
			return;
		}
		matchpathcon(path, 0700, &context);
		setfscreatecon(context);
}
コード例 #6
0
void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode)
{
	security_context_t scontext = NULL;

	if (!selinux_enabled)
		return;
	if (matchpathcon(file, mode, &scontext) < 0) {
		err(udev, "matchpathcon(%s) failed\n", file);
		return;
	}
	if (setfscreatecon(scontext) < 0)
		err(udev, "setfscreatecon %s failed: %m\n", file);
	freecon(scontext);
}
コード例 #7
0
ファイル: port-linux.c プロジェクト: 2trill2spill/freebsd
void
ssh_selinux_setfscreatecon(const char *path)
{
	security_context_t context;

	if (!ssh_selinux_enabled())
		return;
	if (path == NULL) {
		setfscreatecon(NULL);
		return;
	}
	if (matchpathcon(path, 0700, &context) == 0)
		setfscreatecon(context);
}
コード例 #8
0
ファイル: matchpathcon.c プロジェクト: AlickHill/Lantern
static int print_matchpathcon(char *path, int noprint)
{
	char *buf;
	int rc = matchpathcon(path, 0, &buf);
	if (rc < 0) {
		bb_perror_msg("matchpathcon(%s) failed", path);
		return 1;
	}
	if (!noprint)
		printf("%s\t%s\n", path, buf);
	else
		printf("%s\n", buf);

	freecon(buf);
	return 0;
}
コード例 #9
0
ファイル: security_selinux.c プロジェクト: intgr/libvirt
/* Set fcon to the appropriate label for path and mode, or return -1.  */
static int
getContext(const char *newpath, mode_t mode, security_context_t *fcon)
{
#if HAVE_SELINUX_LABEL_H
    struct selabel_handle *handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
    int ret;

    if (handle == NULL)
        return -1;

    ret = selabel_lookup(handle, fcon, newpath, mode);
    selabel_close(handle);
    return ret;
#else
    return matchpathcon(newpath, mode, fcon);
#endif
}
コード例 #10
0
ファイル: copydir.c プロジェクト: OPSF/uClinux
static int selinux_file_context (const char *dst_name)
{
	security_context_t scontext = NULL;

	if (selinux_enabled < 0)
		selinux_enabled = is_selinux_enabled () > 0;
	if (selinux_enabled) {
		if (matchpathcon (dst_name, 0, &scontext) < 0)
			if (security_getenforce ())
				return 1;
		if (setfscreatecon (scontext) < 0)
			if (security_getenforce ())
				return 1;
		freecon (scontext);
	}
	return 0;
}
コード例 #11
0
ファイル: matchpathcon.c プロジェクト: keloyang/sebusybox
int printmatchpathcon(char *path, int header)
{
	char *buf;
	int rc = matchpathcon(path, 0, &buf);
	if (rc < 0) {
		fprintf(stderr, "matchpathcon(%s) failed: %s\n", path,
			strerror(errno));
		return 1;
	}
	if (header)
		printf("%s\t%s\n", path, buf);
	else
		printf("%s\n", buf);

	freecon(buf);
	return 0;
}
コード例 #12
0
ファイル: timedatex.c プロジェクト: AdamWill/timedatex
static void set_default_file_context(const gchar *path, const gchar *target) {
#ifdef HAVE_SELINUX
	security_context_t con;

	if (!is_selinux_enabled())
		return;

	if (matchpathcon_init_prefix(NULL, target))
		return;

	if (!matchpathcon(LOCALTIME_PATH, 0, &con)) {
		lsetfilecon(path, con);
		freecon(con);
	}

	matchpathcon_fini();
#endif
}
コード例 #13
0
ファイル: rpmsx.c プロジェクト: avokhmin/RPM5
const char * rpmsxMatch(rpmsx sx, const char *fn, mode_t mode)
{
    const char * scon = NULL;

    if (sx == NULL) sx = rpmsxI();

#if defined(WITH_SELINUX)
    if (sx->fn) {
	static char nocon[] = "";
	int rc = matchpathcon(fn, mode, (security_context_t *)&scon);
	if (rc < 0)
	    scon = xstrdup(nocon);
    }
#endif

if (_rpmsx_debug < 0 || (_rpmsx_debug > 0 && scon != NULL && *scon != '\0' &&strcmp("(null)", scon)))
fprintf(stderr, "<-- %s(%p,%s,0%o) \"%s\"\n", __FUNCTION__, sx, fn, mode, scon);
    return scon;
}
コード例 #14
0
ファイル: matchpathcon.c プロジェクト: SELinuxProject/selinux
static int printmatchpathcon(const char *path, int header, int mode)
{
	char *buf;
	int rc = matchpathcon(path, mode, &buf);
	if (rc < 0) {
		if (errno == ENOENT) {
			buf = strdup("<<none>>");
		} else {
			fprintf(stderr, "matchpathcon(%s) failed: %s\n", path,
				strerror(errno));
			return 1;
		}
	}
	if (header)
		printf("%s\t%s\n", path, buf);
	else
		printf("%s\n", buf);

	freecon(buf);
	return 0;
}
コード例 #15
0
ファイル: selinux.c プロジェクト: PallaviKumariJha/SSSD
/*
 * selinux_file_context - Set the security context before any file or
 *                        directory creation.
 *
 *  selinux_file_context () should be called before any creation of file,
 *  symlink, directory, ...
 *
 *  Callers may have to Reset SELinux to create files with default
 *  contexts:
 *      reset_selinux_file_context();
 */
int selinux_file_context(const char *dst_name)
{
    security_context_t scontext = NULL;

    if (is_selinux_enabled() == 1) {
        /* Get the default security context for this file */
        if (matchpathcon(dst_name, 0, &scontext) < 0) {
            if (security_getenforce () != 0) {
                return 1;
            }
        }
        /* Set the security context for the next created file */
        if (setfscreatecon(scontext) < 0) {
            if (security_getenforce() != 0) {
                return 1;
            }
        }
        freecon(scontext);
    }

    return 0;
}
コード例 #16
0
ファイル: archives.c プロジェクト: Minipig/dpkg
static void
set_selinux_path_context(const char *matchpath, const char *path, mode_t mode)
{
#ifdef WITH_SELINUX
  static int selinux_enabled = -1;
  security_context_t scontext = NULL;
  int ret;

  /* If there's no file type, just give up. */
  if ((mode & S_IFMT) == 0)
    return;

  /* Set selinux_enabled if it is not already set (singleton). */
  if (selinux_enabled < 0)
    selinux_enabled = (is_selinux_enabled() > 0);

  /* If SE Linux is not enabled just do nothing. */
  if (!selinux_enabled)
    return;

  /* XXX: Well, we could use set_matchpathcon_printf() to redirect the
   * errors from the following bit, but that seems too much effort. */

  /* Do nothing if we can't figure out what the context is, or if it has
   * no context; in which case the default context shall be applied. */
  ret = matchpathcon(matchpath, mode & S_IFMT, &scontext);
  if (ret == -1 || (ret == 0 && scontext == NULL))
    return;

  if (strcmp(scontext, "<<none>>") != 0) {
    if (lsetfilecon(path, scontext) < 0)
      /* XXX: This might need to be fatal instead!? */
      perror("Error setting security context for next file object:");
  }

  freecon(scontext);
#endif /* WITH_SELINUX */
}
コード例 #17
0
ファイル: mkswap.c プロジェクト: Cheezzolo123/MonteDroid
static void mkswap_selinux_setcontext(int fd, const char *path)
{
	struct stat stbuf;

	if (!is_selinux_enabled())
		return;

	if (fstat(fd, &stbuf) < 0)
		bb_perror_msg_and_die("fstat failed");
	if (S_ISREG(stbuf.st_mode)) {
		security_context_t newcon;
		security_context_t oldcon = NULL;
		context_t context;

		if (fgetfilecon(fd, &oldcon) < 0) {
			if (errno != ENODATA)
				goto error;
			if (matchpathcon(path, stbuf.st_mode, &oldcon) < 0)
				goto error;
		}
		context = context_new(oldcon);
		if (!context || context_type_set(context, "swapfile_t"))
			goto error;
		newcon = context_str(context);
		if (!newcon)
			goto error;
		/* fsetfilecon_raw is hidden */
		if (strcmp(oldcon, newcon) != 0 && fsetfilecon(fd, newcon) < 0)
			goto error;
		if (ENABLE_FEATURE_CLEAN_UP) {
			context_free(context);
			freecon(oldcon);
		}
	}
	return;
 error:
	bb_perror_msg_and_die("SELinux relabeling failed");
}
コード例 #18
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;
}
コード例 #19
0
ファイル: mkswap.c プロジェクト: pradeepkr12/util-linux
int main(int argc, char **argv)
{
	struct mkswap_control ctl = { .fd = -1 };
	int c;
	uint64_t sz;
	int version = SWAP_VERSION;
	char *block_count = NULL, *strsz = NULL;
#ifdef HAVE_LIBUUID
	const char *opt_uuid = NULL;
	uuid_t uuid_dat;
#endif
	static const struct option longopts[] = {
		{ "check",       no_argument,       0, 'c' },
		{ "force",       no_argument,       0, 'f' },
		{ "pagesize",    required_argument, 0, 'p' },
		{ "label",       required_argument, 0, 'L' },
		{ "swapversion", required_argument, 0, 'v' },
		{ "uuid",        required_argument, 0, 'U' },
		{ "version",     no_argument,       0, 'V' },
		{ "help",        no_argument,       0, 'h' },
		{ NULL,          0, 0, 0 }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while((c = getopt_long(argc, argv, "cfp:L:v:U:Vh", longopts, NULL)) != -1) {
		switch (c) {
		case 'c':
			ctl.check = 1;
			break;
		case 'f':
			ctl.force = 1;
			break;
		case 'p':
			ctl.user_pagesize = strtou32_or_err(optarg, _("parsing page size failed"));
			break;
		case 'L':
			ctl.opt_label = optarg;
			break;
		case 'v':
			version = strtos32_or_err(optarg, _("parsing version number failed"));
			if (version != SWAP_VERSION)
				errx(EXIT_FAILURE,
					_("swapspace version %d is not supported"), version);
			break;
		case 'U':
#ifdef HAVE_LIBUUID
			opt_uuid = optarg;
#else
			warnx(_("warning: ignoring -U (UUIDs are unsupported by %s)"),
				program_invocation_short_name);
#endif
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			exit(EXIT_SUCCESS);
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}
	}

	if (optind < argc)
		ctl.devname = argv[optind++];
	if (optind < argc)
		block_count = argv[optind++];
	if (optind != argc) {
		warnx(_("only one device argument is currently supported"));
		usage(stderr);
	}

#ifdef HAVE_LIBUUID
	if(opt_uuid) {
		if (uuid_parse(opt_uuid, uuid_dat) != 0)
			errx(EXIT_FAILURE, _("error: parsing UUID failed"));
	} else
		uuid_generate(uuid_dat);
	ctl.uuid = uuid_dat;
#endif

	init_signature_page(&ctl);	/* get pagesize and allocate signature page */

	if (!ctl.devname) {
		warnx(_("error: Nowhere to set up swap on?"));
		usage(stderr);
	}
	if (block_count) {
		/* this silly user specified the number of blocks explicitly */
		uint64_t blks = strtou64_or_err(block_count,
					_("invalid block count argument"));
		ctl.npages = blks / (ctl.pagesize / 1024);
	}

	sz = get_size(&ctl);
	if (!ctl.npages)
		ctl.npages = sz;
	else if (ctl.npages > sz && !ctl.force)
		errx(EXIT_FAILURE,
			_("error: "
			  "size %llu KiB is larger than device size %ju KiB"),
			ctl.npages * (ctl.pagesize / 1024), sz * (ctl.pagesize / 1024));

	if (ctl.npages < MIN_GOODPAGES)
		errx(EXIT_FAILURE,
		     _("error: swap area needs to be at least %ld KiB"),
		     (long)(MIN_GOODPAGES * ctl.pagesize / 1024));
	if (ctl.npages > UINT32_MAX) {
		/* true when swap is bigger than 17.59 terabytes */
		ctl.npages = UINT32_MAX;
		warnx(_("warning: truncating swap area to %llu KiB"),
			ctl.npages * ctl.pagesize / 1024);
	}

	if (is_mounted(ctl.devname))
		errx(EXIT_FAILURE, _("error: "
			"%s is mounted; will not make swapspace"),
			ctl.devname);

	open_device(&ctl);

	if (ctl.check)
		check_blocks(&ctl);

	wipe_device(&ctl);

	assert(ctl.hdr);
	ctl.hdr->version = version;
	ctl.hdr->last_page = ctl.npages - 1;
	ctl.hdr->nr_badpages = ctl.nbadpages;

	if ((ctl.npages - MIN_GOODPAGES) < ctl.nbadpages)
		errx(EXIT_FAILURE, _("Unable to set up swap-space: unreadable"));

	sz = (ctl.npages - ctl.nbadpages - 1) * ctl.pagesize;
	strsz = size_to_human_string(SIZE_SUFFIX_SPACE | SIZE_SUFFIX_3LETTER, sz);

	printf(_("Setting up swapspace version %d, size = %s (%ju bytes)\n"),
		version, strsz, sz);
	free(strsz);

	set_signature(&ctl);
	set_uuid_and_label(&ctl);

	write_header_to_device(&ctl);

	deinit_signature_page(&ctl);

#ifdef HAVE_LIBSELINUX
	if (S_ISREG(ctl.devstat.st_mode) && is_selinux_enabled() > 0) {
		security_context_t context_string;
		security_context_t oldcontext;
		context_t newcontext;

		if (fgetfilecon(ctl.fd, &oldcontext) < 0) {
			if (errno != ENODATA)
				err(EXIT_FAILURE,
					_("%s: unable to obtain selinux file label"),
					ctl.devname);
			if (matchpathcon(ctl.devname, ctl.devstat.st_mode, &oldcontext))
				errx(EXIT_FAILURE, _("unable to matchpathcon()"));
		}
		if (!(newcontext = context_new(oldcontext)))
			errx(EXIT_FAILURE, _("unable to create new selinux context"));
		if (context_type_set(newcontext, SELINUX_SWAPFILE_TYPE))
			errx(EXIT_FAILURE, _("couldn't compute selinux context"));

		context_string = context_str(newcontext);

		if (strcmp(context_string, oldcontext)!=0) {
			if (fsetfilecon(ctl.fd, context_string))
				err(EXIT_FAILURE, _("unable to relabel %s to %s"),
						ctl.devname, context_string);
		}
		context_free(newcontext);
		freecon(oldcontext);
	}
#endif
	/*
	 * A subsequent swapon() will fail if the signature
	 * is not actually on disk. (This is a kernel bug.)
	 * The fsync() in close_fd() will take care of writing.
	 */
	if (close_fd(ctl.fd) != 0)
		err(EXIT_FAILURE, _("write failed"));
	return EXIT_SUCCESS;
}
コード例 #20
0
ファイル: mkswap.c プロジェクト: AnunkunramA/util-linux
int
main(int argc, char **argv) {
	struct stat statbuf;
	struct swap_header_v1_2 *hdr;
	int c;
	unsigned long long maxpages;
	unsigned long long goodpages;
	unsigned long long sz;
	off_t offset;
	int force = 0;
	int version = 1;
	char *block_count = 0;
	char *opt_label = NULL;
	unsigned char *uuid = NULL;
#ifdef HAVE_LIBUUID
	const char *opt_uuid = NULL;
	uuid_t uuid_dat;
#endif
	static const struct option longopts[] = {
		{ "check",       no_argument,       0, 'c' },
		{ "force",       no_argument,       0, 'f' },
		{ "pagesize",    required_argument, 0, 'p' },
		{ "label",       required_argument, 0, 'L' },
		{ "swapversion", required_argument, 0, 'v' },
		{ "uuid",        required_argument, 0, 'U' },
		{ "version",     no_argument,       0, 'V' },
		{ "help",        no_argument,       0, 'h' },
		{ NULL,          0, 0, 0 }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while((c = getopt_long(argc, argv, "cfp:L:v:U:Vh", longopts, NULL)) != -1) {
		switch (c) {
		case 'c':
			check=1;
			break;
		case 'f':
			force=1;
			break;
		case 'p':
			user_pagesize = strtou32_or_err(optarg, _("parsing page size failed"));
			break;
		case 'L':
			opt_label = optarg;
			break;
		case 'v':
			version = strtos32_or_err(optarg, _("parsing version number failed"));
			break;
		case 'U':
#ifdef HAVE_LIBUUID
			opt_uuid = optarg;
#else
			warnx(_("warning: ignoring -U (UUIDs are unsupported by %s)"),
				program_invocation_short_name);
#endif
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			exit(EXIT_SUCCESS);
		case 'h':
			usage(stdout);
		default:
			usage(stderr);
		}
	}
	if (optind < argc)
		device_name = argv[optind++];
	if (optind < argc)
		block_count = argv[optind++];
	if (optind != argc) {
		warnx(_("only one device argument is currently supported"));
		usage(stderr);
	}

	if (version != 1)
		errx(EXIT_FAILURE,
			_("swapspace version %d is not supported"), version);

#ifdef HAVE_LIBUUID
	if(opt_uuid) {
		if (uuid_parse(opt_uuid, uuid_dat) != 0)
			errx(EXIT_FAILURE, _("error: parsing UUID failed"));
	} else
		uuid_generate(uuid_dat);
	uuid = uuid_dat;
#endif

	init_signature_page();	/* get pagesize */

	if (!device_name) {
		warnx(_("error: Nowhere to set up swap on?"));
		usage(stderr);
	}
	if (block_count) {
		/* this silly user specified the number of blocks explicitly */
		uint64_t blks = strtou64_or_err(block_count,
					_("invalid block count argument"));
		PAGES = blks / (pagesize / 1024);
	}
	sz = get_size(device_name);
	if (!PAGES)
		PAGES = sz;
	else if (PAGES > sz && !force) {
		errx(EXIT_FAILURE,
			_("error: "
			  "size %llu KiB is larger than device size %llu KiB"),
			PAGES*(pagesize/1024), sz*(pagesize/1024));
	}

	if (PAGES < MIN_GOODPAGES) {
		warnx(_("error: swap area needs to be at least %ld KiB"),
			(long)(MIN_GOODPAGES * pagesize/1024));
		usage(stderr);
	}

#ifdef __linux__
	if (get_linux_version() >= KERNEL_VERSION(2,3,4))
		maxpages = UINT_MAX + 1ULL;
	else if (get_linux_version() >= KERNEL_VERSION(2,2,1))
		maxpages = V1_MAX_PAGES;
	else
#endif
		maxpages = V1_OLD_MAX_PAGES;

	if (PAGES > maxpages) {
		PAGES = maxpages;
		warnx(_("warning: truncating swap area to %llu KiB"),
			PAGES * pagesize / 1024);
	}

	if (is_mounted(device_name))
		errx(EXIT_FAILURE, _("error: "
			"%s is mounted; will not make swapspace"),
			device_name);

	if (stat(device_name, &statbuf) < 0) {
		perror(device_name);
		exit(EXIT_FAILURE);
	}
	if (S_ISBLK(statbuf.st_mode))
		DEV = open(device_name, O_RDWR | O_EXCL);
	else
		DEV = open(device_name, O_RDWR);

	if (DEV < 0) {
		perror(device_name);
		exit(EXIT_FAILURE);
	}

	if (!S_ISBLK(statbuf.st_mode))
		check=0;
	else if (blkdev_is_misaligned(DEV))
		warnx(_("warning: %s is misaligned"), device_name);

	if (check)
		check_blocks();

	wipe_device(DEV, device_name, force);

	hdr = (struct swap_header_v1_2 *) signature_page;
	hdr->version = 1;
	hdr->last_page = PAGES - 1;
	hdr->nr_badpages = badpages;

	if (badpages > PAGES - MIN_GOODPAGES)
		errx(EXIT_FAILURE, _("Unable to set up swap-space: unreadable"));

	goodpages = PAGES - badpages - 1;
	printf(_("Setting up swapspace version 1, size = %llu KiB\n"),
		goodpages * pagesize / 1024);

	write_signature("SWAPSPACE2");
	write_uuid_and_label(uuid, opt_label);

	offset = 1024;
	if (lseek(DEV, offset, SEEK_SET) != offset)
		errx(EXIT_FAILURE, _("unable to rewind swap-device"));
	if (write_all(DEV, (char *) signature_page + offset,
				    pagesize - offset) == -1)
		err(EXIT_FAILURE,
			_("%s: unable to write signature page"),
			device_name);

#ifdef HAVE_LIBSELINUX
	if (S_ISREG(statbuf.st_mode) && is_selinux_enabled() > 0) {
		security_context_t context_string;
		security_context_t oldcontext;
		context_t newcontext;

		if (fgetfilecon(DEV, &oldcontext) < 0) {
			if (errno != ENODATA)
				err(EXIT_FAILURE,
					_("%s: unable to obtain selinux file label"),
					device_name);
			if (matchpathcon(device_name, statbuf.st_mode, &oldcontext))
				errx(EXIT_FAILURE, _("unable to matchpathcon()"));
		}
		if (!(newcontext = context_new(oldcontext)))
			errx(EXIT_FAILURE, _("unable to create new selinux context"));
		if (context_type_set(newcontext, SELINUX_SWAPFILE_TYPE))
			errx(EXIT_FAILURE, _("couldn't compute selinux context"));

		context_string = context_str(newcontext);

		if (strcmp(context_string, oldcontext)!=0) {
			if (fsetfilecon(DEV, context_string))
				err(EXIT_FAILURE, _("unable to relabel %s to %s"),
						device_name, context_string);
		}
		context_free(newcontext);
		freecon(oldcontext);
	}
#endif
	/*
	 * A subsequent swapon() will fail if the signature
	 * is not actually on disk. (This is a kernel bug.)
	 * The fsync() in close_fd() will take care of writing.
	 */
	if (close_fd(DEV) != 0)
		err(EXIT_FAILURE, _("write failed"));
	return EXIT_SUCCESS;
}
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);
}
コード例 #22
0
ファイル: mkswap.c プロジェクト: tcdog001/autelan
int
main(int argc, char ** argv) {
	struct stat statbuf;
	struct swap_header_v1_2 *hdr;
	int i;
	unsigned long long maxpages;
	unsigned long long goodpages;
	unsigned long long sz;
	off_t offset;
	int force = 0;
	int version = 1;
	char *block_count = 0;
	char *pp;
	char *opt_label = NULL;
	unsigned char *uuid = NULL;
#ifdef HAVE_LIBUUID
	const char *opt_uuid = NULL;
	uuid_t uuid_dat;
#endif

	program_name = (argc && *argv) ? argv[0] : "mkswap";
	if ((pp = strrchr(program_name, '/')) != NULL)
		program_name = pp+1;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	if (argc == 2 &&
	    (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
		printf(_("%s (%s)\n"), program_name, PACKAGE_STRING);
		exit(0);
	}

	for (i=1; i<argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
				case 'c':
					check=1;
					break;
				case 'f':
					force=1;
					break;
				case 'p':
					pp = argv[i]+2;
					if (!*pp && i+1 < argc)
						pp = argv[++i];
					if (isnzdigit(*pp))
						user_pagesize = atoi(pp);
					else
						usage();
					break;
			        case 'L':
					pp = argv[i]+2;
					if (!*pp && i+1 < argc)
						pp = argv[++i];
					opt_label = pp;
				        break;
				case 'v':
					version = atoi(argv[i]+2);
					break;
				case 'U':
#ifdef HAVE_LIBUUID
					opt_uuid = argv[i]+2;
					if (!*opt_uuid && i+1 < argc)
						opt_uuid = argv[++i];
#else
					fprintf(stderr, _("%1$s: warning: ignore -U (UUIDs are unsupported by %1$s)\n"),
						program_name);
#endif
					break;
				default:
					usage();
			}
		} else if (!device_name) {
			device_name = argv[i];
		} else if (!block_count) {
			block_count = argv[i];
		} else
			usage();
	}

	if (version != 1) {
		fprintf(stderr, _("%s: does not support swapspace version %d.\n"),
			program_name, version);
		exit(EXIT_FAILURE);
	}

#ifdef HAVE_LIBUUID
	if(opt_uuid) {
		if (uuid_parse(opt_uuid, uuid_dat) != 0)
			die(_("error: UUID parsing failed"));
	} else
		uuid_generate(uuid_dat);
	uuid = uuid_dat;
#endif

	init_signature_page();	/* get pagesize */
	atexit(deinit_signature_page);

	if (!device_name) {
		fprintf(stderr,
			_("%s: error: Nowhere to set up swap on?\n"),
			program_name);
		usage();
	}
	if (block_count) {
		/* this silly user specified the number of blocks explicitly */
		char *tmp = NULL;
		long long blks;

		errno = 0;
		blks = strtoll(block_count, &tmp, 0);
		if ((tmp == block_count) ||
		    (tmp && *tmp) ||
		    (errno != 0 && (blks == LLONG_MAX || blks == LLONG_MIN)) ||
		    blks < 0)
			usage();

		PAGES = blks / (pagesize / 1024);
	}
	sz = get_size(device_name);
	if (!PAGES) {
		PAGES = sz;
	} else if (PAGES > sz && !force) {
		fprintf(stderr,
			_("%s: error: "
			  "size %llu KiB is larger than device size %llu KiB\n"),
			program_name,
			PAGES*(pagesize/1024), sz*(pagesize/1024));
		exit(1);
	}

	if (PAGES < MIN_GOODPAGES) {
		fprintf(stderr,
			_("%s: error: swap area needs to be at least %ld KiB\n"),
			program_name, (long)(MIN_GOODPAGES * pagesize/1024));
		usage();
	}

#ifdef __linux__
	if (get_linux_version() >= KERNEL_VERSION(2,3,4))
		maxpages = UINT_MAX + 1ULL;
	else if (get_linux_version() >= KERNEL_VERSION(2,2,1))
		maxpages = V1_MAX_PAGES;
	else
#endif
		maxpages = V1_OLD_MAX_PAGES;

	if (PAGES > maxpages) {
		PAGES = maxpages;
		fprintf(stderr,
			_("%s: warning: truncating swap area to %llu KiB\n"),
			program_name, PAGES * pagesize / 1024);
	}

	if (stat(device_name, &statbuf) < 0) {
		perror(device_name);
		exit(EXIT_FAILURE);
	}
	if (S_ISBLK(statbuf.st_mode))
		DEV = open(device_name, O_RDWR | O_EXCL);
	else
		DEV = open(device_name, O_RDWR);

	if (DEV < 0) {
		perror(device_name);
		exit(1);
	}

	/* Want a block device. Probably not /dev/hda or /dev/hdb. */
	if (!S_ISBLK(statbuf.st_mode))
		check=0;
	else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340) {
		fprintf(stderr,
			_("%s: error: "
			  "will not try to make swapdevice on '%s'\n"),
			program_name, device_name);
		exit(1);
	} else if (check_mount()) {
		fprintf(stderr,
			_("%s: error: "
			  "%s is mounted; will not make swapspace.\n"),
			program_name, device_name);
		exit(1);
	}

	if (check)
		check_blocks();

	zap_bootbits(DEV, device_name, force, S_ISBLK(statbuf.st_mode));

	hdr = (struct swap_header_v1_2 *) signature_page;
	hdr->version = 1;
	hdr->last_page = PAGES - 1;
	hdr->nr_badpages = badpages;

	if (badpages > PAGES - MIN_GOODPAGES)
		die(_("Unable to set up swap-space: unreadable"));

	goodpages = PAGES - badpages - 1;
	printf(_("Setting up swapspace version 1, size = %llu KiB\n"),
		goodpages * pagesize / 1024);

	write_signature("SWAPSPACE2");
	write_uuid_and_label(uuid, opt_label);

	offset = 1024;
	if (lseek(DEV, offset, SEEK_SET) != offset)
		die(_("unable to rewind swap-device"));
	if (write_all(DEV, (char *) signature_page + offset,
				    pagesize - offset) == -1) {
		fprintf(stderr, _("%s: %s: unable to write signature page: %s"),
			program_name, device_name, strerror(errno));
		exit(1);
	}

	/*
	 * A subsequent swapon() will fail if the signature
	 * is not actually on disk. (This is a kernel bug.)
	 */
#ifdef HAVE_FSYNC
	if (fsync(DEV))
		 die(_("fsync failed"));
#endif

#ifdef HAVE_LIBSELINUX
	if (S_ISREG(statbuf.st_mode) && is_selinux_enabled() > 0) {
		security_context_t context_string;
		security_context_t oldcontext;
		context_t newcontext;

		if (fgetfilecon(DEV, &oldcontext) < 0) {
			if (errno != ENODATA) {
				fprintf(stderr, _("%s: %s: unable to obtain selinux file label: %s\n"),
						program_name, device_name,
						strerror(errno));
				exit(1);
			}
			if (matchpathcon(device_name, statbuf.st_mode, &oldcontext))
				die(_("unable to matchpathcon()"));
		}
		if (!(newcontext = context_new(oldcontext)))
			die(_("unable to create new selinux context"));
		if (context_type_set(newcontext, SELINUX_SWAPFILE_TYPE))
			die(_("couldn't compute selinux context"));

		context_string = context_str(newcontext);

		if (strcmp(context_string, oldcontext)!=0) {
			if (fsetfilecon(DEV, context_string)) {
				fprintf(stderr, _("%s: unable to relabel %s to %s: %s\n"),
						program_name, device_name,
						context_string,
						strerror(errno));
				exit(1);
			}
		}
		context_free(newcontext);
		freecon(oldcontext);
	}
#endif
	return 0;
}