1c18ec02fSPetter Reinholdtsen /* -*-mode: C; indent-tabs-mode: t; -*- 2c18ec02fSPetter Reinholdtsen * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 3c18ec02fSPetter Reinholdtsen * 4c18ec02fSPetter Reinholdtsen * Redistribution and use in source and binary forms, with or without 5c18ec02fSPetter Reinholdtsen * modification, are permitted provided that the following conditions 6c18ec02fSPetter Reinholdtsen * are met: 7c18ec02fSPetter Reinholdtsen * 8c18ec02fSPetter Reinholdtsen * Redistribution of source code must retain the above copyright 9c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer. 10c18ec02fSPetter Reinholdtsen * 11c18ec02fSPetter Reinholdtsen * Redistribution in binary form must reproduce the above copyright 12c18ec02fSPetter Reinholdtsen * notice, this list of conditions and the following disclaimer in the 13c18ec02fSPetter Reinholdtsen * documentation and/or other materials provided with the distribution. 14c18ec02fSPetter Reinholdtsen * 15c18ec02fSPetter Reinholdtsen * Neither the name of Sun Microsystems, Inc. or the names of 16c18ec02fSPetter Reinholdtsen * contributors may be used to endorse or promote products derived 17c18ec02fSPetter Reinholdtsen * from this software without specific prior written permission. 18c18ec02fSPetter Reinholdtsen * 19c18ec02fSPetter Reinholdtsen * This software is provided "AS IS," without a warranty of any kind. 20c18ec02fSPetter Reinholdtsen * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 21c18ec02fSPetter Reinholdtsen * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 22c18ec02fSPetter Reinholdtsen * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 23c18ec02fSPetter Reinholdtsen * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 24c18ec02fSPetter Reinholdtsen * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 25c18ec02fSPetter Reinholdtsen * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 26c18ec02fSPetter Reinholdtsen * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 27c18ec02fSPetter Reinholdtsen * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 28c18ec02fSPetter Reinholdtsen * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 29c18ec02fSPetter Reinholdtsen * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 30c18ec02fSPetter Reinholdtsen * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31c18ec02fSPetter Reinholdtsen */ 32c18ec02fSPetter Reinholdtsen 33c18ec02fSPetter Reinholdtsen #include <stdlib.h> 34c18ec02fSPetter Reinholdtsen #include <stdio.h> 35c18ec02fSPetter Reinholdtsen #include <string.h> 36c18ec02fSPetter Reinholdtsen #include <strings.h> 37c18ec02fSPetter Reinholdtsen #include <sys/types.h> 38c18ec02fSPetter Reinholdtsen #include <sys/socket.h> 39c18ec02fSPetter Reinholdtsen #include <netinet/in.h> 40c18ec02fSPetter Reinholdtsen #include <arpa/inet.h> 41c18ec02fSPetter Reinholdtsen #include <errno.h> 42c18ec02fSPetter Reinholdtsen #include <unistd.h> 43c18ec02fSPetter Reinholdtsen #include <signal.h> 44c18ec02fSPetter Reinholdtsen 45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h> 46c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h> 47c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h> 48c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h> 49c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_lanp.h> 50c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_channel.h> 51c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h> 52c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_constants.h> 53e4be291cSZdenek Styblik #include <ipmitool/ipmi_user.h> 54c18ec02fSPetter Reinholdtsen 55c18ec02fSPetter Reinholdtsen extern int csv_output; 56c18ec02fSPetter Reinholdtsen extern int verbose; 57c18ec02fSPetter Reinholdtsen 58c18ec02fSPetter Reinholdtsen void printf_channel_usage (void); 59c18ec02fSPetter Reinholdtsen 60c18ec02fSPetter Reinholdtsen /** 61c18ec02fSPetter Reinholdtsen * ipmi_1_5_authtypes 62c18ec02fSPetter Reinholdtsen * 63c18ec02fSPetter Reinholdtsen * Create a string describing the supported authentication types as 64c18ec02fSPetter Reinholdtsen * specificed by the parameter n 65c18ec02fSPetter Reinholdtsen */ 66c18ec02fSPetter Reinholdtsen static const char * 67c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(uint8_t n) 68c18ec02fSPetter Reinholdtsen { 69c18ec02fSPetter Reinholdtsen uint32_t i; 70c18ec02fSPetter Reinholdtsen static char supportedTypes[128]; 71c18ec02fSPetter Reinholdtsen 720a1f5c03SZdenek Styblik memset(supportedTypes, 0, sizeof(supportedTypes)); 73c18ec02fSPetter Reinholdtsen for (i = 0; ipmi_authtype_vals[i].val != 0; i++) { 74c18ec02fSPetter Reinholdtsen if (n & ipmi_authtype_vals[i].val) { 75c18ec02fSPetter Reinholdtsen strcat(supportedTypes, ipmi_authtype_vals[i].str); 76c18ec02fSPetter Reinholdtsen strcat(supportedTypes, " "); 77c18ec02fSPetter Reinholdtsen } 78c18ec02fSPetter Reinholdtsen } 79c18ec02fSPetter Reinholdtsen 80c18ec02fSPetter Reinholdtsen return supportedTypes; 81c18ec02fSPetter Reinholdtsen } 82c18ec02fSPetter Reinholdtsen 83c18ec02fSPetter Reinholdtsen 84c18ec02fSPetter Reinholdtsen 85c18ec02fSPetter Reinholdtsen /** 86c18ec02fSPetter Reinholdtsen * ipmi_get_channel_auth_cap 87c18ec02fSPetter Reinholdtsen * 88c18ec02fSPetter Reinholdtsen * return 0 on success 89c18ec02fSPetter Reinholdtsen * -1 on failure 90c18ec02fSPetter Reinholdtsen */ 91c18ec02fSPetter Reinholdtsen int 92a87b2cccSZdenek Styblik ipmi_get_channel_auth_cap(struct ipmi_intf *intf, uint8_t channel, uint8_t priv) 93c18ec02fSPetter Reinholdtsen { 94c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 95c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 96c18ec02fSPetter Reinholdtsen struct get_channel_auth_cap_rsp auth_cap; 97c18ec02fSPetter Reinholdtsen uint8_t msg_data[2]; 98c18ec02fSPetter Reinholdtsen 99a87b2cccSZdenek Styblik /* Ask for IPMI v2 data as well */ 100a87b2cccSZdenek Styblik msg_data[0] = channel | 0x80; 101c18ec02fSPetter Reinholdtsen msg_data[1] = priv; 102c18ec02fSPetter Reinholdtsen 103c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 104a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 105a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_AUTH_CAP; 106c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 107c18ec02fSPetter Reinholdtsen req.msg.data_len = 2; 108c18ec02fSPetter Reinholdtsen 109c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 110c18ec02fSPetter Reinholdtsen 111c18ec02fSPetter Reinholdtsen if ((rsp == NULL) || (rsp->ccode > 0)) { 112c18ec02fSPetter Reinholdtsen /* 113c18ec02fSPetter Reinholdtsen * It's very possible that this failed because we asked for IPMI v2 data 114c18ec02fSPetter Reinholdtsen * Ask again, without requesting IPMI v2 data 115c18ec02fSPetter Reinholdtsen */ 116c18ec02fSPetter Reinholdtsen msg_data[0] &= 0x7F; 117c18ec02fSPetter Reinholdtsen 118c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 119c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 120c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Authentication Capabilities"); 121a87b2cccSZdenek Styblik return (-1); 122c18ec02fSPetter Reinholdtsen } 123c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 124c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Authentication Capabilities failed: %s", 125c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 126a87b2cccSZdenek Styblik return (-1); 127c18ec02fSPetter Reinholdtsen } 128c18ec02fSPetter Reinholdtsen } 129c18ec02fSPetter Reinholdtsen 130c18ec02fSPetter Reinholdtsen memcpy(&auth_cap, rsp->data, sizeof(struct get_channel_auth_cap_rsp)); 131c18ec02fSPetter Reinholdtsen 132c18ec02fSPetter Reinholdtsen printf("Channel number : %d\n", 133c18ec02fSPetter Reinholdtsen auth_cap.channel_number); 134c18ec02fSPetter Reinholdtsen printf("IPMI v1.5 auth types : %s\n", 135c18ec02fSPetter Reinholdtsen ipmi_1_5_authtypes(auth_cap.enabled_auth_types)); 136c18ec02fSPetter Reinholdtsen 137a87b2cccSZdenek Styblik if (auth_cap.v20_data_available) { 138c18ec02fSPetter Reinholdtsen printf("KG status : %s\n", 139c18ec02fSPetter Reinholdtsen (auth_cap.kg_status) ? "non-zero" : "default (all zeroes)"); 140a87b2cccSZdenek Styblik } 141c18ec02fSPetter Reinholdtsen 142c18ec02fSPetter Reinholdtsen printf("Per message authentication : %sabled\n", 143c18ec02fSPetter Reinholdtsen (auth_cap.per_message_auth) ? "dis" : "en"); 144c18ec02fSPetter Reinholdtsen printf("User level authentication : %sabled\n", 145c18ec02fSPetter Reinholdtsen (auth_cap.user_level_auth) ? "dis" : "en"); 146c18ec02fSPetter Reinholdtsen 147c18ec02fSPetter Reinholdtsen printf("Non-null user names exist : %s\n", 148c18ec02fSPetter Reinholdtsen (auth_cap.non_null_usernames) ? "yes" : "no"); 149c18ec02fSPetter Reinholdtsen printf("Null user names exist : %s\n", 150c18ec02fSPetter Reinholdtsen (auth_cap.null_usernames) ? "yes" : "no"); 151c18ec02fSPetter Reinholdtsen printf("Anonymous login enabled : %s\n", 152c18ec02fSPetter Reinholdtsen (auth_cap.anon_login_enabled) ? "yes" : "no"); 153c18ec02fSPetter Reinholdtsen 154c18ec02fSPetter Reinholdtsen if (auth_cap.v20_data_available) { 155c18ec02fSPetter Reinholdtsen printf("Channel supports IPMI v1.5 : %s\n", 156c18ec02fSPetter Reinholdtsen (auth_cap.ipmiv15_support) ? "yes" : "no"); 157c18ec02fSPetter Reinholdtsen printf("Channel supports IPMI v2.0 : %s\n", 158c18ec02fSPetter Reinholdtsen (auth_cap.ipmiv20_support) ? "yes" : "no"); 159c18ec02fSPetter Reinholdtsen } 160c18ec02fSPetter Reinholdtsen 161c18ec02fSPetter Reinholdtsen /* 162c18ec02fSPetter Reinholdtsen * If there is support for an OEM authentication type, there is some 163c18ec02fSPetter Reinholdtsen * information. 164c18ec02fSPetter Reinholdtsen */ 165c18ec02fSPetter Reinholdtsen if (auth_cap.enabled_auth_types & IPMI_1_5_AUTH_TYPE_BIT_OEM) { 166c18ec02fSPetter Reinholdtsen printf("IANA Number for OEM : %d\n", 167c18ec02fSPetter Reinholdtsen auth_cap.oem_id[0] | 168c18ec02fSPetter Reinholdtsen auth_cap.oem_id[1] << 8 | 169c18ec02fSPetter Reinholdtsen auth_cap.oem_id[2] << 16); 170c18ec02fSPetter Reinholdtsen printf("OEM Auxiliary Data : 0x%x\n", 171c18ec02fSPetter Reinholdtsen auth_cap.oem_aux_data); 172c18ec02fSPetter Reinholdtsen } 173c18ec02fSPetter Reinholdtsen 174c18ec02fSPetter Reinholdtsen return 0; 175c18ec02fSPetter Reinholdtsen } 176c18ec02fSPetter Reinholdtsen 177c18ec02fSPetter Reinholdtsen 178c18ec02fSPetter Reinholdtsen 179c18ec02fSPetter Reinholdtsen /** 180c18ec02fSPetter Reinholdtsen * ipmi_get_channel_info 181c18ec02fSPetter Reinholdtsen * 182c18ec02fSPetter Reinholdtsen * returns 0 on success 183c18ec02fSPetter Reinholdtsen * -1 on failure 184c18ec02fSPetter Reinholdtsen * 185c18ec02fSPetter Reinholdtsen */ 186c18ec02fSPetter Reinholdtsen int 187c18ec02fSPetter Reinholdtsen ipmi_get_channel_info(struct ipmi_intf *intf, uint8_t channel) 188c18ec02fSPetter Reinholdtsen { 189c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 190c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 191c18ec02fSPetter Reinholdtsen uint8_t rqdata[2]; 192c18ec02fSPetter Reinholdtsen uint8_t medium; 193c18ec02fSPetter Reinholdtsen struct get_channel_info_rsp channel_info; 194c18ec02fSPetter Reinholdtsen struct get_channel_access_rsp channel_access; 195c18ec02fSPetter Reinholdtsen 196c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 197a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 198a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_INFO; 199c18ec02fSPetter Reinholdtsen req.msg.data = &channel; 200c18ec02fSPetter Reinholdtsen req.msg.data_len = 1; 201c18ec02fSPetter Reinholdtsen 202c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 203c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 204c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Info"); 205c18ec02fSPetter Reinholdtsen return -1; 206c18ec02fSPetter Reinholdtsen } 207c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 208c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Info failed: %s", 209c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 210c18ec02fSPetter Reinholdtsen return -1; 211c18ec02fSPetter Reinholdtsen } 212c18ec02fSPetter Reinholdtsen 213c18ec02fSPetter Reinholdtsen memcpy(&channel_info, rsp->data, sizeof(struct get_channel_info_rsp)); 214c18ec02fSPetter Reinholdtsen 215c18ec02fSPetter Reinholdtsen printf("Channel 0x%x info:\n", channel_info.channel_number); 216c18ec02fSPetter Reinholdtsen 217c18ec02fSPetter Reinholdtsen printf(" Channel Medium Type : %s\n", 218c18ec02fSPetter Reinholdtsen val2str(channel_info.channel_medium, ipmi_channel_medium_vals)); 219c18ec02fSPetter Reinholdtsen 220c18ec02fSPetter Reinholdtsen printf(" Channel Protocol Type : %s\n", 221c18ec02fSPetter Reinholdtsen val2str(channel_info.channel_protocol, ipmi_channel_protocol_vals)); 222c18ec02fSPetter Reinholdtsen 223c18ec02fSPetter Reinholdtsen printf(" Session Support : "); 224c18ec02fSPetter Reinholdtsen switch (channel_info.session_support) { 225c18ec02fSPetter Reinholdtsen case 0x0: 226c18ec02fSPetter Reinholdtsen printf("session-less\n"); 227c18ec02fSPetter Reinholdtsen break; 228c18ec02fSPetter Reinholdtsen case 0x1: 229c18ec02fSPetter Reinholdtsen printf("single-session\n"); 230c18ec02fSPetter Reinholdtsen break; 231c18ec02fSPetter Reinholdtsen case 0x2: 232c18ec02fSPetter Reinholdtsen printf("multi-session\n"); 233c18ec02fSPetter Reinholdtsen break; 234c18ec02fSPetter Reinholdtsen case 0x3: 235c18ec02fSPetter Reinholdtsen default: 236c18ec02fSPetter Reinholdtsen printf("session-based\n"); 237c18ec02fSPetter Reinholdtsen break; 238c18ec02fSPetter Reinholdtsen } 239c18ec02fSPetter Reinholdtsen 240c18ec02fSPetter Reinholdtsen printf(" Active Session Count : %d\n", 241c18ec02fSPetter Reinholdtsen channel_info.active_sessions); 242c18ec02fSPetter Reinholdtsen 243c18ec02fSPetter Reinholdtsen printf(" Protocol Vendor ID : %d\n", 244c18ec02fSPetter Reinholdtsen channel_info.vendor_id[0] | 245c18ec02fSPetter Reinholdtsen channel_info.vendor_id[1] << 8 | 246c18ec02fSPetter Reinholdtsen channel_info.vendor_id[2] << 16); 247c18ec02fSPetter Reinholdtsen 248c18ec02fSPetter Reinholdtsen 249c18ec02fSPetter Reinholdtsen /* only proceed if this is LAN channel */ 250c18ec02fSPetter Reinholdtsen medium = ipmi_get_channel_medium(intf, channel); 251c18ec02fSPetter Reinholdtsen if (medium != IPMI_CHANNEL_MEDIUM_LAN && 252c18ec02fSPetter Reinholdtsen medium != IPMI_CHANNEL_MEDIUM_LAN_OTHER) { 253c18ec02fSPetter Reinholdtsen return 0; 254c18ec02fSPetter Reinholdtsen } 255c18ec02fSPetter Reinholdtsen 256c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 257c18ec02fSPetter Reinholdtsen rqdata[0] = channel & 0xf; 258c18ec02fSPetter Reinholdtsen 259c18ec02fSPetter Reinholdtsen /* get volatile settings */ 260c18ec02fSPetter Reinholdtsen rqdata[1] = 0x80; /* 0x80=active */ 261a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 262a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_ACCESS; 263c18ec02fSPetter Reinholdtsen req.msg.data = rqdata; 264c18ec02fSPetter Reinholdtsen req.msg.data_len = 2; 265c18ec02fSPetter Reinholdtsen 266c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 267c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 268c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Access (volatile)"); 269c18ec02fSPetter Reinholdtsen return -1; 270c18ec02fSPetter Reinholdtsen } 271c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 272c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Access (volatile) failed: %s", 273c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 274c18ec02fSPetter Reinholdtsen return -1; 275c18ec02fSPetter Reinholdtsen } 276c18ec02fSPetter Reinholdtsen 277c18ec02fSPetter Reinholdtsen memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp)); 278c18ec02fSPetter Reinholdtsen 279c18ec02fSPetter Reinholdtsen 280c18ec02fSPetter Reinholdtsen printf(" Volatile(active) Settings\n"); 281c18ec02fSPetter Reinholdtsen printf(" Alerting : %sabled\n", 282c18ec02fSPetter Reinholdtsen (channel_access.alerting) ? "dis" : "en"); 283c18ec02fSPetter Reinholdtsen printf(" Per-message Auth : %sabled\n", 284c18ec02fSPetter Reinholdtsen (channel_access.per_message_auth) ? "dis" : "en"); 285c18ec02fSPetter Reinholdtsen printf(" User Level Auth : %sabled\n", 286c18ec02fSPetter Reinholdtsen (channel_access.user_level_auth) ? "dis" : "en"); 287c18ec02fSPetter Reinholdtsen 288c18ec02fSPetter Reinholdtsen printf(" Access Mode : "); 289c18ec02fSPetter Reinholdtsen switch (channel_access.access_mode) { 290c18ec02fSPetter Reinholdtsen case 0: 291c18ec02fSPetter Reinholdtsen printf("disabled\n"); 292c18ec02fSPetter Reinholdtsen break; 293c18ec02fSPetter Reinholdtsen case 1: 294c18ec02fSPetter Reinholdtsen printf("pre-boot only\n"); 295c18ec02fSPetter Reinholdtsen break; 296c18ec02fSPetter Reinholdtsen case 2: 297c18ec02fSPetter Reinholdtsen printf("always available\n"); 298c18ec02fSPetter Reinholdtsen break; 299c18ec02fSPetter Reinholdtsen case 3: 300c18ec02fSPetter Reinholdtsen printf("shared\n"); 301c18ec02fSPetter Reinholdtsen break; 302c18ec02fSPetter Reinholdtsen default: 303c18ec02fSPetter Reinholdtsen printf("unknown\n"); 304c18ec02fSPetter Reinholdtsen break; 305c18ec02fSPetter Reinholdtsen } 306c18ec02fSPetter Reinholdtsen 307c18ec02fSPetter Reinholdtsen /* get non-volatile settings */ 308c18ec02fSPetter Reinholdtsen 309c18ec02fSPetter Reinholdtsen rqdata[1] = 0x40; /* 0x40=non-volatile */ 310c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 311c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 312c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Access (non-volatile)"); 313c18ec02fSPetter Reinholdtsen return -1; 314c18ec02fSPetter Reinholdtsen } 315c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 316c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Access (non-volatile) failed: %s", 317c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 318c18ec02fSPetter Reinholdtsen return -1; 319c18ec02fSPetter Reinholdtsen } 320c18ec02fSPetter Reinholdtsen 321c18ec02fSPetter Reinholdtsen memcpy(&channel_access, rsp->data, sizeof(struct get_channel_access_rsp)); 322c18ec02fSPetter Reinholdtsen 323c18ec02fSPetter Reinholdtsen printf(" Non-Volatile Settings\n"); 324c18ec02fSPetter Reinholdtsen printf(" Alerting : %sabled\n", 325c18ec02fSPetter Reinholdtsen (channel_access.alerting) ? "dis" : "en"); 326c18ec02fSPetter Reinholdtsen printf(" Per-message Auth : %sabled\n", 327c18ec02fSPetter Reinholdtsen (channel_access.per_message_auth) ? "dis" : "en"); 328c18ec02fSPetter Reinholdtsen printf(" User Level Auth : %sabled\n", 329c18ec02fSPetter Reinholdtsen (channel_access.user_level_auth) ? "dis" : "en"); 330c18ec02fSPetter Reinholdtsen 331c18ec02fSPetter Reinholdtsen printf(" Access Mode : "); 332c18ec02fSPetter Reinholdtsen switch (channel_access.access_mode) { 333c18ec02fSPetter Reinholdtsen case 0: 334c18ec02fSPetter Reinholdtsen printf("disabled\n"); 335c18ec02fSPetter Reinholdtsen break; 336c18ec02fSPetter Reinholdtsen case 1: 337c18ec02fSPetter Reinholdtsen printf("pre-boot only\n"); 338c18ec02fSPetter Reinholdtsen break; 339c18ec02fSPetter Reinholdtsen case 2: 340c18ec02fSPetter Reinholdtsen printf("always available\n"); 341c18ec02fSPetter Reinholdtsen break; 342c18ec02fSPetter Reinholdtsen case 3: 343c18ec02fSPetter Reinholdtsen printf("shared\n"); 344c18ec02fSPetter Reinholdtsen break; 345c18ec02fSPetter Reinholdtsen default: 346c18ec02fSPetter Reinholdtsen printf("unknown\n"); 347c18ec02fSPetter Reinholdtsen break; 348c18ec02fSPetter Reinholdtsen } 349c18ec02fSPetter Reinholdtsen 350c18ec02fSPetter Reinholdtsen return 0; 351c18ec02fSPetter Reinholdtsen } 352c18ec02fSPetter Reinholdtsen 353*585cb7c8SZdenek Styblik /* ipmi_get_user_access - Get User Access for given Channel and User or Users. 354*585cb7c8SZdenek Styblik * 355*585cb7c8SZdenek Styblik * @intf - IPMI interface 356*585cb7c8SZdenek Styblik * @channel - IPMI Channel we're getting access for 357*585cb7c8SZdenek Styblik * @userid - User ID. If 0 is passed, all IPMI users will be listed 358*585cb7c8SZdenek Styblik * 359*585cb7c8SZdenek Styblik * returns - 0 on success, (-1) on error 360*585cb7c8SZdenek Styblik */ 361c18ec02fSPetter Reinholdtsen static int 362c18ec02fSPetter Reinholdtsen ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t userid) 363c18ec02fSPetter Reinholdtsen { 364e4be291cSZdenek Styblik struct user_access_t user_access; 365e4be291cSZdenek Styblik struct user_name_t user_name; 366e4be291cSZdenek Styblik int ccode = 0; 367a87b2cccSZdenek Styblik int curr_uid; 368a87b2cccSZdenek Styblik int init = 1; 369e4be291cSZdenek Styblik int max_uid = 0; 370c18ec02fSPetter Reinholdtsen 37148117f5dSZdenek Styblik curr_uid = userid ? userid : 1; 372a87b2cccSZdenek Styblik do { 373e4be291cSZdenek Styblik memset(&user_access, 0, sizeof(user_access)); 374e4be291cSZdenek Styblik user_access.channel = channel; 375e4be291cSZdenek Styblik user_access.user_id = curr_uid; 376e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 377e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 378e4be291cSZdenek Styblik lprintf(LOG_ERR, 379e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 380e4be291cSZdenek Styblik channel, curr_uid); 381e4be291cSZdenek Styblik return (-1); 382c18ec02fSPetter Reinholdtsen } 383c18ec02fSPetter Reinholdtsen 384e4be291cSZdenek Styblik memset(&user_name, 0, sizeof(user_name)); 385e4be291cSZdenek Styblik user_name.user_id = curr_uid; 386e4be291cSZdenek Styblik ccode = _ipmi_get_user_name(intf, &user_name); 387e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 388e4be291cSZdenek Styblik lprintf(LOG_ERR, "Unable to Get User Name (id %d)", curr_uid); 389e4be291cSZdenek Styblik return (-1); 390c18ec02fSPetter Reinholdtsen } 391c18ec02fSPetter Reinholdtsen if (init) { 392c18ec02fSPetter Reinholdtsen printf("Maximum User IDs : %d\n", user_access.max_user_ids); 393c18ec02fSPetter Reinholdtsen printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); 394c18ec02fSPetter Reinholdtsen max_uid = user_access.max_user_ids; 395c18ec02fSPetter Reinholdtsen init = 0; 396c18ec02fSPetter Reinholdtsen } 397c18ec02fSPetter Reinholdtsen 398c18ec02fSPetter Reinholdtsen printf("\n"); 399c18ec02fSPetter Reinholdtsen printf("User ID : %d\n", curr_uid); 400e4be291cSZdenek Styblik printf("User Name : %s\n", user_name.user_name); 401c18ec02fSPetter Reinholdtsen printf("Fixed Name : %s\n", 402c18ec02fSPetter Reinholdtsen (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); 403c18ec02fSPetter Reinholdtsen printf("Access Available : %s\n", 404c18ec02fSPetter Reinholdtsen (user_access.callin_callback) ? "callback" : "call-in / callback"); 405c18ec02fSPetter Reinholdtsen printf("Link Authentication : %sabled\n", 406c18ec02fSPetter Reinholdtsen (user_access.link_auth) ? "en" : "dis"); 407c18ec02fSPetter Reinholdtsen printf("IPMI Messaging : %sabled\n", 408c18ec02fSPetter Reinholdtsen (user_access.ipmi_messaging) ? "en" : "dis"); 409c18ec02fSPetter Reinholdtsen printf("Privilege Level : %s\n", 410c18ec02fSPetter Reinholdtsen val2str(user_access.privilege_limit, ipmi_privlvl_vals)); 411c18ec02fSPetter Reinholdtsen 412c18ec02fSPetter Reinholdtsen curr_uid ++; 413c18ec02fSPetter Reinholdtsen } while (!userid && curr_uid <= max_uid); 414c18ec02fSPetter Reinholdtsen 415c18ec02fSPetter Reinholdtsen return 0; 416c18ec02fSPetter Reinholdtsen } 417c18ec02fSPetter Reinholdtsen 418c18ec02fSPetter Reinholdtsen static const char * 419c18ec02fSPetter Reinholdtsen iana_string(uint32_t iana) 420c18ec02fSPetter Reinholdtsen { 421c18ec02fSPetter Reinholdtsen static char s[10]; 422c18ec02fSPetter Reinholdtsen 423a87b2cccSZdenek Styblik if (iana) { 424c18ec02fSPetter Reinholdtsen sprintf(s, "%06x", iana); 425c18ec02fSPetter Reinholdtsen return s; 426a87b2cccSZdenek Styblik } else { 427c18ec02fSPetter Reinholdtsen return "N/A"; 428c18ec02fSPetter Reinholdtsen } 429a87b2cccSZdenek Styblik } 430c18ec02fSPetter Reinholdtsen 431c18ec02fSPetter Reinholdtsen 432c18ec02fSPetter Reinholdtsen static int 433a87b2cccSZdenek Styblik ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, 434c18ec02fSPetter Reinholdtsen uint8_t channel) 435c18ec02fSPetter Reinholdtsen { 436c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 437c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 438c18ec02fSPetter Reinholdtsen 439c18ec02fSPetter Reinholdtsen uint8_t oem_record; 440c18ec02fSPetter Reinholdtsen uint8_t rqdata[3]; 441c18ec02fSPetter Reinholdtsen uint32_t iana; 442c18ec02fSPetter Reinholdtsen uint8_t auth_alg, integrity_alg, crypt_alg; 443c18ec02fSPetter Reinholdtsen uint8_t cipher_suite_id; 444c18ec02fSPetter Reinholdtsen uint8_t list_index = 0; 445a87b2cccSZdenek Styblik /* 0x40 sets * 16 bytes per set */ 446a87b2cccSZdenek Styblik uint8_t cipher_suite_data[1024]; 447c18ec02fSPetter Reinholdtsen uint16_t offset = 0; 448a87b2cccSZdenek Styblik /* how much was returned, total */ 449a87b2cccSZdenek Styblik uint16_t cipher_suite_data_length = 0; 450c18ec02fSPetter Reinholdtsen 451c18ec02fSPetter Reinholdtsen memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); 452c18ec02fSPetter Reinholdtsen 453c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 454a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 455a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; 456c18ec02fSPetter Reinholdtsen req.msg.data = rqdata; 457c18ec02fSPetter Reinholdtsen req.msg.data_len = 3; 458c18ec02fSPetter Reinholdtsen 459c18ec02fSPetter Reinholdtsen rqdata[0] = channel; 460c18ec02fSPetter Reinholdtsen rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); 461a87b2cccSZdenek Styblik /* Always ask for cipher suite format */ 462a87b2cccSZdenek Styblik rqdata[2] = 0x80; 463c18ec02fSPetter Reinholdtsen 464c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 465c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 466c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 467c18ec02fSPetter Reinholdtsen return -1; 468c18ec02fSPetter Reinholdtsen } 469c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 470c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 471c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 472c18ec02fSPetter Reinholdtsen return -1; 473c18ec02fSPetter Reinholdtsen } 474c18ec02fSPetter Reinholdtsen 475c18ec02fSPetter Reinholdtsen 476a87b2cccSZdenek Styblik /* 477a87b2cccSZdenek Styblik * Grab the returned channel number once. We assume it's the same 478a87b2cccSZdenek Styblik * in future calls. 479a87b2cccSZdenek Styblik */ 480a87b2cccSZdenek Styblik if (rsp->data_len >= 1) { 481c18ec02fSPetter Reinholdtsen channel = rsp->data[0]; 482a87b2cccSZdenek Styblik } 483c18ec02fSPetter Reinholdtsen 484a87b2cccSZdenek Styblik while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { 485a87b2cccSZdenek Styblik /* 486a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 487a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 488a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 489a87b2cccSZdenek Styblik */ 490c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 491c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 492c18ec02fSPetter Reinholdtsen 493a87b2cccSZdenek Styblik /* 494a87b2cccSZdenek Styblik * Increment our list for the next call 495a87b2cccSZdenek Styblik */ 496c18ec02fSPetter Reinholdtsen ++list_index; 497c18ec02fSPetter Reinholdtsen rqdata[2] = (rqdata[2] & 0x80) + list_index; 498c18ec02fSPetter Reinholdtsen 499c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 500c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 501c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 502c18ec02fSPetter Reinholdtsen return -1; 503c18ec02fSPetter Reinholdtsen } 504c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 505c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 506c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 507c18ec02fSPetter Reinholdtsen return -1; 508c18ec02fSPetter Reinholdtsen } 509c18ec02fSPetter Reinholdtsen } 510c18ec02fSPetter Reinholdtsen 511c18ec02fSPetter Reinholdtsen /* Copy last chunk */ 512a87b2cccSZdenek Styblik if(rsp->data_len > 1) { 513a87b2cccSZdenek Styblik /* 514a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 515a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 516a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 517a87b2cccSZdenek Styblik */ 518c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 519c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 520c18ec02fSPetter Reinholdtsen } 521c18ec02fSPetter Reinholdtsen 522a87b2cccSZdenek Styblik /* We can chomp on all our data now. */ 523c18ec02fSPetter Reinholdtsen cipher_suite_data_length = offset; 524c18ec02fSPetter Reinholdtsen offset = 0; 525c18ec02fSPetter Reinholdtsen 526a87b2cccSZdenek Styblik if (! csv_output) { 527c18ec02fSPetter Reinholdtsen printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); 528a87b2cccSZdenek Styblik } 529a87b2cccSZdenek Styblik while (offset < cipher_suite_data_length) { 530a87b2cccSZdenek Styblik if (cipher_suite_data[offset++] == 0xC0) { 531a87b2cccSZdenek Styblik /* standard type */ 532a87b2cccSZdenek Styblik oem_record = 0; 533c18ec02fSPetter Reinholdtsen iana = 0; 534c18ec02fSPetter Reinholdtsen 535a87b2cccSZdenek Styblik /* Verify that we have at least a full record left; id + 3 algs */ 536a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 537a87b2cccSZdenek Styblik lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 538a87b2cccSZdenek Styblik return -1; 539a87b2cccSZdenek Styblik } 540a87b2cccSZdenek Styblik cipher_suite_id = cipher_suite_data[offset++]; 541a87b2cccSZdenek Styblik } else if (cipher_suite_data[offset++] == 0xC1) { 542a87b2cccSZdenek Styblik /* OEM record type */ 543a87b2cccSZdenek Styblik oem_record = 1; 544a87b2cccSZdenek Styblik 545a87b2cccSZdenek Styblik /* Verify that we have at least a full record left 546a87b2cccSZdenek Styblik * id + iana + 3 algs 547a87b2cccSZdenek Styblik */ 548a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 549c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 550c18ec02fSPetter Reinholdtsen return -1; 551c18ec02fSPetter Reinholdtsen } 552c18ec02fSPetter Reinholdtsen 553c18ec02fSPetter Reinholdtsen cipher_suite_id = cipher_suite_data[offset++]; 554c18ec02fSPetter Reinholdtsen 555a87b2cccSZdenek Styblik /* Grab the IANA */ 556c18ec02fSPetter Reinholdtsen iana = 557c18ec02fSPetter Reinholdtsen cipher_suite_data[offset] | 558c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 1] << 8) | 559c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 2] << 16); 560c18ec02fSPetter Reinholdtsen offset += 3; 561a87b2cccSZdenek Styblik } else { 562c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); 563c18ec02fSPetter Reinholdtsen return -1; 564c18ec02fSPetter Reinholdtsen } 565c18ec02fSPetter Reinholdtsen 566a87b2cccSZdenek Styblik /* 567a87b2cccSZdenek Styblik * Grab the algorithms for this cipher suite. I guess we can't be 568a87b2cccSZdenek Styblik * sure of what order they'll come in. Also, I suppose we default 569a87b2cccSZdenek Styblik * to the NONE algorithm if one were absent. This part of the spec is 570a87b2cccSZdenek Styblik * poorly written -- I have read the errata document. For now, I'm only 571a87b2cccSZdenek Styblik * allowing one algorithm per type (auth, integrity, crypt) because I 572a87b2cccSZdenek Styblik * don't I understand how it could be otherwise. 573a87b2cccSZdenek Styblik */ 574c18ec02fSPetter Reinholdtsen auth_alg = IPMI_AUTH_RAKP_NONE; 575c18ec02fSPetter Reinholdtsen integrity_alg = IPMI_INTEGRITY_NONE; 576c18ec02fSPetter Reinholdtsen crypt_alg = IPMI_CRYPT_NONE; 577c18ec02fSPetter Reinholdtsen 578c18ec02fSPetter Reinholdtsen while (((cipher_suite_data[offset] & 0xC0) != 0xC0) && 579c18ec02fSPetter Reinholdtsen ((cipher_suite_data_length - offset) > 0)) 580c18ec02fSPetter Reinholdtsen { 581c18ec02fSPetter Reinholdtsen switch (cipher_suite_data[offset] & 0xC0) 582c18ec02fSPetter Reinholdtsen { 583c18ec02fSPetter Reinholdtsen case 0x00: 584a87b2cccSZdenek Styblik /* Authentication algorithm specifier */ 585c18ec02fSPetter Reinholdtsen auth_alg = cipher_suite_data[offset++] & 0x3F; 586c18ec02fSPetter Reinholdtsen break; 587c18ec02fSPetter Reinholdtsen case 0x40: 588a87b2cccSZdenek Styblik /* Interity algorithm specifier */ 589c18ec02fSPetter Reinholdtsen integrity_alg = cipher_suite_data[offset++] & 0x3F; 590c18ec02fSPetter Reinholdtsen break; 591c18ec02fSPetter Reinholdtsen case 0x80: 592a87b2cccSZdenek Styblik /* Confidentiality algorithm specifier */ 593c18ec02fSPetter Reinholdtsen crypt_alg = cipher_suite_data[offset++] & 0x3F; 594c18ec02fSPetter Reinholdtsen break; 595c18ec02fSPetter Reinholdtsen } 596c18ec02fSPetter Reinholdtsen } 597a87b2cccSZdenek Styblik /* We have everything we need to spit out a cipher suite record */ 598c18ec02fSPetter Reinholdtsen printf((csv_output? "%d,%s,%s,%s,%s\n" : 599c18ec02fSPetter Reinholdtsen "%-4d %-7s %-15s %-15s %-15s\n"), 600c18ec02fSPetter Reinholdtsen cipher_suite_id, 601c18ec02fSPetter Reinholdtsen iana_string(iana), 602c18ec02fSPetter Reinholdtsen val2str(auth_alg, ipmi_auth_algorithms), 603c18ec02fSPetter Reinholdtsen val2str(integrity_alg, ipmi_integrity_algorithms), 604c18ec02fSPetter Reinholdtsen val2str(crypt_alg, ipmi_encryption_algorithms)); 605c18ec02fSPetter Reinholdtsen } 606c18ec02fSPetter Reinholdtsen return 0; 607c18ec02fSPetter Reinholdtsen } 608c18ec02fSPetter Reinholdtsen 609c18ec02fSPetter Reinholdtsen 610c18ec02fSPetter Reinholdtsen 611c18ec02fSPetter Reinholdtsen uint8_t 612c18ec02fSPetter Reinholdtsen ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) 613c18ec02fSPetter Reinholdtsen { 614c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 615c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 616c18ec02fSPetter Reinholdtsen struct get_channel_info_rsp info; 617c18ec02fSPetter Reinholdtsen 618c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 619c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; 620c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_GET_CHANNEL_INFO; 621c18ec02fSPetter Reinholdtsen req.msg.data = &channel; 622c18ec02fSPetter Reinholdtsen req.msg.data_len = 1; 623c18ec02fSPetter Reinholdtsen 624c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 625c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 626c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Info command failed"); 627c18ec02fSPetter Reinholdtsen return 0; 628c18ec02fSPetter Reinholdtsen } 629c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 630a87b2cccSZdenek Styblik if (rsp->ccode == 0xcc) { 631c18ec02fSPetter Reinholdtsen return IPMI_CHANNEL_MEDIUM_RESERVED; 632a87b2cccSZdenek Styblik } 633c18ec02fSPetter Reinholdtsen lprintf(LOG_INFO, "Get Channel Info command failed: %s", 634c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 635c18ec02fSPetter Reinholdtsen return IPMI_CHANNEL_MEDIUM_RESERVED; 636c18ec02fSPetter Reinholdtsen } 637c18ec02fSPetter Reinholdtsen 638c18ec02fSPetter Reinholdtsen memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp)); 639c18ec02fSPetter Reinholdtsen 640c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "Channel type: %s", 641c18ec02fSPetter Reinholdtsen val2str(info.channel_medium, ipmi_channel_medium_vals)); 642c18ec02fSPetter Reinholdtsen 643c18ec02fSPetter Reinholdtsen return info.channel_medium; 644c18ec02fSPetter Reinholdtsen } 645c18ec02fSPetter Reinholdtsen 646c18ec02fSPetter Reinholdtsen uint8_t 647c18ec02fSPetter Reinholdtsen ipmi_current_channel_medium(struct ipmi_intf *intf) 648c18ec02fSPetter Reinholdtsen { 649c18ec02fSPetter Reinholdtsen return ipmi_get_channel_medium(intf, 0xE); 650c18ec02fSPetter Reinholdtsen } 651c18ec02fSPetter Reinholdtsen 652*585cb7c8SZdenek Styblik /* printf_channel_usage - print-out help. */ 653c18ec02fSPetter Reinholdtsen void 654c18ec02fSPetter Reinholdtsen printf_channel_usage() 655c18ec02fSPetter Reinholdtsen { 656a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 657a87b2cccSZdenek Styblik "Channel Commands: authcap <channel number> <max privilege>"); 658a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 659a87b2cccSZdenek Styblik " getaccess <channel number> [user id]"); 660a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 661a87b2cccSZdenek Styblik " setaccess <channel number> " 662c18ec02fSPetter Reinholdtsen "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); 663a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 664a87b2cccSZdenek Styblik " info [channel number]"); 665a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 666a87b2cccSZdenek Styblik " getciphers <ipmi | sol> [channel]"); 667a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 668a87b2cccSZdenek Styblik ""); 669a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 670a87b2cccSZdenek Styblik "Possible privilege levels are:"); 671a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 672a87b2cccSZdenek Styblik " 1 Callback level"); 673a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 674a87b2cccSZdenek Styblik " 2 User level"); 675a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 676a87b2cccSZdenek Styblik " 3 Operator level"); 677a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 678a87b2cccSZdenek Styblik " 4 Administrator level"); 679a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 680a87b2cccSZdenek Styblik " 5 OEM Proprietary level"); 681a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 682a87b2cccSZdenek Styblik " 15 No access"); 683c18ec02fSPetter Reinholdtsen } 684c18ec02fSPetter Reinholdtsen 685*585cb7c8SZdenek Styblik /* ipmi_set_user_access - Query BMC for current Channel ACLs, parse CLI args 686*585cb7c8SZdenek Styblik * and update current ACLs. 687*585cb7c8SZdenek Styblik * 688*585cb7c8SZdenek Styblik * returns - 0 on success, (-1) on error 689*585cb7c8SZdenek Styblik */ 690e4be291cSZdenek Styblik int 691e4be291cSZdenek Styblik ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv) 692e4be291cSZdenek Styblik { 693e4be291cSZdenek Styblik struct user_access_t user_access = {0}; 694e4be291cSZdenek Styblik int ccode = 0; 695e4be291cSZdenek Styblik int i = 0; 696e4be291cSZdenek Styblik uint8_t channel = 0; 697e4be291cSZdenek Styblik uint8_t priv = 0; 698e4be291cSZdenek Styblik uint8_t user_id = 0; 699e4be291cSZdenek Styblik if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { 700e4be291cSZdenek Styblik printf_channel_usage(); 701e4be291cSZdenek Styblik return 0; 702e4be291cSZdenek Styblik } else if (argc < 3) { 703e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 704e4be291cSZdenek Styblik printf_channel_usage(); 705e4be291cSZdenek Styblik return (-1); 706e4be291cSZdenek Styblik } 707e4be291cSZdenek Styblik if (is_ipmi_channel_num(argv[0], &channel) != 0 708e4be291cSZdenek Styblik || is_ipmi_user_id(argv[1], &user_id) != 0) { 709e4be291cSZdenek Styblik return (-1); 710e4be291cSZdenek Styblik } 711e4be291cSZdenek Styblik user_access.channel = channel; 712e4be291cSZdenek Styblik user_access.user_id = user_id; 713e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 714e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 715e4be291cSZdenek Styblik lprintf(LOG_ERR, 716e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 717e4be291cSZdenek Styblik channel, user_id); 718e4be291cSZdenek Styblik return (-1); 719e4be291cSZdenek Styblik } 720e4be291cSZdenek Styblik for (i = 3; i < argc; i ++) { 721e4be291cSZdenek Styblik if (strncmp(argv[i], "callin=", 7) == 0) { 722e4be291cSZdenek Styblik if (strncmp(argv[i] + 7, "off", 3) == 0) { 723e4be291cSZdenek Styblik user_access.callin_callback = 1; 724e4be291cSZdenek Styblik } else { 725e4be291cSZdenek Styblik user_access.callin_callback = 0; 726e4be291cSZdenek Styblik } 727e4be291cSZdenek Styblik } else if (strncmp(argv[i], "link=", 5) == 0) { 728e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 729e4be291cSZdenek Styblik user_access.link_auth = 0; 730e4be291cSZdenek Styblik } else { 731e4be291cSZdenek Styblik user_access.link_auth = 1; 732e4be291cSZdenek Styblik } 733e4be291cSZdenek Styblik } else if (strncmp(argv[i], "ipmi=", 5) == 0) { 734e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 735e4be291cSZdenek Styblik user_access.ipmi_messaging = 0; 736e4be291cSZdenek Styblik } else { 737e4be291cSZdenek Styblik user_access.ipmi_messaging = 1; 738e4be291cSZdenek Styblik } 739e4be291cSZdenek Styblik } else if (strncmp(argv[i], "privilege=", 10) == 0) { 740e4be291cSZdenek Styblik if (str2uchar(argv[i] + 10, &priv) != 0) { 741e4be291cSZdenek Styblik lprintf(LOG_ERR, 742e4be291cSZdenek Styblik "Numeric value expected, but '%s' given.", 743e4be291cSZdenek Styblik argv[i] + 10); 744e4be291cSZdenek Styblik return (-1); 745e4be291cSZdenek Styblik } 746e4be291cSZdenek Styblik user_access.privilege_limit = priv; 747e4be291cSZdenek Styblik } else { 748e4be291cSZdenek Styblik lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]); 749e4be291cSZdenek Styblik return (-1); 750e4be291cSZdenek Styblik } 751e4be291cSZdenek Styblik } 752708be8bcSZdenek Styblik ccode = _ipmi_set_user_access(intf, &user_access, 0); 753e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 754e4be291cSZdenek Styblik lprintf(LOG_ERR, 755e4be291cSZdenek Styblik "Unable to Set User Access (channel %d id %d)", 756e4be291cSZdenek Styblik channel, user_id); 757e4be291cSZdenek Styblik return (-1); 758e4be291cSZdenek Styblik } 759e4be291cSZdenek Styblik printf("Set User Access (channel %d id %d) successful.\n", 760e4be291cSZdenek Styblik channel, user_id); 761e4be291cSZdenek Styblik return 0; 762e4be291cSZdenek Styblik } 763c18ec02fSPetter Reinholdtsen 764c18ec02fSPetter Reinholdtsen int 765c18ec02fSPetter Reinholdtsen ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) 766c18ec02fSPetter Reinholdtsen { 767c18ec02fSPetter Reinholdtsen int retval = 0; 768a87b2cccSZdenek Styblik uint8_t channel; 769a87b2cccSZdenek Styblik uint8_t priv = 0; 7700562c809SZdenek Styblik if (argc < 1) { 7710562c809SZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 772c18ec02fSPetter Reinholdtsen printf_channel_usage(); 7730562c809SZdenek Styblik return (-1); 7740562c809SZdenek Styblik } else if (strncmp(argv[0], "help", 4) == 0) { 7750562c809SZdenek Styblik printf_channel_usage(); 7760562c809SZdenek Styblik return 0; 777a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "authcap", 7) == 0) { 778c18ec02fSPetter Reinholdtsen if (argc != 3) { 779c18ec02fSPetter Reinholdtsen printf_channel_usage(); 780c18ec02fSPetter Reinholdtsen return (-1); 7810562c809SZdenek Styblik } 782140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0 783140add9dSZdenek Styblik || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { 784c18ec02fSPetter Reinholdtsen return (-1); 785c18ec02fSPetter Reinholdtsen } 786c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_auth_cap(intf, channel, priv); 787a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getaccess", 10) == 0) { 788140add9dSZdenek Styblik uint8_t user_id = 0; 7890562c809SZdenek Styblik if ((argc < 2) || (argc > 3)) { 790e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 7910562c809SZdenek Styblik printf_channel_usage(); 7920562c809SZdenek Styblik return (-1); 7930562c809SZdenek Styblik } 794140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 795c18ec02fSPetter Reinholdtsen return (-1); 796c18ec02fSPetter Reinholdtsen } 797c18ec02fSPetter Reinholdtsen if (argc == 3) { 798140add9dSZdenek Styblik if (is_ipmi_user_id(argv[2], &user_id) != 0) { 799c18ec02fSPetter Reinholdtsen return (-1); 800c18ec02fSPetter Reinholdtsen } 801c18ec02fSPetter Reinholdtsen } 802140add9dSZdenek Styblik retval = ipmi_get_user_access(intf, channel, user_id); 803a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "setaccess", 9) == 0) { 804e4be291cSZdenek Styblik return ipmi_set_user_access(intf, (argc - 1), &(argv[1])); 805a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "info", 4) == 0) { 806140add9dSZdenek Styblik channel = 0xE; 807a87b2cccSZdenek Styblik if (argc > 2) { 808c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8090562c809SZdenek Styblik return (-1); 8100562c809SZdenek Styblik } 811c18ec02fSPetter Reinholdtsen if (argc == 2) { 812140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 813c18ec02fSPetter Reinholdtsen return (-1); 814c18ec02fSPetter Reinholdtsen } 815c18ec02fSPetter Reinholdtsen } 816140add9dSZdenek Styblik retval = ipmi_get_channel_info(intf, channel); 817a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getciphers", 10) == 0) { 8180562c809SZdenek Styblik /* channel getciphers <ipmi|sol> [channel] */ 819140add9dSZdenek Styblik channel = 0xE; 820c18ec02fSPetter Reinholdtsen if ((argc < 2) || (argc > 3) || 821a87b2cccSZdenek Styblik (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { 822c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8230562c809SZdenek Styblik return (-1); 8240562c809SZdenek Styblik } 825c18ec02fSPetter Reinholdtsen if (argc == 3) { 826140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 827c18ec02fSPetter Reinholdtsen return (-1); 828c18ec02fSPetter Reinholdtsen } 829c18ec02fSPetter Reinholdtsen } 830c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_cipher_suites(intf, 8310562c809SZdenek Styblik argv[1], /* ipmi | sol */ 832140add9dSZdenek Styblik channel); 833a87b2cccSZdenek Styblik } else { 834c18ec02fSPetter Reinholdtsen printf("Invalid CHANNEL command: %s\n", argv[0]); 835c18ec02fSPetter Reinholdtsen printf_channel_usage(); 836c18ec02fSPetter Reinholdtsen retval = -1; 837c18ec02fSPetter Reinholdtsen } 838c18ec02fSPetter Reinholdtsen return retval; 839c18ec02fSPetter Reinholdtsen } 840