From 63ed82d0840a8bc83a2183dc70e0da087ffcae44dbbd70d84d5f79f0c3e4e525 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 15 Jan 2015 15:15:51 +0000 Subject: [PATCH] Accepting request 281420 from home:trenn:branches:systemsmanagement - Update to latest ipmitool sources. This is version 1.8.15 (git tag: IPMITOOL_1_8_15) plus mainline patches up to commit 708be8bc450f907cddb6d9e4b83aee6ba67b7d04 Date: Fri Jan 9 12:48:35 2015 +0100 OBS-URL: https://build.opensuse.org/request/show/281420 OBS-URL: https://build.opensuse.org/package/show/systemsmanagement/ipmitool?expand=0&rev=28 --- ...tream-comments-to-289-add-whitespace.patch | 47 +- automake-1.13.patch | 10 +- fix_file_permissions.patch | 18 +- fwum_enhance_output.patch | 10 +- ipmitool-1.8.10-implicit-fortify-decl.patch | 27 +- ipmitool-1.8.13.tar.bz2 | 3 - ipmitool-1.8.15.tar.bz2 | 3 + ipmitool-1_8_15_HEAD.patch | 3660 +++++++++++++++++ ipmitool.changes | 8 + ipmitool.spec | 12 +- latest_compile_fixes.patch | 175 + several_more_compile_fixes.patch | 127 +- 12 files changed, 3974 insertions(+), 126 deletions(-) delete mode 100644 ipmitool-1.8.13.tar.bz2 create mode 100644 ipmitool-1.8.15.tar.bz2 create mode 100644 ipmitool-1_8_15_HEAD.patch create mode 100644 latest_compile_fixes.patch diff --git a/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch b/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch index 47a7211..fb2fa55 100644 --- a/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch +++ b/0001-Incorporate-upstream-comments-to-289-add-whitespace.patch @@ -8,10 +8,10 @@ Subject: [PATCH] Incorporate upstream comments to #289, add whitespace, other contrib/bmc-snmp-proxy | 130 +++++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 54 deletions(-) -diff --git a/contrib/bmc-snmp-proxy b/contrib/bmc-snmp-proxy -index 1704ef3..98479b9 100644 ---- a/contrib/bmc-snmp-proxy -+++ b/contrib/bmc-snmp-proxy +Index: ipmitool-1.8.15/contrib/bmc-snmp-proxy +=================================================================== +--- ipmitool-1.8.15.orig/contrib/bmc-snmp-proxy 2015-01-14 14:34:05.488699284 +0100 ++++ ipmitool-1.8.15/contrib/bmc-snmp-proxy 2015-01-14 14:34:05.508699284 +0100 @@ -3,7 +3,7 @@ # # bmc-snmp-proxy: Set SNMP proxy to BMC (Baseboard Management Controller) @@ -21,7 +21,7 @@ index 1704ef3..98479b9 100644 # # Authors: Charles Rose # Jordan Hargrave -@@ -20,9 +20,9 @@ +@@ -24,9 +24,9 @@ SYSCONF_DIR="/etc/sysconfig" CONFIG="${SYSCONF_DIR}/bmc-snmp-proxy" @@ -34,7 +34,7 @@ index 1704ef3..98479b9 100644 TRAPD_CONF="/etc/snmp/snmptrapd.conf" -@@ -57,14 +57,16 @@ bmc_info_exists() +@@ -61,14 +61,16 @@ else RETVAL=2 fi @@ -52,7 +52,7 @@ index 1704ef3..98479b9 100644 return $RETVAL } -@@ -77,11 +79,12 @@ write_snmp_conf() +@@ -81,11 +83,12 @@ printf "###############################################\n" printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" printf "###############################################\n" @@ -70,7 +70,7 @@ index 1704ef3..98479b9 100644 printf "###############################################\n" } -@@ -92,6 +95,7 @@ valid_ip() +@@ -96,6 +99,7 @@ printf -- "%s" "${1}"| grep -Eq \ "^${octet}\\.${octet}\\.${octet}\\.${octet}$" @@ -78,7 +78,7 @@ index 1704ef3..98479b9 100644 return $? } -@@ -112,37 +116,38 @@ set_snmp_proxy() +@@ -116,37 +120,38 @@ if check_vars; then PROXY_TOKEN="-c ${BMC_COMMUNITY} ${BMC_IPv4} ${BMC_OID}" @@ -132,7 +132,7 @@ index 1704ef3..98479b9 100644 fi } ############################################################################# -@@ -152,6 +157,7 @@ disable_snmp_proxy() +@@ -156,6 +161,7 @@ pick_alert_dest() { test_ip="$1" @@ -140,7 +140,7 @@ index 1704ef3..98479b9 100644 for ALERT_DEST in `seq 1 4` do temp_ip=$(${IPMITOOL} lan alert print ${CHANNEL} ${ALERT_DEST}\ -@@ -165,12 +171,12 @@ pick_alert_dest() +@@ -169,12 +175,12 @@ set_alert_dest_ip() { ${IPMITOOL} lan alert set ${CHANNEL} ${ALERT_DEST} ipaddr ${1} \ @@ -156,7 +156,7 @@ index 1704ef3..98479b9 100644 # Pick the first active LAN channel for CHANNEL in `seq 1 14` do -@@ -180,12 +186,12 @@ bmc_alert_dest() +@@ -184,12 +190,12 @@ # If TRAPD_IP is already set as an alert dest, if pick_alert_dest "${TRAPD_IP}"; then @@ -172,7 +172,7 @@ index 1704ef3..98479b9 100644 return $RETVAL # set: the TRAPD_IP set_alert_dest_ip "${TRAPD_IP}" -@@ -193,42 +199,54 @@ bmc_alert_dest() +@@ -197,42 +203,54 @@ # No free alert destinations RETVAL=9 fi @@ -236,7 +236,7 @@ index 1704ef3..98479b9 100644 printf "###############################################\n" } -@@ -236,10 +254,9 @@ config_trapd() +@@ -240,10 +258,9 @@ { # Proceed only if snmptrapd is available on the system if [ -f ${TRAPD_CONF} ]; then @@ -249,7 +249,7 @@ index 1704ef3..98479b9 100644 fi } -@@ -249,6 +266,7 @@ trap_sink_exists() +@@ -253,6 +270,7 @@ # multiple FORWARD_HOST=$(awk '/^trap.*sink/{print $2}; /^informsink/{print $2}' \ /etc/snmp/snmpd*conf | head -1) @@ -257,7 +257,7 @@ index 1704ef3..98479b9 100644 if [ -z "${FORWARD_HOST}" ]; then # there is no trapsink setup. return 1 -@@ -261,19 +279,20 @@ trap_sink_exists() +@@ -265,19 +283,20 @@ trap_forward() { NO_TRAP=0 @@ -283,7 +283,7 @@ index 1704ef3..98479b9 100644 else NO_TRAP=1 fi -@@ -288,7 +307,6 @@ service_reload() +@@ -292,7 +311,6 @@ service $1 reload [ $? -ne 0 ] && RETVAL=6 fi @@ -291,7 +291,7 @@ index 1704ef3..98479b9 100644 } ############################################################################# -@@ -296,11 +314,12 @@ start() +@@ -300,11 +318,12 @@ { if bmc_info_exists && check_snmp; then touch ${LOCKFILE} @@ -305,7 +305,7 @@ index 1704ef3..98479b9 100644 [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ service_reload snmptrapd fi -@@ -316,10 +335,11 @@ stop() +@@ -320,10 +339,11 @@ [ $RETVAL -eq 0 ] && service_reload snmpd if [ "${TRAP_FORWARD}" = "yes" ]; then @@ -318,7 +318,7 @@ index 1704ef3..98479b9 100644 rm -f ${LOCKFILE} fi } -@@ -329,12 +349,13 @@ status() +@@ -333,12 +353,13 @@ { eval_gettext "${SCRIPT_NAME}: snmp proxy to BMC is " # Checking for lockfile is better. @@ -333,7 +333,7 @@ index 1704ef3..98479b9 100644 echo RETVAL=0 } -@@ -360,10 +381,10 @@ case "$RETVAL" in +@@ -364,10 +385,10 @@ 0|1) ;; 2) eval_gettext "${SCRIPT_NAME}: failed to read ${BMC_INFO} " 1>&2 ;; 3) eval_gettext "${SCRIPT_NAME}: failed to get proxy config." 1>&2 ;; @@ -346,7 +346,7 @@ index 1704ef3..98479b9 100644 8) eval_gettext "${SCRIPT_NAME}: failed to set IPMI alert dest." 1>&2 ;; 9) eval_gettext "${SCRIPT_NAME}: no free IPMI alert dest." 1>&2 ;; 10) eval_gettext "${SCRIPT_NAME}: failed to set IPMI PEF." 1>&2 ;; -@@ -375,6 +396,7 @@ esac +@@ -379,6 +400,7 @@ if [ ${RETVAL} -gt 1 ]; then eval_gettext " Return code: ${RETVAL}"; echo fi @@ -354,6 +354,3 @@ index 1704ef3..98479b9 100644 exit ${RETVAL} ############################################################################# # end of file --- -1.8.3.1 - diff --git a/automake-1.13.patch b/automake-1.13.patch index a57bb11..5ee8c14 100644 --- a/automake-1.13.patch +++ b/automake-1.13.patch @@ -1,11 +1,11 @@ -Index: ipmitool-1.8.13/configure.in +Index: ipmitool-1.8.15/configure.ac =================================================================== ---- ipmitool-1.8.13.orig/configure.in -+++ ipmitool-1.8.13/configure.in -@@ -4,7 +4,7 @@ dnl +--- ipmitool-1.8.15.orig/configure.ac 2015-01-14 14:33:29.432698711 +0100 ++++ ipmitool-1.8.15/configure.ac 2015-01-14 14:33:39.440698870 +0100 +@@ -4,7 +4,7 @@ AC_INIT([src/ipmitool.c]) AC_CANONICAL_SYSTEM - AM_INIT_AUTOMAKE([ipmitool], [1.8.13-cvs]) + AM_INIT_AUTOMAKE([ipmitool], [1.8.15-cvs]) -AM_CONFIG_HEADER(config.h) +AC_CONFIG_HEADER(config.h) AC_CONFIG_SRCDIR([src/ipmitool.c]) diff --git a/fix_file_permissions.patch b/fix_file_permissions.patch index a7e08a1..3ad2009 100644 --- a/fix_file_permissions.patch +++ b/fix_file_permissions.patch @@ -1,8 +1,8 @@ -Index: ipmitool-1.8.13/lib/helper.c +Index: ipmitool-1.8.15/lib/helper.c =================================================================== ---- ipmitool-1.8.13.orig/lib/helper.c -+++ ipmitool-1.8.13/lib/helper.c -@@ -657,7 +657,6 @@ ipmi_start_daemon(struct ipmi_intf *intf +--- ipmitool-1.8.15.orig/lib/helper.c 2015-01-14 14:28:25.104693872 +0100 ++++ ipmitool-1.8.15/lib/helper.c 2015-01-14 14:28:30.392693957 +0100 +@@ -659,7 +659,6 @@ #endif chdir("/"); @@ -10,11 +10,11 @@ Index: ipmitool-1.8.13/lib/helper.c for (fd=0; fd<64; fd++) { if (fd != intf->fd) -Index: ipmitool-1.8.13/src/ipmievd.c +Index: ipmitool-1.8.15/src/ipmievd.c =================================================================== ---- ipmitool-1.8.13.orig/src/ipmievd.c -+++ ipmitool-1.8.13/src/ipmievd.c -@@ -700,6 +700,7 @@ ipmievd_main(struct ipmi_event_intf * ei +--- ipmitool-1.8.15.orig/src/ipmievd.c 2015-01-14 14:28:25.112693873 +0100 ++++ ipmitool-1.8.15/src/ipmievd.c 2015-01-14 14:28:30.392693957 +0100 +@@ -701,6 +701,7 @@ int i, rc; int daemon = 1; struct sigaction act; @@ -22,7 +22,7 @@ Index: ipmitool-1.8.13/src/ipmievd.c memset(pidfile, 0, 64); sprintf(pidfile, "%s%d", DEFAULT_PIDFILE, eintf->intf->devnum); -@@ -761,8 +762,9 @@ ipmievd_main(struct ipmi_event_intf * ei +@@ -762,8 +763,9 @@ ipmi_start_daemon(eintf->intf); diff --git a/fwum_enhance_output.patch b/fwum_enhance_output.patch index f4b918e..1b22e3a 100644 --- a/fwum_enhance_output.patch +++ b/fwum_enhance_output.patch @@ -1,8 +1,8 @@ -Index: ipmitool-1.8.13/lib/ipmi_fwum.c +Index: ipmitool-1.8.15/lib/ipmi_fwum.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_fwum.c -+++ ipmitool-1.8.13/lib/ipmi_fwum.c -@@ -1102,12 +1102,14 @@ ipmi_kfwum_checkfwcompat(tKFWUM_BoardInf +--- ipmitool-1.8.15.orig/lib/ipmi_fwum.c 2015-01-14 14:28:25.108693872 +0100 ++++ ipmitool-1.8.15/lib/ipmi_fwum.c 2015-01-14 14:28:27.080693904 +0100 +@@ -1099,12 +1099,14 @@ int compatible = 0; if (boardInfo.iana != firmInfo.iana) { lprintf(LOG_ERR, @@ -19,7 +19,7 @@ Index: ipmitool-1.8.13/lib/ipmi_fwum.c compatible = (-1); } if (compatible != 0) { -@@ -1125,6 +1127,10 @@ printf_kfwum_info(tKFWUM_BoardInfo board +@@ -1122,6 +1124,10 @@ printf( "Target IANA number : %u\n", boardInfo.iana); printf( diff --git a/ipmitool-1.8.10-implicit-fortify-decl.patch b/ipmitool-1.8.10-implicit-fortify-decl.patch index ccce7b4..791bedc 100644 --- a/ipmitool-1.8.10-implicit-fortify-decl.patch +++ b/ipmitool-1.8.10-implicit-fortify-decl.patch @@ -6,8 +6,8 @@ forwardported from 1.8.10 to 1.8.11. Index: lib/ipmi_sdradd.c =================================================================== ---- lib/ipmi_sdradd.c.orig -+++ lib/ipmi_sdradd.c +--- lib/ipmi_sdradd.c.orig 2015-01-14 15:38:00.728760259 +0100 ++++ lib/ipmi_sdradd.c 2015-01-14 15:38:11.500760430 +0100 @@ -38,6 +38,7 @@ #include #include @@ -18,8 +18,8 @@ Index: lib/ipmi_sdradd.c #include Index: lib/ipmi_hpmfwupg.c =================================================================== ---- lib/ipmi_hpmfwupg.c.orig -+++ lib/ipmi_hpmfwupg.c +--- lib/ipmi_hpmfwupg.c.orig 2015-01-14 15:38:00.728760259 +0100 ++++ lib/ipmi_hpmfwupg.c 2015-01-14 15:38:11.504760430 +0100 @@ -40,6 +40,8 @@ #include "../src/plugins/lan/md5.h" #include @@ -29,15 +29,24 @@ Index: lib/ipmi_hpmfwupg.c #include #if HAVE_CONFIG_H -Index: configure.in +Index: configure.ac =================================================================== ---- configure.in.orig -+++ configure.in -@@ -25,6 +25,7 @@ AC_CHECK_HEADERS([sys/byteorder.h bytesw +--- configure.ac.orig 2015-01-14 15:38:00.728760259 +0100 ++++ configure.ac 2015-01-14 16:29:03.744808956 +0100 +@@ -25,6 +25,7 @@ AC_C_CONST AC_C_INLINE AC_C_BIGENDIAN +AC_GNU_SOURCE - AC_FUNC_MALLOC AC_FUNC_SELECT_ARGTYPES + AC_FUNC_STRTOD +@@ -32,7 +33,7 @@ + AC_CHECK_FUNCS([memmove memset strchr strdup strerror]) + AC_CHECK_FUNCS([getpassphrase]) + +-CFLAGS="$CFLAGS -Wall -Wextra -std=c99 -pedantic -Wformat -Wformat-nonliteral" ++CFLAGS="$CFLAGS -fno-strict-aliasing -Wreturn-type -std=c99" + + AM_PROG_LIBTOOL + LIBTOOL="$LIBTOOL --silent" diff --git a/ipmitool-1.8.13.tar.bz2 b/ipmitool-1.8.13.tar.bz2 deleted file mode 100644 index 5433993..0000000 --- a/ipmitool-1.8.13.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:df2f7f44b6f72db87fb33e99a7df02ae2dec6cf915322b9bab0c0745bf8d5748 -size 426220 diff --git a/ipmitool-1.8.15.tar.bz2 b/ipmitool-1.8.15.tar.bz2 new file mode 100644 index 0000000..1d3f4c1 --- /dev/null +++ b/ipmitool-1.8.15.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:130d452916a85c00ef827498e4a86ac9b4a123e22624b59360dffb0426aae988 +size 435535 diff --git a/ipmitool-1_8_15_HEAD.patch b/ipmitool-1_8_15_HEAD.patch new file mode 100644 index 0000000..4701c34 --- /dev/null +++ b/ipmitool-1_8_15_HEAD.patch @@ -0,0 +1,3660 @@ +These is the git diff of version IPMITOOL_1_8_15 up to latest HEAD. +Last patch is: +commit 708be8bc450f907cddb6d9e4b83aee6ba67b7d04 +Author: Zdenek Styblik +Date: Fri Jan 9 12:48:35 2015 +0100 +Repo: git://git.code.sf.net/p/ipmitool/source + +Signed-off-by: Thomas Renninger + +diff --git a/configure.ac b/configure.ac +index 6c5ccfb..d7c5620 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -26,14 +26,13 @@ AC_C_CONST + AC_C_INLINE + AC_C_BIGENDIAN + +-AC_FUNC_MALLOC + AC_FUNC_SELECT_ARGTYPES + AC_FUNC_STRTOD + AC_CHECK_FUNCS([alarm gethostbyname getaddrinfo getifaddrs socket select]) + AC_CHECK_FUNCS([memmove memset strchr strdup strerror]) + AC_CHECK_FUNCS([getpassphrase]) + +-CFLAGS="$CFLAGS -fno-strict-aliasing -Wreturn-type" ++CFLAGS="$CFLAGS -Wall -Wextra -std=c99 -pedantic -Wformat -Wformat-nonliteral" + + AM_PROG_LIBTOOL + LIBTOOL="$LIBTOOL --silent" +diff --git a/include/ipmitool/helper.h b/include/ipmitool/helper.h +index b6ee7fa..b7ad628 100644 +--- a/include/ipmitool/helper.h ++++ b/include/ipmitool/helper.h +@@ -83,9 +83,12 @@ int str2ushort(const char * str, uint16_t * ushrt_ptr); + int str2char(const char * str, int8_t * chr_ptr); + int str2uchar(const char * str, uint8_t * uchr_ptr); + ++int eval_ccode(const int ccode); ++ + int is_fru_id(const char *argv_ptr, uint8_t *fru_id_ptr); + int is_ipmi_channel_num(const char *argv_ptr, uint8_t *channel_ptr); + int is_ipmi_user_id(const char *argv_ptr, uint8_t *ipmi_uid_ptr); ++int is_ipmi_user_priv_limit(const char *argv_ptr, uint8_t *ipmi_priv_limit_ptr); + + uint16_t str2val(const char * str, const struct valstr * vs); + void print_valstr(const struct valstr * vs, const char * title, int loglevel); +diff --git a/include/ipmitool/ipmi_channel.h b/include/ipmitool/ipmi_channel.h +index 7cbb9ad..a59065b 100644 +--- a/include/ipmitool/ipmi_channel.h ++++ b/include/ipmitool/ipmi_channel.h +@@ -181,74 +181,6 @@ struct get_channel_access_rsp { + #pragma pack(0) + #endif + +-#ifdef HAVE_PRAGMA_PACK +-#pragma pack(1) +-#endif +-struct get_user_access_rsp { +-#if WORDS_BIGENDIAN +- uint8_t __reserved1 : 2; +- uint8_t max_user_ids : 6; +- uint8_t __reserved2 : 2; +- uint8_t enabled_user_ids : 6; +- uint8_t __reserved3 : 2; +- uint8_t fixed_user_ids : 6; +- uint8_t __reserved4 : 1; +- uint8_t callin_callback : 1; +- uint8_t link_auth : 1; +- uint8_t ipmi_messaging : 1; +- uint8_t privilege_limit : 4; +-#else +- uint8_t max_user_ids : 6; +- uint8_t __reserved1 : 2; +- uint8_t enabled_user_ids : 6; +- uint8_t __reserved2 : 2; +- uint8_t fixed_user_ids : 6; +- uint8_t __reserved3 : 2; +- uint8_t privilege_limit : 4; +- uint8_t ipmi_messaging : 1; +- uint8_t link_auth : 1; +- uint8_t callin_callback : 1; +- uint8_t __reserved4 : 1; +-#endif +-} ATTRIBUTE_PACKING; +-#ifdef HAVE_PRAGMA_PACK +-#pragma pack(0) +-#endif +- +-#ifdef HAVE_PRAGMA_PACK +-#pragma pack(1) +-#endif +-struct set_user_access_data { +-#if WORDS_BIGENDIAN +- uint8_t change_bits : 1; +- uint8_t callin_callback : 1; +- uint8_t link_auth : 1; +- uint8_t ipmi_messaging : 1; +- uint8_t channel : 4; +- uint8_t __reserved1 : 2; +- uint8_t user_id : 6; +- uint8_t __reserved2 : 4; +- uint8_t privilege_limit : 4; +- uint8_t __reserved3 : 4; +- uint8_t session_limit : 4; +-#else +- uint8_t channel : 4; +- uint8_t ipmi_messaging : 1; +- uint8_t link_auth : 1; +- uint8_t callin_callback : 1; +- uint8_t change_bits : 1; +- uint8_t user_id : 6; +- uint8_t __reserved1 : 2; +- uint8_t privilege_limit : 4; +- uint8_t __reserved2 : 4; +- uint8_t session_limit : 4; +- uint8_t __reserved3 : 4; +-#endif +-} ATTRIBUTE_PACKING; +-#ifdef HAVE_PRAGMA_PACK +-#pragma pack(0) +-#endif +- + uint8_t ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel); + uint8_t ipmi_current_channel_medium(struct ipmi_intf * intf); + int ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv); +diff --git a/include/ipmitool/ipmi_mc.h b/include/ipmitool/ipmi_mc.h +index 5546a3a..a840f78 100644 +--- a/include/ipmitool/ipmi_mc.h ++++ b/include/ipmitool/ipmi_mc.h +@@ -157,6 +157,9 @@ struct ipm_get_watchdog_rsp { + #define IPMI_SYSINFO_SET0_SIZE 14 + #define IPMI_SYSINFO_SETN_SIZE 16 + ++/* System Information "Parameter selector" values: */ ++#define IPMI_SYSINFO_SET_STATE 0x00 ++#define IPMI_SYSINFO_SYSTEM_FW_VERSION 0x01 + #define IPMI_SYSINFO_HOSTNAME 0x02 + #define IPMI_SYSINFO_PRIMARY_OS_NAME 0x03 + #define IPMI_SYSINFO_OS_NAME 0x04 +diff --git a/include/ipmitool/ipmi_sel.h b/include/ipmitool/ipmi_sel.h +index cacdb2d..53a8c1f 100644 +--- a/include/ipmitool/ipmi_sel.h ++++ b/include/ipmitool/ipmi_sel.h +@@ -690,41 +690,41 @@ static struct ipmi_event_sensor_types sensor_specific_types[] __attribute__((unu + }; + + static uint16_t supermicro_x9dal[] = { +- 0x0635 ++ 0x0635, 0xFFFF + }; + + static uint16_t supermicro_x9db[] = { +- 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637 ++ 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637, 0xFFFF + }; + + static uint16_t supermicro_x9sb[] = { +- 0x0651 ++ 0x0651, 0xFFFF + }; + + static uint16_t supermicro_x9[] = { +- 0x0635, 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637, 0x0651 ++ 0x0635, 0x0733, 0x0722, 0x0703, 0x0721, 0x0716, 0x0637, 0x0651, 0xFFFF + }; + + static uint16_t supermicro_b8[] = { +- 0x000A, 0x061c, 0x0620, 0x0101, 0x061f, 0x0612, 0x061e ++ 0x000A, 0x061c, 0x0620, 0x0101, 0x061f, 0x0612, 0x061e, 0xFFFF + }; + + static uint16_t supermicro_h8[] = { + 0xa111, 0x0408, 0x0811, 0x1411, 0x0911, 0x1211, 0x1011, 0xcd11, 0x1111, 0xbe11, 0xce11, 0xbd11, + 0xbc11, 0xa911, 0xaa11, 0xbd11, 0xcb11, 0xad11, 0xa811, 0xac11, 0xaf11, 0xa511, 0xa011, 0x1611, + 0x2511, 0xbf11, 0x1511, 0x2211, 0x2411, 0x1911, 0xab11, 0xd011, 0xae11, 0xca11, 0x0409, 0xa211, +- 0xa311, 0x1311, 0xba11, 0xa711, 0xd111, 0x1711, 0xcf11, 0x2011, 0x1811 ++ 0xa311, 0x1311, 0xba11, 0xa711, 0xd111, 0x1711, 0xcf11, 0x2011, 0x1811, 0xFFFF + }; + + static uint16_t supermicro_p8[] = { +- 0x6480, 0x7380, 0x6280, 0x7480, 0x5980 ++ 0x6480, 0x7380, 0x6280, 0x7480, 0x5980, 0xFFFF + }; + + static uint16_t supermicro_x8[] = { + 0xa880, 0x0403, 0x0100, 0x0601, 0x0001, 0x0404, 0x0606, 0x0608, 0x0632, 0x0400, 0x0401, 0x0006, + 0x040a, 0xf280, 0x060f, 0x0609, 0x0008, 0x0613, 0x061b, 0x0007, 0x0600, 0x060c, 0x060d, 0x0614, + 0x060c, 0x0003, 0x040b, 0x0621, 0x0610, 0x0638, 0xf380, 0x060b, 0x040d, 0x0605, 0x062d, 0x060e, +- 0x061a, 0xf580, 0x062e, 0x0009 ++ 0x061a, 0xf580, 0x062e, 0x0009, 0xFFFF + }; + + static uint16_t supermicro_X8[] = { +@@ -736,7 +736,7 @@ static uint16_t supermicro_X8[] = { + 0x0601, 0x0001, 0x0404, 0x0606, 0x0608, 0x0632, 0x0400, 0x0401, 0x0006, 0x040a, 0xf280, 0x060f, + 0x0609, 0x0008, 0x0613, 0x061b, 0x0007, 0x0600, 0x060c, 0x060d, 0x0614, 0x060c, 0x0003, 0x040b, + 0x0621, 0x0610, 0x0638, 0xf380, 0x060b, 0x040d, 0x0605, 0x062d, 0x060e, 0x061a, 0xf580, 0x062e, +- 0x0009 ++ 0x0009, 0xFFFF + }; + + int ipmi_sel_main(struct ipmi_intf *, int, char **); +diff --git a/include/ipmitool/ipmi_user.h b/include/ipmitool/ipmi_user.h +index 4a8e481..b298bb3 100644 +--- a/include/ipmitool/ipmi_user.h ++++ b/include/ipmitool/ipmi_user.h +@@ -38,58 +38,38 @@ + #endif + #include + ++#define IPMI_USER_ENABLE_UNSPECIFIED 0x00 ++#define IPMI_USER_ENABLE_ENABLED 0x40 ++#define IPMI_USER_ENABLE_DISABLED 0x80 ++#define IPMI_USER_ENABLE_RESERVED 0xC0 + +-/* +- * The GET USER ACCESS response from table 22-32 of the IPMI v2.0 spec +- */ +-struct user_access_rsp { +-#if WORDS_BIGENDIAN +- uint8_t __reserved1 : 2; +- uint8_t maximum_ids : 6; +-#else +- uint8_t maximum_ids : 6; +- uint8_t __reserved1 : 2; +-#endif +- +-#if WORDS_BIGENDIAN +- uint8_t __reserved2 : 2; +- uint8_t enabled_user_count : 6; +-#else +- uint8_t enabled_user_count : 6; +- uint8_t __reserved2 : 2; +-#endif +- +-#if WORDS_BIGENDIAN +- uint8_t __reserved3 : 2; +- uint8_t fixed_name_count : 6; +-#else +- uint8_t fixed_name_count : 6; +- uint8_t __reserved3 : 2; +-#endif +- +-#ifdef HAVE_PRAGMA_PACK +-#pragma pack(1) +-#endif +-#if WORDS_BIGENDIAN +- uint8_t __reserved4 : 1; +- uint8_t no_callin_access : 1; +- uint8_t link_auth_access : 1; +- uint8_t ipmi_messaging_access : 1; +- uint8_t channel_privilege_limit : 4; +-#else +- uint8_t channel_privilege_limit : 4; +- uint8_t ipmi_messaging_access : 1; +- uint8_t link_auth_access : 1; +- uint8_t no_callin_access : 1; +- uint8_t __reserved4 : 1; +-#endif +-} ATTRIBUTE_PACKING; +-#ifdef HAVE_PRAGMA_PACK +-#pragma pack(0) +-#endif +- ++/* (22.27) Get and (22.26) Set User Access */ ++struct user_access_t { ++ uint8_t callin_callback; ++ uint8_t channel; ++ uint8_t enabled_user_ids; ++ uint8_t enable_status; ++ uint8_t fixed_user_ids; ++ uint8_t ipmi_messaging; ++ uint8_t link_auth; ++ uint8_t max_user_ids; ++ uint8_t privilege_limit; ++ uint8_t session_limit; ++ uint8_t user_id; ++}; + ++/* (22.29) Get User Name */ ++struct user_name_t { ++ uint8_t user_id; ++ uint8_t user_name[17]; ++}; + + int ipmi_user_main(struct ipmi_intf *, int, char **); ++int _ipmi_get_user_access(struct ipmi_intf *intf, ++ struct user_access_t *user_access_rsp); ++int _ipmi_get_user_name(struct ipmi_intf *intf, struct user_name_t *user_name); ++int _ipmi_set_user_access(struct ipmi_intf *intf, ++ struct user_access_t *user_access_req, ++ uint8_t change_priv_limit_only); + + #endif /* IPMI_USER_H */ +diff --git a/lib/dimm_spd.c b/lib/dimm_spd.c +index 91ae117..912b211 100644 +--- a/lib/dimm_spd.c ++++ b/lib/dimm_spd.c +@@ -867,9 +867,11 @@ ipmi_spd_print(uint8_t *spd_data, int len) + int sdram_width = 0; + int mem_size = 0; + int lrank_dimm; ++ uint32_t year; ++ uint32_t week; + +- if (len < 148) +- return -1; /* we need first 91 bytes to do our thing */ ++ if (len < 348) ++ return -1; + + /* "Logical rank" referes to the individually addressable die + * in a 3DS stack and has no meaning for monolithic or +@@ -879,7 +881,7 @@ ipmi_spd_print(uint8_t *spd_data, int len) + * rank per package rank. + */ + lrank_dimm = (spd_data[12]>>3&0x3) + 1; /* Number of Package Ranks per DIMM */ +- if ((spd_data[6] & 0x3) == 0x10) { /* 3DS package Type */ ++ if ((spd_data[6] & 0x3) == 0x2) { /* 3DS package Type */ + lrank_dimm *= ((spd_data[6]>>4)&0x3) + 1; /* Die Count */ + } + sdram_cap = ldexp(256,(spd_data[4]&15)); +@@ -931,8 +933,8 @@ ipmi_spd_print(uint8_t *spd_data, int len) + + } + +- u_int year = (spd_data[323]>>4)*10 + spd_data[323]&15; +- u_int week = (spd_data[324]>>4)*10 + spd_data[324]&15; ++ year = ((spd_data[323] >> 4) * 10) + (spd_data[323] & 15); ++ week = ((spd_data[324]>>4) * 10) + (spd_data[324] & 15); + printf(" Manufacture Date : year %4d week %2d\n", + 2000 + year, week); + +@@ -948,6 +950,9 @@ ipmi_spd_print(uint8_t *spd_data, int len) + } + else + { ++ if (len < 100) { ++ return (-1); ++ } + ii = (spd_data[3] & 0x0f) + (spd_data[4] & 0x0f) - 17; + k = ((spd_data[5] & 0x7) + 1) * spd_data[17]; + +@@ -1064,7 +1069,6 @@ ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id) + offset = 0; + memset(spd_data, 0, fru.size); + do { +- int i; + msg_data[0] = id; + msg_data[1] = offset & 0xFF; + msg_data[2] = offset >> 8; +diff --git a/lib/helper.c b/lib/helper.c +index 95d641e..30546f7 100644 +--- a/lib/helper.c ++++ b/lib/helper.c +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _POSIX_SOURCE + + #include + #include +@@ -671,6 +672,37 @@ ipmi_start_daemon(struct ipmi_intf *intf) + dup(fd); + } + ++/* eval_ccode - evaluate return value of _ipmi_* functions and print error error ++ * message, if conditions are met. ++ * ++ * @ccode - return value of _ipmi_* function. ++ * ++ * returns - 0 if ccode is 0, otherwise (-1) and error might get printed-out. ++ */ ++int ++eval_ccode(const int ccode) ++{ ++ if (ccode == 0) { ++ return 0; ++ } else if (ccode < 0) { ++ switch (ccode) { ++ case (-1): ++ lprintf(LOG_ERR, "IPMI response is NULL."); ++ break; ++ case (-2): ++ lprintf(LOG_ERR, "Unexpected data length received."); ++ break; ++ default: ++ break; ++ } ++ return (-1); ++ } else { ++ lprintf(LOG_ERR, "IPMI command failed: %s", ++ val2str(ccode, completion_code_vals)); ++ return (-1); ++ } ++} ++ + /* is_fru_id - wrapper for str-2-int FRU ID conversion. Message is printed + * on error. + * FRU ID range: <0..255> +@@ -700,9 +732,9 @@ is_fru_id(const char *argv_ptr, uint8_t *fru_id_ptr) + /* is_ipmi_channel_num - wrapper for str-2-int Channel conversion. Message is + * printed on error. + * +- * 6.3 Channel Numbers, p. 45, IPMIv2 spec. +- * Valid channel numbers are: <0..7>, +- * Reserved channel numbers: <8-D> ++ * 6.3 Channel Numbers, p. 49, IPMIv2 spec. rev1.1 ++ * Valid channel numbers are: <0x0..0xB>, <0xE-0xF> ++ * Reserved channel numbers: <0xC-0xD> + * + * @argv_ptr: source string to convert from; usually argv + * @channel_ptr: pointer where to store result +@@ -719,14 +751,14 @@ is_ipmi_channel_num(const char *argv_ptr, uint8_t *channel_ptr) + return (-1); + } + if ((str2uchar(argv_ptr, channel_ptr) == 0) +- && ((*channel_ptr >= 0x0 && *channel_ptr <= 0x7) ++ && (*channel_ptr <= 0xB + || (*channel_ptr >= 0xE && *channel_ptr <= 0xF))) { + return 0; + } + lprintf(LOG_ERR, + "Given Channel number '%s' is either invalid or out of range.", + argv_ptr); +- lprintf(LOG_ERR, "Channel number must be from ranges: <0..7>, <0xE..0xF>"); ++ lprintf(LOG_ERR, "Channel number must be from ranges: <0x0..0xB>, <0xE..0xF>"); + return (-1); + } + +@@ -760,6 +792,36 @@ is_ipmi_user_id(const char *argv_ptr, uint8_t *ipmi_uid_ptr) + return (-1); + } + ++/* is_ipmi_user_priv_limit - check whether given value is valid User Privilege ++ * Limit, eg. IPMI v2 spec, 22.27 Get User Access Command. ++ * ++ * @priv_limit: User Privilege Limit ++ * ++ * returns 0 if Priv Limit is valid ++ * returns (-1) when Priv Limit is invalid ++ */ ++int ++is_ipmi_user_priv_limit(const char *argv_ptr, uint8_t *ipmi_priv_limit_ptr) ++{ ++ if (!argv_ptr || !ipmi_priv_limit_ptr) { ++ lprintf(LOG_ERR, ++ "is_ipmi_user_priv_limit(): invalid argument(s)."); ++ return (-1); ++ } ++ if ((str2uchar(argv_ptr, ipmi_priv_limit_ptr) != 0) ++ || ((*ipmi_priv_limit_ptr < 0x01 ++ || *ipmi_priv_limit_ptr > 0x05) ++ && *ipmi_priv_limit_ptr != 0x0F)) { ++ lprintf(LOG_ERR, ++ "Given Privilege Limit '%s' is invalid.", ++ argv_ptr); ++ lprintf(LOG_ERR, ++ "Privilege Limit is limited to <0x1..0x5> and <0xF>."); ++ return (-1); ++ } ++ return 0; ++} ++ + uint16_t + ipmi_get_oem_id(struct ipmi_intf *intf) + { +diff --git a/lib/hpm2.c b/lib/hpm2.c +index 6cb2f80..6420629 100644 +--- a/lib/hpm2.c ++++ b/lib/hpm2.c +@@ -213,8 +213,8 @@ int hpm2_get_lan_channel_capabilities(struct ipmi_intf * intf, + /* send */ + rsp = intf->sendrecv(intf, &req); + +- if (rsp) { +- lprintf(LOG_NOTICE, "Error sending request"); ++ if (!rsp) { ++ lprintf(LOG_NOTICE, "Error sending request."); + return -1; + } + +diff --git a/lib/ipmi_channel.c b/lib/ipmi_channel.c +index 43db338..8a52f9e 100644 +--- a/lib/ipmi_channel.c ++++ b/lib/ipmi_channel.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + extern int csv_output; + extern int verbose; +@@ -68,8 +69,7 @@ ipmi_1_5_authtypes(uint8_t n) + uint32_t i; + static char supportedTypes[128]; + +- bzero(supportedTypes, 128); +- ++ memset(supportedTypes, 0, sizeof(supportedTypes)); + for (i = 0; ipmi_authtype_vals[i].val != 0; i++) { + if (n & ipmi_authtype_vals[i].val) { + strcat(supportedTypes, ipmi_authtype_vals[i].str); +@@ -89,27 +89,26 @@ ipmi_1_5_authtypes(uint8_t n) + * -1 on failure + */ + int +-ipmi_get_channel_auth_cap(struct ipmi_intf * intf, +- uint8_t channel, +- uint8_t priv) ++ipmi_get_channel_auth_cap(struct ipmi_intf *intf, uint8_t channel, uint8_t priv) + { +- struct ipmi_rs * rsp; ++ struct ipmi_rs *rsp; + struct ipmi_rq req; + struct get_channel_auth_cap_rsp auth_cap; + uint8_t msg_data[2]; + +- msg_data[0] = channel | 0x80; // Ask for IPMI v2 data as well ++ /* Ask for IPMI v2 data as well */ ++ msg_data[0] = channel | 0x80; + msg_data[1] = priv; + + memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; // 0x06 +- req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; // 0x38 +- req.msg.data = msg_data; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; ++ req.msg.data = msg_data; + req.msg.data_len = 2; + + rsp = intf->sendrecv(intf, &req); + +- if ((rsp == NULL) || (rsp->ccode > 0)) { ++ if ((rsp == NULL) || (rsp->ccode > 0)) { + /* + * It's very possible that this failed because we asked for IPMI v2 data + * Ask again, without requesting IPMI v2 data +@@ -119,12 +118,12 @@ ipmi_get_channel_auth_cap(struct ipmi_intf * intf, + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { + lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities"); +- return -1; ++ return (-1); + } + if (rsp->ccode > 0) { + lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s", + val2str(rsp->ccode, completion_code_vals)); +- return -1; ++ return (-1); + } + } + +@@ -135,9 +134,10 @@ ipmi_get_channel_auth_cap(struct ipmi_intf * intf, + printf("IPMI v1.5 auth types : %s\n", + ipmi_1_5_authtypes(auth_cap.enabled_auth_types)); + +- if (auth_cap.v20_data_available) ++ if (auth_cap.v20_data_available) { + printf("KG status : %s\n", + (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)"); ++ } + + printf("Per message authentication : %sabled\n", + (auth_cap.per_message_auth) ? "dis" : "en"); +@@ -184,18 +184,18 @@ ipmi_get_channel_auth_cap(struct ipmi_intf * intf, + * + */ + int +-ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel) ++ipmi_get_channel_info(struct ipmi_intf *intf, uint8_t channel) + { +- struct ipmi_rs * rsp; ++ struct ipmi_rs *rsp; + struct ipmi_rq req; + uint8_t rqdata[2]; + uint8_t medium; +- struct get_channel_info_rsp channel_info; ++ struct get_channel_info_rsp channel_info; + struct get_channel_access_rsp channel_access; + + memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; // 0x06 +- req.msg.cmd = IPMI_GET_CHANNEL_INFO; // 0x42 ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_GET_CHANNEL_INFO; + req.msg.data = &channel; + req.msg.data_len = 1; + +@@ -257,10 +257,9 @@ ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel) + rqdata[0] = channel & 0xf; + + /* get volatile settings */ +- + rqdata[1] = 0x80; /* 0x80=active */ +- req.msg.netfn = IPMI_NETFN_APP; // 0x06 +- req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; // 0x41 ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; + req.msg.data = rqdata; + req.msg.data_len = 2; + +@@ -352,61 +351,35 @@ ipmi_get_channel_info(struct ipmi_intf * intf, uint8_t channel) + } + + static int +-ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid) ++ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t userid) + { +- struct ipmi_rs * rsp; +- struct ipmi_rq req1, req2; +- uint8_t rqdata[2]; +- struct get_user_access_rsp user_access; +- int curr_uid, max_uid = 0, init = 1; +- +- curr_uid = userid ? : 1; +- +- memset(&req1, 0, sizeof(req1)); +- req1.msg.netfn = IPMI_NETFN_APP; +- req1.msg.cmd = IPMI_GET_USER_ACCESS; +- req1.msg.data = rqdata; +- req1.msg.data_len = 2; +- +- memset(&req2, 0, sizeof(req2)); +- req2.msg.netfn = IPMI_NETFN_APP; +- req2.msg.cmd = IPMI_GET_USER_NAME; +- req2.msg.data = rqdata; +- req2.msg.data_len = 1; +- +- do +- { +- rqdata[0] = channel & 0xf; +- rqdata[1] = curr_uid & 0x3f; +- +- rsp = intf->sendrecv(intf, &req1); +- if (rsp == NULL) { +- lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)", +- rqdata[0], rqdata[1]); +- return -1; +- } +- if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s", +- rqdata[0], rqdata[1], +- val2str(rsp->ccode, completion_code_vals)); +- return -1; ++ struct user_access_t user_access; ++ struct user_name_t user_name; ++ int ccode = 0; ++ int curr_uid; ++ int init = 1; ++ int max_uid = 0; ++ ++ curr_uid = userid ? userid : 1; ++ do { ++ memset(&user_access, 0, sizeof(user_access)); ++ user_access.channel = channel; ++ user_access.user_id = curr_uid; ++ ccode = _ipmi_get_user_access(intf, &user_access); ++ if (eval_ccode(ccode) != 0) { ++ lprintf(LOG_ERR, ++ "Unable to Get User Access (channel %d id %d)", ++ channel, curr_uid); ++ return (-1); + } + +- memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp)); +- +- rqdata[0] = curr_uid & 0x3f; +- +- rsp = intf->sendrecv(intf, &req2); +- if (rsp == NULL) { +- lprintf(LOG_ERR, "Unable to Get User Name (id %d)", rqdata[0]); +- return -1; +- } +- if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Get User Name (id %d) failed: %s", +- rqdata[0], val2str(rsp->ccode, completion_code_vals)); +- return -1; ++ memset(&user_name, 0, sizeof(user_name)); ++ user_name.user_id = curr_uid; ++ ccode = _ipmi_get_user_name(intf, &user_name); ++ if (eval_ccode(ccode) != 0) { ++ lprintf(LOG_ERR, "Unable to Get User Name (id %d)", curr_uid); ++ return (-1); + } +- + if (init) { + printf("Maximum User IDs : %d\n", user_access.max_user_ids); + printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); +@@ -416,7 +389,7 @@ ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid) + + printf("\n"); + printf("User ID : %d\n", curr_uid); +- printf("User Name : %s\n", rsp->data); ++ printf("User Name : %s\n", user_name.user_name); + printf("Fixed Name : %s\n", + (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); + printf("Access Available : %s\n", +@@ -429,162 +402,56 @@ ipmi_get_user_access(struct ipmi_intf * intf, uint8_t channel, uint8_t userid) + val2str(user_access.privilege_limit, ipmi_privlvl_vals)); + + curr_uid ++; +- + } while (!userid && curr_uid <= max_uid); + + return 0; + } + +-static int +-ipmi_set_user_access(struct ipmi_intf * intf, int argc, char ** argv) +-{ +- uint8_t channel, privilege_limit, userid; +- struct ipmi_rs * rsp; +- struct ipmi_rq req; +- uint8_t rqdata[2]; +- struct get_user_access_rsp user_access; +- struct set_user_access_data set_access; +- int i; +- +- if ((argc < 3) || (strncmp(argv[0], "help", 4) == 0)) { +- printf_channel_usage(); +- return 0; +- } +- +- if (str2uchar(argv[0], &channel) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[0]); +- return (-1); +- } +- if (str2uchar(argv[1], &userid) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]); +- return (-1); +- } +- +- memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; +- req.msg.cmd = IPMI_GET_USER_ACCESS; +- req.msg.data = rqdata; +- req.msg.data_len = 2; +- +- rqdata[0] = channel & 0xf; +- rqdata[1] = userid & 0x3f; +- +- rsp = intf->sendrecv(intf, &req); +- if (rsp == NULL) { +- lprintf(LOG_ERR, "Unable to Get User Access (channel %d id %d)", +- rqdata[0], rqdata[1]); +- return -1; +- } +- if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Get User Access (channel %d id %d) failed: %s", +- rqdata[0], rqdata[1], +- val2str(rsp->ccode, completion_code_vals)); +- return -1; +- } +- +- memcpy(&user_access, rsp->data, sizeof(struct get_user_access_rsp)); +- +- memset(&set_access, 0, sizeof(set_access)); +- set_access.change_bits = 1; +- set_access.callin_callback = user_access.callin_callback; +- set_access.link_auth = user_access.link_auth; +- set_access.ipmi_messaging = user_access.ipmi_messaging; +- set_access.channel = channel; +- set_access.user_id = userid; +- set_access.privilege_limit = user_access.privilege_limit; +- set_access.session_limit = 0; +- +- for (i = 2; i < argc; i ++) +- { +- if (strncmp(argv[i], "callin=", 7) == 0) { +- set_access.callin_callback = !(strncmp (argv[i]+7, "off", 3)); +- } +- else if (strncmp(argv[i], "link=", 5) == 0) { +- set_access.link_auth = strncmp (argv[i]+5, "off", 3); +- } +- else if (strncmp(argv[i], "ipmi=", 5) == 0) { +- set_access.ipmi_messaging = strncmp (argv[i]+5, "off", 3); +- } +- else if (strncmp(argv[i], "privilege=", 10) == 0) { +- if (str2uchar(argv[i]+10, &privilege_limit) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[i]+10); +- return (-1); +- } +- set_access.privilege_limit = privilege_limit; +- } +- else { +- printf ("Invalid option: %s\n", argv [i]); +- return -1; +- } +- } +- +- memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; +- req.msg.cmd = IPMI_SET_USER_ACCESS; +- req.msg.data = (uint8_t *) &set_access; +- req.msg.data_len = 4; +- +- rsp = intf->sendrecv(intf, &req); +- if (rsp == NULL) { +- lprintf(LOG_ERR, "Unable to Set User Access (channel %d id %d)", +- set_access.channel, set_access.user_id); +- return -1; +- } +- if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Set User Access (channel %d id %d) failed: %s", +- set_access.channel, set_access.user_id, +- val2str(rsp->ccode, completion_code_vals)); +- return -1; +- } +- +- return 0; +-} +- +- + static const char * + iana_string(uint32_t iana) + { + static char s[10]; + +- if (iana) +- { ++ if (iana) { + sprintf(s, "%06x", iana); + return s; +- } +- else ++ } else { + return "N/A"; ++ } + } + + + static int +-ipmi_get_channel_cipher_suites(struct ipmi_intf * intf, +- const char * payload_type, +- uint8_t channel) ++ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, ++ uint8_t channel) + { +- struct ipmi_rs * rsp; ++ struct ipmi_rs *rsp; + struct ipmi_rq req; + +- uint8_t oem_record; +- uint8_t rqdata[3]; ++ uint8_t oem_record; ++ uint8_t rqdata[3]; + uint32_t iana; +- uint8_t auth_alg, integrity_alg, crypt_alg; +- uint8_t cipher_suite_id; +- uint8_t list_index = 0; +- uint8_t cipher_suite_data[1024]; // 0x40 sets * 16 bytes per set ++ uint8_t auth_alg, integrity_alg, crypt_alg; ++ uint8_t cipher_suite_id; ++ uint8_t list_index = 0; ++ /* 0x40 sets * 16 bytes per set */ ++ uint8_t cipher_suite_data[1024]; + uint16_t offset = 0; +- uint16_t cipher_suite_data_length = 0; // how much was returned, total ++ /* how much was returned, total */ ++ uint16_t cipher_suite_data_length = 0; + + memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); + + memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; // 0x06 +- req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; // 0x54 ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; + req.msg.data = rqdata; + req.msg.data_len = 3; + + rqdata[0] = channel; + rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); +- rqdata[2] = 0x80; // Always ask for cipher suite format ++ /* Always ask for cipher suite format */ ++ rqdata[2] = 0x80; + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) { +@@ -598,23 +465,26 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf * intf, + } + + +- // Grab the returned channel number once. We assume it's the same +- // in future calls. +- if (rsp->data_len >= 1) ++ /* ++ * Grab the returned channel number once. We assume it's the same ++ * in future calls. ++ */ ++ if (rsp->data_len >= 1) { + channel = rsp->data[0]; +- +- while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) +- { +- // +- // We got back cipher suite data -- store it. +- //printf("copying data to offset %d\n", offset); +- //printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); ++ } ++ ++ while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { ++ /* ++ * We got back cipher suite data -- store it. ++ * printf("copying data to offset %d\n", offset); ++ * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); ++ */ + memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); + offset += rsp->data_len - 1; + +- // +- // Increment our list for the next call +- // ++ /* ++ * Increment our list for the next call ++ */ + ++list_index; + rqdata[2] = (rqdata[2] & 0x80) + list_index; + +@@ -631,78 +501,68 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf * intf, + } + + /* Copy last chunk */ +- if(rsp->data_len > 1) +- { +- // +- // We got back cipher suite data -- store it. +- //printf("copying data to offset %d\n", offset); +- //printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); ++ if(rsp->data_len > 1) { ++ /* ++ * We got back cipher suite data -- store it. ++ * printf("copying data to offset %d\n", offset); ++ * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); ++ */ + memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); + offset += rsp->data_len - 1; + } + +- // +- // We can chomp on all our data now. +- // ++ /* We can chomp on all our data now. */ + cipher_suite_data_length = offset; + offset = 0; + +- if (! csv_output) ++ if (! csv_output) { + printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); +- +- while (offset < cipher_suite_data_length) +- { +- if (cipher_suite_data[offset++] == 0xC0) +- { +- oem_record = 0; // standard type +- iana = 0; ++ } ++ while (offset < cipher_suite_data_length) { ++ if (cipher_suite_data[offset++] == 0xC0) { ++ /* standard type */ ++ oem_record = 0; ++ iana = 0; + +- // Verify that we have at least a full record left +- if ((cipher_suite_data_length - offset) < 4) // id + 3 algs +- { ++ /* Verify that we have at least a full record left; id + 3 algs */ ++ if ((cipher_suite_data_length - offset) < 4) { + lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); + return -1; + } +- + cipher_suite_id = cipher_suite_data[offset++]; +- +- } +- else if (cipher_suite_data[offset++] == 0xC1) +- { +- oem_record = 1; // OEM record type +- +- // Verify that we have at least a full record left +- if ((cipher_suite_data_length - offset) < 4) // id + iana + 3 algs +- { ++ } else if (cipher_suite_data[offset++] == 0xC1) { ++ /* OEM record type */ ++ oem_record = 1; ++ ++ /* Verify that we have at least a full record left ++ * id + iana + 3 algs ++ */ ++ if ((cipher_suite_data_length - offset) < 4) { + lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); + return -1; + } + + cipher_suite_id = cipher_suite_data[offset++]; + +- // +- // Grab the IANA +- // ++ /* Grab the IANA */ + iana = + cipher_suite_data[offset] | + (cipher_suite_data[offset + 1] << 8) | + (cipher_suite_data[offset + 2] << 16); + offset += 3; +- } +- else +- { ++ } else { + lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); + return -1; + } + +- // +- // Grab the algorithms for this cipher suite. I guess we can't be +- // sure of what order they'll come in. Also, I suppose we default +- // to the NONE algorithm if one were absent. This part of the spec is +- // poorly written -- I have read the errata document. For now, I'm only +- // allowing one algorithm per type (auth, integrity, crypt) because I +- // don't I understand how it could be otherwise. +- // ++ /* ++ * Grab the algorithms for this cipher suite. I guess we can't be ++ * sure of what order they'll come in. Also, I suppose we default ++ * to the NONE algorithm if one were absent. This part of the spec is ++ * poorly written -- I have read the errata document. For now, I'm only ++ * allowing one algorithm per type (auth, integrity, crypt) because I ++ * don't I understand how it could be otherwise. ++ */ + auth_alg = IPMI_AUTH_RAKP_NONE; + integrity_alg = IPMI_INTEGRITY_NONE; + crypt_alg = IPMI_CRYPT_NONE; +@@ -713,24 +573,20 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf * intf, + switch (cipher_suite_data[offset] & 0xC0) + { + case 0x00: +- // Authentication algorithm specifier ++ /* Authentication algorithm specifier */ + auth_alg = cipher_suite_data[offset++] & 0x3F; + break; + case 0x40: +- // Interity algorithm specifier ++ /* Interity algorithm specifier */ + integrity_alg = cipher_suite_data[offset++] & 0x3F; + break; + case 0x80: +- // Confidentiality algorithm specifier ++ /* Confidentiality algorithm specifier */ + crypt_alg = cipher_suite_data[offset++] & 0x3F; + break; + } + } +- +- +- // +- // We have everything we need to spit out a cipher suite record +- // ++ /* We have everything we need to spit out a cipher suite record */ + printf((csv_output? "%d,%s,%s,%s,%s\n" : + "%-4d %-7s %-15s %-15s %-15s\n"), + cipher_suite_id, +@@ -739,17 +595,15 @@ ipmi_get_channel_cipher_suites(struct ipmi_intf * intf, + val2str(integrity_alg, ipmi_integrity_algorithms), + val2str(crypt_alg, ipmi_encryption_algorithms)); + } +- +- + return 0; + } + + + + uint8_t +-ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel) ++ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) + { +- struct ipmi_rs * rsp; ++ struct ipmi_rs *rsp; + struct ipmi_rq req; + struct get_channel_info_rsp info; + +@@ -765,8 +619,9 @@ ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel) + return 0; + } + if (rsp->ccode > 0) { +- if (rsp->ccode == 0xcc) ++ if (rsp->ccode == 0xcc) { + return IPMI_CHANNEL_MEDIUM_RESERVED; ++ } + lprintf(LOG_INFO, "Get Channel Info command failed: %s", + val2str(rsp->ccode, completion_code_vals)); + return IPMI_CHANNEL_MEDIUM_RESERVED; +@@ -781,7 +636,7 @@ ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel) + } + + uint8_t +-ipmi_current_channel_medium(struct ipmi_intf * intf) ++ipmi_current_channel_medium(struct ipmi_intf *intf) + { + return ipmi_get_channel_medium(intf, 0xE); + } +@@ -789,115 +644,182 @@ ipmi_current_channel_medium(struct ipmi_intf * intf) + void + printf_channel_usage() + { +- lprintf(LOG_NOTICE, "Channel Commands: authcap "); +- lprintf(LOG_NOTICE, " getaccess [user id]"); +- lprintf(LOG_NOTICE, " setaccess " +- " [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); +- lprintf(LOG_NOTICE, " info [channel number]"); +- lprintf(LOG_NOTICE, " getciphers [channel]\n"); +- lprintf(LOG_NOTICE, "Possible privilege levels are:"); +- lprintf(LOG_NOTICE, " 1 Callback level"); +- lprintf(LOG_NOTICE, " 2 User level"); +- lprintf(LOG_NOTICE, " 3 Operator level"); +- lprintf(LOG_NOTICE, " 4 Administrator level"); +- lprintf(LOG_NOTICE, " 5 OEM Proprietary level"); +- lprintf(LOG_NOTICE, " 15 No access"); ++ lprintf(LOG_NOTICE, ++"Channel Commands: authcap "); ++ lprintf(LOG_NOTICE, ++" getaccess [user id]"); ++ lprintf(LOG_NOTICE, ++" setaccess " ++" [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); ++ lprintf(LOG_NOTICE, ++" info [channel number]"); ++ lprintf(LOG_NOTICE, ++" getciphers [channel]"); ++ lprintf(LOG_NOTICE, ++""); ++ lprintf(LOG_NOTICE, ++"Possible privilege levels are:"); ++ lprintf(LOG_NOTICE, ++" 1 Callback level"); ++ lprintf(LOG_NOTICE, ++" 2 User level"); ++ lprintf(LOG_NOTICE, ++" 3 Operator level"); ++ lprintf(LOG_NOTICE, ++" 4 Administrator level"); ++ lprintf(LOG_NOTICE, ++" 5 OEM Proprietary level"); ++ lprintf(LOG_NOTICE, ++" 15 No access"); + } + +- + int +-ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv) ++ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv) + { +- int retval = 0; +- uint8_t channel, priv = 0; +- +- if ((argc == 0) || (strncmp(argv[0], "help", 4) == 0)) +- { ++ struct user_access_t user_access = {0}; ++ int ccode = 0; ++ int i = 0; ++ uint8_t channel = 0; ++ uint8_t priv = 0; ++ uint8_t user_id = 0; ++ if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { + printf_channel_usage(); ++ return 0; ++ } else if (argc < 3) { ++ lprintf(LOG_ERR, "Not enough parameters given."); ++ printf_channel_usage(); ++ return (-1); + } +- else if (strncmp(argv[0], "authcap", 7) == 0) +- { +- if (argc != 3) { +- printf_channel_usage(); +- return (-1); +- } else { +- if (str2uchar(argv[1], &channel) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]); +- return (-1); ++ if (is_ipmi_channel_num(argv[0], &channel) != 0 ++ || is_ipmi_user_id(argv[1], &user_id) != 0) { ++ return (-1); ++ } ++ user_access.channel = channel; ++ user_access.user_id = user_id; ++ ccode = _ipmi_get_user_access(intf, &user_access); ++ if (eval_ccode(ccode) != 0) { ++ lprintf(LOG_ERR, ++ "Unable to Get User Access (channel %d id %d)", ++ channel, user_id); ++ return (-1); ++ } ++ for (i = 3; i < argc; i ++) { ++ if (strncmp(argv[i], "callin=", 7) == 0) { ++ if (strncmp(argv[i] + 7, "off", 3) == 0) { ++ user_access.callin_callback = 1; ++ } else { ++ user_access.callin_callback = 0; ++ } ++ } else if (strncmp(argv[i], "link=", 5) == 0) { ++ if (strncmp(argv[i] + 5, "off", 3) == 0) { ++ user_access.link_auth = 0; ++ } else { ++ user_access.link_auth = 1; + } +- if (str2uchar(argv[2], &priv) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[2]); ++ } else if (strncmp(argv[i], "ipmi=", 5) == 0) { ++ if (strncmp(argv[i] + 5, "off", 3) == 0) { ++ user_access.ipmi_messaging = 0; ++ } else { ++ user_access.ipmi_messaging = 1; ++ } ++ } else if (strncmp(argv[i], "privilege=", 10) == 0) { ++ if (str2uchar(argv[i] + 10, &priv) != 0) { ++ lprintf(LOG_ERR, ++ "Numeric value expected, but '%s' given.", ++ argv[i] + 10); + return (-1); + } +- retval = ipmi_get_channel_auth_cap(intf, channel, priv); ++ user_access.privilege_limit = priv; ++ } else { ++ lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]); ++ return (-1); + } + } +- else if (strncmp(argv[0], "getaccess", 10) == 0) +- { +- if ((argc < 2) || (argc > 3)) ++ ccode = _ipmi_set_user_access(intf, &user_access, 0); ++ if (eval_ccode(ccode) != 0) { ++ lprintf(LOG_ERR, ++ "Unable to Set User Access (channel %d id %d)", ++ channel, user_id); ++ return (-1); ++ } ++ printf("Set User Access (channel %d id %d) successful.\n", ++ channel, user_id); ++ return 0; ++} ++ ++int ++ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ int retval = 0; ++ uint8_t channel; ++ uint8_t priv = 0; ++ if (argc < 1) { ++ lprintf(LOG_ERR, "Not enough parameters given."); ++ printf_channel_usage(); ++ return (-1); ++ } else if (strncmp(argv[0], "help", 4) == 0) { ++ printf_channel_usage(); ++ return 0; ++ } else if (strncmp(argv[0], "authcap", 7) == 0) { ++ if (argc != 3) { + printf_channel_usage(); +- else { +- uint8_t ch = 0; +- uint8_t id = 0; +- if (str2uchar(argv[1], &ch) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]); ++ return (-1); ++ } ++ if (is_ipmi_channel_num(argv[1], &channel) != 0 ++ || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { ++ return (-1); ++ } ++ retval = ipmi_get_channel_auth_cap(intf, channel, priv); ++ } else if (strncmp(argv[0], "getaccess", 10) == 0) { ++ uint8_t user_id = 0; ++ if ((argc < 2) || (argc > 3)) { ++ lprintf(LOG_ERR, "Not enough parameters given."); ++ printf_channel_usage(); ++ return (-1); ++ } ++ if (is_ipmi_channel_num(argv[1], &channel) != 0) { ++ return (-1); ++ } ++ if (argc == 3) { ++ if (is_ipmi_user_id(argv[2], &user_id) != 0) { + return (-1); + } +- if (argc == 3) { +- if (str2uchar(argv[2], &id) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[2]); +- return (-1); +- } +- } +- retval = ipmi_get_user_access(intf, ch, id); + } +- } +- else if (strncmp(argv[0], "setaccess", 9) == 0) +- { +- retval = ipmi_set_user_access(intf, argc-1, &(argv[1])); +- } +- else if (strncmp(argv[0], "info", 4) == 0) +- { +- if (argc > 2) ++ retval = ipmi_get_user_access(intf, channel, user_id); ++ } else if (strncmp(argv[0], "setaccess", 9) == 0) { ++ return ipmi_set_user_access(intf, (argc - 1), &(argv[1])); ++ } else if (strncmp(argv[0], "info", 4) == 0) { ++ channel = 0xE; ++ if (argc > 2) { + printf_channel_usage(); +- else { +- uint8_t ch = 0xe; +- if (argc == 2) { +- if (str2uchar(argv[1], &ch) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[1]); +- return (-1); +- } ++ return (-1); ++ } ++ if (argc == 2) { ++ if (is_ipmi_channel_num(argv[1], &channel) != 0) { ++ return (-1); + } +- retval = ipmi_get_channel_info(intf, ch); + } +- } +- +- // it channel getciphers [channel] +- else if (strncmp(argv[0], "getciphers", 10) == 0) +- { +- if ((argc < 2) || (argc > 3) || +- (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) ++ retval = ipmi_get_channel_info(intf, channel); ++ } else if (strncmp(argv[0], "getciphers", 10) == 0) { ++ /* channel getciphers [channel] */ ++ channel = 0xE; ++ if ((argc < 2) || (argc > 3) || ++ (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { + printf_channel_usage(); +- else +- { +- uint8_t ch = 0xe; +- if (argc == 3) { +- if (str2uchar(argv[2], &ch) != 0) { +- lprintf(LOG_ERR, "Numeric value expected, but '%s' given.", argv[2]); +- return (-1); +- } ++ return (-1); ++ } ++ if (argc == 3) { ++ if (is_ipmi_channel_num(argv[1], &channel) != 0) { ++ return (-1); + } +- retval = ipmi_get_channel_cipher_suites(intf, +- argv[1], // ipmi | sol +- ch); + } +- } +- else +- { ++ retval = ipmi_get_channel_cipher_suites(intf, ++ argv[1], /* ipmi | sol */ ++ channel); ++ } else { + printf("Invalid CHANNEL command: %s\n", argv[0]); + printf_channel_usage(); + retval = -1; + } +- + return retval; + } +diff --git a/lib/ipmi_delloem.c b/lib/ipmi_delloem.c +index 308c513..3cfed96 100644 +--- a/lib/ipmi_delloem.c ++++ b/lib/ipmi_delloem.c +@@ -453,6 +453,8 @@ ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv) + } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + } + } else if ((strncmp(argv[current_arg], "lcdqualifier\0", 13) == 0) +@@ -477,6 +479,8 @@ ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv) + } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + } + } else if ((strncmp(argv[current_arg], "errordisplay\0", 13) == 0) +@@ -499,6 +503,8 @@ ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv) + } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + } + } else if ((strncmp(argv[current_arg], "none\0", 5) == 0) +@@ -529,6 +535,8 @@ ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv) + } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + } + } else if (strncmp(argv[current_arg], "frontpanelaccess\0", 17) == 0) { +@@ -546,16 +554,22 @@ ipmi_delloem_lcd_main(struct ipmi_intf * intf, int argc, char ** argv) + } else if (strncmp(argv[current_arg], "help\0", 5) == 0) { + ipmi_lcd_usage(); + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + } + } else if( (strncmp(argv[current_arg], "help\0", 5) == 0) + && (iDRAC_FLAG==0)) { + ipmi_lcd_usage(); + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + return -1; + } + } else { ++ lprintf(LOG_ERR, "Invalid DellOEM command: %s", ++ argv[current_arg]); + ipmi_lcd_usage(); + return -1; + } +diff --git a/lib/ipmi_ekanalyzer.c b/lib/ipmi_ekanalyzer.c +index 96d3b44..8c6d12d 100644 +--- a/lib/ipmi_ekanalyzer.c ++++ b/lib/ipmi_ekanalyzer.c +@@ -2773,6 +2773,10 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type, + ret = fread(additional_data, size_board, 1, input_file); + if ((ret != 1) || ferror(input_file)) { + lprintf(LOG_ERR, "Invalid Additional Data!"); ++ if (additional_data != NULL) { ++ free(additional_data); ++ additional_data = NULL; ++ } + goto out; + } + printf("Additional Custom Mfg. Data: %02x", +diff --git a/lib/ipmi_firewall.c b/lib/ipmi_firewall.c +index 8bda398..2803bc0 100644 +--- a/lib/ipmi_firewall.c ++++ b/lib/ipmi_firewall.c +@@ -1110,7 +1110,11 @@ ipmi_firewall_reset(struct ipmi_intf * intf, int argc, char ** argv) + unsigned int l, n, c, ret; + unsigned char enables[MAX_COMMAND_BYTES]; + +- if (argc > 0 || (argc > 0 && strncmp(argv[0], "help", 4) == 0)) { ++ if (argc < 1) { ++ lprintf(LOG_ERR, "Not enough parameters given."); ++ printf_firewall_usage(); ++ return (-1); ++ } else if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { + printf_firewall_usage(); + return 0; + } +diff --git a/lib/ipmi_fwum.c b/lib/ipmi_fwum.c +index 68f40d4..066d929 100644 +--- a/lib/ipmi_fwum.c ++++ b/lib/ipmi_fwum.c +@@ -571,7 +571,7 @@ KfwumGetDeviceInfo(struct ipmi_intf *intf, unsigned char output, + pGetDevId->fw_rev1, pGetDevId->fw_rev2 >> 4, + pGetDevId->fw_rev2 & 0x0f); + if (((pBoardInfo->iana == IPMI_OEM_KONTRON) +- && (pBoardInfo->boardId = KFWUM_BOARD_KONTRON_5002))) { ++ && (pBoardInfo->boardId == KFWUM_BOARD_KONTRON_5002))) { + printf(" SDR %u", pGetDevId->aux_fw_rev[0]); + } + printf("\n"); +@@ -837,11 +837,8 @@ KfwumFinishFirmwareImage(struct ipmi_intf *intf, tKFWUM_InFirmwareInfo firmInfo) + do { + rsp = intf->sendrecv(intf, &req); + } while (rsp == NULL || rsp->ccode == 0xc0); +- if (!rsp) { +- lprintf(LOG_ERR, +- "Error in FWUM Firmware Finish Firmware Image Download Command."); +- return (-1); +- } else if (rsp->ccode != 0) { ++ ++ if (rsp->ccode != 0) { + lprintf(LOG_ERR, + "FWUM Firmware Finish Firmware Image Download returned %x", + rsp->ccode); +diff --git a/lib/ipmi_kontronoem.c b/lib/ipmi_kontronoem.c +index 48dc684..6a24831 100644 +--- a/lib/ipmi_kontronoem.c ++++ b/lib/ipmi_kontronoem.c +@@ -105,7 +105,7 @@ ipmi_kontronoem_main(struct ipmi_intf *intf, int argc, char **argv) + if (argc < 2) { + lprintf(LOG_ERR, "Not enough parameters given."); + ipmi_kontron_nextboot_help(); +- rc = (-1); ++ return (-1); + } + rc = ipmi_kontron_nextboot_set(intf, (argc - 1), (argv + 1)); + if (rc == 0) { +diff --git a/lib/ipmi_lanp.c b/lib/ipmi_lanp.c +index 060e753..11e0d9c 100644 +--- a/lib/ipmi_lanp.c ++++ b/lib/ipmi_lanp.c +@@ -1198,8 +1198,7 @@ get_cmdline_cipher_suite_priv_data(char * arg, uint8_t * buf) + * data 3 - maximum priv level for third (LSN) and fourth (MSN) ciphers + * data 9 - maximum priv level for 15th (LSN) cipher. + */ +- bzero(buf, 9); +- ++ memset(buf, 0, 9); + for (i = 0; i < 15; ++i) + { + unsigned char priv_level = IPMI_SESSION_PRIV_ADMIN; +diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c +index 2bbbe4b..26f3457 100644 +--- a/lib/ipmi_main.c ++++ b/lib/ipmi_main.c +@@ -1,21 +1,21 @@ + /* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +- * ++ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: +- * ++ * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. +- * ++ * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. +- * ++ * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. +- * ++ * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _XOPEN_SOURCE 700 + + #include + #include +@@ -263,13 +264,18 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_ + * + * This insures that the IOL session gets freed + * for other callers. +- * ++ * + * returns -1 + */ + void ipmi_catch_sigint() + { + if (ipmi_main_intf != NULL) { + printf("\nSIGN INT: Close Interface %s\n",ipmi_main_intf->desc); ++ /* reduce retry count to a single retry */ ++ if (ipmi_main_intf->session) { ++ ipmi_main_intf->session->retry = 1; ++ } ++ /* close interface */ + ipmi_main_intf->close(ipmi_main_intf); + } + exit(-1); +diff --git a/lib/ipmi_mc.c b/lib/ipmi_mc.c +index 2890c90..a93134e 100644 +--- a/lib/ipmi_mc.c ++++ b/lib/ipmi_mc.c +@@ -130,43 +130,41 @@ struct bitfield_data { + const char * name; + const char * desc; + uint32_t mask; +-}; +- +-struct bitfield_data mc_enables_bf[] = { ++} mc_enables_bf[] = { + { +- name: "recv_msg_intr", +- desc: "Receive Message Queue Interrupt", +- mask: 1<<0, ++ .name = "recv_msg_intr", ++ .desc = "Receive Message Queue Interrupt", ++ .mask = 1<<0, + }, + { +- name: "event_msg_intr", +- desc: "Event Message Buffer Full Interrupt", +- mask: 1<<1, ++ .name = "event_msg_intr", ++ .desc = "Event Message Buffer Full Interrupt", ++ .mask = 1<<1, + }, + { +- name: "event_msg", +- desc: "Event Message Buffer", +- mask: 1<<2, ++ .name = "event_msg", ++ .desc = "Event Message Buffer", ++ .mask = 1<<2, + }, + { +- name: "system_event_log", +- desc: "System Event Logging", +- mask: 1<<3, ++ .name = "system_event_log", ++ .desc = "System Event Logging", ++ .mask = 1<<3, + }, + { +- name: "oem0", +- desc: "OEM 0", +- mask: 1<<5, ++ .name = "oem0", ++ .desc = "OEM 0", ++ .mask = 1<<5, + }, + { +- name: "oem1", +- desc: "OEM 1", +- mask: 1<<6, ++ .name = "oem1", ++ .desc = "OEM 1", ++ .mask = 1<<6, + }, + { +- name: "oem2", +- desc: "OEM 2", +- mask: 1<<7, ++ .name = "oem2", ++ .desc = "OEM 2", ++ .mask = 1<<7, + }, + { NULL }, + }; +@@ -217,6 +215,8 @@ printf_sysinfo_usage(int full_help) + lprintf(LOG_NOTICE, " Valid arguments are:"); + } + lprintf(LOG_NOTICE, ++ " system_fw_version System firmware (e.g. BIOS) version"); ++ lprintf(LOG_NOTICE, + " primary_os_name Primary operating system name"); + lprintf(LOG_NOTICE, " os_name Operating system name"); + lprintf(LOG_NOTICE, +@@ -914,6 +914,8 @@ sysinfo_param(const char *str, int *maxset) + else if (!strcmp(str, "delloem_url")) { + *maxset = 2; + return IPMI_SYSINFO_DELL_URL; ++ } else if (!strcmp(str, "system_fw_version")) { ++ return IPMI_SYSINFO_SYSTEM_FW_VERSION; + } + + return (-1); +diff --git a/lib/ipmi_oem.c b/lib/ipmi_oem.c +index 89495c0..96db2ea 100644 +--- a/lib/ipmi_oem.c ++++ b/lib/ipmi_oem.c +@@ -42,34 +42,34 @@ static int ipmi_oem_ibm(struct ipmi_intf * intf); + + static struct ipmi_oem_handle ipmi_oem_list[] = { + { +- name: "supermicro", +- desc: "Supermicro IPMIv1.5 BMC with OEM LAN authentication support", +- setup: ipmi_oem_supermicro, ++ .name = "supermicro", ++ .desc = "Supermicro IPMIv1.5 BMC with OEM LAN authentication support", ++ .setup = ipmi_oem_supermicro, + }, + { +- name: "intelwv2", +- desc: "Intel SE7501WV2 IPMIv1.5 BMC with extra LAN communication support", ++ .name = "intelwv2", ++ .desc = "Intel SE7501WV2 IPMIv1.5 BMC with extra LAN communication support", + }, + { +- name: "intelplus", +- desc: "Intel IPMI 2.0 BMC with RMCP+ communication support", ++ .name = "intelplus", ++ .desc = "Intel IPMI 2.0 BMC with RMCP+ communication support", + }, + { +- name: "icts", +- desc: "IPMI 2.0 ICTS compliance support", ++ .name = "icts", ++ .desc = "IPMI 2.0 ICTS compliance support", + }, + { +- name: "ibm", +- desc: "IBM OEM support", +- setup: ipmi_oem_ibm, ++ .name = "ibm", ++ .desc = "IBM OEM support", ++ .setup = ipmi_oem_ibm, + }, + { +- name: "i82571spt", +- desc: "Intel 82571 MAC with integrated RMCP+ support in super pass-through mode", ++ .name = "i82571spt", ++ .desc = "Intel 82571 MAC with integrated RMCP+ support in super pass-through mode", + }, + { +- name: "kontron", +- desc: "Kontron OEM big buffer support" ++ .name = "kontron", ++ .desc = "Kontron OEM big buffer support" + }, + { 0 } + }; +diff --git a/lib/ipmi_pef.c b/lib/ipmi_pef.c +index 154bf40..1beebf0 100644 +--- a/lib/ipmi_pef.c ++++ b/lib/ipmi_pef.c +@@ -674,7 +674,7 @@ ipmi_pef_list_policies(struct ipmi_intf * intf) + + tbl_size = ipmi_pef_get_policy_table(intf, &ptbl); + if (!tbl_size) { +- if (!ptbl) { ++ if (ptbl != NULL) { + free(ptbl); + ptbl = NULL; + } +@@ -808,7 +808,7 @@ ipmi_pef_get_info(struct ipmi_intf * intf) + uint8_t actions, tbl_size; + + tbl_size = ipmi_pef_get_policy_table(intf, &ptbl); +- if (!ptbl) { ++ if (ptbl != NULL) { + free(ptbl); + ptbl = NULL; + } +diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c +index 7a66aa5..914d11d 100644 +--- a/lib/ipmi_picmg.c ++++ b/lib/ipmi_picmg.c +@@ -1745,18 +1745,8 @@ ipmi_picmg_clk_set(struct ipmi_intf * intf, int argc, char ** argv) + } + } + +-#if 1 +-printf("## ID: %d\n", msg_data[1]); +-printf("## index: %d\n", msg_data[2]); +-printf("## setting: 0x%02x\n", msg_data[3]); +-printf("## family: %d\n", msg_data[4]); +-printf("## acc: %d\n", msg_data[5]); +-printf("## freq: %ld\n", freq ); +-printf("## res: %d\n", msg_data[10]); +-#endif + + rsp = intf->sendrecv(intf, &req); +- + if (!rsp) { + lprintf(LOG_ERR, "No valid response received."); + return -1; +diff --git a/lib/ipmi_sdradd.c b/lib/ipmi_sdradd.c +index f3bc271..a445a6e 100644 +--- a/lib/ipmi_sdradd.c ++++ b/lib/ipmi_sdradd.c +@@ -633,6 +633,7 @@ ipmi_sdr_read_records(const char *filename, struct sdrr_queue *queue) + queue->tail->next = sdrr; + queue->tail = sdrr; + } ++ close(fd); + return rc; + } + +diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c +index 67e12e3..81d007e 100644 +--- a/lib/ipmi_sel.c ++++ b/lib/ipmi_sel.c +@@ -536,7 +536,6 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec) + int data1; + int data2; + int data3; +- int length; + int sensor_type; + uint8_t i = 0; + uint16_t oem_id = 0; +@@ -587,17 +586,19 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec) + /* check the chipset type */ + oem_id = ipmi_get_oem_id(intf); + if (oem_id == 0) { ++ if (desc != NULL) { ++ free(desc); ++ desc = NULL; ++ } + return NULL; + } +- length = sizeof(supermicro_X8); +- for (i = 0; i < length; i++) { ++ for (i = 0; supermicro_X8[i] != 0xFFFF; i++) { + if (oem_id == supermicro_X8[i]) { + chipset_type = 0; + break; + } + } +- length = sizeof(supermicro_x9); +- for (i = 0; i < length; i++) { ++ for (i = 0; supermicro_x9[i] != 0xFFFF; i++) { + if (oem_id == supermicro_x9[i]) { + chipset_type = 2; + break; +@@ -1234,6 +1235,8 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char + sfx = ipmi_get_oem_desc(intf, rec); + break; + /* add your oem sensor assignation here */ ++ default: ++ break; + } + if( evt == NULL ){ + lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description", +@@ -1247,6 +1250,8 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char + code = rec->sel_type.standard_type.sensor_type; + sfx = ipmi_get_oem_desc(intf, rec); + break; ++ default: ++ break; + } + } + if( evt == NULL ){ +@@ -1915,6 +1920,8 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt) + case IPMI_OEM_SUPERMICRO_47488: + print_sensor = 0; + break; ++ default: ++ break; + } + /* + * Sensor-Specific Discrete +@@ -2919,7 +2926,7 @@ ipmi_sel_show_entry(struct ipmi_intf * intf, int argc, char ** argv) + + /* print SDR entry */ + oldv = verbose; +- verbose = verbose ? : 1; ++ verbose = verbose ? verbose : 1; + switch (sdr->type) { + case SDR_RECORD_TYPE_FULL_SENSOR: + case SDR_RECORD_TYPE_COMPACT_SENSOR: +diff --git a/lib/ipmi_sensor.c b/lib/ipmi_sensor.c +index c138c67..d77ed01 100644 +--- a/lib/ipmi_sensor.c ++++ b/lib/ipmi_sensor.c +@@ -1,21 +1,21 @@ + /* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. +- * ++ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: +- * ++ * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. +- * ++ * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. +- * ++ * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. +- * ++ * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A +@@ -52,8 +52,8 @@ void print_sensor_thresh_usage(); + // static + int + ipmi_sensor_get_sensor_reading_factors( +- struct ipmi_intf * intf, +- struct sdr_record_full_sensor * sensor, ++ struct ipmi_intf * intf, ++ struct sdr_record_full_sensor * sensor, + uint8_t reading) + { + struct ipmi_rq req; +@@ -88,9 +88,9 @@ ipmi_sensor_get_sensor_reading_factors( + return -1; + } else { + /* Update SDR copy with updated Reading Factors for this reading */ +- /* Note: +- * The Format of the returned data is exactly as in the SDR definition (Little Endian Format), +- * therefore we can use raw copy operation here. ++ /* Note: ++ * The Format of the returned data is exactly as in the SDR definition (Little Endian Format), ++ * therefore we can use raw copy operation here. + * Note: rsp->data[0] would point to the next valid entry in the sampling table + */ + // BUGBUG: uses 'hardcoded' length information from SDR Definition +@@ -892,8 +892,20 @@ ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv) + /* need to set verbose level to 1 */ + v = verbose; + verbose = 1; +- if (ipmi_sdr_print_listentry(intf, sdr) < 0) { +- rc = (-1); ++ switch (sdr->type) { ++ case SDR_RECORD_TYPE_FULL_SENSOR: ++ case SDR_RECORD_TYPE_COMPACT_SENSOR: ++ if (ipmi_sensor_print_fc(intf, ++ (struct sdr_record_common_sensor *) sdr->record.common, ++ sdr->type)) { ++ rc = -1; ++ } ++ break; ++ default: ++ if (ipmi_sdr_print_listentry(intf, sdr) < 0) { ++ rc = (-1); ++ } ++ break; + } + verbose = v; + sdr = NULL; +diff --git a/lib/ipmi_sol.c b/lib/ipmi_sol.c +index cf58b44..244a27e 100644 +--- a/lib/ipmi_sol.c ++++ b/lib/ipmi_sol.c +@@ -1300,7 +1300,7 @@ ipmi_sol_deactivate(struct ipmi_intf * intf, int instance) + req.msg.data_len = 6; + req.msg.data = data; + +- bzero(data, sizeof(data)); ++ memset(data, 0, sizeof(data)); + data[0] = IPMI_PAYLOAD_TYPE_SOL; /* payload type */ + data[1] = instance; /* payload instance. */ + +@@ -1942,10 +1942,6 @@ ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv) + print_sol_usage(); + return -1; + } +- if (argc == 1 || argc > 4) { +- print_sol_usage(); +- return -1; +- } + if (argc >= 3) { + if (is_ipmi_channel_num(argv[2], &channel) != 0) { + return (-1); +diff --git a/lib/ipmi_sunoem.c b/lib/ipmi_sunoem.c +index 16a6090..7f7a58b 100644 +--- a/lib/ipmi_sunoem.c ++++ b/lib/ipmi_sunoem.c +@@ -1361,9 +1361,6 @@ ipmi_sunoem_echo(struct ipmi_intf * intf, int argc, char *argv[]) + + /* Fill in data packet */ + for (i = 0; i < ECHO_DATA_SIZE; i++) { +- if (i > UINT8_MAX) +- break; +- + echo_req.data[i] = (uint8_t) i; + } + +diff --git a/lib/ipmi_tsol.c b/lib/ipmi_tsol.c +index b4e3cc1..d7460bd 100644 +--- a/lib/ipmi_tsol.c ++++ b/lib/ipmi_tsol.c +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _DEFAULT_SOURCE + + #include + #include +@@ -411,8 +412,10 @@ ipmi_tsol_main(struct ipmi_intf *intf, int argc, char **argv) + print_tsol_usage(); + return 0; + } else { ++ lprintf(LOG_ERR, "Invalid tsol command: '%s'\n", ++ argv[i]); + print_tsol_usage(); +- return 0; ++ return (-1); + } + } + +@@ -440,7 +443,7 @@ ipmi_tsol_main(struct ipmi_intf *intf, int argc, char **argv) + return (-1); + } + sa_in->sin_family = host->h_addrtype; +- memcpy(&sa_in->sin_addr, host->h_addr, host->h_length); ++ memcpy(&sa_in->sin_addr, host->h_addr_list[0], host->h_length); + } + + fd_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +diff --git a/lib/ipmi_user.c b/lib/ipmi_user.c +index d7e5890..31a5ca5 100644 +--- a/lib/ipmi_user.c ++++ b/lib/ipmi_user.c +@@ -58,244 +58,245 @@ extern int csv_output; + #define IPMI_PASSWORD_SET_PASSWORD 0x02 + #define IPMI_PASSWORD_TEST_PASSWORD 0x03 + +-/* +- * ipmi_get_user_access ++/* _ipmi_get_user_access - Get User Access for given channel. Results are stored ++ * into passed struct. + * +- * param intf [in] +- * param channel_number [in] +- * param user_id [in] +- * param user_access [out] ++ * @intf - IPMI interface ++ * @user_access_rsp - ptr to user_access_t with UID and Channel set + * +- * return 0 on succes +- * 1 on failure ++ * returns - negative number means error, positive is a ccode + */ +-static int +-ipmi_get_user_access( +- struct ipmi_intf *intf, +- uint8_t channel_number, +- uint8_t user_id, +- struct user_access_rsp *user_access) ++int ++_ipmi_get_user_access(struct ipmi_intf *intf, ++ struct user_access_t *user_access_rsp) + { +- struct ipmi_rs * rsp; +- struct ipmi_rq req; +- uint8_t msg_data[2]; +- +- memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ +- req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */ +- req.msg.data = msg_data; ++ struct ipmi_rq req = {0}; ++ struct ipmi_rs *rsp; ++ uint8_t data[2]; ++ if (user_access_rsp == NULL) { ++ return (-3); ++ } ++ data[0] = user_access_rsp->channel & 0x0F; ++ data[1] = user_access_rsp->user_id & 0x3F; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_GET_USER_ACCESS; ++ req.msg.data = data; + req.msg.data_len = 2; +- +- +- /* The channel number will remain constant throughout this function */ +- msg_data[0] = channel_number; +- msg_data[1] = user_id; +- + rsp = intf->sendrecv(intf, &req); +- + if (rsp == NULL) { +- lprintf(LOG_ERR, "Get User Access command failed " +- "(channel %d, user %d)", channel_number, user_id); +- return -1; +- } +- if (rsp->ccode > 0) { +- lprintf(LOG_ERR, "Get User Access command failed " +- "(channel %d, user %d): %s", channel_number, user_id, +- val2str(rsp->ccode, completion_code_vals)); +- return -1; ++ return (-1); ++ } else if (rsp->ccode != 0) { ++ return rsp->ccode; ++ } else if (rsp->data_len != 4) { ++ return (-2); + } +- +- memcpy(user_access, +- rsp->data, +- sizeof(struct user_access_rsp)); +- +- return 0; ++ user_access_rsp->max_user_ids = rsp->data[0] & 0x3F; ++ user_access_rsp->enable_status = rsp->data[1] & 0xC0; ++ user_access_rsp->enabled_user_ids = rsp->data[1] & 0x3F; ++ user_access_rsp->fixed_user_ids = rsp->data[2] & 0x3F; ++ user_access_rsp->callin_callback = rsp->data[3] & 0x40; ++ user_access_rsp->link_auth = rsp->data[3] & 0x20; ++ user_access_rsp->ipmi_messaging = rsp->data[3] & 0x10; ++ user_access_rsp->privilege_limit = rsp->data[3] & 0x0F; ++ return rsp->ccode; + } + +- +- +-/* +- * ipmi_get_user_name ++/* _ipmi_get_user_name - Fetch User Name for given User ID. User Name is stored ++ * into passed structure. + * +- * param intf [in] +- * param channel_number [in] +- * param user_id [in] +- * param user_name [out] ++ * @intf - ipmi interface ++ * @user_name - user_name_t struct with UID set + * +- * return 0 on succes +- * 1 on failure ++ * returns - negative number means error, positive is a ccode + */ +-static int +-ipmi_get_user_name( +- struct ipmi_intf *intf, +- uint8_t user_id, +- char *user_name) ++int ++_ipmi_get_user_name(struct ipmi_intf *intf, struct user_name_t *user_name_ptr) + { +- struct ipmi_rs * rsp; +- struct ipmi_rq req; +- uint8_t msg_data[1]; +- +- memset(user_name, 0, 17); +- +- memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ +- req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */ +- req.msg.data = msg_data; ++ struct ipmi_rq req = {0}; ++ struct ipmi_rs *rsp; ++ uint8_t data[1]; ++ if (user_name_ptr == NULL) { ++ return (-3); ++ } ++ data[0] = user_name_ptr->user_id & 0x3F; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_GET_USER_NAME; ++ req.msg.data = data; + req.msg.data_len = 1; +- +- msg_data[0] = user_id; +- + rsp = intf->sendrecv(intf, &req); +- + if (rsp == NULL) { +- lprintf(LOG_ERR, "Get User Name command failed (user %d)", +- user_id); +- return -1; +- } +- if (rsp->ccode > 0) { +- if (rsp->ccode == 0xcc) +- return 0; +- lprintf(LOG_ERR, "Get User Name command failed (user %d): %s", +- user_id, val2str(rsp->ccode, completion_code_vals)); +- return -1; ++ return (-1); ++ } else if (rsp->ccode > 0) { ++ return rsp->ccode; ++ } else if (rsp->data_len != 17) { ++ return (-2); + } +- +- memcpy(user_name, rsp->data, 16); +- +- return 0; ++ memset(user_name_ptr->user_name, '\0', 17); ++ memcpy(user_name_ptr->user_name, rsp->data, 16); ++ return rsp->ccode; + } + +- +- ++/* _ipmi_set_user_access - Set User Access for given channel. ++ * ++ * @intf - IPMI interface ++ * @user_access_req - ptr to user_access_t with desired User Access. ++ * @change_priv_limit_only - change User's privilege limit only ++ * ++ * returns - negative number means error, positive is a ccode ++ */ ++int ++_ipmi_set_user_access(struct ipmi_intf *intf, ++ struct user_access_t *user_access_req, ++ uint8_t change_priv_limit_only) ++{ ++ uint8_t data[4]; ++ struct ipmi_rq req = {0}; ++ struct ipmi_rs *rsp; ++ if (user_access_req == NULL) { ++ return (-3); ++ } ++ data[0] = change_priv_limit_only ? 0x00 : 0x80; ++ if (user_access_req->callin_callback) { ++ data[0] |= 0x40; ++ } ++ if (user_access_req->link_auth) { ++ data[0] |= 0x20; ++ } ++ if (user_access_req->ipmi_messaging) { ++ data[0] |= 0x10; ++ } ++ data[0] |= (user_access_req->channel & 0x0F); ++ data[1] = user_access_req->user_id & 0x3F; ++ data[2] = user_access_req->privilege_limit & 0x0F; ++ data[3] = user_access_req->session_limit & 0x0F; ++ req.msg.netfn = IPMI_NETFN_APP; ++ req.msg.cmd = IPMI_SET_USER_ACCESS; ++ req.msg.data = data; ++ req.msg.data_len = 4; ++ rsp = intf->sendrecv(intf, &req); ++ if (rsp == NULL) { ++ return (-1); ++ } else { ++ return rsp->ccode; ++ } ++} + + static void +-dump_user_access( +- uint8_t user_id, +- const char * user_name, +- struct user_access_rsp * user_access) ++dump_user_access(const char *user_name, ++ struct user_access_t *user_access) + { + static int printed_header = 0; +- +- if (! printed_header) +- { ++ if (!printed_header) { + printf("ID Name Callin Link Auth IPMI Msg " +- "Channel Priv Limit\n"); ++ "Channel Priv Limit\n"); + printed_header = 1; + } +- + printf("%-4d%-17s%-8s%-11s%-11s%-s\n", +- user_id, +- user_name, +- user_access->no_callin_access? "false": "true ", +- user_access->link_auth_access? "true ": "false", +- user_access->ipmi_messaging_access? "true ": "false", +- val2str(user_access->channel_privilege_limit, +- ipmi_privlvl_vals)); ++ user_access->user_id, ++ user_name, ++ user_access->callin_callback? "false": "true ", ++ user_access->link_auth? "true ": "false", ++ user_access->ipmi_messaging? "true ": "false", ++ val2str(user_access->privilege_limit, ++ ipmi_privlvl_vals)); + } + + + + static void +-dump_user_access_csv( +- uint8_t user_id, +- const char *user_name, +- struct user_access_rsp *user_access) ++dump_user_access_csv(const char *user_name, ++ struct user_access_t *user_access) + { + printf("%d,%s,%s,%s,%s,%s\n", +- user_id, +- user_name, +- user_access->no_callin_access? "false": "true", +- user_access->link_auth_access? "true": "false", +- user_access->ipmi_messaging_access? "true": "false", +- val2str(user_access->channel_privilege_limit, +- ipmi_privlvl_vals)); ++ user_access->user_id, ++ user_name, ++ user_access->callin_callback? "false": "true", ++ user_access->link_auth? "true": "false", ++ user_access->ipmi_messaging? "true": "false", ++ val2str(user_access->privilege_limit, ++ ipmi_privlvl_vals)); + } + ++/* ipmi_print_user_list - List IPMI Users and their ACLs for given channel. ++ * ++ * @intf - IPMI interface ++ * @channel_number - IPMI channel ++ * ++ * returns - 0 on success, (-1) on error ++ */ + static int +-ipmi_print_user_list( +- struct ipmi_intf *intf, +- uint8_t channel_number) ++ipmi_print_user_list(struct ipmi_intf *intf, uint8_t channel_number) + { +- /* This is where you were! */ +- char user_name[17]; +- struct user_access_rsp user_access; ++ struct user_access_t user_access = {0}; ++ struct user_name_t user_name = {0}; ++ int ccode = 0; + uint8_t current_user_id = 1; +- +- +- do +- { +- if (ipmi_get_user_access(intf, +- channel_number, +- current_user_id, +- &user_access)) +- return -1; +- +- +- if (ipmi_get_user_name(intf, +- current_user_id, +- user_name)) +- return -1; +- +- if ((current_user_id == 0) || +- user_access.link_auth_access || +- user_access.ipmi_messaging_access || +- strcmp("", user_name)) +- { +- if (csv_output) +- dump_user_access_csv(current_user_id, +- user_name, &user_access); +- else +- dump_user_access(current_user_id, +- user_name, +- &user_access); ++ do { ++ memset(&user_access, 0, sizeof(user_access)); ++ user_access.user_id = current_user_id; ++ user_access.channel = channel_number; ++ ccode = _ipmi_get_user_access(intf, &user_access); ++ if (eval_ccode(ccode) != 0) { ++ return (-1); ++ } ++ memset(&user_name, 0, sizeof(user_name)); ++ user_name.user_id = current_user_id; ++ ccode = _ipmi_get_user_name(intf, &user_name); ++ if (eval_ccode(ccode) != 0) { ++ return (-1); ++ } ++ if ((current_user_id == 0) ++ || user_access.link_auth ++ || user_access.ipmi_messaging ++ || strcmp("", (char *)user_name.user_name)) { ++ if (csv_output) { ++ dump_user_access_csv((char *)user_name.user_name, ++ &user_access); ++ } else { ++ dump_user_access((char *)user_name.user_name, ++ &user_access); ++ } + } +- +- + ++current_user_id; +- } while((current_user_id <= user_access.maximum_ids) && +- (current_user_id <= IPMI_UID_MAX)); /* Absolute maximum allowed by spec */ +- +- ++ } while ((current_user_id <= user_access.max_user_ids) ++ && (current_user_id <= IPMI_UID_MAX)); + return 0; + } + +- +- ++/* ipmi_print_user_summary - print User statistics for given channel ++ * ++ * @intf - IPMI interface ++ * @channel_number - channel number ++ * ++ * returns - 0 on success, (-1) on error ++ */ + static int +-ipmi_print_user_summary( +- struct ipmi_intf * intf, +- uint8_t channel_number) ++ipmi_print_user_summary(struct ipmi_intf *intf, uint8_t channel_number) + { +- struct user_access_rsp user_access; +- +- if (ipmi_get_user_access(intf, +- channel_number, +- 1, +- &user_access)) +- return -1; +- +- if (csv_output) +- { +- printf("%d,%d,%d\n", +- user_access.maximum_ids, +- user_access.enabled_user_count, +- user_access.fixed_name_count); ++ struct user_access_t user_access = {0}; ++ int ccode = 0; ++ user_access.channel = channel_number; ++ user_access.user_id = 1; ++ ccode = _ipmi_get_user_access(intf, &user_access); ++ if (eval_ccode(ccode) != 0) { ++ return (-1); + } +- else +- { +- printf("Maximum IDs : %d\n", +- user_access.maximum_ids); +- printf("Enabled User Count : %d\n", +- user_access.enabled_user_count); +- printf("Fixed Name Count : %d\n", +- user_access.fixed_name_count); ++ if (csv_output) { ++ printf("%" PRIu8 ",%" PRIu8 ",%" PRIu8 "\n", ++ user_access.max_user_ids, ++ user_access.enabled_user_ids, ++ user_access.fixed_user_ids); ++ } else { ++ printf("Maximum IDs : %" PRIu8 "\n", ++ user_access.max_user_ids); ++ printf("Enabled User Count : %" PRIu8 "\n", ++ user_access.enabled_user_ids); ++ printf("Fixed Name Count : %" PRIu8 "\n", ++ user_access.fixed_user_ids); + } +- + return 0; + } + +- +- + /* + * ipmi_user_set_username + */ +@@ -343,47 +344,6 @@ ipmi_user_set_username( + return 0; + } + +-static int +-ipmi_user_set_userpriv( +- struct ipmi_intf *intf, +- uint8_t channel, +- uint8_t user_id, +- const unsigned char privLevel) +-{ +- struct ipmi_rs *rsp; +- struct ipmi_rq req; +- uint8_t msg_data[4] = {0, 0, 0, 0}; +- +- memset(&req, 0, sizeof(req)); +- req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ +- req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */ +- req.msg.data = msg_data; +- req.msg.data_len = 4; +- +- /* The channel number will remain constant throughout this function */ +- msg_data[0] = (channel & 0x0f); +- msg_data[1] = (user_id & 0x3f); +- msg_data[2] = (privLevel & 0x0f); +- msg_data[3] = 0; +- +- rsp = intf->sendrecv(intf, &req); +- +- if (rsp == NULL) +- { +- lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)", +- user_id); +- return -1; +- } +- if (rsp->ccode > 0) +- { +- lprintf(LOG_ERR, "Set Privilege Level command failed (user %d): %s", +- user_id, val2str(rsp->ccode, completion_code_vals)); +- return -1; +- } +- +- return 0; +-} +- + /* + * ipmi_user_set_password + * +@@ -441,8 +401,6 @@ ipmi_user_set_password( + return 0; + } + +- +- + /* + * ipmi_user_test_password + * +@@ -487,16 +445,40 @@ ipmi_user_test_password( + static void + print_user_usage(void) + { +- lprintf(LOG_NOTICE, "User Commands:"); +- lprintf(LOG_NOTICE, " summary []"); +- lprintf(LOG_NOTICE, " list []"); +- lprintf(LOG_NOTICE, " set name "); +- lprintf(LOG_NOTICE, " set password []"); +- lprintf(LOG_NOTICE, " disable "); +- lprintf(LOG_NOTICE, " enable "); + lprintf(LOG_NOTICE, +- " priv []"); +- lprintf(LOG_NOTICE, " test <16|20> [\n"); ++"User Commands:"); ++ lprintf(LOG_NOTICE, ++" summary []"); ++ lprintf(LOG_NOTICE, ++" list []"); ++ lprintf(LOG_NOTICE, ++" set name "); ++ lprintf(LOG_NOTICE, ++" set password [ <16|20>]"); ++ lprintf(LOG_NOTICE, ++" disable "); ++ lprintf(LOG_NOTICE, ++" enable "); ++ lprintf(LOG_NOTICE, ++" priv []"); ++ lprintf(LOG_NOTICE, ++" Privilege levels:"); ++ lprintf(LOG_NOTICE, ++" * 0x1 - Callback"); ++ lprintf(LOG_NOTICE, ++" * 0x2 - User"); ++ lprintf(LOG_NOTICE, ++" * 0x3 - Operator"); ++ lprintf(LOG_NOTICE, ++" * 0x4 - Administrator"); ++ lprintf(LOG_NOTICE, ++" * 0x5 - OEM Proprietary"); ++ lprintf(LOG_NOTICE, ++" * 0xF - No Access"); ++ lprintf(LOG_NOTICE, ""); ++ lprintf(LOG_NOTICE, ++" test <16|20> ["); ++ lprintf(LOG_NOTICE, ""); + } + + +@@ -509,328 +491,276 @@ ipmi_user_build_password_prompt(uint8_t user_id) + return prompt; + } + +- +-/* +- * ipmi_user_main ++/* ask_password - ask user for password + * +- * Upon entry to this function argv should contain our arguments +- * specific to this subcommand +- */ +-int +-ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) ++ * @user_id: User ID which will be built-in into text ++ * ++ * @returns pointer to char with password ++ */ ++char * ++ask_password(uint8_t user_id) + { +- int retval = 0; ++ const char *password_prompt = ++ ipmi_user_build_password_prompt(user_id); ++# ifdef HAVE_GETPASSPHRASE ++ return getpassphrase(password_prompt); ++# else ++ return (char*)getpass(password_prompt); ++# endif ++} + +- /* +- * Help +- */ +- if (argc == 0 || strncmp(argv[0], "help", 4) == 0) +- { ++int ++ipmi_user_summary(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ /* Summary*/ ++ uint8_t channel; ++ if (argc == 1) { ++ channel = 0x0E; /* Ask about the current channel */ ++ } else if (argc == 2) { ++ if (is_ipmi_channel_num(argv[1], &channel) != 0) { ++ return (-1); ++ } ++ } else { + print_user_usage(); ++ return (-1); + } ++ return ipmi_print_user_summary(intf, channel); ++} + +- /* +- * Summary +- */ +- else if (strncmp(argv[0], "summary", 7) == 0) +- { +- uint8_t channel; +- +- if (argc == 1) +- channel = 0x0E; /* Ask about the current channel */ +- else if (argc == 2) +- { +- if (str2uchar(argv[1], &channel) != 0) +- { +- lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); +- return (-1); +- } +- } +- else +- { +- print_user_usage(); +- return -1; ++int ++ipmi_user_list(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ /* List */ ++ uint8_t channel; ++ if (argc == 1) { ++ channel = 0x0E; /* Ask about the current channel */ ++ } else if (argc == 2) { ++ if (is_ipmi_channel_num(argv[1], &channel) != 0) { ++ return (-1); + } +- +- retval = ipmi_print_user_summary(intf, channel); ++ } else { ++ print_user_usage(); ++ return (-1); + } ++ return ipmi_print_user_list(intf, channel); ++} + +- +- /* +- * List +- */ +- else if (strncmp(argv[0], "list", 4) == 0) +- { +- uint8_t channel; +- +- if (argc == 1) +- channel = 0x0E; /* Ask about the current channel */ +- else if (argc == 2) +- { +- if (str2uchar(argv[1], &channel) != 0) +- { +- lprintf(LOG_ERR, "Invalid channel: %s", argv[1]); +- return (-1); +- } +- } +- else +- { +- print_user_usage(); +- return -1; +- } +- +- retval = ipmi_print_user_list(intf, channel); ++int ++ipmi_user_test(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ /* Test */ ++ char *password = NULL; ++ int password_length = 0; ++ uint8_t user_id = 0; ++ /* a little irritating, isn't it */ ++ if (argc != 3 && argc != 4) { ++ print_user_usage(); ++ return (-1); + } +- +- +- +- /* +- * Test +- */ +- else if (strncmp(argv[0], "test", 4) == 0) +- { +- // a little irritating, isn't it +- if (argc == 3 || argc == 4) +- { +- char * password = NULL; +- int password_length = 0; +- uint8_t user_id = 0; +- if (is_ipmi_user_id(argv[1], &user_id)) { +- return (-1); +- } +- if (str2int(argv[2], &password_length) != 0 +- || (password_length != 16 && password_length != 20)) { +- lprintf(LOG_ERR, +- "Given password length '%s' is invalid.", +- argv[2]); +- lprintf(LOG_ERR, "Expected value is either 16 or 20."); +- return (-1); +- } +- +- if (argc == 3) +- { +- /* We need to prompt for a password */ +- +- char * tmp; +- const char * password_prompt = +- ipmi_user_build_password_prompt(user_id); +-# ifdef HAVE_GETPASSPHRASE +- tmp = getpassphrase (password_prompt); +-# else +- tmp = (char*)getpass (password_prompt); +-# endif +- if (tmp != NULL) { +- password = strdup(tmp); +- tmp = NULL; +- } +- if (password == NULL) { +- lprintf(LOG_ERR, "ipmitool: malloc failure"); +- return -1; +- } +- } +- else { +- password = strdup(argv[3]); +- } +- +- +- retval = ipmi_user_test_password(intf, +- user_id, +- password, +- password_length == 20); +- if (password != NULL) { +- free(password); +- password = NULL; +- } +- } +- else +- { +- print_user_usage(); +- return -1; ++ if (is_ipmi_user_id(argv[1], &user_id)) { ++ return (-1); ++ } ++ if (str2int(argv[2], &password_length) != 0 ++ || (password_length != 16 && password_length != 20)) { ++ lprintf(LOG_ERR, ++ "Given password length '%s' is invalid.", ++ argv[2]); ++ lprintf(LOG_ERR, "Expected value is either 16 or 20."); ++ return (-1); ++ } ++ if (argc == 3) { ++ /* We need to prompt for a password */ ++ password = ask_password(user_id); ++ if (password == NULL) { ++ lprintf(LOG_ERR, "ipmitool: malloc failure"); ++ return (-1); + } ++ } else { ++ password = argv[3]; + } ++ return ipmi_user_test_password(intf, ++ user_id, ++ password, ++ password_length == 20); ++} + +- /* +- * Set +- */ +- else if (strncmp(argv[0], "set", 3) == 0) +- { +- /* +- * Set Password +- */ +- if ((argc >= 3) && +- (strncmp("password", argv[1], 8) == 0)) +- { +- char * password = NULL; +- uint8_t user_id = 0; +- if (is_ipmi_user_id(argv[2], &user_id)) { +- return (-1); +- } +- +- if (argc == 3) +- { +- /* We need to prompt for a password */ +- char * tmp; +- const char * password_prompt = +- ipmi_user_build_password_prompt(user_id); +-# ifdef HAVE_GETPASSPHRASE +- tmp = getpassphrase (password_prompt); +-# else +- tmp = (char*)getpass (password_prompt); +-# endif +- if (tmp != NULL) { +- password = strdup(tmp); +- tmp = NULL; +- } +- if (password == NULL) { +- lprintf(LOG_ERR, "ipmitool: malloc failure"); +- return -1; +- } +-# ifdef HAVE_GETPASSPHRASE +- tmp = getpassphrase (password_prompt); +-# else +- tmp = (char*)getpass (password_prompt); +-# endif +- if (tmp == NULL) { +- lprintf(LOG_ERR, "ipmitool: malloc failure"); +- return (-1); +- } +- if (strlen(password) != strlen(tmp) +- || strncmp(password, tmp, strlen(tmp))) { +- lprintf(LOG_ERR, "Passwords do not match."); +- free(password); +- password = NULL; +- return -1; +- } +- tmp = NULL; +- } else { +- password = strdup(argv[3]); +- } +- +- if (password == NULL) { +- lprintf(LOG_ERR, "Unable to parse password argument."); +- return -1; +- } +- else if (strlen(password) > 20) +- { +- lprintf(LOG_ERR, "Password is too long (> 20 bytes)"); +- return -1; +- } ++int ++ipmi_user_priv(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ struct user_access_t user_access; ++ int ccode = 0; + +- retval = ipmi_user_set_password(intf, +- user_id, +- IPMI_PASSWORD_SET_PASSWORD, +- password, +- strlen(password) > 16); +- if (password != NULL) { +- free(password); +- password = NULL; +- } ++ if (argc != 3 && argc != 4) { ++ print_user_usage(); ++ return (-1); ++ } ++ if (argc == 4) { ++ if (is_ipmi_channel_num(argv[3], &user_access.channel) != 0) { ++ return (-1); + } ++ } else { ++ /* Use channel running on */ ++ user_access.channel = 0x0E; ++ } ++ if (is_ipmi_user_priv_limit(argv[2], &user_access.privilege_limit) != 0 ++ || is_ipmi_user_id(argv[1], &user_access.user_id) != 0) { ++ return (-1); ++ } ++ ccode = _ipmi_set_user_access(intf, &user_access, 1); ++ if (eval_ccode(ccode) != 0) { ++ lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)", ++ user_access.user_id); ++ return (-1); ++ } else { ++ printf("Set Privilege Level command successful (user %d)", ++ user_access.user_id); ++ return 0; ++ } ++} + +- /* +- * Set Name +- */ +- else if ((argc >= 2) && +- (strncmp("name", argv[1], 4) == 0)) +- { +- uint8_t user_id = 0; +- if (argc != 4) +- { +- print_user_usage(); +- return -1; +- } +- if (is_ipmi_user_id(argv[2], &user_id)) { +- return (-1); +- } +- +- if (strlen(argv[3]) > 16) +- { +- lprintf(LOG_ERR, "Username is too long (> 16 bytes)"); +- return -1; +- } ++int ++ipmi_user_mod(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ /* Disable / Enable */ ++ uint8_t user_id; ++ uint8_t operation; ++ char null_password[16]; /* Not used, but required */ + +- retval = ipmi_user_set_username(intf, user_id, argv[3]); +- } +- else +- { +- print_user_usage(); +- return -1; +- } ++ if (argc != 2) { ++ print_user_usage(); ++ return (-1); ++ } ++ if (is_ipmi_user_id(argv[1], &user_id)) { ++ return (-1); + } ++ memset(null_password, 0, sizeof(null_password)); ++ operation = (strncmp(argv[0], "disable", 7) == 0) ? ++ IPMI_PASSWORD_DISABLE_USER : IPMI_PASSWORD_ENABLE_USER; + +- else if (strncmp(argv[0], "priv", 4) == 0) +- { +- uint8_t user_id; +- uint8_t priv_level; +- uint8_t channel = 0x0e; /* Use channel running on */ ++ /* Last parameter is ignored */ ++ return ipmi_user_set_password(intf, user_id, operation, null_password, 0); ++} + +- if (argc != 3 && argc != 4) +- { +- print_user_usage(); +- return -1; +- } ++int ++ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ char *password = NULL; ++ uint8_t password_type = 16; ++ uint8_t user_id = 0; ++ if (is_ipmi_user_id(argv[2], &user_id)) { ++ return (-1); ++ } + +- if (argc == 4) +- { +- if (str2uchar(argv[3], &channel) != 0) +- { +- lprintf(LOG_ERR, "Invalid channel: %s", argv[3]); +- return (-1); +- } +- channel = (channel & 0x0f); ++ if (argc == 3) { ++ /* We need to prompt for a password */ ++ char *tmp; ++ password = ask_password(user_id); ++ if (password == NULL) { ++ lprintf(LOG_ERR, "ipmitool: malloc failure"); ++ return (-1); + } +- +- if (str2uchar(argv[2], &priv_level) != 0) +- { +- lprintf(LOG_ERR, "Invalid privilege level: %s", argv[2]); ++ tmp = ask_password(user_id); ++ if (tmp == NULL) { ++ lprintf(LOG_ERR, "ipmitool: malloc failure"); + return (-1); + } +- priv_level = (priv_level & 0x0f); +- +- if (is_ipmi_user_id(argv[1], &user_id)) { ++ if (strlen(password) != strlen(tmp) ++ || strncmp(password, tmp, strlen(tmp))) { ++ lprintf(LOG_ERR, "Passwords do not match."); + return (-1); + } ++ } else { ++ password = argv[3]; ++ if (argc > 4) { ++ if ((str2uchar(argv[4], &password_type) != 0) ++ || (password_type != 16 && password_type != 20)) { ++ lprintf(LOG_ERR, "Invalid password length '%s'", argv[4]); ++ return (-1); ++ } ++ } else { ++ password_type = 16; ++ } ++ } + +- retval = ipmi_user_set_userpriv(intf,channel,user_id,priv_level); ++ if (password == NULL) { ++ lprintf(LOG_ERR, "Unable to parse password argument."); ++ return (-1); ++ } else if (strlen(password) > 20) { ++ lprintf(LOG_ERR, "Password is too long (> 20 bytes)"); ++ return (-1); + } + +- /* +- * Disable / Enable +- */ +- else if ((strncmp(argv[0], "disable", 7) == 0) || +- (strncmp(argv[0], "enable", 6) == 0)) +- { +- uint8_t user_id; +- uint8_t operation; +- char null_password[16]; /* Not used, but required */ ++ return ipmi_user_set_password(intf, ++ user_id, ++ IPMI_PASSWORD_SET_PASSWORD, ++ password, ++ password_type > 16); ++} + +- memset(null_password, 0, sizeof(null_password)); ++int ++ipmi_user_name(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ /* Set Name */ ++ uint8_t user_id = 0; ++ if (argc != 4) { ++ print_user_usage(); ++ return (-1); ++ } ++ if (is_ipmi_user_id(argv[2], &user_id)) { ++ return (-1); ++ } ++ if (strlen(argv[3]) > 16) { ++ lprintf(LOG_ERR, "Username is too long (> 16 bytes)"); ++ return (-1); ++ } + +- if (argc != 2) +- { +- print_user_usage(); +- return -1; +- } ++ return ipmi_user_set_username(intf, user_id, argv[3]); ++} + +- if (is_ipmi_user_id(argv[1], &user_id)) { ++/* ++ * ipmi_user_main ++ * ++ * Upon entry to this function argv should contain our arguments ++ * specific to this subcommand ++ */ ++int ++ipmi_user_main(struct ipmi_intf *intf, int argc, char **argv) ++{ ++ if (argc == 0) { ++ lprintf(LOG_ERR, "Not enough parameters given."); ++ print_user_usage(); ++ return (-1); ++ } ++ if (strncmp(argv[0], "help", 4) == 0) { ++ /* Help */ ++ print_user_usage(); ++ return 0; ++ } else if (strncmp(argv[0], "summary", 7) == 0) { ++ return ipmi_user_summary(intf, argc, argv); ++ } else if (strncmp(argv[0], "list", 4) == 0) { ++ return ipmi_user_list(intf, argc, argv); ++ } else if (strncmp(argv[0], "test", 4) == 0) { ++ return ipmi_user_test(intf, argc, argv); ++ } else if (strncmp(argv[0], "set", 3) == 0) { ++ /* Set */ ++ if ((argc >= 3) ++ && (strncmp("password", argv[1], 8) == 0)) { ++ return ipmi_user_password(intf, argc, argv); ++ } else if ((argc >= 2) ++ && (strncmp("name", argv[1], 4) == 0)) { ++ return ipmi_user_name(intf, argc, argv); ++ } else { ++ print_user_usage(); + return (-1); + } +- +- operation = (strncmp(argv[0], "disable", 7) == 0) ? +- IPMI_PASSWORD_DISABLE_USER : IPMI_PASSWORD_ENABLE_USER; +- +- retval = ipmi_user_set_password(intf, +- user_id, +- operation, +- null_password, +- 0); /* This field is ignored */ +- } +- else +- { +- retval = -1; ++ } else if (strncmp(argv[0], "priv", 4) == 0) { ++ return ipmi_user_priv(intf, argc, argv); ++ } else if ((strncmp(argv[0], "disable", 7) == 0) ++ || (strncmp(argv[0], "enable", 6) == 0)) { ++ return ipmi_user_mod(intf, argc, argv); ++ } else { + lprintf(LOG_ERR, "Invalid user command: '%s'\n", argv[0]); + print_user_usage(); ++ return (-1); + } +- +- return retval; + } +diff --git a/src/ipmievd.c b/src/ipmievd.c +index f940579..fec5493 100644 +--- a/src/ipmievd.c ++++ b/src/ipmievd.c +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _XOPEN_SOURCE 700 + + #include + #include +@@ -122,13 +123,13 @@ static int openipmi_setup(struct ipmi_event_intf * eintf); + static int openipmi_wait(struct ipmi_event_intf * eintf); + static int openipmi_read(struct ipmi_event_intf * eintf); + static struct ipmi_event_intf openipmi_event_intf = { +- name: "open", +- desc: "OpenIPMI asyncronous notification of events", +- prefix: "", +- setup: openipmi_setup, +- wait: openipmi_wait, +- read: openipmi_read, +- log: log_event, ++ .name = "open", ++ .desc = "OpenIPMI asyncronous notification of events", ++ .prefix = "", ++ .setup = openipmi_setup, ++ .wait = openipmi_wait, ++ .read = openipmi_read, ++ .log = log_event, + }; + #endif + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +@@ -139,13 +140,13 @@ static int selwatch_wait(struct ipmi_event_intf * eintf); + static int selwatch_read(struct ipmi_event_intf * eintf); + static int selwatch_check(struct ipmi_event_intf * eintf); + static struct ipmi_event_intf selwatch_event_intf = { +- name: "sel", +- desc: "Poll SEL for notification of events", +- setup: selwatch_setup, +- wait: selwatch_wait, +- read: selwatch_read, +- check: selwatch_check, +- log: log_event, ++ .name = "sel", ++ .desc = "Poll SEL for notification of events", ++ .setup = selwatch_setup, ++ .wait = selwatch_wait, ++ .read = selwatch_read, ++ .check = selwatch_check, ++ .log = log_event, + }; + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +@@ -283,7 +284,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) + eintf->prefix, + type, + sdr->record.full->id_string, +- desc ? : "", ++ desc ? desc : "", + (evt->sel_type.standard_type.event_dir + ? "Deasserted" : "Asserted"), + (trigger_reading==(int)trigger_reading) ? 0 : 2, +@@ -303,7 +304,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) + */ + lprintf(LOG_NOTICE, "%s%s sensor %s %s %s", + eintf->prefix, type, +- sdr->record.full->id_string, desc ? : "", ++ sdr->record.full->id_string, desc ? desc : "", + (evt->sel_type.standard_type.event_dir + ? "Deasserted" : "Asserted")); + if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) { +@@ -316,7 +317,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) + */ + lprintf(LOG_NOTICE, "%s%s sensor %s %s %s", + eintf->prefix, type, +- sdr->record.full->id_string, desc ? : "", ++ sdr->record.full->id_string, desc ? desc : "", + (evt->sel_type.standard_type.event_dir + ? "Deasserted" : "Asserted")); + } +@@ -325,7 +326,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) + case SDR_RECORD_TYPE_COMPACT_SENSOR: + lprintf(LOG_NOTICE, "%s%s sensor %s - %s %s", + eintf->prefix, type, +- sdr->record.compact->id_string, desc ? : "", ++ sdr->record.compact->id_string, desc ? desc : "", + (evt->sel_type.standard_type.event_dir + ? "Deasserted" : "Asserted")); + break; +@@ -333,7 +334,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt) + default: + lprintf(LOG_NOTICE, "%s%s sensor - %s", + eintf->prefix, type, +- evt->sel_type.standard_type.sensor_num, desc ? : ""); ++ evt->sel_type.standard_type.sensor_num, desc ? desc : ""); + break; + } + +diff --git a/src/ipmishell.c b/src/ipmishell.c +index 4eebcd8..c5b6af0 100644 +--- a/src/ipmishell.c ++++ b/src/ipmishell.c +@@ -467,6 +467,10 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv) + __argv[__argc++] = strdup(tok); + if (__argv[__argc-1] == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); ++ if (fp) { ++ fclose(fp); ++ fp = NULL; ++ } + return -1; + } + tmp = __argv[__argc-1]; +diff --git a/src/plugins/dummy/dummy.c b/src/plugins/dummy/dummy.c +index eb2d086..1d7f167 100644 +--- a/src/plugins/dummy/dummy.c ++++ b/src/plugins/dummy/dummy.c +@@ -117,7 +117,7 @@ data_write(int fd, void *data_ptr, int data_len) + /* TODO - add poll() */ + data_written = write(fd, data_ptr, data_len); + errno_save = errno; +- if (data_read > 0) { ++ if (data_written > 0) { + data_total+= data_written; + } + if (errno_save != 0) { +@@ -149,9 +149,6 @@ static void + ipmi_dummyipmi_close(struct ipmi_intf *intf) + { + struct dummy_rq req; +- int data_total = 0; +- int data_written = 0; +- int try = 0; + if (intf->fd < 0) { + return; + } +@@ -276,11 +273,11 @@ ipmi_dummyipmi_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req) + } + + struct ipmi_intf ipmi_dummy_intf = { +- name: "dummy", +- desc: "Linux DummyIPMI Interface", +- open: ipmi_dummyipmi_open, +- close: ipmi_dummyipmi_close, +- sendrecv: ipmi_dummyipmi_send_cmd, +- my_addr: IPMI_BMC_SLAVE_ADDR, +- target_addr: IPMI_BMC_SLAVE_ADDR, ++ .name = "dummy", ++ .desc = "Linux DummyIPMI Interface", ++ .open = ipmi_dummyipmi_open, ++ .close = ipmi_dummyipmi_close, ++ .sendrecv = ipmi_dummyipmi_send_cmd, ++ .my_addr = IPMI_BMC_SLAVE_ADDR, ++ .target_addr = IPMI_BMC_SLAVE_ADDR, + }; +diff --git a/src/plugins/free/free.c b/src/plugins/free/free.c +index f89925d..56c8157 100644 +--- a/src/plugins/free/free.c ++++ b/src/plugins/free/free.c +@@ -203,12 +203,12 @@ static void ipmi_free_close(struct ipmi_intf * intf) + + static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) + { +- u_int8_t lun = req->msg.lun; +- u_int8_t cmd = req->msg.cmd; +- u_int8_t netfn = req->msg.netfn; +- u_int8_t rq_buf[IPMI_BUF_SIZE]; +- u_int8_t rs_buf[IPMI_BUF_SIZE]; +- u_int32_t rs_buf_len = IPMI_BUF_SIZE; ++ uint8_t lun = req->msg.lun; ++ uint8_t cmd = req->msg.cmd; ++ uint8_t netfn = req->msg.netfn; ++ uint8_t rq_buf[IPMI_BUF_SIZE]; ++ uint8_t rs_buf[IPMI_BUF_SIZE]; ++ uint32_t rs_buf_len = IPMI_BUF_SIZE; + int32_t rs_len; + + static struct ipmi_rs rsp; +diff --git a/src/plugins/imb/imb.c b/src/plugins/imb/imb.c +index cb97e81..0044159 100644 +--- a/src/plugins/imb/imb.c ++++ b/src/plugins/imb/imb.c +@@ -121,11 +121,11 @@ static struct ipmi_rs * ipmi_imb_send_cmd(struct ipmi_intf * intf, struct ipmi_r + } + + struct ipmi_intf ipmi_imb_intf = { +- name: "imb", +- desc: "Intel IMB Interface", +- open: ipmi_imb_open, +- close: ipmi_imb_close, +- sendrecv: ipmi_imb_send_cmd, +- target_addr: IPMI_BMC_SLAVE_ADDR, ++ .name = "imb", ++ .desc = "Intel IMB Interface", ++ .open = ipmi_imb_open, ++ .close = ipmi_imb_close, ++ .sendrecv = ipmi_imb_send_cmd, ++ .target_addr = IPMI_BMC_SLAVE_ADDR, + }; + +diff --git a/src/plugins/imb/imbapi.c b/src/plugins/imb/imbapi.c +index 37d3abe..111df62 100644 +--- a/src/plugins/imb/imbapi.c ++++ b/src/plugins/imb/imbapi.c +@@ -1981,7 +1981,7 @@ MapPhysicalMemory(int startAddress,int addressLength, int *virtualAddress ) + unsigned int length = addressLength; + off_t startpAddress = (off_t)startAddress; + unsigned int diff; +- caddr_t startvAddress; ++ char *startvAddress; + + if ((startAddress == 0) || (addressLength <= 0)) + return ACCESN_ERROR; +@@ -2000,13 +2000,13 @@ MapPhysicalMemory(int startAddress,int addressLength, int *virtualAddress ) + startpAddress -= diff; + length += diff; + +- if ( (startvAddress = mmap( (caddr_t)0, ++ if ( (startvAddress = mmap(0, + length, + PROT_READ, + MAP_SHARED, + fd, + startpAddress +- ) ) == (caddr_t)-1) ++ ) ) == MAP_FAILED) + { + char buf[128]; + +diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c +index a84237e..542b9ec 100644 +--- a/src/plugins/ipmi_intf.c ++++ b/src/plugins/ipmi_intf.c +@@ -29,6 +29,8 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _XOPEN_SOURCE 700 ++#define _GNU_SOURCE 1 + + #include + #include +diff --git a/src/plugins/lan/lan.c b/src/plugins/lan/lan.c +index dd90706..5eda274 100644 +--- a/src/plugins/lan/lan.c ++++ b/src/plugins/lan/lan.c +@@ -29,12 +29,15 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _POSIX_SOURCE + + #include + #include + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -100,19 +103,19 @@ static void ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size + static void ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size); + + struct ipmi_intf ipmi_lan_intf = { +- name: "lan", +- desc: "IPMI v1.5 LAN Interface", +- setup: ipmi_lan_setup, +- open: ipmi_lan_open, +- close: ipmi_lan_close, +- sendrecv: ipmi_lan_send_cmd, +- sendrsp: ipmi_lan_send_rsp, +- recv_sol: ipmi_lan_recv_sol, +- send_sol: ipmi_lan_send_sol, +- keepalive: ipmi_lan_keepalive, +- set_max_request_data_size: ipmi_lan_set_max_rq_data_size, +- set_max_response_data_size: ipmi_lan_set_max_rp_data_size, +- target_addr: IPMI_BMC_SLAVE_ADDR, ++ .name = "lan", ++ .desc = "IPMI v1.5 LAN Interface", ++ .setup = ipmi_lan_setup, ++ .open = ipmi_lan_open, ++ .close = ipmi_lan_close, ++ .sendrecv = ipmi_lan_send_cmd, ++ .sendrsp = ipmi_lan_send_rsp, ++ .recv_sol = ipmi_lan_recv_sol, ++ .send_sol = ipmi_lan_send_sol, ++ .keepalive = ipmi_lan_keepalive, ++ .set_max_request_data_size = ipmi_lan_set_max_rq_data_size, ++ .set_max_response_data_size = ipmi_lan_set_max_rp_data_size, ++ .target_addr = IPMI_BMC_SLAVE_ADDR, + }; + + static struct ipmi_rq_entry * +@@ -248,7 +251,8 @@ static struct ipmi_rs * + ipmi_lan_recv_packet(struct ipmi_intf * intf) + { + static struct ipmi_rs rsp; +- fd_set read_set, err_set; ++ fd_set read_set; ++ fd_set err_set; + struct timeval tmout; + int ret; + +@@ -1548,10 +1552,12 @@ static int + ipmi_lan_keepalive(struct ipmi_intf * intf) + { + struct ipmi_rs * rsp; +- struct ipmi_rq req = { msg: { +- netfn: IPMI_NETFN_APP, +- cmd: 1, +- }}; ++ struct ipmi_rq req = { ++ .msg = { ++ .netfn = IPMI_NETFN_APP, ++ .cmd = 1, ++ } ++ }; + + if (!intf->opened) + return 0; +diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c +index 0bff5b2..739dfd1 100644 +--- a/src/plugins/lanplus/lanplus.c ++++ b/src/plugins/lanplus/lanplus.c +@@ -29,12 +29,15 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _POSIX_SOURCE + + #include + #include + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -126,18 +129,18 @@ static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t siz + static uint8_t bridgePossible = 0; + + struct ipmi_intf ipmi_lanplus_intf = { +- name: "lanplus", +- desc: "IPMI v2.0 RMCP+ LAN Interface", +- setup: ipmi_lanplus_setup, +- open: ipmi_lanplus_open, +- close: ipmi_lanplus_close, +- sendrecv: ipmi_lanplus_send_ipmi_cmd, +- recv_sol: ipmi_lanplus_recv_sol, +- send_sol: ipmi_lanplus_send_sol, +- keepalive: ipmi_lanplus_keepalive, +- set_max_request_data_size: ipmi_lanp_set_max_rq_data_size, +- set_max_response_data_size: ipmi_lanp_set_max_rp_data_size, +- target_addr: IPMI_BMC_SLAVE_ADDR, ++ .name = "lanplus", ++ .desc = "IPMI v2.0 RMCP+ LAN Interface", ++ .setup = ipmi_lanplus_setup, ++ .open = ipmi_lanplus_open, ++ .close = ipmi_lanplus_close, ++ .sendrecv = ipmi_lanplus_send_ipmi_cmd, ++ .recv_sol = ipmi_lanplus_recv_sol, ++ .send_sol = ipmi_lanplus_send_sol, ++ .keepalive = ipmi_lanplus_keepalive, ++ .set_max_request_data_size = ipmi_lanp_set_max_rq_data_size, ++ .set_max_response_data_size = ipmi_lanp_set_max_rp_data_size, ++ .target_addr = IPMI_BMC_SLAVE_ADDR, + }; + + +@@ -2574,7 +2577,7 @@ ack_sol_packet( + { + struct ipmi_v2_payload ack; + +- bzero(&ack, sizeof(struct ipmi_v2_payload)); ++ memset(&ack, 0, sizeof(struct ipmi_v2_payload)); + + ack.payload_type = IPMI_PAYLOAD_TYPE_SOL; + +@@ -3049,9 +3052,18 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf) + } + memcpy(msg + 28, session->username, msg[27]); + +- v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1; +- v2_payload.payload_length = +- IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]); ++ v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1; ++ if (ipmi_oem_active(intf, "i82571spt")) { ++ /* ++ * The IPMI v2.0 spec hints on that all user name bytes ++ * must be occupied (29:44). The Intel 82571 GbE refuses ++ * to establish a session if this field is shorter. ++ */ ++ v2_payload.payload_length = IPMI_RAKP1_MESSAGE_SIZE; ++ } else { ++ v2_payload.payload_length = ++ IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]); ++ } + v2_payload.payload.rakp_1_message.message = msg; + + rsp = ipmi_lanplus_send_payload(intf, &v2_payload); +@@ -3417,8 +3429,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf) + goto fail; + } + +- if (!ipmi_oem_active(intf, "i82571spt") && ! auth_cap.v20_data_available) +- { ++ if (!ipmi_oem_active(intf, "i82571spt") && ! auth_cap.v20_data_available) { + lprintf(LOG_INFO, "This BMC does not support IPMI v2 / RMCP+"); + goto fail; + } +@@ -3582,10 +3593,12 @@ static int + ipmi_lanplus_keepalive(struct ipmi_intf * intf) + { + struct ipmi_rs * rsp; +- struct ipmi_rq req = { msg: { +- netfn: IPMI_NETFN_APP, +- cmd: 1, +- }}; ++ struct ipmi_rq req = { ++ .msg = { ++ .netfn = IPMI_NETFN_APP, ++ .cmd = 1, ++ } ++ }; + + if (!intf->opened) + return 0; +diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c +index f1ea0dd..512a816 100644 +--- a/src/plugins/open/open.c ++++ b/src/plugins/open/open.c +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _POSIX_SOURCE + + #include + #include +@@ -38,6 +39,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -164,11 +166,11 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) + struct ipmi_recv recv; + struct ipmi_addr addr; + struct ipmi_system_interface_addr bmc_addr = { +- addr_type: IPMI_SYSTEM_INTERFACE_ADDR_TYPE, +- channel: IPMI_BMC_CHANNEL, ++ .addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE, ++ .channel = IPMI_BMC_CHANNEL, + }; + struct ipmi_ipmb_addr ipmb_addr = { +- addr_type: IPMI_IPMB_ADDR_TYPE, ++ .addr_type = IPMI_IPMB_ADDR_TYPE, + }; + struct ipmi_req _req; + static struct ipmi_rs rsp; +@@ -432,13 +434,13 @@ int ipmi_openipmi_setup(struct ipmi_intf * intf) + } + + struct ipmi_intf ipmi_open_intf = { +- name: "open", +- desc: "Linux OpenIPMI Interface", +- setup: ipmi_openipmi_setup, +- open: ipmi_openipmi_open, +- close: ipmi_openipmi_close, +- sendrecv: ipmi_openipmi_send_cmd, +- set_my_addr: ipmi_openipmi_set_my_addr, +- my_addr: IPMI_BMC_SLAVE_ADDR, +- target_addr: 0, /* init so -m local_addr does not cause bridging */ ++ .name = "open", ++ .desc = "Linux OpenIPMI Interface", ++ .setup = ipmi_openipmi_setup, ++ .open = ipmi_openipmi_open, ++ .close = ipmi_openipmi_close, ++ .sendrecv = ipmi_openipmi_send_cmd, ++ .set_my_addr = ipmi_openipmi_set_my_addr, ++ .my_addr = IPMI_BMC_SLAVE_ADDR, ++ .target_addr = 0, /* init so -m local_addr does not cause bridging */ + }; +diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c +index 871593f..d81fe8e 100644 +--- a/src/plugins/serial/serial_basic.c ++++ b/src/plugins/serial/serial_basic.c +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _GNU_SOURCE 1 + + /* Serial Interface, Basic Mode plugin. */ + +@@ -1014,11 +1015,11 @@ serial_bm_set_my_addr(struct ipmi_intf * intf, uint8_t addr) + * Serial BM interface + */ + struct ipmi_intf ipmi_serial_bm_intf = { +- name: "serial-basic", +- desc: "Serial Interface, Basic Mode", +- setup: serial_bm_setup, +- open: serial_bm_open, +- close: serial_bm_close, +- sendrecv: serial_bm_send_request, +- set_my_addr:serial_bm_set_my_addr ++ .name = "serial-basic", ++ .desc = "Serial Interface, Basic Mode", ++ .setup = serial_bm_setup, ++ .open = serial_bm_open, ++ .close = serial_bm_close, ++ .sendrecv = serial_bm_send_request, ++ .set_my_addr = serial_bm_set_my_addr + }; +diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c +index 34c6fc5..a49738d 100644 +--- a/src/plugins/serial/serial_terminal.c ++++ b/src/plugins/serial/serial_terminal.c +@@ -29,6 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ ++#define _GNU_SOURCE 1 + + /* Serial Interface, Terminal Mode plugin. */ + +@@ -904,11 +905,11 @@ ipmi_serial_term_set_my_addr(struct ipmi_intf * intf, uint8_t addr) + } + + struct ipmi_intf ipmi_serial_term_intf = { +- name: "serial-terminal", +- desc: "Serial Interface, Terminal Mode", +- setup: ipmi_serial_term_setup, +- open: ipmi_serial_term_open, +- close: ipmi_serial_term_close, +- sendrecv: ipmi_serial_term_send_cmd, +- set_my_addr:ipmi_serial_term_set_my_addr ++ .name = "serial-terminal", ++ .desc = "Serial Interface, Terminal Mode", ++ .setup = ipmi_serial_term_setup, ++ .open = ipmi_serial_term_open, ++ .close = ipmi_serial_term_close, ++ .sendrecv = ipmi_serial_term_send_cmd, ++ .set_my_addr = ipmi_serial_term_set_my_addr + }; diff --git a/ipmitool.changes b/ipmitool.changes index 1454aa8..7eee2d0 100644 --- a/ipmitool.changes +++ b/ipmitool.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Jan 15 13:56:40 UTC 2015 - trenn@suse.de + +- Update to latest ipmitool sources. + This is version 1.8.15 (git tag: IPMITOOL_1_8_15) plus mainline patches up + to commit 708be8bc450f907cddb6d9e4b83aee6ba67b7d04 + Date: Fri Jan 9 12:48:35 2015 +0100 + ------------------------------------------------------------------- Thu Mar 6 11:50:59 UTC 2014 - trenn@suse.de diff --git a/ipmitool.spec b/ipmitool.spec index 8c5f79e..c7340f0 100644 --- a/ipmitool.spec +++ b/ipmitool.spec @@ -27,19 +27,20 @@ Url: http://ipmitool.sourceforge.net/ Summary: Utility for IPMI Control License: BSD-3-Clause Group: System/Management -Version: 1.8.13 +Version: 1.8.15 Release: 0 Source: http://heanet.dl.sourceforge.net/sourceforge/%{name}/%{name}-%{version}.tar.bz2 Source1: ipmievd.service Source2: ipmievd.sysconf -Patch1: ipmitool-1.8.10-implicit-fortify-decl.patch +Patch1: ipmitool-1_8_15_HEAD.patch Patch3: fwum_enhance_output.patch -Patch4: sdradd_close_file_handle.patch Patch6: fix_file_permissions.patch Patch8: several_more_compile_fixes.patch Patch9: automake-1.13.patch Patch10: ipmitool_adjust_suse.paths Patch11: 0001-Incorporate-upstream-comments-to-289-add-whitespace.patch +Patch12: ipmitool-1.8.10-implicit-fortify-decl.patch +Patch13: latest_compile_fixes.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build # bmc-snmp-proxy needs /usr/sbin/snmpd Requires: net-snmp @@ -66,14 +67,15 @@ and setting LAN configuration, and chassis power control. %prep %setup -q -%patch1 -p0 +%patch1 -p1 %patch3 -p1 -%patch4 -p1 %patch6 -p1 %patch8 -p1 %patch9 -p1 %patch10 -p1 %patch11 -p1 +%patch12 -p0 +%patch13 -p1 %build touch INSTALL NEWS diff --git a/latest_compile_fixes.patch b/latest_compile_fixes.patch new file mode 100644 index 0000000..99f2bb1 --- /dev/null +++ b/latest_compile_fixes.patch @@ -0,0 +1,175 @@ +Fix compile issues + +Use _XOPEN_SOURCE 500 in ipmi_main to get getpass defined. +from manpage: +getpass(): + Since glibc 2.2.2: + _BSD_SOURCE || + (_XOPEN_SOURCE >= 500 || + _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && + !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) + +and more compiler warning fixing stuff... + +Signed-off-by: Thomas Renninger + +Index: ipmitool-1.8.15/lib/ipmi_chassis.c +=================================================================== +--- ipmitool-1.8.15.orig/lib/ipmi_chassis.c 2015-01-14 16:28:54.020808802 +0100 ++++ ipmitool-1.8.15/lib/ipmi_chassis.c 2015-01-15 10:16:29.193827184 +0100 +@@ -30,6 +30,7 @@ + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + ++#include + #include + #include + #include +Index: ipmitool-1.8.15/lib/ipmi_main.c +=================================================================== +--- ipmitool-1.8.15.orig/lib/ipmi_main.c 2015-01-14 14:44:12.916708941 +0100 ++++ ipmitool-1.8.15/lib/ipmi_main.c 2015-01-15 10:17:02.977827721 +0100 +@@ -29,7 +29,7 @@ + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ +-#define _XOPEN_SOURCE 700 ++#define _XOPEN_SOURCE 500 + + #include + #include +Index: ipmitool-1.8.15/lib/ipmi_sel.c +=================================================================== +--- ipmitool-1.8.15.orig/lib/ipmi_sel.c 2015-01-14 14:44:12.916708941 +0100 ++++ ipmitool-1.8.15/lib/ipmi_sel.c 2015-01-15 10:25:03.161835356 +0100 +@@ -2391,18 +2391,18 @@ + evt.sel_type.standard_type.timestamp; + + /* skip timestamp */ +- cursor = index((const char *)cursor, ';'); ++ cursor = strchr((const char *)cursor, ';'); + cursor++; + + /* FIXME: parse originator */ + evt.sel_type.standard_type.gen_id = 0x0020; + + /* skip originator info */ +- cursor = index((const char *)cursor, ';'); ++ cursor = strchr((const char *)cursor, ';'); + cursor++; + + /* Get sensor type */ +- cursor = index((const char *)cursor, '('); ++ cursor = strchr((const char *)cursor, '('); + cursor++; + + errno = 0; +@@ -2413,7 +2413,7 @@ + status = (-1); + break; + } +- cursor = index((const char *)cursor, ','); ++ cursor = strchr((const char *)cursor, ','); + cursor++; + + errno = 0; +@@ -2426,7 +2426,7 @@ + } + + /* skip to event type info */ +- cursor = index((const char *)cursor, ':'); ++ cursor = strchr((const char *)cursor, ':'); + cursor++; + + errno = 0; +@@ -2439,7 +2439,7 @@ + } + + /* skip to event dir info */ +- cursor = index((const char *)cursor, '('); ++ cursor = strchr((const char *)cursor, '('); + cursor++; + if (*cursor == 'a') { + evt.sel_type.standard_type.event_dir = 0; +@@ -2447,7 +2447,7 @@ + evt.sel_type.standard_type.event_dir = 1; + } + /* skip to data info */ +- cursor = index((const char *)cursor, ' '); ++ cursor = strchr((const char *)cursor, ' '); + cursor++; + + if (evt.sel_type.standard_type.sensor_type == 0xF0) { +@@ -2466,7 +2466,7 @@ + } + + /* Get to previous state */ +- cursor = index((const char *)cursor, 'M'); ++ cursor = strchr((const char *)cursor, 'M'); + cursor++; + + /* Set previous state */ +@@ -2480,7 +2480,7 @@ + } + + /* Get to current state */ +- cursor = index((const char *)cursor, 'M'); ++ cursor = strchr((const char *)cursor, 'M'); + cursor++; + + /* Set current state */ +@@ -2494,7 +2494,7 @@ + } + + /* skip to cause */ +- cursor = index((const char *)cursor, '='); ++ cursor = strchr((const char *)cursor, '='); + cursor++; + errno = 0; + evt.sel_type.standard_type.event_data[1] |= +@@ -2513,7 +2513,7 @@ + status = (-1); + break; + } +- cursor = index((const char *)cursor, ' '); ++ cursor = strchr((const char *)cursor, ' '); + cursor++; + + errno = 0; +@@ -2525,7 +2525,7 @@ + break; + } + +- cursor = index((const char *)cursor, ' '); ++ cursor = strchr((const char *)cursor, ' '); + cursor++; + + errno = 0; +Index: ipmitool-1.8.15/src/ipmishell.c +=================================================================== +--- ipmitool-1.8.15.orig/src/ipmishell.c 2015-01-14 14:44:12.924708941 +0100 ++++ ipmitool-1.8.15/src/ipmishell.c 2015-01-15 10:27:18.445837506 +0100 +@@ -30,6 +30,9 @@ + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + ++/* strdup needs this */ ++#define _XOPEN_SOURCE 500 ++ + #include + #include + #include +Index: ipmitool-1.8.15/lib/log.c +=================================================================== +--- ipmitool-1.8.15.orig/lib/log.c 2015-01-14 15:37:57.444760206 +0100 ++++ ipmitool-1.8.15/lib/log.c 2015-01-15 10:28:25.441838572 +0100 +@@ -30,6 +30,9 @@ + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + ++/* strdup needs this */ ++#define _XOPEN_SOURCE 500 ++ + #include + #include + #include diff --git a/several_more_compile_fixes.patch b/several_more_compile_fixes.patch index 7cdf567..96f87ef 100644 --- a/several_more_compile_fixes.patch +++ b/several_more_compile_fixes.patch @@ -1,47 +1,53 @@ -Index: ipmitool-1.8.13/lib/ipmi_ekanalyzer.c +Cleanup and compiler issues only, no functional change + +Changes partly very old and not possible to find the original author. + +Signed-off-by: Thomas Renninger + +Index: ipmitool-1.8.15/lib/ipmi_ekanalyzer.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_ekanalyzer.c -+++ ipmitool-1.8.13/lib/ipmi_ekanalyzer.c -@@ -397,7 +397,6 @@ ipmi_ekanalyzer_usage( void ) +--- ipmitool-1.8.15.orig/lib/ipmi_ekanalyzer.c 2015-01-14 14:27:59.116693459 +0100 ++++ ipmitool-1.8.15/lib/ipmi_ekanalyzer.c 2015-01-14 14:28:08.504693609 +0100 +@@ -399,7 +399,6 @@ static int - ipmi_ek_get_file_type( char * argument ) + ipmi_ek_get_file_type(char *argument) { -- int index_name=0; - int filetype = ERROR_STATUS; - - if( strlen (argument) > MIN_ARGUMENT ){ -@@ -3383,7 +3382,7 @@ ipmi_ek_display_board_p2p_record( struct - offset += sizeof(struct fru_picmgext_guid); - } - -- for ( offset; -+ for ( ; - offset < record->header.len; - offset += sizeof(struct fru_picmgext_link_desc) - ) { -@@ -3552,7 +3551,7 @@ ipmi_ek_display_radial_ipmb0_record( str - - printf(" IPMB-0 Hub Descriptor Count: 0x%02x", record->data[offset++]); - if (record->data[offset] > 0){ -- for (offset; offset < record->header.len;){ -+ for (; offset < record->header.len;){ - unsigned char entry_count = 0; - printf(" IPMB-0 Hub Descriptor\n"); - printf("\tHardware Address: 0x%02x\n", record->data[offset++]); -@@ -3995,7 +3994,7 @@ ipmi_ek_display_clock_config_record( str - (feature > 1) & 1, - (feature&1)?"Source":"Receiver"); - printf("\tFamily: 0x%02x - AccLVL: 0x%02x\n", family, accuracy); -- printf("\tFRQ: %-9ld - min: %-9ld - max: %-9ld\n", -+ printf("\tFRQ: %-9lu - min: %-9ld - max: %-9ld\n", - freq, min_freq, max_freq); - } - printf("\n"); -Index: ipmitool-1.8.13/lib/ipmi_fwum.c +- int index_name=0; + int filetype = ERROR_STATUS; + if (strlen(argument) <= MIN_ARGUMENT) { + return filetype; +@@ -3366,7 +3365,7 @@ + printf("\n"); + offset += sizeof(struct fru_picmgext_guid); + } +- for (offset; ++ for (; + offset < record->header.len; + offset += sizeof(struct fru_picmgext_link_desc)) { + /* to solve little endian/big endian problem */ +@@ -3525,7 +3524,7 @@ + if (record->data[offset] < 1) { + return; + } +- for (offset; offset < record->header.len;) { ++ for (; offset < record->header.len;) { + unsigned char entry_count = 0; + printf(" IPMB-0 Hub Descriptor\n"); + printf("\tHardware Address: 0x%02x\n", +@@ -3983,7 +3982,7 @@ + (feature & 1) ? "Source" : "Receiver"); + printf("\tFamily: 0x%02x - AccLVL: 0x%02x\n", + family, accuracy); +- printf("\tFRQ: %-9ld - min: %-9ld - max: %-9ld\n", ++ printf("\tFRQ: %-9lu - min: %-9lu - max: %-9lu\n", + freq, min_freq, max_freq); + } + printf("\n"); +Index: ipmitool-1.8.15/lib/ipmi_fwum.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_fwum.c -+++ ipmitool-1.8.13/lib/ipmi_fwum.c -@@ -861,7 +861,6 @@ KfwumUploadFirmware(struct ipmi_intf *in +--- ipmitool-1.8.15.orig/lib/ipmi_fwum.c 2015-01-14 14:27:59.116693459 +0100 ++++ ipmitool-1.8.15/lib/ipmi_fwum.c 2015-01-14 14:28:08.504693609 +0100 +@@ -858,7 +858,6 @@ unsigned long lastAddress = 0; unsigned char sequenceNumber = 0; unsigned char retry = FWUM_MAX_UPLOAD_RETRY; @@ -49,11 +55,11 @@ Index: ipmitool-1.8.13/lib/ipmi_fwum.c do { writeSize = save_fw_nfo.bufferSize - save_fw_nfo.overheadSize; /* Reach the end */ -Index: ipmitool-1.8.13/lib/ipmi_isol.c +Index: ipmitool-1.8.15/lib/ipmi_isol.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_isol.c -+++ ipmitool-1.8.13/lib/ipmi_isol.c -@@ -413,7 +413,6 @@ ipmi_isol_deactivate(struct ipmi_intf * +--- ipmitool-1.8.15.orig/lib/ipmi_isol.c 2015-01-14 14:27:59.116693459 +0100 ++++ ipmitool-1.8.15/lib/ipmi_isol.c 2015-01-14 14:28:08.504693609 +0100 +@@ -413,7 +413,6 @@ struct ipmi_rs * rsp; struct ipmi_rq req; uint8_t data[6]; @@ -61,11 +67,11 @@ Index: ipmitool-1.8.13/lib/ipmi_isol.c memset(&req, 0, sizeof(req)); req.msg.netfn = IPMI_NETFN_ISOL; -Index: ipmitool-1.8.13/lib/ipmi_picmg.c +Index: ipmitool-1.8.15/lib/ipmi_picmg.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_picmg.c -+++ ipmitool-1.8.13/lib/ipmi_picmg.c -@@ -878,7 +878,7 @@ ipmi_picmg_portstate_get(struct ipmi_int +--- ipmitool-1.8.15.orig/lib/ipmi_picmg.c 2015-01-14 14:25:17.556690891 +0100 ++++ ipmitool-1.8.15/lib/ipmi_picmg.c 2015-01-14 14:28:08.504693609 +0100 +@@ -878,7 +878,7 @@ } else if (d->type >= 0x06 && d->type <= 0xef) { @@ -74,7 +80,7 @@ Index: ipmitool-1.8.13/lib/ipmi_picmg.c } else if (d->type >= 0xf0 && d->type <= 0xfe) { -@@ -1690,7 +1690,7 @@ ipmi_picmg_clk_get(struct ipmi_intf * in +@@ -1690,7 +1690,7 @@ oemval2str( rsp->data[3], rsp->data[4], picmg_clk_accuracy_vals)); @@ -83,20 +89,11 @@ Index: ipmitool-1.8.13/lib/ipmi_picmg.c } } } -@@ -1751,7 +1751,7 @@ printf("## index: %d\n", msg_data[2]); - printf("## setting: 0x%02x\n", msg_data[3]); - printf("## family: %d\n", msg_data[4]); - printf("## acc: %d\n", msg_data[5]); --printf("## freq: %ld\n", freq ); -+printf("## freq: %lu\n", freq ); - printf("## res: %d\n", msg_data[10]); - #endif - -Index: ipmitool-1.8.13/lib/ipmi_sdradd.c +Index: ipmitool-1.8.15/lib/ipmi_sdradd.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_sdradd.c -+++ ipmitool-1.8.13/lib/ipmi_sdradd.c -@@ -576,7 +576,6 @@ ipmi_sdr_add_from_list(struct ipmi_intf +--- ipmitool-1.8.15.orig/lib/ipmi_sdradd.c 2015-01-14 14:27:59.120693459 +0100 ++++ ipmitool-1.8.15/lib/ipmi_sdradd.c 2015-01-14 14:28:08.504693609 +0100 +@@ -575,7 +575,6 @@ static int ipmi_sdr_read_records(const char *filename, struct sdrr_queue *queue) { @@ -104,10 +101,10 @@ Index: ipmitool-1.8.13/lib/ipmi_sdradd.c int rc = 0; int fd; uint8_t binHdr[5]; -Index: ipmitool-1.8.13/lib/ipmi_sdr.c +Index: ipmitool-1.8.15/lib/ipmi_sdr.c =================================================================== ---- ipmitool-1.8.13.orig/lib/ipmi_sdr.c -+++ ipmitool-1.8.13/lib/ipmi_sdr.c +--- ipmitool-1.8.15.orig/lib/ipmi_sdr.c 2015-01-14 14:27:59.120693459 +0100 ++++ ipmitool-1.8.15/lib/ipmi_sdr.c 2015-01-14 14:28:08.508693609 +0100 @@ -52,6 +52,7 @@ #include #include