static void config_print(pool_conf_t *conf) { char *buf; pool_value_t *pv; const char *tgt; if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) != PO_SUCCESS) die(gettext(ERR_OPEN_DYNAMIC), get_errstr()); if ((pv = pool_value_alloc()) == NULL || pool_get_property(conf, pool_conf_to_elem(conf), "system.name", pv) == POC_INVAL || pool_value_get_string(pv, &tgt) != PO_SUCCESS) die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION), "unknown", get_errstr()); if ((buf = pool_conf_info(conf, PO_TRUE)) == NULL) die(gettext(ERR_GET_ELEMENT_DETAILS), gettext(CONFIGURATION), tgt, get_errstr()); pool_value_free(pv); (void) printf("%s", buf); free(buf); (void) pool_conf_close(conf); }
static void config_destroy(pool_conf_t *conf) { if (pool_conf_open(conf, pool_dynamic_location(), PO_RDWR) != PO_SUCCESS) die(gettext(ERR_OPEN_DYNAMIC), get_errstr()); if (pool_conf_remove(conf) != PO_SUCCESS) die(gettext(ERR_REMOVE_DYNAMIC), get_errstr()); }
static int precheck_pkt(fko_srv_options_t *opts, spa_pkt_info_t *spa_pkt, spa_data_t *spadat, char **raw_digest) { int res = 0, packet_data_len = 0; packet_data_len = spa_pkt->packet_data_len; res = preprocess_spa_data(opts, spa_pkt); if(res != FKO_SUCCESS) { log_msg(LOG_DEBUG, "[%s] preprocess_spa_data() returned error %i: '%s' for incoming packet.", spadat->pkt_source_ip, res, get_errstr(res)); return 0; } if(opts->foreground == 1 && opts->verbose > 2) { printf("[+] candidate SPA packet payload:\n"); hex_dump(spa_pkt->packet_data, packet_data_len); } if(! src_check(opts, spa_pkt, spadat, raw_digest)) return 0; return 1; }
char * strerror (int error) { static char buf[1024]; DWORD winerr = (DWORD) error; const char *str = get_errstr (winerr); if (str != NULL) strcpy (buf, str); else strwinerror (buf, winerr); return buf; }
int print_resource_binding(const char *type, pid_t pid) { char *resource_name; if ((resource_name = pool_get_resource_binding(type, pid)) == NULL) warn(gettext("getting '%s' binding for %d: %s\n"), type, (int)pid, get_errstr()); else (void) printf("%d\t%s\t%s\n", (int)pid, type, resource_name); free(resource_name); return (PO_SUCCESS); }
void exec_cmd(char *pool_name, char *argv[]) { if (pool_set_binding(pool_name, P_PID, getpid()) != PO_SUCCESS) { warn(gettext("binding to pool '%s': %s\n"), pool_name, get_errstr()); error = E_ERROR; return; } if (execvp(argv[0], argv) == -1) die(gettext("exec of %s failed"), argv[0]); /*NOTREACHED*/ }
static void config_commit(pool_conf_t *conf, const char *static_conf_name) { if (pool_conf_open(conf, static_conf_name, Nflag || !Sflag ? PO_RDONLY : PO_RDWR) != PO_SUCCESS) die(gettext(ERR_OPEN_STATIC), static_conf_name, get_errstr()); if (pool_conf_validate(conf, POV_RUNTIME) != PO_SUCCESS) die(gettext(ERR_VALIDATE_RUNTIME), static_conf_name); if (!Nflag) { if (pool_conf_commit(conf, PO_TRUE) != PO_SUCCESS) die(gettext(ERR_COMMIT_DYNAMIC), static_conf_name, get_errstr()); /* * Dump the updated state to the specified location */ if (Sflag) { if (pool_conf_commit(conf, PO_FALSE) != PO_SUCCESS) die(gettext(ERR_COMMIT_STATIC), static_conf_name, get_errstr()); } } (void) pool_conf_close(conf); }
/* Process the SPA packet data */ void incoming_spa(fko_srv_options_t *opts) { /* Always a good idea to initialize ctx to null if it will be used * repeatedly (especially when using fko_new_with_data()). */ fko_ctx_t ctx = NULL; char *spa_ip_demark, *gpg_id, *raw_digest = NULL; time_t now_ts; int res, status, ts_diff, enc_type, stanza_num=0; int added_replay_digest = 0, pkt_data_len=0; int is_err, cmd_exec_success = 0, attempted_decrypt = 0; int conf_pkt_age = 0; char dump_buf[CTX_DUMP_BUFSIZE]; spa_pkt_info_t *spa_pkt = &(opts->spa_pkt); /* This will hold our pertinent SPA data. */ spa_data_t spadat; /* Loop through all access stanzas looking for a match */ acc_stanza_t *acc = opts->acc_stanzas; acc_string_list_t *gpg_id_ndx; unsigned char is_gpg_match = 0; inet_ntop(AF_INET, &(spa_pkt->packet_src_ip), spadat.pkt_source_ip, sizeof(spadat.pkt_source_ip)); /* At this point, we want to validate and (if needed) preprocess the * SPA data and/or to be reasonably sure we have a SPA packet (i.e * try to eliminate obvious non-spa packets). */ pkt_data_len = spa_pkt->packet_data_len; res = preprocess_spa_data(opts, spadat.pkt_source_ip); if(res != FKO_SUCCESS) { log_msg(LOG_DEBUG, "[%s] preprocess_spa_data() returned error %i: '%s' for incoming packet.", spadat.pkt_source_ip, res, get_errstr(res)); return; } if(opts->foreground == 1 && opts->verbose > 2) { printf("[+] candidate SPA packet payload:\n"); hex_dump(spa_pkt->packet_data, pkt_data_len); } if(strncasecmp(opts->config[CONF_ENABLE_SPA_PACKET_AGING], "Y", 1) == 0) { conf_pkt_age = strtol_wrapper(opts->config[CONF_MAX_SPA_PACKET_AGE], 0, RCHK_MAX_SPA_PACKET_AGE, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) { log_msg(LOG_ERR, "[*] [%s] invalid MAX_SPA_PACKET_AGE", spadat.pkt_source_ip); return; } } if (is_src_match(opts->acc_stanzas, ntohl(spa_pkt->packet_src_ip))) { if(strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0) { /* Check for a replay attack */ res = get_raw_digest(&raw_digest, (char *)spa_pkt->packet_data); if(res != FKO_SUCCESS) { if (raw_digest != NULL) free(raw_digest); return; } if (raw_digest == NULL) return; if (is_replay(opts, raw_digest) != SPA_MSG_SUCCESS) { free(raw_digest); return; } } } else { log_msg(LOG_WARNING, "No access data found for source IP: %s", spadat.pkt_source_ip ); return; } /* Now that we know there is a matching access.conf stanza and the * incoming SPA packet is not a replay, see if we should grant any * access */ while(acc) { res = FKO_SUCCESS; cmd_exec_success = 0; attempted_decrypt = 0; stanza_num++; /* Start access loop with a clean FKO context */ if(ctx != NULL) { if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA) log_msg(LOG_WARNING, "[%s] (stanza #%d) fko_destroy() could not zero out sensitive data buffer.", spadat.pkt_source_ip, stanza_num, fko_errstr(res) ); ctx = NULL; } /* Check for a match for the SPA source IP and the access stanza */ if(! compare_addr_list(acc->source_list, ntohl(spa_pkt->packet_src_ip))) { acc = acc->next; continue; } log_msg(LOG_INFO, "(stanza #%d) SPA Packet from IP: %s received with access source match", stanza_num, spadat.pkt_source_ip); log_msg(LOG_DEBUG, "SPA Packet: '%s'", spa_pkt->packet_data); /* Make sure this access stanza has not expired */ if(acc->access_expire_time > 0) { if(acc->expired) { acc = acc->next; continue; } else { if(time(NULL) > acc->access_expire_time) { log_msg(LOG_INFO, "[%s] (stanza #%d) Access stanza has expired", spadat.pkt_source_ip, stanza_num); acc->expired = 1; acc = acc->next; continue; } } } /* Get encryption type and try its decoding routine first (if the key * for that type is set) */ enc_type = fko_encryption_type((char *)spa_pkt->packet_data); if(acc->use_rijndael) { if (acc->key == NULL) { log_msg(LOG_ERR, "[%s] (stanza #%d) No KEY for RIJNDAEL encrypted messages", spadat.pkt_source_ip, stanza_num ); acc = acc->next; continue; } /* Command mode messages may be quite long */ if(acc->enable_cmd_exec || enc_type == FKO_ENCRYPTION_RIJNDAEL) { res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, acc->key, acc->key_len, acc->encryption_mode, acc->hmac_key, acc->hmac_key_len, acc->hmac_type); attempted_decrypt = 1; if(res == FKO_SUCCESS) cmd_exec_success = 1; } } if(acc->use_gpg && enc_type == FKO_ENCRYPTION_GPG && cmd_exec_success == 0) { /* For GPG we create the new context without decrypting on the fly * so we can set some GPG parameters first. */ if(acc->gpg_decrypt_pw != NULL || acc->gpg_allow_no_pw) { res = fko_new_with_data(&ctx, (char *)spa_pkt->packet_data, NULL, 0, FKO_ENC_MODE_ASYMMETRIC, acc->hmac_key, acc->hmac_key_len, acc->hmac_type); if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error creating fko context (before decryption): %s", spadat.pkt_source_ip, stanza_num, fko_errstr(res) ); acc = acc->next; continue; } /* Set whatever GPG parameters we have. */ if(acc->gpg_exe != NULL) { res = fko_set_gpg_exe(ctx, acc->gpg_exe); if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error setting GPG path %s: %s", spadat.pkt_source_ip, stanza_num, acc->gpg_exe, fko_errstr(res) ); acc = acc->next; continue; } } if(acc->gpg_home_dir != NULL) { res = fko_set_gpg_home_dir(ctx, acc->gpg_home_dir); if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error setting GPG keyring path to %s: %s", spadat.pkt_source_ip, stanza_num, acc->gpg_home_dir, fko_errstr(res) ); acc = acc->next; continue; } } if(acc->gpg_decrypt_id != NULL) fko_set_gpg_recipient(ctx, acc->gpg_decrypt_id); /* If GPG_REQUIRE_SIG is set for this acc stanza, then set * the FKO context accordingly and check the other GPG Sig- * related parameters. This also applies when REMOTE_ID is * set. */ if(acc->gpg_require_sig) { fko_set_gpg_signature_verify(ctx, 1); /* Set whether or not to ignore signature verification errors. */ fko_set_gpg_ignore_verify_error(ctx, acc->gpg_ignore_sig_error); } else { fko_set_gpg_signature_verify(ctx, 0); fko_set_gpg_ignore_verify_error(ctx, 1); } /* Now decrypt the data. */ res = fko_decrypt_spa_data(ctx, acc->gpg_decrypt_pw, 0); attempted_decrypt = 1; } } if(attempted_decrypt == 0) { log_msg(LOG_ERR, "(stanza #%d) No stanza encryption mode match for encryption type: %i.", stanza_num, enc_type); acc = acc->next; continue; } /* Do we have a valid FKO context? Did the SPA decrypt properly? */ if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error creating fko context: %s", spadat.pkt_source_ip, stanza_num, fko_errstr(res)); if(IS_GPG_ERROR(res)) log_msg(LOG_WARNING, "[%s] (stanza #%d) - GPG ERROR: %s", spadat.pkt_source_ip, stanza_num, fko_gpg_errstr(ctx)); acc = acc->next; continue; } /* Add this SPA packet into the replay detection cache */ if (added_replay_digest == 0 && strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0) { res = add_replay(opts, raw_digest); if (res != SPA_MSG_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Could not add digest to replay cache", spadat.pkt_source_ip, stanza_num); acc = acc->next; continue; } added_replay_digest = 1; } /* At this point, we assume the SPA data is valid. Now we need to see * if it meets our access criteria. */ log_msg(LOG_DEBUG, "[%s] (stanza #%d) SPA Decode (res=%i):", spadat.pkt_source_ip, stanza_num, res); res = dump_ctx_to_buffer(ctx, dump_buf, sizeof(dump_buf)); if (res == FKO_SUCCESS) log_msg(LOG_DEBUG, "%s", dump_buf); else log_msg(LOG_WARNING, "Unable to dump FKO context: %s", fko_errstr(res)); /* First, if this is a GPG message, and GPG_REMOTE_ID list is not empty, * then we need to make sure this incoming message is signer ID matches * an entry in the list. */ if(enc_type == FKO_ENCRYPTION_GPG && acc->gpg_require_sig) { res = fko_get_gpg_signature_id(ctx, &gpg_id); if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error pulling the GPG signature ID from the context: %s", spadat.pkt_source_ip, stanza_num, fko_gpg_errstr(ctx)); acc = acc->next; continue; } log_msg(LOG_INFO, "[%s] (stanza #%d) Incoming SPA data signed by '%s'.", spadat.pkt_source_ip, stanza_num, gpg_id); if(acc->gpg_remote_id != NULL) { is_gpg_match = 0; for(gpg_id_ndx = acc->gpg_remote_id_list; gpg_id_ndx != NULL; gpg_id_ndx=gpg_id_ndx->next) { res = fko_gpg_signature_id_match(ctx, gpg_id_ndx->str, &is_gpg_match); if(res != FKO_SUCCESS) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error in GPG siganture comparision: %s", spadat.pkt_source_ip, stanza_num, fko_gpg_errstr(ctx)); acc = acc->next; continue; } if(is_gpg_match) break; } if(! is_gpg_match) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Incoming SPA packet signed by ID: %s, but that ID is not the GPG_REMOTE_ID list.", spadat.pkt_source_ip, stanza_num, gpg_id); acc = acc->next; continue; } } } /* Populate our spa data struct for future reference. */ res = get_spa_data_fields(ctx, &spadat); /* Figure out what our timeout will be. If it is specified in the SPA * data, then use that. If not, try the FW_ACCESS_TIMEOUT from the * access.conf file (if there is one). Otherwise use the default. */ if(spadat.client_timeout > 0) spadat.fw_access_timeout = spadat.client_timeout; else if(acc->fw_access_timeout > 0) spadat.fw_access_timeout = acc->fw_access_timeout; else spadat.fw_access_timeout = DEF_FW_ACCESS_TIMEOUT; if(res != FKO_SUCCESS) { log_msg(LOG_ERR, "[%s] (stanza #%d) Unexpected error pulling SPA data from the context: %s", spadat.pkt_source_ip, stanza_num, fko_errstr(res)); acc = acc->next; continue; } /* Check packet age if so configured. */ if(strncasecmp(opts->config[CONF_ENABLE_SPA_PACKET_AGING], "Y", 1) == 0) { time(&now_ts); ts_diff = abs(now_ts - spadat.timestamp); if(ts_diff > conf_pkt_age) { log_msg(LOG_WARNING, "[%s] (stanza #%d) SPA data time difference is too great (%i seconds).", spadat.pkt_source_ip, stanza_num, ts_diff); acc = acc->next; continue; } } /* At this point, we have enough to check the embedded (or packet source) * IP address against the defined access rights. We start by splitting * the spa msg source IP from the remainder of the message. */ spa_ip_demark = strchr(spadat.spa_message, ','); if(spa_ip_demark == NULL) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Error parsing SPA message string: %s", spadat.pkt_source_ip, stanza_num, fko_errstr(res)); acc = acc->next; continue; } if((spa_ip_demark-spadat.spa_message) < MIN_IPV4_STR_LEN-1 || (spa_ip_demark-spadat.spa_message) > MAX_IPV4_STR_LEN) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Invalid source IP in SPA message, ignoring SPA packet", spadat.pkt_source_ip, stanza_num, fko_errstr(res)); if(ctx != NULL) { if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA) log_msg(LOG_WARNING, "[%s] (stanza #%d) fko_destroy() could not zero out sensitive data buffer.", spadat.pkt_source_ip, stanza_num, fko_errstr(res) ); ctx = NULL; } break; } strlcpy(spadat.spa_message_src_ip, spadat.spa_message, (spa_ip_demark-spadat.spa_message)+1); if(! is_valid_ipv4_addr(spadat.spa_message_src_ip)) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Invalid source IP in SPA message, ignoring SPA packet", spadat.pkt_source_ip, stanza_num, fko_errstr(res)); if(ctx != NULL) { if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA) log_msg(LOG_WARNING, "[%s] (stanza #%d) fko_destroy() could not zero out sensitive data buffer.", spadat.pkt_source_ip, stanza_num, fko_errstr(res) ); ctx = NULL; } break; } strlcpy(spadat.spa_message_remain, spa_ip_demark+1, MAX_DECRYPTED_SPA_LEN); /* If use source IP was requested (embedded IP of 0.0.0.0), make sure it * is allowed. */ if(strcmp(spadat.spa_message_src_ip, "0.0.0.0") == 0) { if(acc->require_source_address) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Got 0.0.0.0 when valid source IP was required.", spadat.pkt_source_ip, stanza_num ); acc = acc->next; continue; } spadat.use_src_ip = spadat.pkt_source_ip; } else spadat.use_src_ip = spadat.spa_message_src_ip; /* If REQUIRE_USERNAME is set, make sure the username in this SPA data * matches. */ if(acc->require_username != NULL) { if(strcmp(spadat.username, acc->require_username) != 0) { log_msg(LOG_WARNING, "[%s] (stanza #%d) Username in SPA data (%s) does not match required username: %s", spadat.pkt_source_ip, stanza_num, spadat.username, acc->require_username ); acc = acc->next; continue; } } /* Take action based on SPA message type. */ if(spadat.message_type == FKO_LOCAL_NAT_ACCESS_MSG || spadat.message_type == FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG || spadat.message_type == FKO_NAT_ACCESS_MSG || spadat.message_type == FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG) { #if FIREWALL_IPTABLES if(strncasecmp(opts->config[CONF_ENABLE_IPT_FORWARDING], "Y", 1)!=0) { log_msg(LOG_WARNING, "(stanza #%d) SPA packet from %s requested NAT access, but is not enabled", stanza_num, spadat.pkt_source_ip ); acc = acc->next; continue; } #else log_msg(LOG_WARNING, "(stanza #%d) SPA packet from %s requested unsupported NAT access", stanza_num, spadat.pkt_source_ip ); acc = acc->next; continue; #endif } /* Command messages. */ if(spadat.message_type == FKO_COMMAND_MSG) { if(!acc->enable_cmd_exec) { log_msg(LOG_WARNING, "[%s] (stanza #%d) SPA Command message are not allowed in the current configuration.", spadat.pkt_source_ip, stanza_num ); acc = acc->next; continue; } else { log_msg(LOG_INFO, "[%s] (stanza #%d) Processing SPA Command message: command='%s'.", spadat.pkt_source_ip, stanza_num, spadat.spa_message_remain ); /* Do we need to become another user? If so, we call * run_extcmd_as and pass the cmd_exec_uid. */ if(acc->cmd_exec_user != NULL && strncasecmp(acc->cmd_exec_user, "root", 4) != 0) { log_msg(LOG_INFO, "[%s] (stanza #%d) Setting effective user to %s (UID=%i) before running command.", spadat.pkt_source_ip, stanza_num, acc->cmd_exec_user, acc->cmd_exec_uid); res = run_extcmd_as(acc->cmd_exec_uid, spadat.spa_message_remain, NULL, 0, 0); } else /* Just run it as we are (root that is). */ res = run_extcmd(spadat.spa_message_remain, NULL, 0, 5); /* --DSS XXX: I have found that the status (and res for that * matter) have been unreliable indicators of the * actual exit status of some commands. Not sure * why yet. For now, we will take what we get. */ status = WEXITSTATUS(res); if(opts->verbose > 1) log_msg(LOG_WARNING, "[%s] (stanza #%d) CMD_EXEC: command returned %i", spadat.pkt_source_ip, stanza_num, status); if(status != 0) res = SPA_MSG_COMMAND_ERROR; if(ctx != NULL) { if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA) log_msg(LOG_WARNING, "[%s] (stanza #%d) fko_destroy() could not zero out sensitive data buffer.", spadat.pkt_source_ip, stanza_num, fko_errstr(res) ); ctx = NULL; } /* we processed the command on a matching access stanza, so we * don't look for anything else to do with this SPA packet */ break; } } /* From this point forward, we have some kind of access message. So * we first see if access is allowed by checking access against * restrict_ports and open_ports. * * --DSS TODO: We should add BLACKLIST support here as well. */ if(! acc_check_port_access(acc, spadat.spa_message_remain)) { log_msg(LOG_WARNING, "[%s] (stanza #%d) One or more requested protocol/ports was denied per access.conf.", spadat.pkt_source_ip, stanza_num ); acc = acc->next; continue; } /* At this point, we process the SPA request and break out of the * access stanza loop (first valid access stanza stops us looking * for others). */ process_spa_request(opts, acc, &spadat); if(ctx != NULL) { if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA) log_msg(LOG_WARNING, "[%s] (stanza #%d) fko_destroy() could not zero out sensitive data buffer.", spadat.pkt_source_ip, stanza_num ); ctx = NULL; } break; } if (raw_digest != NULL) free(raw_digest); if(ctx != NULL) { if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA) log_msg(LOG_WARNING, "[%s] fko_destroy() could not zero out sensitive data buffer.", spadat.pkt_source_ip ); ctx = NULL; } return; }
int main(int argc, char *argv[]) { char c; pool_conf_t *conf = NULL; const char *static_conf_loc; (void) getpname(argv[0]); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, "cdensx")) != EOF) { switch (c) { case 'c': /* Create (or modify) system configuration */ Cflag++; break; case 'd': /* Disable the pools facility */ Dflag++; break; case 'e': /* Enable the pools facility */ Eflag++; break; case 'n': /* Don't actually do anything */ Nflag++; break; case 's': /* Update the submitted configuration */ Sflag++; break; case 'x': /* Delete current system configuration */ Xflag++; break; case '?': default: usage(); /*NOTREACHED*/ } } /* * Not all flags can be used at the same time. */ if ((Cflag || Sflag || Dflag || Eflag) && Xflag) usage(); if ((Dflag || Eflag) && (Cflag || Sflag || Xflag)) usage(); if (Dflag && Eflag) usage(); argc -= optind; argv += optind; if (! (Cflag || Sflag)) { if (argc != 0) usage(); } else { if (argc == 0) static_conf_loc = pool_static_location(); else if (argc == 1) static_conf_loc = argv[0]; else usage(); } if (!Nflag && (Cflag + Dflag + Eflag + Xflag != 0) && !priv_ineffect(PRIV_SYS_RES_CONFIG)) die(gettext(ERR_PERMISSIONS)); if (Dflag) { if (pool_set_status(POOL_DISABLED) != PO_SUCCESS) die(gettext(ERR_DISABLE)); } else if (Eflag) { if (pool_set_status(POOL_ENABLED) != PO_SUCCESS) { if (errno == EEXIST) die(gettext(ERR_ENABLE ": System has active processor sets\n")); else die(gettext(ERR_ENABLE)); } } else { if ((conf = pool_conf_alloc()) == NULL) die(gettext(ERR_NOMEM)); if (Cflag + Sflag + Xflag == 0) { /* * No flags means print current system configuration */ config_print(conf); } else if (!Nflag && Xflag) { /* * Destroy active pools configuration and * remove the state file. */ config_destroy(conf); } else { /* * Commit a new configuration. */ if (Cflag) config_commit(conf, static_conf_loc); else { /* * Dump the dynamic state to the * specified location */ if (!Nflag && Sflag) { if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY) != PO_SUCCESS) die(gettext(ERR_OPEN_DYNAMIC), get_errstr()); if (pool_conf_export(conf, static_conf_loc, POX_NATIVE) != PO_SUCCESS) die(gettext(ERR_EXPORT_DYNAMIC), static_conf_loc, get_errstr()); (void) pool_conf_close(conf); } } } pool_conf_free(conf); } return (E_PO_SUCCESS); }
void process_ids(char *pool_name, uint_t flags, idtype_t idtype, char *idstr, int argc, char *argv[]) { int i; id_t id; for (i = 0; i < argc; i++) { char *endp; char *poolname; errno = 0; id = (id_t)strtol(argv[i], &endp, 10); if (errno != 0 || (endp && endp != argv[i] + strlen(argv[i])) || (idtype == P_ZONEID && getzonenamebyid(id, NULL, 0) == -1)) { /* * The string does not completely parse to * an integer, or it represents an invalid * zone id. */ /* * It must be a project or zone name. */ if (idtype == P_ZONEID) { if (zone_get_id(argv[i], &id) != 0) { warn(gettext("invalid zone '%s'\n"), argv[i]); error = E_ERROR; continue; } /* make sure the zone is booted */ if (id == -1) { warn(gettext("zone '%s' is not " "active\n"), argv[i]); error = E_ERROR; continue; } } else if (idtype == P_PROJID) { if ((id = getprojidbyname(argv[i])) < 0) { warn(gettext("failed to get project " "id for project: '%s'"), argv[i]); error = E_ERROR; continue; } } else { warn(gettext("invalid %s '%s'\n"), idstr, argv[i]); error = E_ERROR; continue; } } if (flags & pFLAG) { if (pool_set_binding(pool_name, idtype, id) != PO_SUCCESS) { warn(gettext("binding %s %ld to pool '%s': " "%s\n"), idstr, id, pool_name, get_errstr()); error = E_ERROR; } continue; } if (flags & qFLAG) { if ((poolname = pool_get_binding(id)) == NULL) { warn(gettext("couldn't determine binding for " "pid %ld: %s\n"), id, get_errstr()); error = E_ERROR; } else { (void) printf("%ld\t%s\n", id, poolname); free(poolname); } } if (flags & QFLAG) { uint_t j, count; const char **resource_types; (void) pool_resource_type_list(NULL, &count); if ((resource_types = malloc(count * sizeof (const char *))) == NULL) { warn(gettext("couldn't allocate query memory " "for pid %ld: %s\n"), id, get_errstr()); error = E_ERROR; } (void) pool_resource_type_list(resource_types, &count); for (j = 0; j < count; j++) (void) print_resource_binding(resource_types[j], (pid_t)id); free(resource_types); } } }
int main(int argc, char *argv[]) { char c; int i; idtype_t idtype = P_PID; char *idstr = "pid"; char *pool_name = NULL; uint_t flags = 0; int status; (void) getpname(argv[0]); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); while ((c = getopt(argc, argv, OPTS)) != EOF) { switch (c) { case 'Q': if (flags & (qFLAG | iFLAG | pFLAG)) usage(); flags |= QFLAG; break; case 'e': if (flags & (iFLAG | qFLAG | QFLAG)) usage(); flags |= eFLAG; break; case 'i': for (i = 0; idtypes[i].str != NULL; i++) { if (strcmp(optarg, idtypes[i].str) == 0) { idtype = idtypes[i].idtype; idstr = idtypes[i].str; break; } } if ((flags & (iFLAG | qFLAG | QFLAG)) || idtypes[i].str == NULL) usage(); flags |= iFLAG; break; case 'p': if (flags & (pFLAG | qFLAG | QFLAG)) usage(); flags |= pFLAG; pool_name = optarg; break; case 'q': if (flags & (pFLAG | iFLAG | QFLAG)) usage(); flags |= qFLAG; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (flags & eFLAG && pool_name == NULL) usage(); if (argc < 1 || (flags & (pFLAG | qFLAG | QFLAG)) == 0) usage(); /* * Check to see that the pools facility is enabled */ if (pool_get_status(&status) != PO_SUCCESS) die((ERR_OPEN_DYNAMIC), get_errstr()); if (status == POOL_DISABLED) die((ERR_OPEN_DYNAMIC), strerror(ENOTACTIVE)); if (flags & eFLAG) exec_cmd(pool_name, argv); /*NOTREACHED*/ else process_ids(pool_name, flags, idtype, idstr, argc, argv); return (error); }