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> 53*e4be291cSZdenek 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 353c18ec02fSPetter Reinholdtsen static int 354c18ec02fSPetter Reinholdtsen ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t userid) 355c18ec02fSPetter Reinholdtsen { 356*e4be291cSZdenek Styblik struct user_access_t user_access; 357*e4be291cSZdenek Styblik struct user_name_t user_name; 358*e4be291cSZdenek Styblik int ccode = 0; 359a87b2cccSZdenek Styblik int curr_uid; 360a87b2cccSZdenek Styblik int init = 1; 361*e4be291cSZdenek Styblik int max_uid = 0; 362c18ec02fSPetter Reinholdtsen 36348117f5dSZdenek Styblik curr_uid = userid ? userid : 1; 364a87b2cccSZdenek Styblik do { 365*e4be291cSZdenek Styblik memset(&user_access, 0, sizeof(user_access)); 366*e4be291cSZdenek Styblik user_access.channel = channel; 367*e4be291cSZdenek Styblik user_access.user_id = curr_uid; 368*e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 369*e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 370*e4be291cSZdenek Styblik lprintf(LOG_ERR, 371*e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 372*e4be291cSZdenek Styblik channel, curr_uid); 373*e4be291cSZdenek Styblik return (-1); 374c18ec02fSPetter Reinholdtsen } 375c18ec02fSPetter Reinholdtsen 376*e4be291cSZdenek Styblik memset(&user_name, 0, sizeof(user_name)); 377*e4be291cSZdenek Styblik user_name.user_id = curr_uid; 378*e4be291cSZdenek Styblik ccode = _ipmi_get_user_name(intf, &user_name); 379*e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 380*e4be291cSZdenek Styblik lprintf(LOG_ERR, "Unable to Get User Name (id %d)", curr_uid); 381*e4be291cSZdenek Styblik return (-1); 382c18ec02fSPetter Reinholdtsen } 383c18ec02fSPetter Reinholdtsen if (init) { 384c18ec02fSPetter Reinholdtsen printf("Maximum User IDs : %d\n", user_access.max_user_ids); 385c18ec02fSPetter Reinholdtsen printf("Enabled User IDs : %d\n", user_access.enabled_user_ids); 386c18ec02fSPetter Reinholdtsen max_uid = user_access.max_user_ids; 387c18ec02fSPetter Reinholdtsen init = 0; 388c18ec02fSPetter Reinholdtsen } 389c18ec02fSPetter Reinholdtsen 390c18ec02fSPetter Reinholdtsen printf("\n"); 391c18ec02fSPetter Reinholdtsen printf("User ID : %d\n", curr_uid); 392*e4be291cSZdenek Styblik printf("User Name : %s\n", user_name.user_name); 393c18ec02fSPetter Reinholdtsen printf("Fixed Name : %s\n", 394c18ec02fSPetter Reinholdtsen (curr_uid <= user_access.fixed_user_ids) ? "Yes" : "No"); 395c18ec02fSPetter Reinholdtsen printf("Access Available : %s\n", 396c18ec02fSPetter Reinholdtsen (user_access.callin_callback) ? "callback" : "call-in / callback"); 397c18ec02fSPetter Reinholdtsen printf("Link Authentication : %sabled\n", 398c18ec02fSPetter Reinholdtsen (user_access.link_auth) ? "en" : "dis"); 399c18ec02fSPetter Reinholdtsen printf("IPMI Messaging : %sabled\n", 400c18ec02fSPetter Reinholdtsen (user_access.ipmi_messaging) ? "en" : "dis"); 401c18ec02fSPetter Reinholdtsen printf("Privilege Level : %s\n", 402c18ec02fSPetter Reinholdtsen val2str(user_access.privilege_limit, ipmi_privlvl_vals)); 403c18ec02fSPetter Reinholdtsen 404c18ec02fSPetter Reinholdtsen curr_uid ++; 405c18ec02fSPetter Reinholdtsen } while (!userid && curr_uid <= max_uid); 406c18ec02fSPetter Reinholdtsen 407c18ec02fSPetter Reinholdtsen return 0; 408c18ec02fSPetter Reinholdtsen } 409c18ec02fSPetter Reinholdtsen 410c18ec02fSPetter Reinholdtsen static const char * 411c18ec02fSPetter Reinholdtsen iana_string(uint32_t iana) 412c18ec02fSPetter Reinholdtsen { 413c18ec02fSPetter Reinholdtsen static char s[10]; 414c18ec02fSPetter Reinholdtsen 415a87b2cccSZdenek Styblik if (iana) { 416c18ec02fSPetter Reinholdtsen sprintf(s, "%06x", iana); 417c18ec02fSPetter Reinholdtsen return s; 418a87b2cccSZdenek Styblik } else { 419c18ec02fSPetter Reinholdtsen return "N/A"; 420c18ec02fSPetter Reinholdtsen } 421a87b2cccSZdenek Styblik } 422c18ec02fSPetter Reinholdtsen 423c18ec02fSPetter Reinholdtsen 424c18ec02fSPetter Reinholdtsen static int 425a87b2cccSZdenek Styblik ipmi_get_channel_cipher_suites(struct ipmi_intf *intf, const char *payload_type, 426c18ec02fSPetter Reinholdtsen uint8_t channel) 427c18ec02fSPetter Reinholdtsen { 428c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 429c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 430c18ec02fSPetter Reinholdtsen 431c18ec02fSPetter Reinholdtsen uint8_t oem_record; 432c18ec02fSPetter Reinholdtsen uint8_t rqdata[3]; 433c18ec02fSPetter Reinholdtsen uint32_t iana; 434c18ec02fSPetter Reinholdtsen uint8_t auth_alg, integrity_alg, crypt_alg; 435c18ec02fSPetter Reinholdtsen uint8_t cipher_suite_id; 436c18ec02fSPetter Reinholdtsen uint8_t list_index = 0; 437a87b2cccSZdenek Styblik /* 0x40 sets * 16 bytes per set */ 438a87b2cccSZdenek Styblik uint8_t cipher_suite_data[1024]; 439c18ec02fSPetter Reinholdtsen uint16_t offset = 0; 440a87b2cccSZdenek Styblik /* how much was returned, total */ 441a87b2cccSZdenek Styblik uint16_t cipher_suite_data_length = 0; 442c18ec02fSPetter Reinholdtsen 443c18ec02fSPetter Reinholdtsen memset(cipher_suite_data, 0, sizeof(cipher_suite_data)); 444c18ec02fSPetter Reinholdtsen 445c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 446a87b2cccSZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 447a87b2cccSZdenek Styblik req.msg.cmd = IPMI_GET_CHANNEL_CIPHER_SUITES; 448c18ec02fSPetter Reinholdtsen req.msg.data = rqdata; 449c18ec02fSPetter Reinholdtsen req.msg.data_len = 3; 450c18ec02fSPetter Reinholdtsen 451c18ec02fSPetter Reinholdtsen rqdata[0] = channel; 452c18ec02fSPetter Reinholdtsen rqdata[1] = ((strncmp(payload_type, "ipmi", 4) == 0)? 0: 1); 453a87b2cccSZdenek Styblik /* Always ask for cipher suite format */ 454a87b2cccSZdenek Styblik rqdata[2] = 0x80; 455c18ec02fSPetter Reinholdtsen 456c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 457c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 458c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 459c18ec02fSPetter Reinholdtsen return -1; 460c18ec02fSPetter Reinholdtsen } 461c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 462c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 463c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 464c18ec02fSPetter Reinholdtsen return -1; 465c18ec02fSPetter Reinholdtsen } 466c18ec02fSPetter Reinholdtsen 467c18ec02fSPetter Reinholdtsen 468a87b2cccSZdenek Styblik /* 469a87b2cccSZdenek Styblik * Grab the returned channel number once. We assume it's the same 470a87b2cccSZdenek Styblik * in future calls. 471a87b2cccSZdenek Styblik */ 472a87b2cccSZdenek Styblik if (rsp->data_len >= 1) { 473c18ec02fSPetter Reinholdtsen channel = rsp->data[0]; 474a87b2cccSZdenek Styblik } 475c18ec02fSPetter Reinholdtsen 476a87b2cccSZdenek Styblik while ((rsp->data_len > 1) && (rsp->data_len == 17) && (list_index < 0x3F)) { 477a87b2cccSZdenek Styblik /* 478a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 479a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 480a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 481a87b2cccSZdenek Styblik */ 482c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 483c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 484c18ec02fSPetter Reinholdtsen 485a87b2cccSZdenek Styblik /* 486a87b2cccSZdenek Styblik * Increment our list for the next call 487a87b2cccSZdenek Styblik */ 488c18ec02fSPetter Reinholdtsen ++list_index; 489c18ec02fSPetter Reinholdtsen rqdata[2] = (rqdata[2] & 0x80) + list_index; 490c18ec02fSPetter Reinholdtsen 491c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 492c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 493c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to Get Channel Cipher Suites"); 494c18ec02fSPetter Reinholdtsen return -1; 495c18ec02fSPetter Reinholdtsen } 496c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 497c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Cipher Suites failed: %s", 498c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 499c18ec02fSPetter Reinholdtsen return -1; 500c18ec02fSPetter Reinholdtsen } 501c18ec02fSPetter Reinholdtsen } 502c18ec02fSPetter Reinholdtsen 503c18ec02fSPetter Reinholdtsen /* Copy last chunk */ 504a87b2cccSZdenek Styblik if(rsp->data_len > 1) { 505a87b2cccSZdenek Styblik /* 506a87b2cccSZdenek Styblik * We got back cipher suite data -- store it. 507a87b2cccSZdenek Styblik * printf("copying data to offset %d\n", offset); 508a87b2cccSZdenek Styblik * printbuf(rsp->data + 1, rsp->data_len - 1, "this is the data"); 509a87b2cccSZdenek Styblik */ 510c18ec02fSPetter Reinholdtsen memcpy(cipher_suite_data + offset, rsp->data + 1, rsp->data_len - 1); 511c18ec02fSPetter Reinholdtsen offset += rsp->data_len - 1; 512c18ec02fSPetter Reinholdtsen } 513c18ec02fSPetter Reinholdtsen 514a87b2cccSZdenek Styblik /* We can chomp on all our data now. */ 515c18ec02fSPetter Reinholdtsen cipher_suite_data_length = offset; 516c18ec02fSPetter Reinholdtsen offset = 0; 517c18ec02fSPetter Reinholdtsen 518a87b2cccSZdenek Styblik if (! csv_output) { 519c18ec02fSPetter Reinholdtsen printf("ID IANA Auth Alg Integrity Alg Confidentiality Alg\n"); 520a87b2cccSZdenek Styblik } 521a87b2cccSZdenek Styblik while (offset < cipher_suite_data_length) { 522a87b2cccSZdenek Styblik if (cipher_suite_data[offset++] == 0xC0) { 523a87b2cccSZdenek Styblik /* standard type */ 524a87b2cccSZdenek Styblik oem_record = 0; 525c18ec02fSPetter Reinholdtsen iana = 0; 526c18ec02fSPetter Reinholdtsen 527a87b2cccSZdenek Styblik /* Verify that we have at least a full record left; id + 3 algs */ 528a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 529a87b2cccSZdenek Styblik lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 530a87b2cccSZdenek Styblik return -1; 531a87b2cccSZdenek Styblik } 532a87b2cccSZdenek Styblik cipher_suite_id = cipher_suite_data[offset++]; 533a87b2cccSZdenek Styblik } else if (cipher_suite_data[offset++] == 0xC1) { 534a87b2cccSZdenek Styblik /* OEM record type */ 535a87b2cccSZdenek Styblik oem_record = 1; 536a87b2cccSZdenek Styblik 537a87b2cccSZdenek Styblik /* Verify that we have at least a full record left 538a87b2cccSZdenek Styblik * id + iana + 3 algs 539a87b2cccSZdenek Styblik */ 540a87b2cccSZdenek Styblik if ((cipher_suite_data_length - offset) < 4) { 541c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Incomplete data record in cipher suite data"); 542c18ec02fSPetter Reinholdtsen return -1; 543c18ec02fSPetter Reinholdtsen } 544c18ec02fSPetter Reinholdtsen 545c18ec02fSPetter Reinholdtsen cipher_suite_id = cipher_suite_data[offset++]; 546c18ec02fSPetter Reinholdtsen 547a87b2cccSZdenek Styblik /* Grab the IANA */ 548c18ec02fSPetter Reinholdtsen iana = 549c18ec02fSPetter Reinholdtsen cipher_suite_data[offset] | 550c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 1] << 8) | 551c18ec02fSPetter Reinholdtsen (cipher_suite_data[offset + 2] << 16); 552c18ec02fSPetter Reinholdtsen offset += 3; 553a87b2cccSZdenek Styblik } else { 554c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Bad start of record byte in cipher suite data"); 555c18ec02fSPetter Reinholdtsen return -1; 556c18ec02fSPetter Reinholdtsen } 557c18ec02fSPetter Reinholdtsen 558a87b2cccSZdenek Styblik /* 559a87b2cccSZdenek Styblik * Grab the algorithms for this cipher suite. I guess we can't be 560a87b2cccSZdenek Styblik * sure of what order they'll come in. Also, I suppose we default 561a87b2cccSZdenek Styblik * to the NONE algorithm if one were absent. This part of the spec is 562a87b2cccSZdenek Styblik * poorly written -- I have read the errata document. For now, I'm only 563a87b2cccSZdenek Styblik * allowing one algorithm per type (auth, integrity, crypt) because I 564a87b2cccSZdenek Styblik * don't I understand how it could be otherwise. 565a87b2cccSZdenek Styblik */ 566c18ec02fSPetter Reinholdtsen auth_alg = IPMI_AUTH_RAKP_NONE; 567c18ec02fSPetter Reinholdtsen integrity_alg = IPMI_INTEGRITY_NONE; 568c18ec02fSPetter Reinholdtsen crypt_alg = IPMI_CRYPT_NONE; 569c18ec02fSPetter Reinholdtsen 570c18ec02fSPetter Reinholdtsen while (((cipher_suite_data[offset] & 0xC0) != 0xC0) && 571c18ec02fSPetter Reinholdtsen ((cipher_suite_data_length - offset) > 0)) 572c18ec02fSPetter Reinholdtsen { 573c18ec02fSPetter Reinholdtsen switch (cipher_suite_data[offset] & 0xC0) 574c18ec02fSPetter Reinholdtsen { 575c18ec02fSPetter Reinholdtsen case 0x00: 576a87b2cccSZdenek Styblik /* Authentication algorithm specifier */ 577c18ec02fSPetter Reinholdtsen auth_alg = cipher_suite_data[offset++] & 0x3F; 578c18ec02fSPetter Reinholdtsen break; 579c18ec02fSPetter Reinholdtsen case 0x40: 580a87b2cccSZdenek Styblik /* Interity algorithm specifier */ 581c18ec02fSPetter Reinholdtsen integrity_alg = cipher_suite_data[offset++] & 0x3F; 582c18ec02fSPetter Reinholdtsen break; 583c18ec02fSPetter Reinholdtsen case 0x80: 584a87b2cccSZdenek Styblik /* Confidentiality algorithm specifier */ 585c18ec02fSPetter Reinholdtsen crypt_alg = cipher_suite_data[offset++] & 0x3F; 586c18ec02fSPetter Reinholdtsen break; 587c18ec02fSPetter Reinholdtsen } 588c18ec02fSPetter Reinholdtsen } 589a87b2cccSZdenek Styblik /* We have everything we need to spit out a cipher suite record */ 590c18ec02fSPetter Reinholdtsen printf((csv_output? "%d,%s,%s,%s,%s\n" : 591c18ec02fSPetter Reinholdtsen "%-4d %-7s %-15s %-15s %-15s\n"), 592c18ec02fSPetter Reinholdtsen cipher_suite_id, 593c18ec02fSPetter Reinholdtsen iana_string(iana), 594c18ec02fSPetter Reinholdtsen val2str(auth_alg, ipmi_auth_algorithms), 595c18ec02fSPetter Reinholdtsen val2str(integrity_alg, ipmi_integrity_algorithms), 596c18ec02fSPetter Reinholdtsen val2str(crypt_alg, ipmi_encryption_algorithms)); 597c18ec02fSPetter Reinholdtsen } 598c18ec02fSPetter Reinholdtsen return 0; 599c18ec02fSPetter Reinholdtsen } 600c18ec02fSPetter Reinholdtsen 601c18ec02fSPetter Reinholdtsen 602c18ec02fSPetter Reinholdtsen 603c18ec02fSPetter Reinholdtsen uint8_t 604c18ec02fSPetter Reinholdtsen ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) 605c18ec02fSPetter Reinholdtsen { 606c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 607c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 608c18ec02fSPetter Reinholdtsen struct get_channel_info_rsp info; 609c18ec02fSPetter Reinholdtsen 610c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 611c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; 612c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_GET_CHANNEL_INFO; 613c18ec02fSPetter Reinholdtsen req.msg.data = &channel; 614c18ec02fSPetter Reinholdtsen req.msg.data_len = 1; 615c18ec02fSPetter Reinholdtsen 616c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 617c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 618c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get Channel Info command failed"); 619c18ec02fSPetter Reinholdtsen return 0; 620c18ec02fSPetter Reinholdtsen } 621c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 622a87b2cccSZdenek Styblik if (rsp->ccode == 0xcc) { 623c18ec02fSPetter Reinholdtsen return IPMI_CHANNEL_MEDIUM_RESERVED; 624a87b2cccSZdenek Styblik } 625c18ec02fSPetter Reinholdtsen lprintf(LOG_INFO, "Get Channel Info command failed: %s", 626c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 627c18ec02fSPetter Reinholdtsen return IPMI_CHANNEL_MEDIUM_RESERVED; 628c18ec02fSPetter Reinholdtsen } 629c18ec02fSPetter Reinholdtsen 630c18ec02fSPetter Reinholdtsen memcpy(&info, rsp->data, sizeof(struct get_channel_info_rsp)); 631c18ec02fSPetter Reinholdtsen 632c18ec02fSPetter Reinholdtsen lprintf(LOG_DEBUG, "Channel type: %s", 633c18ec02fSPetter Reinholdtsen val2str(info.channel_medium, ipmi_channel_medium_vals)); 634c18ec02fSPetter Reinholdtsen 635c18ec02fSPetter Reinholdtsen return info.channel_medium; 636c18ec02fSPetter Reinholdtsen } 637c18ec02fSPetter Reinholdtsen 638c18ec02fSPetter Reinholdtsen uint8_t 639c18ec02fSPetter Reinholdtsen ipmi_current_channel_medium(struct ipmi_intf *intf) 640c18ec02fSPetter Reinholdtsen { 641c18ec02fSPetter Reinholdtsen return ipmi_get_channel_medium(intf, 0xE); 642c18ec02fSPetter Reinholdtsen } 643c18ec02fSPetter Reinholdtsen 644c18ec02fSPetter Reinholdtsen void 645c18ec02fSPetter Reinholdtsen printf_channel_usage() 646c18ec02fSPetter Reinholdtsen { 647a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 648a87b2cccSZdenek Styblik "Channel Commands: authcap <channel number> <max privilege>"); 649a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 650a87b2cccSZdenek Styblik " getaccess <channel number> [user id]"); 651a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 652a87b2cccSZdenek Styblik " setaccess <channel number> " 653c18ec02fSPetter Reinholdtsen "<user id> [callin=on|off] [ipmi=on|off] [link=on|off] [privilege=level]"); 654a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 655a87b2cccSZdenek Styblik " info [channel number]"); 656a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 657a87b2cccSZdenek Styblik " getciphers <ipmi | sol> [channel]"); 658a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 659a87b2cccSZdenek Styblik ""); 660a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 661a87b2cccSZdenek Styblik "Possible privilege levels are:"); 662a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 663a87b2cccSZdenek Styblik " 1 Callback level"); 664a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 665a87b2cccSZdenek Styblik " 2 User level"); 666a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 667a87b2cccSZdenek Styblik " 3 Operator level"); 668a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 669a87b2cccSZdenek Styblik " 4 Administrator level"); 670a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 671a87b2cccSZdenek Styblik " 5 OEM Proprietary level"); 672a87b2cccSZdenek Styblik lprintf(LOG_NOTICE, 673a87b2cccSZdenek Styblik " 15 No access"); 674c18ec02fSPetter Reinholdtsen } 675c18ec02fSPetter Reinholdtsen 676*e4be291cSZdenek Styblik int 677*e4be291cSZdenek Styblik ipmi_set_user_access(struct ipmi_intf *intf, int argc, char **argv) 678*e4be291cSZdenek Styblik { 679*e4be291cSZdenek Styblik struct user_access_t user_access = {0}; 680*e4be291cSZdenek Styblik int ccode = 0; 681*e4be291cSZdenek Styblik int i = 0; 682*e4be291cSZdenek Styblik uint8_t channel = 0; 683*e4be291cSZdenek Styblik uint8_t priv = 0; 684*e4be291cSZdenek Styblik uint8_t user_id = 0; 685*e4be291cSZdenek Styblik if (argc > 0 && strncmp(argv[0], "help", 4) == 0) { 686*e4be291cSZdenek Styblik printf_channel_usage(); 687*e4be291cSZdenek Styblik return 0; 688*e4be291cSZdenek Styblik } else if (argc < 3) { 689*e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 690*e4be291cSZdenek Styblik printf_channel_usage(); 691*e4be291cSZdenek Styblik return (-1); 692*e4be291cSZdenek Styblik } 693*e4be291cSZdenek Styblik if (is_ipmi_channel_num(argv[0], &channel) != 0 694*e4be291cSZdenek Styblik || is_ipmi_user_id(argv[1], &user_id) != 0) { 695*e4be291cSZdenek Styblik return (-1); 696*e4be291cSZdenek Styblik } 697*e4be291cSZdenek Styblik user_access.channel = channel; 698*e4be291cSZdenek Styblik user_access.user_id = user_id; 699*e4be291cSZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 700*e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 701*e4be291cSZdenek Styblik lprintf(LOG_ERR, 702*e4be291cSZdenek Styblik "Unable to Get User Access (channel %d id %d)", 703*e4be291cSZdenek Styblik channel, user_id); 704*e4be291cSZdenek Styblik return (-1); 705*e4be291cSZdenek Styblik } 706*e4be291cSZdenek Styblik for (i = 3; i < argc; i ++) { 707*e4be291cSZdenek Styblik if (strncmp(argv[i], "callin=", 7) == 0) { 708*e4be291cSZdenek Styblik if (strncmp(argv[i] + 7, "off", 3) == 0) { 709*e4be291cSZdenek Styblik user_access.callin_callback = 1; 710*e4be291cSZdenek Styblik } else { 711*e4be291cSZdenek Styblik user_access.callin_callback = 0; 712*e4be291cSZdenek Styblik } 713*e4be291cSZdenek Styblik } else if (strncmp(argv[i], "link=", 5) == 0) { 714*e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 715*e4be291cSZdenek Styblik user_access.link_auth = 0; 716*e4be291cSZdenek Styblik } else { 717*e4be291cSZdenek Styblik user_access.link_auth = 1; 718*e4be291cSZdenek Styblik } 719*e4be291cSZdenek Styblik } else if (strncmp(argv[i], "ipmi=", 5) == 0) { 720*e4be291cSZdenek Styblik if (strncmp(argv[i] + 5, "off", 3) == 0) { 721*e4be291cSZdenek Styblik user_access.ipmi_messaging = 0; 722*e4be291cSZdenek Styblik } else { 723*e4be291cSZdenek Styblik user_access.ipmi_messaging = 1; 724*e4be291cSZdenek Styblik } 725*e4be291cSZdenek Styblik } else if (strncmp(argv[i], "privilege=", 10) == 0) { 726*e4be291cSZdenek Styblik if (str2uchar(argv[i] + 10, &priv) != 0) { 727*e4be291cSZdenek Styblik lprintf(LOG_ERR, 728*e4be291cSZdenek Styblik "Numeric value expected, but '%s' given.", 729*e4be291cSZdenek Styblik argv[i] + 10); 730*e4be291cSZdenek Styblik return (-1); 731*e4be291cSZdenek Styblik } 732*e4be291cSZdenek Styblik user_access.privilege_limit = priv; 733*e4be291cSZdenek Styblik } else { 734*e4be291cSZdenek Styblik lprintf(LOG_ERR, "Invalid option: %s\n", argv[i]); 735*e4be291cSZdenek Styblik return (-1); 736*e4be291cSZdenek Styblik } 737*e4be291cSZdenek Styblik } 738*e4be291cSZdenek Styblik ccode = _ipmi_set_user_access(intf, &user_access); 739*e4be291cSZdenek Styblik if (eval_ccode(ccode) != 0) { 740*e4be291cSZdenek Styblik lprintf(LOG_ERR, 741*e4be291cSZdenek Styblik "Unable to Set User Access (channel %d id %d)", 742*e4be291cSZdenek Styblik channel, user_id); 743*e4be291cSZdenek Styblik return (-1); 744*e4be291cSZdenek Styblik } 745*e4be291cSZdenek Styblik printf("Set User Access (channel %d id %d) successful.\n", 746*e4be291cSZdenek Styblik channel, user_id); 747*e4be291cSZdenek Styblik return 0; 748*e4be291cSZdenek Styblik } 749c18ec02fSPetter Reinholdtsen 750c18ec02fSPetter Reinholdtsen int 751c18ec02fSPetter Reinholdtsen ipmi_channel_main(struct ipmi_intf *intf, int argc, char **argv) 752c18ec02fSPetter Reinholdtsen { 753c18ec02fSPetter Reinholdtsen int retval = 0; 754a87b2cccSZdenek Styblik uint8_t channel; 755a87b2cccSZdenek Styblik uint8_t priv = 0; 7560562c809SZdenek Styblik if (argc < 1) { 7570562c809SZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 758c18ec02fSPetter Reinholdtsen printf_channel_usage(); 7590562c809SZdenek Styblik return (-1); 7600562c809SZdenek Styblik } else if (strncmp(argv[0], "help", 4) == 0) { 7610562c809SZdenek Styblik printf_channel_usage(); 7620562c809SZdenek Styblik return 0; 763a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "authcap", 7) == 0) { 764c18ec02fSPetter Reinholdtsen if (argc != 3) { 765c18ec02fSPetter Reinholdtsen printf_channel_usage(); 766c18ec02fSPetter Reinholdtsen return (-1); 7670562c809SZdenek Styblik } 768140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0 769140add9dSZdenek Styblik || is_ipmi_user_priv_limit(argv[2], &priv) != 0) { 770c18ec02fSPetter Reinholdtsen return (-1); 771c18ec02fSPetter Reinholdtsen } 772c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_auth_cap(intf, channel, priv); 773a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getaccess", 10) == 0) { 774140add9dSZdenek Styblik uint8_t user_id = 0; 7750562c809SZdenek Styblik if ((argc < 2) || (argc > 3)) { 776*e4be291cSZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 7770562c809SZdenek Styblik printf_channel_usage(); 7780562c809SZdenek Styblik return (-1); 7790562c809SZdenek Styblik } 780140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 781c18ec02fSPetter Reinholdtsen return (-1); 782c18ec02fSPetter Reinholdtsen } 783c18ec02fSPetter Reinholdtsen if (argc == 3) { 784140add9dSZdenek Styblik if (is_ipmi_user_id(argv[2], &user_id) != 0) { 785c18ec02fSPetter Reinholdtsen return (-1); 786c18ec02fSPetter Reinholdtsen } 787c18ec02fSPetter Reinholdtsen } 788140add9dSZdenek Styblik retval = ipmi_get_user_access(intf, channel, user_id); 789a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "setaccess", 9) == 0) { 790*e4be291cSZdenek Styblik return ipmi_set_user_access(intf, (argc - 1), &(argv[1])); 791a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "info", 4) == 0) { 792140add9dSZdenek Styblik channel = 0xE; 793a87b2cccSZdenek Styblik if (argc > 2) { 794c18ec02fSPetter Reinholdtsen printf_channel_usage(); 7950562c809SZdenek Styblik return (-1); 7960562c809SZdenek Styblik } 797c18ec02fSPetter Reinholdtsen if (argc == 2) { 798140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 799c18ec02fSPetter Reinholdtsen return (-1); 800c18ec02fSPetter Reinholdtsen } 801c18ec02fSPetter Reinholdtsen } 802140add9dSZdenek Styblik retval = ipmi_get_channel_info(intf, channel); 803a87b2cccSZdenek Styblik } else if (strncmp(argv[0], "getciphers", 10) == 0) { 8040562c809SZdenek Styblik /* channel getciphers <ipmi|sol> [channel] */ 805140add9dSZdenek Styblik channel = 0xE; 806c18ec02fSPetter Reinholdtsen if ((argc < 2) || (argc > 3) || 807a87b2cccSZdenek Styblik (strncmp(argv[1], "ipmi", 4) && strncmp(argv[1], "sol", 3))) { 808c18ec02fSPetter Reinholdtsen printf_channel_usage(); 8090562c809SZdenek Styblik return (-1); 8100562c809SZdenek Styblik } 811c18ec02fSPetter Reinholdtsen if (argc == 3) { 812140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 813c18ec02fSPetter Reinholdtsen return (-1); 814c18ec02fSPetter Reinholdtsen } 815c18ec02fSPetter Reinholdtsen } 816c18ec02fSPetter Reinholdtsen retval = ipmi_get_channel_cipher_suites(intf, 8170562c809SZdenek Styblik argv[1], /* ipmi | sol */ 818140add9dSZdenek Styblik channel); 819a87b2cccSZdenek Styblik } else { 820c18ec02fSPetter Reinholdtsen printf("Invalid CHANNEL command: %s\n", argv[0]); 821c18ec02fSPetter Reinholdtsen printf_channel_usage(); 822c18ec02fSPetter Reinholdtsen retval = -1; 823c18ec02fSPetter Reinholdtsen } 824c18ec02fSPetter Reinholdtsen return retval; 825c18ec02fSPetter Reinholdtsen } 826