/*****************************************************************************\
 *  cred.c - Slurm job and sbcast credential functions
 *****************************************************************************
 *  Copyright (C) 2002-2007 The Regents of the University of California.
 *  Copyright (C) 2008-2010 Lawrence Livermore National Security.
 *  Copyright (C) SchedMD LLC.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Morris Jette <jette1@llnl.gov>.
 *  CODE-OCEC-09-009. All rights reserved.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include "config.h"

#include <fcntl.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/time.h>

#include "slurm/slurm_errno.h"
#include "src/common/bitstring.h"
#include "src/common/group_cache.h"
#include "src/common/identity.h"
#include "src/common/job_resources.h"
#include "src/common/list.h"
#include "src/common/log.h"
#include "src/common/macros.h"
#include "src/common/plugin.h"
#include "src/common/plugrack.h"
#include "src/common/slurm_protocol_api.h"
#include "src/common/slurm_protocol_pack.h"
#include "src/common/slurm_time.h"
#include "src/common/uid.h"
#include "src/common/xassert.h"
#include "src/common/xmalloc.h"
#include "src/common/xstring.h"
#include "src/interfaces/cred.h"
#include "src/interfaces/gres.h"
#include "src/interfaces/switch.h"

typedef struct {
	slurm_cred_t *(*cred_create)	(slurm_cred_arg_t *cred_arg,
					 bool sign_it,
					 uint16_t protocol_version);
	slurm_cred_t *(*cred_unpack)	(buf_t *buffer,
					 uint16_t protocol_version);
	char *(*create_net_cred)	(void *addrs,
					 uint16_t protocol_version);
	void *(*extract_net_cred)	(char *net_cred,
					 uint16_t protocol_version);
	sbcast_cred_t *(*sbcast_create)	(sbcast_cred_arg_t *cred,
					 uint16_t protocol_version);
	sbcast_cred_t *(*sbcast_unpack)	(buf_t *buffer, bool verify,
					 uint16_t protocol_version);
} slurm_cred_ops_t;

/*
 * These strings must be in the same order as the fields declared
 * for slurm_cred_ops_t.
 */
static const char *syms[] = {
	"cred_p_create",
	"cred_p_unpack",
	"cred_p_create_net_cred",
	"cred_p_extract_net_cred",
	"sbcast_p_create",
	"sbcast_p_unpack",
};

static slurm_cred_ops_t ops;
static plugin_context_t *g_context = NULL;
static pthread_mutex_t g_context_lock = PTHREAD_MUTEX_INITIALIZER;
static time_t cred_restart_time = (time_t) 0;
static int cred_expire = DEFAULT_EXPIRATION_WINDOW;
static bool enable_nss_slurm = false;
static bool enable_send_gids = true;

/* Initialize the plugin. */
extern int cred_g_init(void)
{
	char *tok;
	char *plugin_type = "cred";
	int retval = SLURM_SUCCESS;
	char *type = NULL;

	/*
	 * Avoid issues with configless if Slurm was built without MUNGE,
	 * as the process that fetches the configs will still trigger
	 * slurm_init(), which will default to cred/munge, which will
	 * then fail to initialize as the plugin will be missing.
	 */
	if (getenv("SLURM_CONFIG_FETCH")) {
		xfree(slurm_conf.cred_type);
		goto done;
	}

	/*					 123456789012 */
	if ((tok = xstrstr(slurm_conf.authinfo, "cred_expire="))) {
		cred_expire = atoi(tok + 12);
		if (cred_expire < 5) {
			error("AuthInfo=cred_expire=%d invalid", cred_expire);
			cred_expire = DEFAULT_EXPIRATION_WINDOW;
		}
	}

	if (xstrcasestr(slurm_conf.launch_params, "enable_nss_slurm"))
		enable_nss_slurm = true;
	else if (xstrcasestr(slurm_conf.launch_params, "disable_send_gids"))
		enable_send_gids = false;

	/* allow the bare plugin name. also handle slurm type quirks */
	type = slurm_conf.cred_type;
	if (!xstrncmp(type, "auth/", 5) || !xstrncmp(type, "cred/", 5))
		type += 5;
	if (!xstrcmp(type, "slurm"))
		type = xstrdup("auth/slurm");
	else
		type = xstrdup_printf("cred/%s", type);

	slurm_mutex_lock(&g_context_lock);
	if (cred_restart_time == (time_t) 0)
		cred_restart_time = time(NULL);
	if (g_context)
		goto done;

	g_context = plugin_context_create(plugin_type, type,
					  (void **) &ops, syms, sizeof(syms));

	if (!g_context) {
		error("cannot create %s context for %s",
		      plugin_type, slurm_conf.cred_type);
		retval = SLURM_ERROR;
		goto done;
	}

done:
	slurm_mutex_unlock(&g_context_lock);
	xfree(type);

	return(retval);
}

/* Terminate the plugin and release all memory. */
extern int cred_g_fini(void)
{
	int rc;

	if (!g_context)
		return SLURM_SUCCESS;

	rc = plugin_context_destroy(g_context);
	g_context = NULL;
	return rc;
}

extern int cred_expiration(void)
{
	return cred_expire;
}

extern slurm_cred_t *slurm_cred_create(slurm_cred_arg_t *arg, bool sign_it,
				       uint16_t protocol_version)
{
	slurm_cred_t *cred = NULL;
	int i = 0, sock_recs = 0;
	bool release_id = false;
	identity_t fake_id = { .uid = arg->uid, .gid = arg->gid, .fake = true };

	xassert(arg);
	xassert(g_context);

	if (arg->uid == SLURM_AUTH_NOBODY) {
		error("%s: refusing to create job %u credential for invalid user nobody",
		      __func__, arg->step_id.job_id);
		return NULL;
	}

	if (arg->gid == SLURM_AUTH_NOBODY) {
		error("%s: refusing to create job %u credential for invalid group nobody",
		      __func__, arg->step_id.job_id);
		return NULL;
	}

	if (arg->sock_core_rep_count) {
		for (i = 0; i < arg->job_nhosts; i++) {
			sock_recs += arg->sock_core_rep_count[i];
			if (sock_recs >= arg->job_nhosts)
				break;
		}
		i++;
	}
	arg->core_array_size = i;

	if (!arg->id && (enable_nss_slurm || enable_send_gids)) {
		release_id = true;
		if (!(arg->id = fetch_identity(arg->uid, arg->gid,
					       enable_nss_slurm))) {
			error("%s: fetch_identity() failed", __func__);
			return NULL;
		}
	} else if (!arg->id) {
		arg->id = &fake_id;
	}

	identity_debug2(arg->id, __func__);
	cred = (*(ops.cred_create))(arg, sign_it, protocol_version);

	/* Release any values populated through _fill_cred_gids(). */
	if (release_id)
		FREE_NULL_IDENTITY(arg->id);

	return cred;
}

extern slurm_cred_t *slurm_cred_faker(slurm_cred_arg_t *arg)
{
	/*
	 * Force this on to ensure pw_name, ngid, gids are all populated.
	 */
	enable_send_gids = true;

	return slurm_cred_create(arg, true, SLURM_PROTOCOL_VERSION);
}

extern void slurm_cred_free_args(slurm_cred_arg_t *arg)
{
	if (!arg)
		return;

	FREE_NULL_IDENTITY(arg->id);
	FREE_NULL_BITMAP(arg->job_core_bitmap);
	FREE_NULL_BITMAP(arg->step_core_bitmap);
	xfree(arg->cores_per_socket);
	xfree(arg->cpu_array);
	xfree(arg->cpu_array_reps);
	FREE_NULL_LIST(arg->job_gres_list);
	FREE_NULL_LIST(arg->step_gres_list);
	xfree(arg->step_hostlist);
	xfree(arg->job_account);
	xfree(arg->job_alias_list);
	xfree(arg->job_comment);
	xfree(arg->job_constraints);
	xfree(arg->job_licenses);
	xfree(arg->job_hostlist);
	xfree(arg->sock_core_rep_count);
	xfree(arg->sockets_per_node);
	xfree(arg->job_mem_alloc);
	xfree(arg->job_mem_alloc_rep_count);
	xfree(arg->job_node_addrs);
	xfree(arg->job_partition);
	xfree(arg->job_reservation);
	xfree(arg->job_std_err);
	xfree(arg->job_std_in);
	xfree(arg->job_std_out);
	xfree(arg->step_mem_alloc);
	xfree(arg->step_mem_alloc_rep_count);

	switch_g_free_stepinfo(arg->switch_step);

	xfree(arg);
}

extern void slurm_cred_unlock_args(slurm_cred_t *cred)
{
	slurm_rwlock_unlock(&cred->mutex);
}

/*
 * Caller *must* release lock.
 */
extern slurm_cred_arg_t *slurm_cred_get_args(slurm_cred_t *cred)
{
	xassert(cred);

	slurm_rwlock_rdlock(&cred->mutex);
	return cred->arg;
}

extern void *slurm_cred_get(slurm_cred_t *cred,
			    cred_data_enum_t cred_data_type)
{
	void *rc = NULL;

	xassert(cred);

	slurm_rwlock_rdlock(&cred->mutex);

	if (!cred->arg) {
		slurm_rwlock_unlock(&cred->mutex);
		return NULL;
	}

	switch (cred_data_type) {
	case CRED_DATA_JOB_GRES_LIST:
		rc = (void *) cred->arg->job_gres_list;
		break;
	case CRED_DATA_JOB_ALIAS_LIST:
		rc = (void *) cred->arg->job_alias_list;
		break;
	case CRED_DATA_JOB_NODE_ADDRS:
		rc = (void *) cred->arg->job_node_addrs;
		break;
	case CRED_DATA_STEP_GRES_LIST:
		rc = (void *) cred->arg->step_gres_list;
		break;
	default:
		error("%s: Invalid arg type requested (%d)", __func__,
		      cred_data_type);

	}
	slurm_rwlock_unlock(&cred->mutex);

	return rc;
}

/*
 * Returns NULL on error.
 *
 * On success, returns a pointer to the arg structure within the credential.
 * Caller *must* release the lock.
 */
extern slurm_cred_arg_t *slurm_cred_verify(slurm_cred_t *cred)
{
	time_t now = time(NULL);
	int errnum;

	xassert(cred);
	xassert(g_context);

	slurm_rwlock_rdlock(&cred->mutex);
	xassert(cred->magic == CRED_MAGIC);

	/* NOTE: the verification checks that the credential was
	 * created by SlurmUser or root */
	if (!cred->verified) {
		errno = ESLURMD_INVALID_JOB_CREDENTIAL;
		goto error;
	}

	if (now > (cred->ctime + cred_expire)) {
		errno = ESLURMD_CREDENTIAL_EXPIRED;
		goto error;
	}

	/* coverity[missing_unlock] */
	return cred->arg;

error:
	errnum = errno;
	slurm_rwlock_unlock(&cred->mutex);
	errno = errnum;
	return NULL;
}


extern void slurm_cred_destroy(slurm_cred_t *cred)
{
	if (cred == NULL)
		return;

	xassert(cred->magic == CRED_MAGIC);

	slurm_rwlock_wrlock(&cred->mutex);
	slurm_cred_free_args(cred->arg);
	FREE_NULL_BUFFER(cred->buffer);
	xfree(cred->signature);
	cred->magic = ~CRED_MAGIC;
	slurm_rwlock_unlock(&cred->mutex);
	slurm_rwlock_destroy(&cred->mutex);

	xfree(cred);
}

extern char *slurm_cred_get_signature(slurm_cred_t *cred)
{
	char *sig = NULL;

	xassert(cred);

	slurm_rwlock_rdlock(&cred->mutex);
	sig = xstrdup(cred->signature);
	slurm_rwlock_unlock(&cred->mutex);

	return sig;
}

extern void slurm_cred_get_mem(slurm_cred_t *credential, char *node_name,
			       const char *func_name,
			       uint64_t *job_mem_limit,
			       uint64_t *step_mem_limit)
{
	slurm_cred_arg_t *cred = credential->arg;
	int rep_idx = -1;
	int node_id = -1;

	/*
	 * Batch steps only have the job_hostlist set and will always be 0 here.
	 */
	if (cred->step_id.step_id == SLURM_BATCH_SCRIPT) {
		rep_idx = 0;
	} else if ((node_id =
		    nodelist_find(cred->job_hostlist, node_name)) >= 0) {
		rep_idx = slurm_get_rep_count_inx(cred->job_mem_alloc_rep_count,
					          cred->job_mem_alloc_size,
						  node_id);

	} else {
		error("Unable to find %s in job hostlist: `%s'",
		      node_name, cred->job_hostlist);
	}

	if (rep_idx < 0)
		error("%s: node_id=%d, not found in job_mem_alloc_rep_count requested job memory not reset.",
		      func_name, node_id);
	else
		*job_mem_limit = cred->job_mem_alloc[rep_idx];

	if (!step_mem_limit) {
		log_flag(CPU_BIND, "%s: Memory extracted from credential for %ps job_mem_limit= %"PRIu64,
			 func_name, &cred->step_id, *job_mem_limit);
		return;
	}

	if (cred->step_mem_alloc) {
		rep_idx = -1;
		if ((node_id =
		     nodelist_find(cred->step_hostlist, node_name)) >= 0) {
			rep_idx = slurm_get_rep_count_inx(
						cred->step_mem_alloc_rep_count,
						cred->step_mem_alloc_size,
						node_id);
		} else {
			error("Unable to find %s in step hostlist: `%s'",
			      node_name, cred->step_hostlist);
		}
		if (rep_idx < 0)
			error("%s: node_id=%d, not found in step_mem_alloc_rep_count",
			      func_name, node_id);
		else
			*step_mem_limit = cred->step_mem_alloc[rep_idx];
	}

	/*
	 * If we are not set or we were sent 0 go with the job_mem_limit value.
	 */
	if (!(*step_mem_limit))
		*step_mem_limit = *job_mem_limit;

	log_flag(CPU_BIND, "Memory extracted from credential for %ps job_mem_limit=%"PRIu64" step_mem_limit=%"PRIu64,
		 &cred->step_id, *job_mem_limit, *step_mem_limit);
}

/* Convert bitmap to string representation with brackets removed */
static char *_core_format(bitstr_t *core_bitmap)
{
	char str[1024], *bracket_ptr;

	bit_fmt(str, sizeof(str), core_bitmap);
	if (str[0] != '[')
		return xstrdup(str);

	/* strip off brackets */
	bracket_ptr = strchr(str, ']');
	if (bracket_ptr)
		bracket_ptr[0] = '\0';
	return xstrdup(str+1);
}

/*
 * Retrieve the set of cores that were allocated to the job and step then
 * format them in the List Format (e.g., "0-2,7,12-14"). Also return
 * job and step's memory limit.
 *
 * NOTE: caller must xfree the returned strings.
 */
extern void format_core_allocs(slurm_cred_t *credential, char *node_name,
			       uint16_t cpus, char **job_alloc_cores,
			       char **step_alloc_cores, uint64_t *job_mem_limit,
			       uint64_t *step_mem_limit)
{
	slurm_cred_arg_t *cred = credential->arg;
	bitstr_t	*job_core_bitmap, *step_core_bitmap;
	hostlist_t *hset = NULL;
	int		host_index = -1;
	uint32_t	i, j, i_first_bit=0, i_last_bit=0;

	xassert(cred);
	xassert(job_alloc_cores);
	xassert(step_alloc_cores);
	if (!(hset = hostlist_create(cred->job_hostlist))) {
		error("Unable to create job hostlist: `%s'",
		      cred->job_hostlist);
		return;
	}
	host_index = hostlist_find(hset, node_name);
	if ((host_index < 0) || (host_index >= cred->job_nhosts)) {
		error("Invalid host_index %d for job %u",
		      host_index, cred->step_id.job_id);
		error("Host %s not in hostlist %s",
		      node_name, cred->job_hostlist);
		hostlist_destroy(hset);
		return;
	}
	host_index++;	/* change from 0-origin to 1-origin */
	for (i=0; host_index; i++) {
		if (host_index > cred->sock_core_rep_count[i]) {
			i_first_bit += cred->sockets_per_node[i] *
				cred->cores_per_socket[i] *
				cred->sock_core_rep_count[i];
			host_index -= cred->sock_core_rep_count[i];
		} else {
			i_first_bit += cred->sockets_per_node[i] *
				cred->cores_per_socket[i] *
				(host_index - 1);
			i_last_bit = i_first_bit +
				cred->sockets_per_node[i] *
				cred->cores_per_socket[i];
			break;
		}
	}

	job_core_bitmap  = bit_alloc(i_last_bit - i_first_bit);
	step_core_bitmap = bit_alloc(i_last_bit - i_first_bit);
	for (i = i_first_bit, j = 0; i < i_last_bit; i++, j++) {
		if (bit_test(cred->job_core_bitmap, i))
			bit_set(job_core_bitmap, j);
		if (bit_test(cred->step_core_bitmap, i))
			bit_set(step_core_bitmap, j);
	}

	slurm_cred_get_mem(credential, node_name, __func__, job_mem_limit,
			   step_mem_limit);

	*job_alloc_cores  = _core_format(job_core_bitmap);
	*step_alloc_cores = _core_format(step_core_bitmap);
	FREE_NULL_BITMAP(job_core_bitmap);
	FREE_NULL_BITMAP(step_core_bitmap);
	hostlist_destroy(hset);
}

/*
 * Retrieve the job and step generic resources (gres) allocate to this job
 * on this node.
 *
 * NOTE: Caller must destroy the returned lists
 */
extern void get_cred_gres(slurm_cred_t *credential, char *node_name,
			  list_t **job_gres_list, list_t **step_gres_list)
{
	slurm_cred_arg_t *cred = credential->arg;
	hostlist_t *hset = NULL;
	int		host_index = -1;

	xassert(cred);
	xassert(job_gres_list);
	xassert(step_gres_list);

	FREE_NULL_LIST(*job_gres_list);
	FREE_NULL_LIST(*step_gres_list);
	if ((cred->job_gres_list == NULL) && (cred->step_gres_list == NULL))
		return;

	if (!(hset = hostlist_create(cred->job_hostlist))) {
		error("Unable to create job hostlist: `%s'",
		      cred->job_hostlist);
		return;
	}
	host_index = hostlist_find(hset, node_name);
	hostlist_destroy(hset);
	if ((host_index < 0) || (host_index >= cred->job_nhosts)) {
		error("Invalid host_index %d for job %u",
		      host_index, cred->step_id.job_id);
		error("Host %s not in credential hostlist %s",
		      node_name, cred->job_hostlist);
		return;
	}

	*job_gres_list = gres_job_state_extract(cred->job_gres_list,
						host_index);
	*step_gres_list = gres_step_state_extract(cred->step_gres_list,
						  host_index);
	return;
}

extern void slurm_cred_pack(slurm_cred_t *cred, buf_t *buffer,
			    uint16_t protocol_version)
{
	xassert(cred);
	xassert(cred->magic == CRED_MAGIC);

	slurm_rwlock_rdlock(&cred->mutex);

	xassert(cred->buffer);
	xassert(cred->buf_version == protocol_version);
	packbuf(cred->buffer, buffer);

	slurm_rwlock_unlock(&cred->mutex);
}

extern slurm_cred_t *slurm_cred_unpack(buf_t *buffer, uint16_t protocol_version)
{
	return (*(ops.cred_unpack))(buffer, protocol_version);
}

extern slurm_cred_t *slurm_cred_alloc(bool alloc_arg)
{
	slurm_cred_t *cred = xmalloc(sizeof(*cred));
	/* Contents initialized to zero */

	slurm_rwlock_init(&cred->mutex);

	if (alloc_arg) {
		cred->arg = xmalloc(sizeof(slurm_cred_arg_t));
		cred->arg->uid = SLURM_AUTH_NOBODY;
		cred->arg->gid = SLURM_AUTH_NOBODY;
	}

	cred->verified = false;

	cred->magic = CRED_MAGIC;

	return cred;
}

/*****************************************************************************\
 *****************       SBCAST CREDENTIAL FUNCTIONS        ******************
\*****************************************************************************/

/* Create an sbcast credential for the specified job and nodes
 *	including digital signature.
 * RET the sbcast credential or NULL on error */
extern sbcast_cred_t *create_sbcast_cred(sbcast_cred_arg_t *arg,
					 uid_t uid, gid_t gid,
					 uint16_t protocol_version)
{
	sbcast_cred_t *sbcast_cred;
	bool release_id = false;
	identity_t fake_id = { .uid = uid, .gid = gid, .fake = true };

	xassert(g_context);

	if (!arg->id && enable_send_gids) {
		release_id = true;
		if (!(arg->id = fetch_identity(uid, gid, false))) {
			error("%s: fetch_identity() failed", __func__);
			return NULL;
		}
	} else if (!arg->id) {
		arg->id = &fake_id;
	}

	if (!(sbcast_cred = (*(ops.sbcast_create))(arg, protocol_version)))
		error("%s: failed to create sbcast credential", __func__);

	if (release_id)
		FREE_NULL_IDENTITY(arg->id);

	return sbcast_cred;
}

/* Delete an sbcast credential created using create_sbcast_cred() or
 *	unpack_sbcast_cred() */
extern void delete_sbcast_cred(sbcast_cred_t *sbcast_cred)
{
	if (!sbcast_cred)
		return;

	FREE_NULL_IDENTITY(sbcast_cred->arg.id);
	xfree(sbcast_cred->arg.nodes);
	FREE_NULL_BUFFER(sbcast_cred->buffer);
	xfree(sbcast_cred->signature);
	xfree(sbcast_cred);
}

/* Pack an sbcast credential into a buffer including the digital signature */
extern void pack_sbcast_cred(sbcast_cred_t *sbcast_cred, buf_t *buffer,
			     uint16_t protocol_version)
{
	xassert(sbcast_cred);

	if (sbcast_cred->buffer) {
		/* already includes signature */
		packbuf(sbcast_cred->buffer, buffer);
	} else {
		/* credential only uses signature */
		packstr(sbcast_cred->signature, buffer);
	}
}

extern sbcast_cred_t *unpack_sbcast_cred(buf_t *buffer, void *msg,
					 uint16_t protocol_version)
{
	file_bcast_msg_t *bmsg = msg;
	bool verify = false;

	if (bmsg && (bmsg->block_no == 1) && !(bmsg->flags & FILE_BCAST_SO))
		verify = true;

	return (*(ops.sbcast_unpack))(buffer, verify, protocol_version);
}

extern void print_sbcast_cred(sbcast_cred_t *sbcast_cred)
{
	info("Sbcast_cred: JobId   %u", sbcast_cred->arg.job_id);
	info("Sbcast_cred: HetJobId %u", sbcast_cred->arg.het_job_id);
	info("Sbcast_cred: StepId  %u", sbcast_cred->arg.step_id);
	info("Sbcast_cred: Nodes   %s", sbcast_cred->arg.nodes);
	info("Sbcast_cred: ctime   %s", slurm_ctime2(&sbcast_cred->ctime));
	info("Sbcast_cred: Expire  %s", slurm_ctime2(&sbcast_cred->arg.expiration));
}

extern char *create_net_cred(void *addrs, uint16_t protocol_version)
{
	xassert(g_context);

	if (!addrs) {
		error("%s: addrs not provided", __func__);
		return NULL;
	}

	return (*(ops.create_net_cred))(addrs, protocol_version);
}

extern void *extract_net_cred(char *net_cred, uint16_t protocol_version)
{
	xassert(g_context);

	if (!net_cred) {
		error("%s: net_cred not provided", __func__);
		return NULL;
	}

	return (*(ops.extract_net_cred))(net_cred, protocol_version);
}

extern void setup_cred_arg(slurm_cred_arg_t *cred_arg, job_record_t *job_ptr)
{
	memset(cred_arg, 0, sizeof(slurm_cred_arg_t));

	cred_arg->id = job_ptr->id;

	cred_arg->gid = job_ptr->group_id;
	cred_arg->job_account = job_ptr->account;
	cred_arg->job_alias_list = job_ptr->alias_list;
	cred_arg->job_comment = job_ptr->comment;
	cred_arg->job_end_time = job_ptr->end_time;
	cred_arg->job_extra = job_ptr->extra;
	cred_arg->job_gres_list = job_ptr->gres_list_alloc;
	cred_arg->job_licenses = job_ptr->licenses;
	cred_arg->job_node_addrs = job_ptr->node_addrs;
	cred_arg->job_reservation = job_ptr->resv_name;
	cred_arg->job_restart_cnt = job_ptr->restart_cnt;
	cred_arg->job_selinux_context = job_ptr->selinux_context;
	cred_arg->job_start_time = job_ptr->start_time;
	cred_arg->uid = job_ptr->user_id;

	if (job_ptr->details) {
		cred_arg->job_constraints = job_ptr->details->features_use;
		cred_arg->job_core_spec = job_ptr->details->core_spec;
		cred_arg->job_ntasks = job_ptr->details->num_tasks;
		cred_arg->job_oversubscribe = get_job_share_value(job_ptr);
		cred_arg->job_std_err = job_ptr->details->std_err;
		cred_arg->job_std_in = job_ptr->details->std_in;
		cred_arg->job_std_out = job_ptr->details->std_out;
		cred_arg->job_x11 = job_ptr->details->x11;
	}

	if (job_ptr->job_resrcs) {
		job_resources_t *resrcs = job_ptr->job_resrcs;
		cred_arg->cores_per_socket = resrcs->cores_per_socket;
		cred_arg->cpu_array_count = resrcs->cpu_array_cnt;
		cred_arg->cpu_array = resrcs->cpu_array_value;
		cred_arg->cpu_array_reps = resrcs->cpu_array_reps;
		cred_arg->job_core_bitmap = resrcs->core_bitmap;
		cred_arg->job_hostlist = resrcs->nodes;
		cred_arg->job_nhosts = resrcs->nhosts;
		cred_arg->sock_core_rep_count = resrcs->sock_core_rep_count;
		cred_arg->sockets_per_node = resrcs->sockets_per_node;
	}

	if (job_ptr->part_ptr)
		cred_arg->job_partition = job_ptr->part_ptr->name;
}
