Exemplo n.º 1
0
static int _set_options(const int argc, char **argv)
{
	int option_index = 0;
	int cc;
	char *next_str = NULL;

	static struct option long_options[] = {
		{"configdir", required_argument, 0, 'c'},
		{"measure", no_argument, 0, 'm'},
		{"testcases", required_argument, 0, 't'},
		{"usage", no_argument, 0, 'U'},
		{"verbose", no_argument, 0, 'v'},
		{0, 0, 0, 0}};

	_init_opts();

	while ((cc = getopt_long(argc, argv, "cmt:Uv",
	                         long_options, &option_index)) != EOF) {
		switch (cc) {
			case 'c':
				params.configdir = xstrdup(optarg);
				break;
			case 'm':
				params.measure++;
				break;
			case 't':
				params.testcases = xstrdup(optarg);
				break;
			case 'U':
				_help_msg();
				return -1;
				break;
			case 'v':
				params.verbose++;
				break;
			case ':':
			case '?': /* getopt() has explained it */
				return -1;
		}
	}

	return 0;
}
Exemplo n.º 2
0
static void _set_options(const int argc, char **argv)
{
	int option_index = 0, c;
	log_options_t logopt = LOG_OPTS_STDERR_ONLY;
	char *next_str = NULL;
	uid_t uid = -1;

	static struct option long_options[] = {
		{"extract", no_argument, 0, 'E'},
		{"help", no_argument, 0, 'h'},
		{"job", required_argument, 0, 'j'},
		{"input", required_argument, 0, 'i'},
		{"level", required_argument, 0, 'l'},
		{"node", required_argument, 0, 'N'},
		{"output", required_argument, 0, 'o'},
		{"profiledir", required_argument, 0, 'p'},
		{"series", required_argument, 0, 's'},
		{"savefiles", no_argument, 0, 'S'},
		{"usage", 0, &params.help, 3},
		{"user", required_argument, 0, 'u'},
		{"verbose", no_argument, 0, 'v'},
		{"version", no_argument, 0, 'V'},
		{0, 0, 0, 0}};

	log_init(xbasename(argv[0]), logopt, 0, NULL);

	_init_opts();

	while (1) {		/* now cycle through the command line */
		c = getopt_long(argc, argv, "Ehi:j:l:N:o:p:s:Su:vV",
				long_options, &option_index);
		if (c == -1)
			break;
		switch (c) {
		case 'E':
			params.mode = SH5UTIL_MODE_EXTRACT;
			break;
		case 'h':
			params.help = 1;
			break;
		case 'i':
			params.input = xstrdup(optarg);
			break;
		case 'j':
			params.job_id = strtol(optarg, &next_str, 10);
			if (next_str[0] == '.')
				params.step_id =
					strtol(next_str+1, NULL, 10);
			break;
		case 'l':
			params.level = xstrdup(optarg);
			break;
		case 'N':
			params.node = xstrdup(optarg);
			break;
		case 'o':
			params.output = xstrdup(optarg);
			break;
		case 'p':
			params.dir = xstrdup(optarg);
			break;
		case 's':
			params.series = xstrdup(optarg);
			break;
		case 'S':
			params.keepfiles = 1;
			break;
		case 'u':
			if (uid_from_string (optarg, &uid) < 0) {
				error("--uid=\"%s\" invalid", optarg);
				exit(1);
			}
			break;
		case (int)'v':
			params.verbose++;
			break;
		case (int)'V':
			print_slurm_version();
			exit(0);
			break;
		case ':':
		case '?': /* getopt() has explained it */
			exit(1);
		}
	}

	if (params.help) {
		switch (params.help) {
		case 1:
		case 3:
			_help_msg();
			break;
		default:
			fprintf(stderr, "bug: --help=%d\n",
				params.help);
		}
		exit(0);
	}

	if (params.job_id == -1)
		fatal("You need to supply a --jobs value.");

	if (uid == -1)
		uid = getuid();

	params.user = uid_to_string(uid);

	if (!params.dir)
		acct_gather_profile_g_get(ACCT_GATHER_PROFILE_DIR, &params.dir);

	if (!params.dir)
		fatal("You need to supply a --profiledir or be on a "
		      "node with a valid acct_gather.conf");

	if (params.verbose) {
		logopt.stderr_level += params.verbose;
		log_alter(logopt, SYSLOG_FACILITY_USER, NULL);
	}

	/* FIXME : For now all these only work for extract.  Seems
	 * like it would be easy to add the logic to "merge" as well.
	 */
	if (params.input || params.level || params.node
	    || (params.step_id != -1) || params.series)
		params.mode = SH5UTIL_MODE_EXTRACT;

	if (params.mode == SH5UTIL_MODE_EXTRACT) {
		if (!params.level)
			params.level = xstrdup("Node:Totals");
		if (!params.input)
			params.input = xstrdup_printf(
				"./job_%d.h5", params.job_id);
		if (!params.output)
			params.output = xstrdup_printf(
				"./extract_%d.csv", params.job_id);

	}

	if (!params.output)
		params.output = xstrdup_printf("./job_%d.h5", params.job_id);

}
Exemplo n.º 3
0
/* Parse arguments, etc then get my socket address/port information. Attempt to
 * adopt this process into a job in the following order:
 * 	1) If the user has only one job on the node, pick that one
 * 	2) Send RPC to source IP of socket. If there is a slurmd at the IP
 * 		address, ask it which job I belong to. On success, pick that one
 *	3) Pick a job semi-randomly (default) or skip the adoption (if
 *		configured)
 */
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags
				__attribute__((unused)), int argc, const char **argv)
{
	int retval = PAM_IGNORE, rc, slurmrc, bufsize, user_jobs;
	char *user_name;
	List steps = NULL;
	step_loc_t *stepd = NULL;
	struct passwd pwd, *pwd_result;
	char *buf = NULL;

	_init_opts();
	_parse_opts(pamh, argc, argv);
	_log_init(opts.log_level);

	switch (opts.action_generic_failure) {
	case CALLERID_ACTION_DENY:
		rc = PAM_PERM_DENIED;
		break;
	case CALLERID_ACTION_ALLOW:
		rc = PAM_SUCCESS;
		break;
	case CALLERID_ACTION_IGNORE:
		rc = PAM_IGNORE;
		break;
		/* Newer gcc versions warn if enum cases are missing */
	default:
		error("The code is broken!!!!");
	}

	retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
	if (user_name == NULL || retval != PAM_SUCCESS)  {
		pam_syslog(pamh, LOG_ERR, "No username in PAM_USER? Fail!");
		return PAM_SESSION_ERR;
	}

	/* Check for an unsafe config that might lock out root. This is a very
	 * basic check that shouldn't be 100% relied on */
	if (!opts.ignore_root &&
	    (opts.action_unknown == CALLERID_ACTION_DENY ||
	     opts.action_no_jobs != CALLERID_ACTION_ALLOW ||
	     opts.action_adopt_failure != CALLERID_ACTION_ALLOW ||
	     opts.action_generic_failure != CALLERID_ACTION_ALLOW
		    )) {
		/* Let's get verbose */
		info("===============================");
		info("Danger!!!");
		info("A crazy admin set ignore_root=0 and some unsafe actions");
		info("You might lock out root!");
		info("If this is desirable, modify the source code");
		info("Setting ignore_root=1 and continuing");
		opts.ignore_root = 1;
	}

	/* Ignoring root is probably best but the admin can allow it */
	if (!strcmp(user_name, "root")) {
		if (opts.ignore_root) {
			info("Ignoring root user");
			return PAM_IGNORE;
		} else {
			/* This administrator is crazy */
			info("Danger!!! This is a connection attempt by root and ignore_root=0 is set! Hope for the best!");
		}
	}

	/* Calculate buffer size for getpwnam_r */
	bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
	if (bufsize == -1)
		bufsize = 16384; /* take a large guess */

	buf = xmalloc(bufsize);
	retval = getpwnam_r(user_name, &pwd, buf, bufsize, &pwd_result);
	if (pwd_result == NULL) {
		if (retval == 0) {
			error("getpwnam_r could not locate %s", user_name);
		} else {
			errno = retval;
			error("getpwnam_r: %m");
		}

		xfree(buf);
		return PAM_SESSION_ERR;
	}

	if (_load_cgroup_config() != SLURM_SUCCESS)
		return rc;

	/* Check if there are any steps on the node from any user. A failure here
	 * likely means failures everywhere so exit on failure or if no local jobs
	 * exist. */
	steps = stepd_available(NULL, opts.node_name);
	if (!steps) {
		error("Error obtaining local step information.");
		goto cleanup;
	}

	/* Check to see if this user has only one job on the node. If so, choose
	 * that job and adopt this process into it (unless configured not to) */
	user_jobs = _user_job_count(steps, pwd.pw_uid, &stepd);
	if (user_jobs == 0) {
		if (opts.action_no_jobs == CALLERID_ACTION_DENY) {
			send_user_msg(pamh,
				      "Access denied by "
				      PAM_MODULE_NAME
				      ": you have no active jobs on this node");
			rc = PAM_PERM_DENIED;
		} else {
			debug("uid %u owns no jobs but action_no_jobs=ignore",
			      pwd.pw_uid);
			rc = PAM_IGNORE;
		}
		goto cleanup;
	} else if (user_jobs == 1) {
		if (opts.single_job_skip_rpc) {
			info("Connection by user %s: user has only one job %u",
			     user_name,
			     stepd->jobid);
			slurmrc = _adopt_process(getpid(), stepd);
			/* If adoption into the only job fails, it is time to
			 * exit. Return code is based on the
			 * action_adopt_failure setting */
			if (slurmrc == SLURM_SUCCESS ||
			    (opts.action_adopt_failure ==
			     CALLERID_ACTION_ALLOW))
				rc = PAM_SUCCESS;
			else
				rc = PAM_PERM_DENIED;
			goto cleanup;
		}
	} else {
		debug("uid %u has %d jobs", pwd.pw_uid, user_jobs);
	}

	/* Single job check turned up nothing (or we skipped it). Make RPC call
	 * to slurmd at source IP. If it can tell us the job, the function calls
	 * _adopt_process */
	rc = _try_rpc(&pwd);
	if (rc == PAM_SUCCESS)
		goto cleanup;

	/* The source of the connection either didn't reply or couldn't
	 * determine the job ID at the source. Proceed to action_unknown */
	rc = _action_unknown(pamh, &pwd, steps);

cleanup:
	FREE_NULL_LIST(steps);
	xfree(buf);
	xfree(slurm_cgroup_conf);
	xfree(opts.node_name);
	return rc;
}