Example #1
0
File: loop.c Project: Excito/parted
static int
loop_probe (const PedDevice* dev)
{
	PedDisk *disk = loop_alloc (dev);
	if (!disk)
		goto error;

	void *buf;
	if (!ptt_read_sector (dev, 0, &buf))
		goto error_destroy_disk;
        int found_sig = !strncmp (buf, LOOP_SIGNATURE, strlen (LOOP_SIGNATURE));
        free (buf);

	int result;
	if (found_sig) {
		result = 1;
	} else {
		PedGeometry*	geom;

		geom = ped_geometry_new (dev, 0, disk->dev->length);
		if (!geom)
			goto error_destroy_disk;
		result = ped_file_system_probe (geom) != NULL;
		ped_geometry_destroy (geom);
	}
	loop_free (disk);
	return result;

error_destroy_disk:
	loop_free (disk);
error:
	return 0;
}
Example #2
0
static void adapt_summary(struct mesh* m)
{
  unsigned long total_elems = comm_add_ulong(mesh_count(m, mesh_dim(m)));
  double minqual = comm_min_double(mesh_min_quality(m));
  unsigned nedges = mesh_count(m, 1);
  double* edge_sizes = mesh_measure_edges_for_adapt(m);
  double min = comm_min_double(doubles_min(edge_sizes, nedges));
  double max = comm_max_double(doubles_max(edge_sizes, nedges));
  loop_free(edge_sizes);
  if (comm_rank() == 0)
    printf("%10lu elements, min quality %.0f%%, metric range %.2f - %.2f\n",
        total_elems, minqual * 100.0, min, max);
}
Example #3
0
int main(int argc, char **argv)
{
    krb5_error_code     retval;
    krb5_context        kcontext;
    verto_ctx *ctx;
    int errout = 0;
    int i;

    setlocale(LC_MESSAGES, "");
    if (strrchr(argv[0], '/'))
        argv[0] = strrchr(argv[0], '/')+1;

    if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) *
                                                  KRB5_KDC_MAX_REALMS))) {
        fprintf(stderr, _("%s: cannot get memory for realm list\n"), argv[0]);
        exit(1);
    }
    memset(kdc_realmlist, 0,
           (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));

    /*
     * A note about Kerberos contexts: This context, "kcontext", is used
     * for the KDC operations, i.e. setup, network connection and error
     * reporting.  The per-realm operations use the "realm_context"
     * associated with each realm.
     */
    retval = krb5int_init_context_kdc(&kcontext);
    if (retval) {
        com_err(argv[0], retval, _("while initializing krb5"));
        exit(1);
    }
    krb5_klog_init(kcontext, "kdc", argv[0], 1);
    kdc_err_context = kcontext;
    kdc_progname = argv[0];
    /* N.B.: After this point, com_err sends output to the KDC log
       file, and not to stderr.  We use the kdc_err wrapper around
       com_err to ensure that the error state exists in the context
       known to the krb5_klog callback. */

    initialize_kdc5_error_table();

    /*
     * Scan through the argument list
     */
    initialize_realms(kcontext, argc, argv);

    ctx = loop_init(VERTO_EV_TYPE_NONE);
    if (!ctx) {
        kdc_err(kcontext, ENOMEM, _("while creating main loop"));
        finish_realms();
        return 1;
    }

    load_preauth_plugins(kcontext);
    load_authdata_plugins(kcontext);

    retval = setup_sam();
    if (retval) {
        kdc_err(kcontext, retval, _("while initializing SAM"));
        finish_realms();
        return 1;
    }

    /* Handle each realm's ports */
    for (i=0; i<kdc_numrealms; i++) {
        char *cp = kdc_realmlist[i]->realm_ports;
        int port;
        while (cp && *cp) {
            if (*cp == ',' || isspace((int) *cp)) {
                cp++;
                continue;
            }
            port = strtol(cp, &cp, 10);
            if (cp == 0)
                break;
            retval = loop_add_udp_port(port);
            if (retval)
                goto net_init_error;
        }

        cp = kdc_realmlist[i]->realm_tcp_ports;
        while (cp && *cp) {
            if (*cp == ',' || isspace((int) *cp)) {
                cp++;
                continue;
            }
            port = strtol(cp, &cp, 10);
            if (cp == 0)
                break;
            retval = loop_add_tcp_port(port);
            if (retval)
                goto net_init_error;
        }
    }

    /*
     * Setup network listeners.  Disallow network reconfig in response to
     * routing socket messages if we're using worker processes, since the
     * children won't be able to re-open the listener sockets.  Hopefully our
     * platform has pktinfo support and doesn't need reconfigs.
     */
    if (workers == 0) {
        retval = loop_setup_routing_socket(ctx, NULL, kdc_progname);
        if (retval) {
            kdc_err(kcontext, retval, _("while initializing routing socket"));
            finish_realms();
            return 1;
        }
        retval = loop_setup_signals(ctx, NULL, reset_for_hangup);
        if (retval) {
            kdc_err(kcontext, retval, _("while initializing signal handlers"));
            finish_realms();
            return 1;
        }
    }
    if ((retval = loop_setup_network(ctx, NULL, kdc_progname))) {
    net_init_error:
        kdc_err(kcontext, retval, _("while initializing network"));
        finish_realms();
        return 1;
    }
    if (!nofork && daemon(0, 0)) {
        kdc_err(kcontext, errno, _("while detaching from tty"));
        finish_realms();
        return 1;
    }
    if (pid_file != NULL) {
        retval = write_pid_file(pid_file);
        if (retval) {
            kdc_err(kcontext, retval, _("while creating PID file"));
            finish_realms();
            return 1;
        }
    }
    if (workers > 0) {
        finish_realms();
        retval = create_workers(ctx, workers);
        if (retval) {
            kdc_err(kcontext, errno, _("creating worker processes"));
            return 1;
        }
        /* We get here only in a worker child process; re-initialize realms. */
        initialize_realms(kcontext, argc, argv);
    }
    krb5_klog_syslog(LOG_INFO, _("commencing operation"));
    if (nofork)
        fprintf(stderr, _("%s: starting...\n"), kdc_progname);

    verto_run(ctx);
    loop_free(ctx);
    krb5_klog_syslog(LOG_INFO, _("shutting down"));
    unload_preauth_plugins(kcontext);
    unload_authdata_plugins(kcontext);
    krb5_klog_close(kdc_context);
    finish_realms();
    if (kdc_realmlist)
        free(kdc_realmlist);
#ifndef NOCACHE
    kdc_free_lookaside(kcontext);
#endif
    krb5_free_context(kcontext);
    return errout;
}
Example #4
0
/*
 * Create num worker processes and return successfully in each child.  The
 * parent process will act as a supervisor and will only return from this
 * function in error cases.
 */
static krb5_error_code
create_workers(verto_ctx *ctx, int num)
{
    krb5_error_code retval;
    int i, status;
    pid_t pid, *pids;
#ifdef POSIX_SIGNALS
    struct sigaction s_action;
#endif /* POSIX_SIGNALS */

    /*
     * Setup our signal handlers which will forward to the children.
     * These handlers will be overriden in the child processes.
     */
#ifdef POSIX_SIGNALS
    (void) sigemptyset(&s_action.sa_mask);
    s_action.sa_flags = 0;
    s_action.sa_handler = on_monitor_signal;
    (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL);
    (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL);
    (void) sigaction(SIGQUIT, &s_action, (struct sigaction *) NULL);
    s_action.sa_handler = on_monitor_sighup;
    (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL);
#else  /* POSIX_SIGNALS */
    signal(SIGINT, on_monitor_signal);
    signal(SIGTERM, on_monitor_signal);
    signal(SIGQUIT, on_monitor_signal);
    signal(SIGHUP, on_monitor_sighup);
#endif /* POSIX_SIGNALS */

    /* Create child worker processes; return in each child. */
    krb5_klog_syslog(LOG_INFO, _("creating %d worker processes"), num);
    pids = calloc(num, sizeof(pid_t));
    if (pids == NULL)
        return ENOMEM;
    for (i = 0; i < num; i++) {
        pid = fork();
        if (pid == 0) {
            verto_reinitialize(ctx);
            retval = loop_setup_signals(ctx, NULL, reset_for_hangup);
            if (retval) {
                krb5_klog_syslog(LOG_ERR, _("Unable to initialize signal "
                                            "handlers in pid %d"), pid);
                return retval;
            }

            /* Avoid race condition */
            if (signal_received)
                exit(0);

            /* Return control to main() in the new worker process. */
            free(pids);
            return 0;
        }
        if (pid == -1) {
            /* Couldn't fork enough times. */
            status = errno;
            terminate_workers(pids, i);
            free(pids);
            return status;
        }
        pids[i] = pid;
    }

    /* We're going to use our own main loop here. */
    loop_free(ctx);

    /* Supervise the worker processes. */
    while (!signal_received) {
        /* Wait until a worker process exits or we get a signal. */
        pid = wait(&status);
        if (pid >= 0) {
            krb5_klog_syslog(LOG_ERR, _("worker %ld exited with status %d"),
                             (long) pid, status);

            /* Remove the pid from the table. */
            for (i = 0; i < num; i++) {
                if (pids[i] == pid)
                    pids[i] = -1;
            }

            /* When one worker process exits, terminate them all, so that KDC
             * crashes behave similarly with or without worker processes. */
            break;
        }

        /* Propagate HUP signal to worker processes if we received one. */
        if (sighup_received) {
            sighup_received = 0;
            for (i = 0; i < num; i++) {
                if (pids[i] != -1)
                    kill(pids[i], SIGHUP);
            }
        }
    }
    if (signal_received)
        krb5_klog_syslog(LOG_INFO, _("signal %d received in supervisor"),
                         signal_received);

    terminate_workers(pids, num);
    free(pids);
    exit(0);
}
Example #5
0
int main(int argc, char **argv)
{
    krb5_error_code     retval;
    krb5_context        kcontext;
    kdc_realm_t *realm;
    verto_ctx *ctx;
    int tcp_listen_backlog;
    int errout = 0;
    int i;

    setlocale(LC_ALL, "");
    if (strrchr(argv[0], '/'))
        argv[0] = strrchr(argv[0], '/')+1;

    shandle.kdc_realmlist = malloc(sizeof(kdc_realm_t *) *
                                   KRB5_KDC_MAX_REALMS);
    if (shandle.kdc_realmlist == NULL) {
        fprintf(stderr, _("%s: cannot get memory for realm list\n"), argv[0]);
        exit(1);
    }
    memset(shandle.kdc_realmlist, 0,
           (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS));

    /*
     * A note about Kerberos contexts: This context, "kcontext", is used
     * for the KDC operations, i.e. setup, network connection and error
     * reporting.  The per-realm operations use the "realm_context"
     * associated with each realm.
     */
    retval = krb5int_init_context_kdc(&kcontext);
    if (retval) {
        com_err(argv[0], retval, _("while initializing krb5"));
        exit(1);
    }
    krb5_klog_init(kcontext, "kdc", argv[0], 1);
    shandle.kdc_err_context = kcontext;
    kdc_progname = argv[0];
    /* N.B.: After this point, com_err sends output to the KDC log
       file, and not to stderr.  We use the kdc_err wrapper around
       com_err to ensure that the error state exists in the context
       known to the krb5_klog callback. */

    initialize_kdc5_error_table();

    /*
     * Scan through the argument list
     */
    initialize_realms(kcontext, argc, argv, &tcp_listen_backlog);

#ifndef NOCACHE
    retval = kdc_init_lookaside(kcontext);
    if (retval) {
        kdc_err(kcontext, retval, _("while initializing lookaside cache"));
        finish_realms();
        return 1;
    }
#endif

    ctx = loop_init(VERTO_EV_TYPE_NONE);
    if (!ctx) {
        kdc_err(kcontext, ENOMEM, _("while creating main loop"));
        finish_realms();
        return 1;
    }

    load_preauth_plugins(&shandle, kcontext, ctx);
    load_authdata_plugins(kcontext);

    retval = setup_sam();
    if (retval) {
        kdc_err(kcontext, retval, _("while initializing SAM"));
        finish_realms();
        return 1;
    }

    /* Add each realm's listener addresses to the loop. */
    for (i = 0; i < shandle.kdc_numrealms; i++) {
        realm = shandle.kdc_realmlist[i];
        if (*realm->realm_listen != '\0') {
            retval = loop_add_udp_address(KRB5_DEFAULT_PORT,
                                          realm->realm_listen);
            if (retval)
                goto net_init_error;
        }
        if (*realm->realm_tcp_listen != '\0') {
            retval = loop_add_tcp_address(KRB5_DEFAULT_PORT,
                                          realm->realm_tcp_listen);
            if (retval)
                goto net_init_error;
        }
    }

    if (workers == 0) {
        retval = loop_setup_signals(ctx, &shandle, reset_for_hangup);
        if (retval) {
            kdc_err(kcontext, retval, _("while initializing signal handlers"));
            finish_realms();
            return 1;
        }
    }
    if ((retval = loop_setup_network(ctx, &shandle, kdc_progname,
                                     tcp_listen_backlog))) {
    net_init_error:
        kdc_err(kcontext, retval, _("while initializing network"));
        finish_realms();
        return 1;
    }
    if (!nofork && daemon(0, 0)) {
        kdc_err(kcontext, errno, _("while detaching from tty"));
        finish_realms();
        return 1;
    }
    if (pid_file != NULL) {
        retval = write_pid_file(pid_file);
        if (retval) {
            kdc_err(kcontext, retval, _("while creating PID file"));
            finish_realms();
            return 1;
        }
    }
    if (workers > 0) {
        finish_realms();
        retval = create_workers(ctx, workers);
        if (retval) {
            kdc_err(kcontext, errno, _("creating worker processes"));
            return 1;
        }
        /* We get here only in a worker child process; re-initialize realms. */
        initialize_realms(kcontext, argc, argv, NULL);
    }

    /* Initialize audit system and audit KDC startup. */
    retval = load_audit_modules(kcontext);
    if (retval) {
        kdc_err(kcontext, retval, _("while loading audit plugin module(s)"));
        finish_realms();
        return 1;
    }
    krb5_klog_syslog(LOG_INFO, _("commencing operation"));
    if (nofork)
        fprintf(stderr, _("%s: starting...\n"), kdc_progname);
    kau_kdc_start(kcontext, TRUE);

    verto_run(ctx);
    loop_free(ctx);
    kau_kdc_stop(kcontext, TRUE);
    krb5_klog_syslog(LOG_INFO, _("shutting down"));
    unload_preauth_plugins(kcontext);
    unload_authdata_plugins(kcontext);
    unload_audit_modules(kcontext);
    krb5_klog_close(kcontext);
    finish_realms();
    if (shandle.kdc_realmlist)
        free(shandle.kdc_realmlist);
#ifndef NOCACHE
    kdc_free_lookaside(kcontext);
#endif
    krb5_free_context(kcontext);
    return errout;
}
Example #6
0
int
main(int argc, char *argv[])
{
    OM_uint32 minor_status;
    gss_buffer_desc in_buf;
    gss_OID nt_krb5_name_oid = (gss_OID)GSS_KRB5_NT_PRINCIPAL_NAME;
    auth_gssapi_name names[4];
    kadm5_config_params params;
    verto_ctx *vctx;
    const char *pid_file = NULL;
    char **db_args = NULL, **tmpargs;
    int ret, i, db_args_size = 0, strong_random = 1, proponly = 0;

    setlocale(LC_ALL, "");
    setvbuf(stderr, NULL, _IONBF, 0);

    names[0].name = names[1].name = names[2].name = names[3].name = NULL;
    names[0].type = names[1].type = names[2].type = names[3].type =
        nt_krb5_name_oid;

    progname = (strrchr(argv[0], '/') != NULL) ? strrchr(argv[0], '/') + 1 :
        argv[0];

    memset(&params, 0, sizeof(params));

    argc--, argv++;
    while (argc) {
        if (strcmp(*argv, "-x") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            db_args_size++;
            tmpargs = realloc(db_args, sizeof(char *) * (db_args_size + 1));
            if (tmpargs == NULL) {
                fprintf(stderr, _("%s: cannot initialize. Not enough "
                                  "memory\n"), progname);
                exit(1);
            }
            db_args = tmpargs;
            db_args[db_args_size - 1] = *argv;
            db_args[db_args_size] = NULL;
        } else if (strcmp(*argv, "-r") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            params.realm = *argv;
            params.mask |= KADM5_CONFIG_REALM;
            argc--, argv++;
            continue;
        } else if (strcmp(*argv, "-m") == 0) {
            params.mkey_from_kbd = 1;
            params.mask |= KADM5_CONFIG_MKEY_FROM_KBD;
        } else if (strcmp(*argv, "-nofork") == 0) {
            nofork = 1;
#ifdef USE_PASSWORD_SERVER
        } else if (strcmp(*argv, "-passwordserver") == 0) {
            kadm5_set_use_password_server();
#endif
#ifndef DISABLE_IPROP
        } else if (strcmp(*argv, "-proponly") == 0) {
            proponly = 1;
#endif
        } else if (strcmp(*argv, "-port") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            params.kadmind_port = atoi(*argv);
            params.mask |= KADM5_CONFIG_KADMIND_PORT;
        } else if (strcmp(*argv, "-P") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            pid_file = *argv;
        } else if (strcmp(*argv, "-W") == 0) {
            strong_random = 0;
        } else if (strcmp(*argv, "-p") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            kdb5_util = *argv;
        } else if (strcmp(*argv, "-F") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            dump_file = *argv;
        } else if (strcmp(*argv, "-K") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            kprop = *argv;
        } else if (strcmp(*argv, "-k") == 0) {
            argc--, argv++;
            if (!argc)
                usage();
            kprop_port = *argv;
        } else {
            break;
        }
        argc--, argv++;
    }

    if (argc != 0)
        usage();

    ret = kadm5_init_krb5_context(&context);
    if (ret) {
        fprintf(stderr, _("%s: %s while initializing context, aborting\n"),
                progname, error_message(ret));
        exit(1);
    }

    krb5_klog_init(context, "admin_server", progname, 1);

    ret = kadm5_init(context, "kadmind", NULL, NULL, &params,
                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, db_args,
                     &global_server_handle);
    if (ret)
        fail_to_start(ret, _("initializing"));

    ret = kadm5_get_config_params(context, 1, &params, &params);
    if (ret)
        fail_to_start(ret, _("getting config parameters"));
    if (!(params.mask & KADM5_CONFIG_REALM))
        fail_to_start(0, _("Missing required realm configuration"));
    if (!(params.mask & KADM5_CONFIG_ACL_FILE))
        fail_to_start(0, _("Missing required ACL file configuration"));

    ret = setup_loop(proponly, &vctx);
    if (ret)
        fail_to_start(ret, _("initializing network"));

    names[0].name = build_princ_name(KADM5_ADMIN_SERVICE, params.realm);
    names[1].name = build_princ_name(KADM5_CHANGEPW_SERVICE, params.realm);
    if (names[0].name == NULL || names[1].name == NULL)
        fail_to_start(0, _("Cannot build GSSAPI auth names"));

    ret = setup_kdb_keytab();
    if (ret)
        fail_to_start(0, _("Cannot set up KDB keytab"));

    if (svcauth_gssapi_set_names(names, 2) == FALSE)
        fail_to_start(0, _("Cannot set GSSAPI authentication names"));

    /* if set_names succeeded, this will too */
    in_buf.value = names[1].name;
    in_buf.length = strlen(names[1].name) + 1;
    (void)gss_import_name(&minor_status, &in_buf, nt_krb5_name_oid,
                          &gss_changepw_name);

    svcauth_gssapi_set_log_badauth2_func(log_badauth, NULL);
    svcauth_gssapi_set_log_badverf_func(log_badverf, NULL);
    svcauth_gssapi_set_log_miscerr_func(log_miscerr, NULL);

    svcauth_gss_set_log_badauth2_func(log_badauth, NULL);
    svcauth_gss_set_log_badverf_func(log_badverf, NULL);
    svcauth_gss_set_log_miscerr_func(log_miscerr, NULL);

    if (svcauth_gss_set_svc_name(GSS_C_NO_NAME) != TRUE)
        fail_to_start(0, _("Cannot initialize GSSAPI service name"));

    ret = acl_init(context, params.acl_file);
    if (ret)
        fail_to_start(ret, _("initializing ACL file"));

    if (!nofork && daemon(0, 0) != 0)
        fail_to_start(errno, _("spawning daemon process"));
    if (pid_file != NULL) {
        ret = write_pid_file(pid_file);
        if (ret)
            fail_to_start(ret, _("creating PID file"));
    }

    krb5_klog_syslog(LOG_INFO, _("Seeding random number generator"));
    ret = krb5_c_random_os_entropy(context, strong_random, NULL);
    if (ret)
        fail_to_start(ret, _("getting random seed"));

    if (params.iprop_enabled == TRUE) {
        ulog_set_role(context, IPROP_MASTER);

        ret = ulog_map(context, params.iprop_logfile, params.iprop_ulogsize);
        if (ret)
            fail_to_start(ret, _("mapping update log"));

        if (nofork) {
            fprintf(stderr,
                    _("%s: create IPROP svc (PROG=%d, VERS=%d)\n"),
                    progname, KRB5_IPROP_PROG, KRB5_IPROP_VERS);
        }
    }

    if (kprop_port == NULL)
        kprop_port = getenv("KPROP_PORT");

    krb5_klog_syslog(LOG_INFO, _("starting"));
    if (nofork)
        fprintf(stderr, _("%s: starting...\n"), progname);

    verto_run(vctx);
    krb5_klog_syslog(LOG_INFO, _("finished, exiting"));

    /* Clean up memory, etc */
    svcauth_gssapi_unset_names();
    kadm5_destroy(global_server_handle);
    loop_free(vctx);
    acl_finish(context);
    (void)gss_release_name(&minor_status, &gss_changepw_name);
    (void)gss_release_name(&minor_status, &gss_oldchangepw_name);
    for (i = 0; i < 4; i++)
        free(names[i].name);

    krb5_klog_close(context);
    krb5_free_context(context);
    exit(2);
}
Example #7
0
int loop_bind(FILE *image_fp, char **loop_dev, int autoclear) {
    struct loop_info64 lo64 = {0};
    int i;

    message(DEBUG, "Called loop_bind(image_fp, **{loop_dev)\n");

    if ( autoclear > 0 ) {
        lo64.lo_flags = LO_FLAGS_AUTOCLEAR;
    }
    lo64.lo_offset = image_offset(image_fp);

    for( i=0; i < MAX_LOOP_DEVS; i++ ) {
        char *test_loopdev = strjoin("/dev/loop", int2str(i));
        FILE *loop_fp;

        if ( is_blk(test_loopdev) < 0 ) {
            message(VERBOSE, "Creating loop device: %s\n", test_loopdev);
            if ( mknod(test_loopdev, S_IFBLK | 0644, makedev(7, i)) < 0 ) {
                message(ERROR, "Could not create %s: %s\n", test_loopdev, strerror(errno));
                ABORT(255);
            }
        }

        if ( ( loop_fp = fopen(test_loopdev, "r+") ) == NULL ) { // Flawfinder: ignore (not user modifyable)
            message(VERBOSE, "Could not open loop device %s: %s\n", test_loopdev, strerror(errno));
            continue;
        }

        message(VERBOSE2, "Attempting to associate image pointer to loop device\n");
        if ( ioctl(fileno(loop_fp), LOOP_SET_FD, fileno(image_fp)) < 0 ) {
            if ( errno == 16 ) {
                message(VERBOSE3, "Loop device is in use: %s\n", test_loopdev);
                fclose(loop_fp);
                continue;
            } else {
                message(WARNING, "Could not associate image to loop %s: %s\n", test_loopdev, strerror(errno));
                fclose(loop_fp);
                continue;
            }
        }

        message(VERBOSE, "Found valid loop device: %s\n", test_loopdev);

        message(VERBOSE2, "Setting loop device flags\n");
        if ( ioctl(fileno(loop_fp), LOOP_SET_STATUS64, &lo64) < 0 ) {
            fprintf(stderr, "ERROR: Failed to set loop flags on loop device: %s\n", strerror(errno));
            (void)ioctl(fileno(loop_fp), LOOP_CLR_FD, 0);
            (void)loop_free(*loop_dev);
            ABORT(255);
        }
        *loop_dev = strdup(test_loopdev);

        message(VERBOSE, "Using loop device: %s\n", *loop_dev);

        message(DEBUG, "Returning loop_bind(image_fp) = 0\n");

        return(0);
    }

    message(ERROR, "No valid loop devices available\n");
    ABORT(255);

    return(-1);
}
Example #8
0
int main(int argc, char ** argv) {
    uid_t uid = geteuid();

    if ( argv[1] == NULL || argv[2] == NULL ) {
        fprintf(stderr, "USAGE: %s [attach/detach] [image/loop]\n", argv[0]);
        return(1);
    }

    message(VERBOSE, "Checking calling user\n");
    if ( uid != 0 ) {
        message(ERROR, "Calling user must be root\n");
        ABORT(1);
    }

    message(VERBOSE, "Checking command: %s\n", argv[1]);
    if ( strcmp(argv[1], "attach") == 0 ) {
        FILE *containerimage_fp;
        char *containerimage;
        char *loop_dev;

        message(VERBOSE, "Preparing to attach container to loop\n");

        containerimage = xstrdup(argv[2]);

        message(VERBOSE, "Evaluating image: %s\n", containerimage);
    
        message(VERBOSE, "Checking if container image exists\n");
        if ( is_file(containerimage) < 0 ) {
            message(ERROR, "Container image not found: %s\n", containerimage);
            ABORT(1);
        }

        message(VERBOSE, "Checking if container can be opened read/write\n");
        if ( !( containerimage_fp = fopen(containerimage, "r+") ) ) { // Flawfinder: ignore
            message(ERROR, "Could not open image %s: %s\n", containerimage, strerror(errno));
            ABORT(255);
        }

        message(DEBUG, "Binding container to loop interface\n");
        if ( loop_bind(containerimage_fp, &loop_dev, 0) < 0 ) {
            message(ERROR, "Could not bind image to loop!\n");
            ABORT(255);
        }

        printf("%s\n", loop_dev);
    } else if (strcmp(argv[1], "detach") == 0 ) {
        char *loop_dev;

        loop_dev = xstrdup(argv[2]);

        message(VERBOSE, "Preparing to detach loop: %s\n", loop_dev);

        message(VERBOSE, "Checking loop device\n");
        if ( is_blk(loop_dev) < 0 ) {
            message(ERROR, "Block device not found: %s\n", loop_dev);
            ABORT(255);
        }

        message(VERBOSE, "Unbinding container image from loop\n");
        if ( loop_free(loop_dev) < 0 ) {
            message(ERROR, "Failed to detach loop device: %s\n", loop_dev);
            ABORT(255);
        }

    }

    return(0);
}