| /*****************************************************************************\ |
| * cred_common.c |
| ***************************************************************************** |
| * Copyright (C) SchedMD LLC. |
| * |
| * 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 "slurm/slurm_errno.h" |
| |
| #include "src/common/bitstring.h" |
| #include "src/common/group_cache.h" |
| #include "src/common/identity.h" |
| #include "src/common/log.h" |
| #include "src/common/slurm_protocol_pack.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" |
| |
| /* |
| * This is a way to avoid breaking RPC compatibility, while allowing an |
| * additional field to be sent. This works by hiding the extra field within |
| * an existing string field behind a trailing NUL. |
| * Two caveats: |
| * - If a NULL pointer was previously sent, it would now be received as instead. |
| * - If the receiving side verifies the string length it will see the full |
| * payload length, which is no longer equal to the strlen(). |
| */ |
| #define safe_unpackstr_and_switch(valp, switch, buf, proto) \ |
| do { \ |
| xassert(buf->magic == BUF_MAGIC); \ |
| if (_unpackstr_and_switch(valp, switch, buf, proto)) \ |
| goto unpack_error; \ |
| } while (0) |
| |
| static void _packstr_and_switch(char *string, void *switch_step, buf_t *buffer, |
| uint16_t protocol_version) |
| { |
| uint32_t start = 0, end = 0; |
| |
| if (!switch_step) { |
| packstr(string, buffer); |
| return; |
| } |
| |
| if (!string) |
| string = ""; |
| |
| start = get_buf_offset(buffer); |
| packstr(string, buffer); |
| switch_g_pack_stepinfo(switch_step, buffer, protocol_version); |
| pack8(0, buffer); /* ensure trailing NUL */ |
| end = get_buf_offset(buffer); |
| set_buf_offset(buffer, start); |
| pack32(end - start - 4, buffer); |
| set_buf_offset(buffer, end); |
| } |
| |
| static int _unpackstr_and_switch(char **string, void **switch_step, |
| buf_t *buffer, uint16_t protocol_version) |
| { |
| uint32_t start = 0; |
| uint32_t len = 0, string_len = 0; |
| |
| start = get_buf_offset(buffer); |
| safe_unpackstr_xmalloc(string, &len, buffer); |
| |
| if (!*string) |
| return SLURM_SUCCESS; |
| |
| /* Ignore this in client commands and slurmd. Only stepd needs it. */ |
| if (!running_in_slurmstepd()) |
| return SLURM_SUCCESS; |
| |
| string_len = strlen(*string) + 1; |
| |
| if (len > string_len) { |
| dynamic_plugin_data_t *switch_tmp = NULL; |
| /* Second hidden field */ |
| uint32_t end = get_buf_offset(buffer); |
| set_buf_offset(buffer, start + string_len + 4); |
| if (switch_g_unpack_stepinfo(&switch_tmp, buffer, |
| protocol_version)) { |
| error("switch_g_unpack_stepinfo: %m"); |
| switch_g_free_stepinfo(switch_tmp); |
| goto unpack_error; |
| } |
| *switch_step = switch_tmp; |
| set_buf_offset(buffer, end); |
| } |
| |
| return SLURM_SUCCESS; |
| |
| unpack_error: |
| return SLURM_ERROR; |
| } |
| |
| extern slurm_cred_t *cred_create(slurm_cred_arg_t *cred, |
| uint16_t protocol_version) |
| { |
| slurm_cred_t *credential; |
| uint32_t tot_core_cnt = 0; |
| buf_t *buffer; |
| |
| time_t ctime = time(NULL); |
| |
| credential = slurm_cred_alloc(false); |
| credential->buffer = buffer = init_buf(4096); |
| credential->buf_version = protocol_version; |
| |
| if (protocol_version >= SLURM_24_11_PROTOCOL_VERSION) { |
| pack_step_id(&cred->step_id, buffer, protocol_version); |
| pack_identity(cred->id, buffer, protocol_version); |
| |
| (void) gres_job_state_pack(cred->job_gres_list, buffer, |
| cred->step_id.job_id, false, |
| protocol_version); |
| gres_step_state_pack(cred->step_gres_list, buffer, |
| &cred->step_id, protocol_version); |
| pack16(cred->job_core_spec, buffer); |
| packstr(cred->job_account, buffer); |
| slurm_pack_addr_array( |
| cred->job_node_addrs, |
| cred->job_node_addrs ? cred->job_nhosts : 0, |
| buffer); |
| packstr(cred->job_alias_list, buffer); |
| packstr(cred->job_comment, buffer); |
| packstr(cred->job_constraints, buffer); |
| pack_time(cred->job_end_time, buffer); |
| packstr(cred->job_extra, buffer); |
| pack16(cred->job_oversubscribe, buffer); |
| packstr(cred->job_partition, buffer); |
| packstr(cred->job_reservation, buffer); |
| pack16(cred->job_restart_cnt, buffer); |
| pack_time(cred->job_start_time, buffer); |
| packstr(cred->job_std_err, buffer); |
| packstr(cred->job_std_in, buffer); |
| packstr(cred->job_std_out, buffer); |
| packstr(cred->step_hostlist, buffer); |
| pack16(cred->job_x11, buffer); |
| pack_time(ctime, buffer); |
| |
| if (cred->job_core_bitmap) |
| tot_core_cnt = bit_size(cred->job_core_bitmap); |
| pack32(tot_core_cnt, buffer); |
| pack_bit_str_hex(cred->job_core_bitmap, buffer); |
| pack_bit_str_hex(cred->step_core_bitmap, buffer); |
| pack16(cred->core_array_size, buffer); |
| if (cred->core_array_size) { |
| pack16_array(cred->cores_per_socket, |
| cred->core_array_size, |
| buffer); |
| pack16_array(cred->sockets_per_node, |
| cred->core_array_size, |
| buffer); |
| pack32_array(cred->sock_core_rep_count, |
| cred->core_array_size, |
| buffer); |
| } |
| pack32(cred->cpu_array_count, buffer); |
| if (cred->cpu_array_count) { |
| pack16_array(cred->cpu_array, |
| cred->cpu_array_count, |
| buffer); |
| pack32_array(cred->cpu_array_reps, |
| cred->cpu_array_count, |
| buffer); |
| } |
| pack32(cred->job_nhosts, buffer); |
| pack32(cred->job_ntasks, buffer); |
| packstr(cred->job_hostlist, buffer); |
| packstr(cred->job_licenses, buffer); |
| pack32(cred->job_mem_alloc_size, buffer); |
| if (cred->job_mem_alloc_size) { |
| pack64_array(cred->job_mem_alloc, |
| cred->job_mem_alloc_size, |
| buffer); |
| pack32_array(cred->job_mem_alloc_rep_count, |
| cred->job_mem_alloc_size, |
| buffer); |
| } |
| pack32(cred->step_mem_alloc_size, buffer); |
| if (cred->step_mem_alloc_size) { |
| pack64_array(cred->step_mem_alloc, |
| cred->step_mem_alloc_size, |
| buffer); |
| pack32_array(cred->step_mem_alloc_rep_count, |
| cred->step_mem_alloc_size, |
| buffer); |
| } |
| packstr(cred->job_selinux_context, buffer); |
| switch_g_pack_stepinfo(cred->switch_step, buffer, |
| protocol_version); |
| } else if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) { |
| pack_step_id(&cred->step_id, buffer, protocol_version); |
| pack_identity(cred->id, buffer, protocol_version); |
| |
| (void) gres_job_state_pack(cred->job_gres_list, buffer, |
| cred->step_id.job_id, false, |
| protocol_version); |
| gres_step_state_pack(cred->step_gres_list, buffer, |
| &cred->step_id, protocol_version); |
| pack16(cred->job_core_spec, buffer); |
| packstr(cred->job_account, buffer); |
| slurm_pack_addr_array( |
| cred->job_node_addrs, |
| cred->job_node_addrs ? cred->job_nhosts : 0, |
| buffer); |
| packstr(cred->job_alias_list, buffer); |
| packstr(cred->job_comment, buffer); |
| packstr(cred->job_constraints, buffer); |
| pack_time(cred->job_end_time, buffer); |
| packstr(cred->job_extra, buffer); |
| pack16(cred->job_oversubscribe, buffer); |
| _packstr_and_switch(cred->job_partition, cred->switch_step, |
| buffer, protocol_version); |
| packstr(cred->job_reservation, buffer); |
| pack16(cred->job_restart_cnt, buffer); |
| pack_time(cred->job_start_time, buffer); |
| packstr(cred->job_std_err, buffer); |
| packstr(cred->job_std_in, buffer); |
| packstr(cred->job_std_out, buffer); |
| packstr(cred->step_hostlist, buffer); |
| pack16(cred->job_x11, buffer); |
| pack_time(ctime, buffer); |
| |
| if (cred->job_core_bitmap) |
| tot_core_cnt = bit_size(cred->job_core_bitmap); |
| pack32(tot_core_cnt, buffer); |
| pack_bit_str_hex(cred->job_core_bitmap, buffer); |
| pack_bit_str_hex(cred->step_core_bitmap, buffer); |
| pack16(cred->core_array_size, buffer); |
| if (cred->core_array_size) { |
| pack16_array(cred->cores_per_socket, |
| cred->core_array_size, |
| buffer); |
| pack16_array(cred->sockets_per_node, |
| cred->core_array_size, |
| buffer); |
| pack32_array(cred->sock_core_rep_count, |
| cred->core_array_size, |
| buffer); |
| } |
| pack32(cred->cpu_array_count, buffer); |
| if (cred->cpu_array_count) { |
| pack16_array(cred->cpu_array, |
| cred->cpu_array_count, |
| buffer); |
| pack32_array(cred->cpu_array_reps, |
| cred->cpu_array_count, |
| buffer); |
| } |
| pack32(cred->job_nhosts, buffer); |
| pack32(cred->job_ntasks, buffer); |
| packstr(cred->job_hostlist, buffer); |
| packstr(cred->job_licenses, buffer); |
| pack32(cred->job_mem_alloc_size, buffer); |
| if (cred->job_mem_alloc_size) { |
| pack64_array(cred->job_mem_alloc, |
| cred->job_mem_alloc_size, |
| buffer); |
| pack32_array(cred->job_mem_alloc_rep_count, |
| cred->job_mem_alloc_size, |
| buffer); |
| } |
| pack32(cred->step_mem_alloc_size, buffer); |
| if (cred->step_mem_alloc_size) { |
| pack64_array(cred->step_mem_alloc, |
| cred->step_mem_alloc_size, |
| buffer); |
| pack32_array(cred->step_mem_alloc_rep_count, |
| cred->step_mem_alloc_size, |
| buffer); |
| } |
| packstr(cred->job_selinux_context, buffer); |
| } |
| |
| return credential; |
| } |
| |
| extern int cred_unpack(void **out, buf_t *buffer, uint16_t protocol_version) |
| { |
| uint32_t len, uint32_tmp; |
| slurm_cred_t *cred = NULL; |
| slurm_cred_arg_t *cred_arg = NULL; |
| char *bit_fmt_str = NULL; |
| dynamic_plugin_data_t *switch_tmp = NULL; |
| uint32_t tot_core_cnt; |
| |
| cred = slurm_cred_alloc(true); |
| cred_arg = cred->arg; |
| if (protocol_version >= SLURM_24_11_PROTOCOL_VERSION) { |
| if (unpack_step_id_members(&cred_arg->step_id, buffer, |
| protocol_version) != SLURM_SUCCESS) |
| goto unpack_error; |
| |
| if (unpack_identity(&cred_arg->id, buffer, protocol_version)) |
| goto unpack_error; |
| |
| if (gres_job_state_unpack(&cred_arg->job_gres_list, buffer, |
| cred_arg->step_id.job_id, |
| protocol_version) |
| != SLURM_SUCCESS) |
| goto unpack_error; |
| if (gres_step_state_unpack(&cred_arg->step_gres_list, |
| buffer, &cred_arg->step_id, |
| protocol_version) |
| != SLURM_SUCCESS) { |
| goto unpack_error; |
| } |
| safe_unpack16(&cred_arg->job_core_spec, buffer); |
| safe_unpackstr(&cred_arg->job_account, buffer); |
| if (slurm_unpack_addr_array(&cred_arg->job_node_addrs, |
| &uint32_tmp, buffer)) |
| goto unpack_error; |
| safe_unpackstr(&cred_arg->job_alias_list, buffer); |
| safe_unpackstr(&cred_arg->job_comment, buffer); |
| safe_unpackstr(&cred_arg->job_constraints, buffer); |
| safe_unpack_time(&cred_arg->job_end_time, buffer); |
| safe_unpackstr(&cred_arg->job_extra, buffer); |
| safe_unpack16(&cred_arg->job_oversubscribe, buffer); |
| safe_unpackstr(&cred_arg->job_partition, buffer); |
| safe_unpackstr(&cred_arg->job_reservation, buffer); |
| safe_unpack16(&cred_arg->job_restart_cnt, buffer); |
| safe_unpack_time(&cred_arg->job_start_time, buffer); |
| safe_unpackstr(&cred_arg->job_std_err, buffer); |
| safe_unpackstr(&cred_arg->job_std_in, buffer); |
| safe_unpackstr(&cred_arg->job_std_out, buffer); |
| safe_unpackstr(&cred_arg->step_hostlist, buffer); |
| safe_unpack16(&cred_arg->job_x11, buffer); |
| safe_unpack_time(&cred->ctime, buffer); |
| safe_unpack32(&tot_core_cnt, buffer); |
| unpack_bit_str_hex(&cred_arg->job_core_bitmap, buffer); |
| unpack_bit_str_hex(&cred_arg->step_core_bitmap, buffer); |
| safe_unpack16(&cred_arg->core_array_size, buffer); |
| if (cred_arg->core_array_size) { |
| safe_unpack16_array(&cred_arg->cores_per_socket, &len, |
| buffer); |
| if (len != cred_arg->core_array_size) |
| goto unpack_error; |
| safe_unpack16_array(&cred_arg->sockets_per_node, &len, |
| buffer); |
| if (len != cred_arg->core_array_size) |
| goto unpack_error; |
| safe_unpack32_array(&cred_arg->sock_core_rep_count, |
| &len, buffer); |
| if (len != cred_arg->core_array_size) |
| goto unpack_error; |
| } |
| safe_unpack32(&cred_arg->cpu_array_count, buffer); |
| if (cred_arg->cpu_array_count) { |
| safe_unpack16_array(&cred_arg->cpu_array, &len, buffer); |
| if (len != cred_arg->cpu_array_count) |
| goto unpack_error; |
| safe_unpack32_array(&cred_arg->cpu_array_reps, &len, |
| buffer); |
| if (len != cred_arg->cpu_array_count) |
| goto unpack_error; |
| } |
| safe_unpack32(&cred_arg->job_nhosts, buffer); |
| safe_unpack32(&cred_arg->job_ntasks, buffer); |
| safe_unpackstr(&cred_arg->job_hostlist, buffer); |
| safe_unpackstr(&cred_arg->job_licenses, buffer); |
| |
| safe_unpack32(&cred_arg->job_mem_alloc_size, buffer); |
| if (cred_arg->job_mem_alloc_size) { |
| safe_unpack64_array(&cred_arg->job_mem_alloc, &len, |
| buffer); |
| if (len != cred_arg->job_mem_alloc_size) |
| goto unpack_error; |
| |
| safe_unpack32_array(&cred_arg->job_mem_alloc_rep_count, |
| &len, buffer); |
| if (len != cred_arg->job_mem_alloc_size) |
| goto unpack_error; |
| |
| } |
| |
| safe_unpack32(&cred_arg->step_mem_alloc_size, buffer); |
| if (cred_arg->step_mem_alloc_size) { |
| safe_unpack64_array(&cred_arg->step_mem_alloc, &len, |
| buffer); |
| if (len != cred_arg->step_mem_alloc_size) |
| goto unpack_error; |
| |
| safe_unpack32_array(&cred_arg->step_mem_alloc_rep_count, |
| &len, buffer); |
| if (len != cred_arg->step_mem_alloc_size) |
| goto unpack_error; |
| } |
| |
| safe_unpackstr(&cred_arg->job_selinux_context, buffer); |
| if (switch_g_unpack_stepinfo(&switch_tmp, buffer, |
| protocol_version)) { |
| switch_g_free_stepinfo(switch_tmp); |
| goto unpack_error; |
| } |
| cred_arg->switch_step = switch_tmp; |
| } else if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) { |
| if (unpack_step_id_members(&cred_arg->step_id, buffer, |
| protocol_version) != SLURM_SUCCESS) |
| goto unpack_error; |
| |
| if (unpack_identity(&cred_arg->id, buffer, protocol_version)) |
| goto unpack_error; |
| |
| if (gres_job_state_unpack(&cred_arg->job_gres_list, buffer, |
| cred_arg->step_id.job_id, |
| protocol_version) |
| != SLURM_SUCCESS) |
| goto unpack_error; |
| if (gres_step_state_unpack(&cred_arg->step_gres_list, |
| buffer, &cred_arg->step_id, |
| protocol_version) |
| != SLURM_SUCCESS) { |
| goto unpack_error; |
| } |
| safe_unpack16(&cred_arg->job_core_spec, buffer); |
| safe_unpackstr(&cred_arg->job_account, buffer); |
| if (slurm_unpack_addr_array(&cred_arg->job_node_addrs, |
| &uint32_tmp, buffer)) |
| goto unpack_error; |
| safe_unpackstr(&cred_arg->job_alias_list, buffer); |
| safe_unpackstr(&cred_arg->job_comment, buffer); |
| safe_unpackstr(&cred_arg->job_constraints, buffer); |
| safe_unpack_time(&cred_arg->job_end_time, buffer); |
| safe_unpackstr(&cred_arg->job_extra, buffer); |
| safe_unpack16(&cred_arg->job_oversubscribe, buffer); |
| safe_unpackstr_and_switch(&cred_arg->job_partition, |
| &cred_arg->switch_step, buffer, |
| protocol_version); |
| safe_unpackstr(&cred_arg->job_reservation, buffer); |
| safe_unpack16(&cred_arg->job_restart_cnt, buffer); |
| safe_unpack_time(&cred_arg->job_start_time, buffer); |
| safe_unpackstr(&cred_arg->job_std_err, buffer); |
| safe_unpackstr(&cred_arg->job_std_in, buffer); |
| safe_unpackstr(&cred_arg->job_std_out, buffer); |
| safe_unpackstr(&cred_arg->step_hostlist, buffer); |
| safe_unpack16(&cred_arg->job_x11, buffer); |
| safe_unpack_time(&cred->ctime, buffer); |
| safe_unpack32(&tot_core_cnt, buffer); |
| unpack_bit_str_hex(&cred_arg->job_core_bitmap, buffer); |
| unpack_bit_str_hex(&cred_arg->step_core_bitmap, buffer); |
| safe_unpack16(&cred_arg->core_array_size, buffer); |
| if (cred_arg->core_array_size) { |
| safe_unpack16_array(&cred_arg->cores_per_socket, &len, |
| buffer); |
| if (len != cred_arg->core_array_size) |
| goto unpack_error; |
| safe_unpack16_array(&cred_arg->sockets_per_node, &len, |
| buffer); |
| if (len != cred_arg->core_array_size) |
| goto unpack_error; |
| safe_unpack32_array(&cred_arg->sock_core_rep_count, |
| &len, buffer); |
| if (len != cred_arg->core_array_size) |
| goto unpack_error; |
| } |
| safe_unpack32(&cred_arg->cpu_array_count, buffer); |
| if (cred_arg->cpu_array_count) { |
| safe_unpack16_array(&cred_arg->cpu_array, &len, buffer); |
| if (len != cred_arg->cpu_array_count) |
| goto unpack_error; |
| safe_unpack32_array(&cred_arg->cpu_array_reps, &len, |
| buffer); |
| if (len != cred_arg->cpu_array_count) |
| goto unpack_error; |
| } |
| safe_unpack32(&cred_arg->job_nhosts, buffer); |
| safe_unpack32(&cred_arg->job_ntasks, buffer); |
| safe_unpackstr(&cred_arg->job_hostlist, buffer); |
| safe_unpackstr(&cred_arg->job_licenses, buffer); |
| |
| safe_unpack32(&cred_arg->job_mem_alloc_size, buffer); |
| if (cred_arg->job_mem_alloc_size) { |
| safe_unpack64_array(&cred_arg->job_mem_alloc, &len, |
| buffer); |
| if (len != cred_arg->job_mem_alloc_size) |
| goto unpack_error; |
| |
| safe_unpack32_array(&cred_arg->job_mem_alloc_rep_count, |
| &len, buffer); |
| if (len != cred_arg->job_mem_alloc_size) |
| goto unpack_error; |
| |
| } |
| |
| safe_unpack32(&cred_arg->step_mem_alloc_size, buffer); |
| if (cred_arg->step_mem_alloc_size) { |
| safe_unpack64_array(&cred_arg->step_mem_alloc, &len, |
| buffer); |
| if (len != cred_arg->step_mem_alloc_size) |
| goto unpack_error; |
| |
| safe_unpack32_array(&cred_arg->step_mem_alloc_rep_count, |
| &len, buffer); |
| if (len != cred_arg->step_mem_alloc_size) |
| goto unpack_error; |
| } |
| |
| safe_unpackstr(&cred_arg->job_selinux_context, buffer); |
| } else { |
| error("%s: protocol_version %hu not supported", |
| __func__, protocol_version); |
| goto unpack_error; |
| } |
| |
| cred_arg->uid = cred_arg->id->uid; |
| cred_arg->gid = cred_arg->id->gid; |
| |
| *out = cred; |
| return SLURM_SUCCESS; |
| |
| unpack_error: |
| xfree(bit_fmt_str); |
| slurm_cred_destroy(cred); |
| return SLURM_ERROR; |
| } |
| |
| extern slurm_cred_t *cred_unpack_with_signature(buf_t *buffer, |
| uint16_t protocol_version) |
| { |
| slurm_cred_t *credential = NULL; |
| uint32_t cred_start, cred_len; |
| |
| cred_start = get_buf_offset(buffer); |
| |
| if ((cred_unpack((void **) &credential, buffer, protocol_version))) |
| goto unpack_error; |
| |
| credential->sig_offset = get_buf_offset(buffer) - cred_start; |
| |
| /* signature follows the main buffer */ |
| safe_unpackstr(&credential->signature, buffer); |
| |
| /* |
| * Both srun and slurmd will unpack the credential just to pack it |
| * again. Hold onto a buffer with the pre-packed representation. |
| */ |
| if (!running_in_slurmstepd()) { |
| cred_len = get_buf_offset(buffer) - cred_start; |
| credential->buffer = init_buf(cred_len); |
| credential->buf_version = protocol_version; |
| memcpy(credential->buffer->head, |
| get_buf_data(buffer) + cred_start, |
| cred_len); |
| credential->buffer->processed = cred_len; |
| } |
| |
| return credential; |
| |
| unpack_error: |
| slurm_cred_destroy(credential); |
| return NULL; |
| } |
| |
| extern buf_t *sbcast_cred_pack(sbcast_cred_arg_t *sbcast_cred, |
| uint16_t protocol_version) |
| { |
| buf_t *buffer = init_buf(4096); |
| time_t now = time(NULL); |
| |
| if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) { |
| pack_identity(sbcast_cred->id, buffer, protocol_version); |
| pack_time(now, buffer); |
| pack_time(sbcast_cred->expiration, buffer); |
| pack32(sbcast_cred->job_id, buffer); |
| pack32(sbcast_cred->het_job_id, buffer); |
| pack32(sbcast_cred->step_id, buffer); |
| packstr(sbcast_cred->nodes, buffer); |
| } |
| |
| return buffer; |
| } |
| |
| extern sbcast_cred_t *sbcast_cred_unpack(buf_t *buffer, uint32_t *siglen, |
| uint16_t protocol_version) |
| { |
| sbcast_cred_t *sbcast_cred = xmalloc(sizeof(*sbcast_cred)); |
| uint32_t cred_start = get_buf_offset(buffer); |
| |
| if (protocol_version >= SLURM_MIN_PROTOCOL_VERSION) { |
| if (unpack_identity(&sbcast_cred->arg.id, buffer, |
| protocol_version)) |
| goto unpack_error; |
| safe_unpack_time(&sbcast_cred->ctime, buffer); |
| safe_unpack_time(&sbcast_cred->arg.expiration, buffer); |
| safe_unpack32(&sbcast_cred->arg.job_id, buffer); |
| safe_unpack32(&sbcast_cred->arg.het_job_id, buffer); |
| safe_unpack32(&sbcast_cred->arg.step_id, buffer); |
| safe_unpackstr(&sbcast_cred->arg.nodes, buffer); |
| |
| if (!sbcast_cred->arg.id->pw_name) { |
| uid_t uid = sbcast_cred->arg.id->uid; |
| gid_t gid = sbcast_cred->arg.id->gid; |
| |
| debug2("%s: need to fetch identity", __func__); |
| FREE_NULL_IDENTITY(sbcast_cred->arg.id); |
| sbcast_cred->arg.id = fetch_identity(uid, gid, false); |
| if (!sbcast_cred->arg.id) |
| goto unpack_error; |
| } |
| } else |
| goto unpack_error; |
| |
| identity_debug2(sbcast_cred->arg.id, __func__); |
| |
| *siglen = get_buf_offset(buffer) - cred_start; |
| |
| /* "signature" must be last */ |
| safe_unpackstr(&sbcast_cred->signature, buffer); |
| if (!sbcast_cred->signature) |
| goto unpack_error; |
| |
| /* |
| * Preserve a copy of the buffer in srun/sbcast to avoid needing to |
| * repack it later. |
| */ |
| if (!running_in_slurmd()) { |
| uint32_t cred_len = get_buf_offset(buffer) - cred_start; |
| sbcast_cred->buffer = init_buf(cred_len); |
| memcpy(sbcast_cred->buffer->head, |
| get_buf_data(buffer) + cred_start, |
| cred_len); |
| sbcast_cred->buffer->processed = cred_len; |
| } |
| |
| return sbcast_cred; |
| |
| unpack_error: |
| delete_sbcast_cred(sbcast_cred); |
| return NULL; |
| } |