/* * 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; }
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); }
/* 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; }
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; }
void ssh_selinux_setfscreatecon(const char *path) { security_context_t context; if (path == NULL) { setfscreatecon(NULL); return; } matchpathcon(path, 0700, &context); setfscreatecon(context); }
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); }
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); }
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; }
/* 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 }
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; }
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; }
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 }
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; }
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; }
/* * 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; }
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 */ }
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"); }
/* 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; }
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; }
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); }
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; }