1c18ec02fSPetter Reinholdtsen /* 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 <string.h> 35c18ec02fSPetter Reinholdtsen #include <stdio.h> 36c18ec02fSPetter Reinholdtsen #include <sys/types.h> 37c18ec02fSPetter Reinholdtsen #include <sys/select.h> 38c18ec02fSPetter Reinholdtsen #include <sys/time.h> 39c18ec02fSPetter Reinholdtsen #include <signal.h> 40c18ec02fSPetter Reinholdtsen #include <unistd.h> 41c18ec02fSPetter Reinholdtsen 42c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h> 43c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h> 44c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h> 45c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h> 46c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_user.h> 47c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_constants.h> 48c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h> 49c18ec02fSPetter Reinholdtsen #include <ipmitool/bswap.h> 50c18ec02fSPetter Reinholdtsen 51c18ec02fSPetter Reinholdtsen 52c18ec02fSPetter Reinholdtsen extern int verbose; 53c18ec02fSPetter Reinholdtsen extern int csv_output; 54c18ec02fSPetter Reinholdtsen 55c18ec02fSPetter Reinholdtsen 56c18ec02fSPetter Reinholdtsen #define IPMI_PASSWORD_DISABLE_USER 0x00 57c18ec02fSPetter Reinholdtsen #define IPMI_PASSWORD_ENABLE_USER 0x01 58c18ec02fSPetter Reinholdtsen #define IPMI_PASSWORD_SET_PASSWORD 0x02 59c18ec02fSPetter Reinholdtsen #define IPMI_PASSWORD_TEST_PASSWORD 0x03 60c18ec02fSPetter Reinholdtsen 6131f9d4c6SZdenek Styblik /* _ipmi_get_user_access - Get User Access for given channel. Results are stored 6231f9d4c6SZdenek Styblik * into passed struct. 6331f9d4c6SZdenek Styblik * 6431f9d4c6SZdenek Styblik * @intf - IPMI interface 6531f9d4c6SZdenek Styblik * @user_access_rsp - ptr to user_access_t with UID and Channel set 6631f9d4c6SZdenek Styblik * 6731f9d4c6SZdenek Styblik * returns - negative number means error, positive is a ccode 6831f9d4c6SZdenek Styblik */ 6931f9d4c6SZdenek Styblik int 7031f9d4c6SZdenek Styblik _ipmi_get_user_access(struct ipmi_intf *intf, 7131f9d4c6SZdenek Styblik struct user_access_t *user_access_rsp) 7231f9d4c6SZdenek Styblik { 7331f9d4c6SZdenek Styblik struct ipmi_rq req = {0}; 7431f9d4c6SZdenek Styblik struct ipmi_rs *rsp; 7531f9d4c6SZdenek Styblik uint8_t data[2]; 7631f9d4c6SZdenek Styblik if (user_access_rsp == NULL) { 7731f9d4c6SZdenek Styblik return (-3); 7831f9d4c6SZdenek Styblik } 7931f9d4c6SZdenek Styblik data[0] = user_access_rsp->channel & 0x0F; 8031f9d4c6SZdenek Styblik data[1] = user_access_rsp->user_id & 0x3F; 8131f9d4c6SZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 8231f9d4c6SZdenek Styblik req.msg.cmd = IPMI_GET_USER_ACCESS; 8331f9d4c6SZdenek Styblik req.msg.data = data; 8431f9d4c6SZdenek Styblik req.msg.data_len = 2; 8531f9d4c6SZdenek Styblik rsp = intf->sendrecv(intf, &req); 8631f9d4c6SZdenek Styblik if (rsp == NULL) { 8731f9d4c6SZdenek Styblik return (-1); 8831f9d4c6SZdenek Styblik } else if (rsp->ccode != 0) { 8931f9d4c6SZdenek Styblik return rsp->ccode; 9031f9d4c6SZdenek Styblik } else if (rsp->data_len != 4) { 9131f9d4c6SZdenek Styblik return (-2); 9231f9d4c6SZdenek Styblik } 9331f9d4c6SZdenek Styblik user_access_rsp->max_user_ids = rsp->data[0] & 0x3F; 9431f9d4c6SZdenek Styblik user_access_rsp->enable_status = rsp->data[1] & 0xC0; 9531f9d4c6SZdenek Styblik user_access_rsp->enabled_user_ids = rsp->data[1] & 0x3F; 9631f9d4c6SZdenek Styblik user_access_rsp->fixed_user_ids = rsp->data[2] & 0x3F; 9731f9d4c6SZdenek Styblik user_access_rsp->callin_callback = rsp->data[3] & 0x40; 9831f9d4c6SZdenek Styblik user_access_rsp->link_auth = rsp->data[3] & 0x20; 9931f9d4c6SZdenek Styblik user_access_rsp->ipmi_messaging = rsp->data[3] & 0x10; 10031f9d4c6SZdenek Styblik user_access_rsp->privilege_limit = rsp->data[3] & 0x0F; 10131f9d4c6SZdenek Styblik return rsp->ccode; 10231f9d4c6SZdenek Styblik } 10331f9d4c6SZdenek Styblik 1046d1afbf3SZdenek Styblik /* _ipmi_get_user_name - Fetch User Name for given User ID. User Name is stored 1056d1afbf3SZdenek Styblik * into passed structure. 1066d1afbf3SZdenek Styblik * 1076d1afbf3SZdenek Styblik * @intf - ipmi interface 1086d1afbf3SZdenek Styblik * @user_name - user_name_t struct with UID set 1096d1afbf3SZdenek Styblik * 1106d1afbf3SZdenek Styblik * returns - negative number means error, positive is a ccode 1116d1afbf3SZdenek Styblik */ 1126d1afbf3SZdenek Styblik int 1136d1afbf3SZdenek Styblik _ipmi_get_user_name(struct ipmi_intf *intf, struct user_name_t *user_name_ptr) 1146d1afbf3SZdenek Styblik { 1156d1afbf3SZdenek Styblik struct ipmi_rq req = {0}; 1166d1afbf3SZdenek Styblik struct ipmi_rs *rsp; 1176d1afbf3SZdenek Styblik uint8_t data[1]; 1186d1afbf3SZdenek Styblik if (user_name_ptr == NULL) { 1196d1afbf3SZdenek Styblik return (-3); 1206d1afbf3SZdenek Styblik } 1216d1afbf3SZdenek Styblik data[0] = user_name_ptr->user_id & 0x3F; 1226d1afbf3SZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 1236d1afbf3SZdenek Styblik req.msg.cmd = IPMI_GET_USER_NAME; 1246d1afbf3SZdenek Styblik req.msg.data = data; 1256d1afbf3SZdenek Styblik req.msg.data_len = 1; 1266d1afbf3SZdenek Styblik rsp = intf->sendrecv(intf, &req); 1276d1afbf3SZdenek Styblik if (rsp == NULL) { 1286d1afbf3SZdenek Styblik return (-1); 1296d1afbf3SZdenek Styblik } else if (rsp->ccode > 0) { 1306d1afbf3SZdenek Styblik return rsp->ccode; 1316d1afbf3SZdenek Styblik } else if (rsp->data_len != 17) { 1326d1afbf3SZdenek Styblik return (-2); 1336d1afbf3SZdenek Styblik } 1346d1afbf3SZdenek Styblik memset(user_name_ptr->user_name, '\0', 17); 1356d1afbf3SZdenek Styblik memcpy(user_name_ptr->user_name, rsp->data, 16); 1366d1afbf3SZdenek Styblik return rsp->ccode; 1376d1afbf3SZdenek Styblik } 1386d1afbf3SZdenek Styblik 13931f9d4c6SZdenek Styblik /* _ipmi_set_user_access - Set User Access for given channel. 14031f9d4c6SZdenek Styblik * 14131f9d4c6SZdenek Styblik * @intf - IPMI interface 14231f9d4c6SZdenek Styblik * @user_access_req - ptr to user_access_t with desired User Access. 14331f9d4c6SZdenek Styblik * 14431f9d4c6SZdenek Styblik * returns - negative number means error, positive is a ccode 14531f9d4c6SZdenek Styblik */ 14631f9d4c6SZdenek Styblik int 14731f9d4c6SZdenek Styblik _ipmi_set_user_access(struct ipmi_intf *intf, 14831f9d4c6SZdenek Styblik struct user_access_t *user_access_req) 14931f9d4c6SZdenek Styblik { 15031f9d4c6SZdenek Styblik uint8_t data[4]; 15131f9d4c6SZdenek Styblik struct ipmi_rq req = {0}; 15231f9d4c6SZdenek Styblik struct ipmi_rs *rsp; 15331f9d4c6SZdenek Styblik if (user_access_req == NULL) { 15431f9d4c6SZdenek Styblik return (-3); 15531f9d4c6SZdenek Styblik } 15631f9d4c6SZdenek Styblik data[0] = 0x80; 15731f9d4c6SZdenek Styblik if (user_access_req->callin_callback) { 15831f9d4c6SZdenek Styblik data[0] |= 0x40; 15931f9d4c6SZdenek Styblik } 16031f9d4c6SZdenek Styblik if (user_access_req->link_auth) { 16131f9d4c6SZdenek Styblik data[0] |= 0x20; 16231f9d4c6SZdenek Styblik } 16331f9d4c6SZdenek Styblik if (user_access_req->ipmi_messaging) { 16431f9d4c6SZdenek Styblik data[0] |= 0x10; 16531f9d4c6SZdenek Styblik } 16631f9d4c6SZdenek Styblik data[0] |= (user_access_req->channel & 0x0F); 16731f9d4c6SZdenek Styblik data[1] = user_access_req->user_id & 0x3F; 16831f9d4c6SZdenek Styblik data[2] = user_access_req->privilege_limit & 0x0F; 16931f9d4c6SZdenek Styblik data[3] = user_access_req->session_limit & 0x0F; 17031f9d4c6SZdenek Styblik req.msg.netfn = IPMI_NETFN_APP; 17131f9d4c6SZdenek Styblik req.msg.cmd = IPMI_SET_USER_ACCESS; 172d099dca9SZdenek Styblik req.msg.data = data; 17331f9d4c6SZdenek Styblik req.msg.data_len = 4; 17431f9d4c6SZdenek Styblik rsp = intf->sendrecv(intf, &req); 17531f9d4c6SZdenek Styblik if (rsp == NULL) { 17631f9d4c6SZdenek Styblik return (-1); 17731f9d4c6SZdenek Styblik } else { 17831f9d4c6SZdenek Styblik return rsp->ccode; 17931f9d4c6SZdenek Styblik } 18031f9d4c6SZdenek Styblik } 18131f9d4c6SZdenek Styblik 182c18ec02fSPetter Reinholdtsen /* 183c18ec02fSPetter Reinholdtsen * ipmi_get_user_access 184c18ec02fSPetter Reinholdtsen * 185c18ec02fSPetter Reinholdtsen * param intf [in] 186c18ec02fSPetter Reinholdtsen * param channel_number [in] 187c18ec02fSPetter Reinholdtsen * param user_id [in] 188c18ec02fSPetter Reinholdtsen * param user_access [out] 189c18ec02fSPetter Reinholdtsen * 190c18ec02fSPetter Reinholdtsen * return 0 on succes 191c18ec02fSPetter Reinholdtsen * 1 on failure 192c18ec02fSPetter Reinholdtsen */ 193c18ec02fSPetter Reinholdtsen static int 194c18ec02fSPetter Reinholdtsen ipmi_get_user_access( 195c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf, 196c18ec02fSPetter Reinholdtsen uint8_t channel_number, 197c18ec02fSPetter Reinholdtsen uint8_t user_id, 198c18ec02fSPetter Reinholdtsen struct user_access_rsp *user_access) 199c18ec02fSPetter Reinholdtsen { 200c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp; 201c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 202c18ec02fSPetter Reinholdtsen uint8_t msg_data[2]; 203c18ec02fSPetter Reinholdtsen 204c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 205c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 206c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */ 207c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 208c18ec02fSPetter Reinholdtsen req.msg.data_len = 2; 209c18ec02fSPetter Reinholdtsen 210c18ec02fSPetter Reinholdtsen 211c18ec02fSPetter Reinholdtsen /* The channel number will remain constant throughout this function */ 212c18ec02fSPetter Reinholdtsen msg_data[0] = channel_number; 213c18ec02fSPetter Reinholdtsen msg_data[1] = user_id; 214c18ec02fSPetter Reinholdtsen 215c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 216c18ec02fSPetter Reinholdtsen 217c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 218c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get User Access command failed " 219c18ec02fSPetter Reinholdtsen "(channel %d, user %d)", channel_number, user_id); 220c18ec02fSPetter Reinholdtsen return -1; 221c18ec02fSPetter Reinholdtsen } 222c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 223c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get User Access command failed " 224c18ec02fSPetter Reinholdtsen "(channel %d, user %d): %s", channel_number, user_id, 225c18ec02fSPetter Reinholdtsen val2str(rsp->ccode, completion_code_vals)); 226c18ec02fSPetter Reinholdtsen return -1; 227c18ec02fSPetter Reinholdtsen } 228c18ec02fSPetter Reinholdtsen 229c18ec02fSPetter Reinholdtsen memcpy(user_access, 230c18ec02fSPetter Reinholdtsen rsp->data, 231c18ec02fSPetter Reinholdtsen sizeof(struct user_access_rsp)); 232c18ec02fSPetter Reinholdtsen 233c18ec02fSPetter Reinholdtsen return 0; 234c18ec02fSPetter Reinholdtsen } 235c18ec02fSPetter Reinholdtsen 236c18ec02fSPetter Reinholdtsen 237c18ec02fSPetter Reinholdtsen 238c18ec02fSPetter Reinholdtsen /* 239c18ec02fSPetter Reinholdtsen * ipmi_get_user_name 240c18ec02fSPetter Reinholdtsen * 241c18ec02fSPetter Reinholdtsen * param intf [in] 242c18ec02fSPetter Reinholdtsen * param channel_number [in] 243c18ec02fSPetter Reinholdtsen * param user_id [in] 244c18ec02fSPetter Reinholdtsen * param user_name [out] 245c18ec02fSPetter Reinholdtsen * 246c18ec02fSPetter Reinholdtsen * return 0 on succes 247c18ec02fSPetter Reinholdtsen * 1 on failure 248c18ec02fSPetter Reinholdtsen */ 249c18ec02fSPetter Reinholdtsen static int 250c18ec02fSPetter Reinholdtsen ipmi_get_user_name( 251c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf, 252c18ec02fSPetter Reinholdtsen uint8_t user_id, 253c18ec02fSPetter Reinholdtsen char *user_name) 254c18ec02fSPetter Reinholdtsen { 255c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp; 256c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 257c18ec02fSPetter Reinholdtsen uint8_t msg_data[1]; 258c18ec02fSPetter Reinholdtsen 259c18ec02fSPetter Reinholdtsen memset(user_name, 0, 17); 260c18ec02fSPetter Reinholdtsen 261c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 262c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 263c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */ 264c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 265c18ec02fSPetter Reinholdtsen req.msg.data_len = 1; 266c18ec02fSPetter Reinholdtsen 267c18ec02fSPetter Reinholdtsen msg_data[0] = user_id; 268c18ec02fSPetter Reinholdtsen 269c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 270c18ec02fSPetter Reinholdtsen 271c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 272c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get User Name command failed (user %d)", 273c18ec02fSPetter Reinholdtsen user_id); 274c18ec02fSPetter Reinholdtsen return -1; 275c18ec02fSPetter Reinholdtsen } 276c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 277c18ec02fSPetter Reinholdtsen if (rsp->ccode == 0xcc) 278c18ec02fSPetter Reinholdtsen return 0; 279c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Get User Name command failed (user %d): %s", 280c18ec02fSPetter Reinholdtsen user_id, val2str(rsp->ccode, completion_code_vals)); 281c18ec02fSPetter Reinholdtsen return -1; 282c18ec02fSPetter Reinholdtsen } 283c18ec02fSPetter Reinholdtsen 284c18ec02fSPetter Reinholdtsen memcpy(user_name, rsp->data, 16); 285c18ec02fSPetter Reinholdtsen 286c18ec02fSPetter Reinholdtsen return 0; 287c18ec02fSPetter Reinholdtsen } 288c18ec02fSPetter Reinholdtsen 289c18ec02fSPetter Reinholdtsen 290c18ec02fSPetter Reinholdtsen 291c18ec02fSPetter Reinholdtsen 292c18ec02fSPetter Reinholdtsen static void 293c18ec02fSPetter Reinholdtsen dump_user_access( 294c18ec02fSPetter Reinholdtsen uint8_t user_id, 295c18ec02fSPetter Reinholdtsen const char * user_name, 296c18ec02fSPetter Reinholdtsen struct user_access_rsp * user_access) 297c18ec02fSPetter Reinholdtsen { 298c18ec02fSPetter Reinholdtsen static int printed_header = 0; 299c18ec02fSPetter Reinholdtsen 300c18ec02fSPetter Reinholdtsen if (! printed_header) 301c18ec02fSPetter Reinholdtsen { 302c18ec02fSPetter Reinholdtsen printf("ID Name Callin Link Auth IPMI Msg " 303c18ec02fSPetter Reinholdtsen "Channel Priv Limit\n"); 304c18ec02fSPetter Reinholdtsen printed_header = 1; 305c18ec02fSPetter Reinholdtsen } 306c18ec02fSPetter Reinholdtsen 307c18ec02fSPetter Reinholdtsen printf("%-4d%-17s%-8s%-11s%-11s%-s\n", 308c18ec02fSPetter Reinholdtsen user_id, 309c18ec02fSPetter Reinholdtsen user_name, 310c18ec02fSPetter Reinholdtsen user_access->no_callin_access? "false": "true ", 311c18ec02fSPetter Reinholdtsen user_access->link_auth_access? "true ": "false", 312c18ec02fSPetter Reinholdtsen user_access->ipmi_messaging_access? "true ": "false", 313c18ec02fSPetter Reinholdtsen val2str(user_access->channel_privilege_limit, 314c18ec02fSPetter Reinholdtsen ipmi_privlvl_vals)); 315c18ec02fSPetter Reinholdtsen } 316c18ec02fSPetter Reinholdtsen 317c18ec02fSPetter Reinholdtsen 318c18ec02fSPetter Reinholdtsen 319c18ec02fSPetter Reinholdtsen static void 320c18ec02fSPetter Reinholdtsen dump_user_access_csv( 321c18ec02fSPetter Reinholdtsen uint8_t user_id, 322c18ec02fSPetter Reinholdtsen const char *user_name, 323c18ec02fSPetter Reinholdtsen struct user_access_rsp *user_access) 324c18ec02fSPetter Reinholdtsen { 325c18ec02fSPetter Reinholdtsen printf("%d,%s,%s,%s,%s,%s\n", 326c18ec02fSPetter Reinholdtsen user_id, 327c18ec02fSPetter Reinholdtsen user_name, 328c18ec02fSPetter Reinholdtsen user_access->no_callin_access? "false": "true", 329c18ec02fSPetter Reinholdtsen user_access->link_auth_access? "true": "false", 330c18ec02fSPetter Reinholdtsen user_access->ipmi_messaging_access? "true": "false", 331c18ec02fSPetter Reinholdtsen val2str(user_access->channel_privilege_limit, 332c18ec02fSPetter Reinholdtsen ipmi_privlvl_vals)); 333c18ec02fSPetter Reinholdtsen } 334c18ec02fSPetter Reinholdtsen 335c18ec02fSPetter Reinholdtsen static int 336c18ec02fSPetter Reinholdtsen ipmi_print_user_list( 337c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf, 338c18ec02fSPetter Reinholdtsen uint8_t channel_number) 339c18ec02fSPetter Reinholdtsen { 340c18ec02fSPetter Reinholdtsen /* This is where you were! */ 341c18ec02fSPetter Reinholdtsen char user_name[17]; 342c18ec02fSPetter Reinholdtsen struct user_access_rsp user_access; 343c18ec02fSPetter Reinholdtsen uint8_t current_user_id = 1; 344c18ec02fSPetter Reinholdtsen 345c18ec02fSPetter Reinholdtsen 346c18ec02fSPetter Reinholdtsen do 347c18ec02fSPetter Reinholdtsen { 348c18ec02fSPetter Reinholdtsen if (ipmi_get_user_access(intf, 349c18ec02fSPetter Reinholdtsen channel_number, 350c18ec02fSPetter Reinholdtsen current_user_id, 351c18ec02fSPetter Reinholdtsen &user_access)) 352c18ec02fSPetter Reinholdtsen return -1; 353c18ec02fSPetter Reinholdtsen 354c18ec02fSPetter Reinholdtsen 355c18ec02fSPetter Reinholdtsen if (ipmi_get_user_name(intf, 356c18ec02fSPetter Reinholdtsen current_user_id, 357c18ec02fSPetter Reinholdtsen user_name)) 358c18ec02fSPetter Reinholdtsen return -1; 359c18ec02fSPetter Reinholdtsen 360c18ec02fSPetter Reinholdtsen if ((current_user_id == 0) || 361c18ec02fSPetter Reinholdtsen user_access.link_auth_access || 362c18ec02fSPetter Reinholdtsen user_access.ipmi_messaging_access || 363c18ec02fSPetter Reinholdtsen strcmp("", user_name)) 364c18ec02fSPetter Reinholdtsen { 365c18ec02fSPetter Reinholdtsen if (csv_output) 366c18ec02fSPetter Reinholdtsen dump_user_access_csv(current_user_id, 367c18ec02fSPetter Reinholdtsen user_name, &user_access); 368c18ec02fSPetter Reinholdtsen else 369c18ec02fSPetter Reinholdtsen dump_user_access(current_user_id, 370c18ec02fSPetter Reinholdtsen user_name, 371c18ec02fSPetter Reinholdtsen &user_access); 372c18ec02fSPetter Reinholdtsen } 373c18ec02fSPetter Reinholdtsen 374c18ec02fSPetter Reinholdtsen 375c18ec02fSPetter Reinholdtsen ++current_user_id; 376c18ec02fSPetter Reinholdtsen } while((current_user_id <= user_access.maximum_ids) && 377c18ec02fSPetter Reinholdtsen (current_user_id <= IPMI_UID_MAX)); /* Absolute maximum allowed by spec */ 378c18ec02fSPetter Reinholdtsen 379c18ec02fSPetter Reinholdtsen 380c18ec02fSPetter Reinholdtsen return 0; 381c18ec02fSPetter Reinholdtsen } 382c18ec02fSPetter Reinholdtsen 383*fb36c693SZdenek Styblik /* ipmi_print_user_summary - print User statistics for given channel 384*fb36c693SZdenek Styblik * 385*fb36c693SZdenek Styblik * @intf - IPMI interface 386*fb36c693SZdenek Styblik * @channel_number - channel number 387*fb36c693SZdenek Styblik * 388*fb36c693SZdenek Styblik * returns - 0 on success, (-1) on error 389*fb36c693SZdenek Styblik */ 390c18ec02fSPetter Reinholdtsen static int 391*fb36c693SZdenek Styblik ipmi_print_user_summary(struct ipmi_intf *intf, uint8_t channel_number) 392c18ec02fSPetter Reinholdtsen { 393*fb36c693SZdenek Styblik struct user_access_t user_access = {0}; 394*fb36c693SZdenek Styblik int ccode = 0; 395*fb36c693SZdenek Styblik user_access.channel = channel_number; 396*fb36c693SZdenek Styblik user_access.user_id = 1; 397*fb36c693SZdenek Styblik ccode = _ipmi_get_user_access(intf, &user_access); 398*fb36c693SZdenek Styblik if (eval_ccode(ccode) != 0) { 399*fb36c693SZdenek Styblik return (-1); 400c18ec02fSPetter Reinholdtsen } 401*fb36c693SZdenek Styblik if (csv_output) { 402*fb36c693SZdenek Styblik printf("%" PRIu8 ",%" PRIu8 ",%" PRIu8 "\n", 403*fb36c693SZdenek Styblik user_access.max_user_ids, 404*fb36c693SZdenek Styblik user_access.enabled_user_ids, 405*fb36c693SZdenek Styblik user_access.fixed_user_ids); 406*fb36c693SZdenek Styblik } else { 407*fb36c693SZdenek Styblik printf("Maximum IDs : %" PRIu8 "\n", 408*fb36c693SZdenek Styblik user_access.max_user_ids); 409*fb36c693SZdenek Styblik printf("Enabled User Count : %" PRIu8 "\n", 410*fb36c693SZdenek Styblik user_access.enabled_user_ids); 411*fb36c693SZdenek Styblik printf("Fixed Name Count : %" PRIu8 "\n", 412*fb36c693SZdenek Styblik user_access.fixed_user_ids); 413c18ec02fSPetter Reinholdtsen } 414c18ec02fSPetter Reinholdtsen return 0; 415c18ec02fSPetter Reinholdtsen } 416c18ec02fSPetter Reinholdtsen 417c18ec02fSPetter Reinholdtsen /* 418c18ec02fSPetter Reinholdtsen * ipmi_user_set_username 419c18ec02fSPetter Reinholdtsen */ 420c18ec02fSPetter Reinholdtsen static int 421c18ec02fSPetter Reinholdtsen ipmi_user_set_username( 422c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf, 423c18ec02fSPetter Reinholdtsen uint8_t user_id, 424c18ec02fSPetter Reinholdtsen const char *name) 425c18ec02fSPetter Reinholdtsen { 426c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp; 427c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 428c18ec02fSPetter Reinholdtsen uint8_t msg_data[17]; 429c18ec02fSPetter Reinholdtsen 430c18ec02fSPetter Reinholdtsen /* 431c18ec02fSPetter Reinholdtsen * Ensure there is space for the name in the request message buffer 432c18ec02fSPetter Reinholdtsen */ 433c18ec02fSPetter Reinholdtsen if (strlen(name) >= sizeof(msg_data)) { 434c18ec02fSPetter Reinholdtsen return -1; 435c18ec02fSPetter Reinholdtsen } 436c18ec02fSPetter Reinholdtsen 437c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 438c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 439c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */ 440c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 441c18ec02fSPetter Reinholdtsen req.msg.data_len = sizeof(msg_data); 442c18ec02fSPetter Reinholdtsen memset(msg_data, 0, sizeof(msg_data)); 443c18ec02fSPetter Reinholdtsen 444c18ec02fSPetter Reinholdtsen /* The channel number will remain constant throughout this function */ 445c18ec02fSPetter Reinholdtsen msg_data[0] = user_id; 446c18ec02fSPetter Reinholdtsen strncpy((char *)(msg_data + 1), name, strlen(name)); 447c18ec02fSPetter Reinholdtsen 448c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 449c18ec02fSPetter Reinholdtsen 450c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 451c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s)", 452c18ec02fSPetter Reinholdtsen user_id, name); 453c18ec02fSPetter Reinholdtsen return -1; 454c18ec02fSPetter Reinholdtsen } 455c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 456c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set User Name command failed (user %d, name %s): %s", 457c18ec02fSPetter Reinholdtsen user_id, name, val2str(rsp->ccode, completion_code_vals)); 458c18ec02fSPetter Reinholdtsen return -1; 459c18ec02fSPetter Reinholdtsen } 460c18ec02fSPetter Reinholdtsen 461c18ec02fSPetter Reinholdtsen return 0; 462c18ec02fSPetter Reinholdtsen } 463c18ec02fSPetter Reinholdtsen 464c18ec02fSPetter Reinholdtsen static int 465c18ec02fSPetter Reinholdtsen ipmi_user_set_userpriv( 466c18ec02fSPetter Reinholdtsen struct ipmi_intf *intf, 467c18ec02fSPetter Reinholdtsen uint8_t channel, 468c18ec02fSPetter Reinholdtsen uint8_t user_id, 469c18ec02fSPetter Reinholdtsen const unsigned char privLevel) 470c18ec02fSPetter Reinholdtsen { 471c18ec02fSPetter Reinholdtsen struct ipmi_rs *rsp; 472c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 473c18ec02fSPetter Reinholdtsen uint8_t msg_data[4] = {0, 0, 0, 0}; 474c18ec02fSPetter Reinholdtsen 475c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 476c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 477c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_SET_USER_ACCESS; /* 0x43 */ 478c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 479c18ec02fSPetter Reinholdtsen req.msg.data_len = 4; 480c18ec02fSPetter Reinholdtsen 481c18ec02fSPetter Reinholdtsen /* The channel number will remain constant throughout this function */ 482c18ec02fSPetter Reinholdtsen msg_data[0] = (channel & 0x0f); 483c18ec02fSPetter Reinholdtsen msg_data[1] = (user_id & 0x3f); 484c18ec02fSPetter Reinholdtsen msg_data[2] = (privLevel & 0x0f); 485c18ec02fSPetter Reinholdtsen msg_data[3] = 0; 486c18ec02fSPetter Reinholdtsen 487c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 488c18ec02fSPetter Reinholdtsen 489c18ec02fSPetter Reinholdtsen if (rsp == NULL) 490c18ec02fSPetter Reinholdtsen { 491c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set Privilege Level command failed (user %d)", 492c18ec02fSPetter Reinholdtsen user_id); 493c18ec02fSPetter Reinholdtsen return -1; 494c18ec02fSPetter Reinholdtsen } 495c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) 496c18ec02fSPetter Reinholdtsen { 497c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set Privilege Level command failed (user %d): %s", 498c18ec02fSPetter Reinholdtsen user_id, val2str(rsp->ccode, completion_code_vals)); 499c18ec02fSPetter Reinholdtsen return -1; 500c18ec02fSPetter Reinholdtsen } 501c18ec02fSPetter Reinholdtsen 502c18ec02fSPetter Reinholdtsen return 0; 503c18ec02fSPetter Reinholdtsen } 504c18ec02fSPetter Reinholdtsen 505c18ec02fSPetter Reinholdtsen /* 506c18ec02fSPetter Reinholdtsen * ipmi_user_set_password 507c18ec02fSPetter Reinholdtsen * 508c18ec02fSPetter Reinholdtsen * This function is responsible for 4 things 509c18ec02fSPetter Reinholdtsen * Enabling/Disabling users 510c18ec02fSPetter Reinholdtsen * Setting/Testing passwords 511c18ec02fSPetter Reinholdtsen */ 512c18ec02fSPetter Reinholdtsen static int 513c18ec02fSPetter Reinholdtsen ipmi_user_set_password( 514c18ec02fSPetter Reinholdtsen struct ipmi_intf * intf, 515c18ec02fSPetter Reinholdtsen uint8_t user_id, 516c18ec02fSPetter Reinholdtsen uint8_t operation, 517c18ec02fSPetter Reinholdtsen const char *password, 518c18ec02fSPetter Reinholdtsen int is_twenty_byte_password) 519c18ec02fSPetter Reinholdtsen { 520c18ec02fSPetter Reinholdtsen struct ipmi_rs * rsp; 521c18ec02fSPetter Reinholdtsen struct ipmi_rq req; 522c18ec02fSPetter Reinholdtsen uint8_t msg_data[22]; 523c18ec02fSPetter Reinholdtsen 524c18ec02fSPetter Reinholdtsen int password_length = (is_twenty_byte_password? 20 : 16); 525c18ec02fSPetter Reinholdtsen 526c18ec02fSPetter Reinholdtsen memset(&req, 0, sizeof(req)); 527c18ec02fSPetter Reinholdtsen req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ 528c18ec02fSPetter Reinholdtsen req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */ 529c18ec02fSPetter Reinholdtsen req.msg.data = msg_data; 530c18ec02fSPetter Reinholdtsen req.msg.data_len = password_length + 2; 531c18ec02fSPetter Reinholdtsen 532c18ec02fSPetter Reinholdtsen 533c18ec02fSPetter Reinholdtsen /* The channel number will remain constant throughout this function */ 534c18ec02fSPetter Reinholdtsen msg_data[0] = user_id; 535c18ec02fSPetter Reinholdtsen 536c18ec02fSPetter Reinholdtsen if (is_twenty_byte_password) 537c18ec02fSPetter Reinholdtsen msg_data[0] |= 0x80; 538c18ec02fSPetter Reinholdtsen 539c18ec02fSPetter Reinholdtsen msg_data[1] = operation; 540c18ec02fSPetter Reinholdtsen 541c18ec02fSPetter Reinholdtsen memset(msg_data + 2, 0, password_length); 542c18ec02fSPetter Reinholdtsen 543c18ec02fSPetter Reinholdtsen if (password != NULL) 544c18ec02fSPetter Reinholdtsen strncpy((char *)(msg_data + 2), password, password_length); 545c18ec02fSPetter Reinholdtsen 546c18ec02fSPetter Reinholdtsen rsp = intf->sendrecv(intf, &req); 547c18ec02fSPetter Reinholdtsen 548c18ec02fSPetter Reinholdtsen if (rsp == NULL) { 549c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set User Password command failed (user %d)", 550c18ec02fSPetter Reinholdtsen user_id); 551c18ec02fSPetter Reinholdtsen return -1; 552c18ec02fSPetter Reinholdtsen } 553c18ec02fSPetter Reinholdtsen if (rsp->ccode > 0) { 554c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Set User Password command failed (user %d): %s", 555c18ec02fSPetter Reinholdtsen user_id, val2str(rsp->ccode, completion_code_vals)); 556c18ec02fSPetter Reinholdtsen return rsp->ccode; 557c18ec02fSPetter Reinholdtsen } 558c18ec02fSPetter Reinholdtsen 559c18ec02fSPetter Reinholdtsen return 0; 560c18ec02fSPetter Reinholdtsen } 561c18ec02fSPetter Reinholdtsen 562c18ec02fSPetter Reinholdtsen 563c18ec02fSPetter Reinholdtsen 564c18ec02fSPetter Reinholdtsen /* 565c18ec02fSPetter Reinholdtsen * ipmi_user_test_password 566c18ec02fSPetter Reinholdtsen * 567c18ec02fSPetter Reinholdtsen * Call ipmi_user_set_password, and interpret the result 568c18ec02fSPetter Reinholdtsen */ 569c18ec02fSPetter Reinholdtsen static int 570c18ec02fSPetter Reinholdtsen ipmi_user_test_password( 571c18ec02fSPetter Reinholdtsen struct ipmi_intf * intf, 572c18ec02fSPetter Reinholdtsen uint8_t user_id, 573c18ec02fSPetter Reinholdtsen const char * password, 574c18ec02fSPetter Reinholdtsen int is_twenty_byte_password) 575c18ec02fSPetter Reinholdtsen { 576c18ec02fSPetter Reinholdtsen int ret; 577c18ec02fSPetter Reinholdtsen 578c18ec02fSPetter Reinholdtsen ret = ipmi_user_set_password(intf, 579c18ec02fSPetter Reinholdtsen user_id, 580c18ec02fSPetter Reinholdtsen IPMI_PASSWORD_TEST_PASSWORD, 581c18ec02fSPetter Reinholdtsen password, 582c18ec02fSPetter Reinholdtsen is_twenty_byte_password); 583c18ec02fSPetter Reinholdtsen 584c18ec02fSPetter Reinholdtsen switch (ret) { 585c18ec02fSPetter Reinholdtsen case 0: 586c18ec02fSPetter Reinholdtsen printf("Success\n"); 587c18ec02fSPetter Reinholdtsen break; 588c18ec02fSPetter Reinholdtsen case 0x80: 589c18ec02fSPetter Reinholdtsen printf("Failure: password incorrect\n"); 590c18ec02fSPetter Reinholdtsen break; 591c18ec02fSPetter Reinholdtsen case 0x81: 592c18ec02fSPetter Reinholdtsen printf("Failure: wrong password size\n"); 593c18ec02fSPetter Reinholdtsen break; 594c18ec02fSPetter Reinholdtsen default: 595c18ec02fSPetter Reinholdtsen printf("Unknown error\n"); 596c18ec02fSPetter Reinholdtsen } 597c18ec02fSPetter Reinholdtsen 598c18ec02fSPetter Reinholdtsen return ((ret == 0) ? 0 : -1); 599c18ec02fSPetter Reinholdtsen } 600c18ec02fSPetter Reinholdtsen 601c18ec02fSPetter Reinholdtsen 602c18ec02fSPetter Reinholdtsen /* 603c18ec02fSPetter Reinholdtsen * print_user_usage 604c18ec02fSPetter Reinholdtsen */ 605c18ec02fSPetter Reinholdtsen static void 606c18ec02fSPetter Reinholdtsen print_user_usage(void) 607c18ec02fSPetter Reinholdtsen { 6081d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6091d1ce49bSZdenek Styblik "User Commands:"); 6101d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6111d1ce49bSZdenek Styblik " summary [<channel number>]"); 6121d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6131d1ce49bSZdenek Styblik " list [<channel number>]"); 6141d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6151d1ce49bSZdenek Styblik " set name <user id> <username>"); 6161d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 617ad77da20SZdenek Styblik " set password <user id> [<password> <16|20>]"); 6181d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6191d1ce49bSZdenek Styblik " disable <user id>"); 6201d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6211d1ce49bSZdenek Styblik " enable <user id>"); 622c18ec02fSPetter Reinholdtsen lprintf(LOG_NOTICE, 623c18ec02fSPetter Reinholdtsen " priv <user id> <privilege level> [<channel number>]"); 6241d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6251d1ce49bSZdenek Styblik " Privilege levels:"); 6261d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6271d1ce49bSZdenek Styblik " * 0x1 - Callback"); 6281d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6291d1ce49bSZdenek Styblik " * 0x2 - User"); 6301d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6311d1ce49bSZdenek Styblik " * 0x3 - Operator"); 6321d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6331d1ce49bSZdenek Styblik " * 0x4 - Administrator"); 6341d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6351d1ce49bSZdenek Styblik " * 0x5 - OEM Proprietary"); 6361d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6371d1ce49bSZdenek Styblik " * 0xF - No Access"); 6381d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, ""); 6391d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, 6401d1ce49bSZdenek Styblik " test <user id> <16|20> [<password]>"); 6411d1ce49bSZdenek Styblik lprintf(LOG_NOTICE, ""); 642c18ec02fSPetter Reinholdtsen } 643c18ec02fSPetter Reinholdtsen 644c18ec02fSPetter Reinholdtsen 645c18ec02fSPetter Reinholdtsen const char * 646c18ec02fSPetter Reinholdtsen ipmi_user_build_password_prompt(uint8_t user_id) 647c18ec02fSPetter Reinholdtsen { 648c18ec02fSPetter Reinholdtsen static char prompt[128]; 649c18ec02fSPetter Reinholdtsen memset(prompt, 0, 128); 650c18ec02fSPetter Reinholdtsen snprintf(prompt, 128, "Password for user %d: ", user_id); 651c18ec02fSPetter Reinholdtsen return prompt; 652c18ec02fSPetter Reinholdtsen } 653c18ec02fSPetter Reinholdtsen 654befb2149SZdenek Styblik /* ask_password - ask user for password 655befb2149SZdenek Styblik * 656befb2149SZdenek Styblik * @user_id: User ID which will be built-in into text 657befb2149SZdenek Styblik * 658befb2149SZdenek Styblik * @returns pointer to char with password 659befb2149SZdenek Styblik */ 660befb2149SZdenek Styblik char * 661befb2149SZdenek Styblik ask_password(uint8_t user_id) 662befb2149SZdenek Styblik { 663befb2149SZdenek Styblik const char *password_prompt = 664befb2149SZdenek Styblik ipmi_user_build_password_prompt(user_id); 665befb2149SZdenek Styblik # ifdef HAVE_GETPASSPHRASE 666befb2149SZdenek Styblik return getpassphrase(password_prompt); 667befb2149SZdenek Styblik # else 668befb2149SZdenek Styblik return (char*)getpass(password_prompt); 669befb2149SZdenek Styblik # endif 670befb2149SZdenek Styblik } 671befb2149SZdenek Styblik 672c18ec02fSPetter Reinholdtsen int 6734d3decc4SZdenek Styblik ipmi_user_summary(struct ipmi_intf *intf, int argc, char **argv) 674c18ec02fSPetter Reinholdtsen { 6753c34aa0eSZdenek Styblik /* Summary*/ 676c18ec02fSPetter Reinholdtsen uint8_t channel; 6773c34aa0eSZdenek Styblik if (argc == 1) { 678c18ec02fSPetter Reinholdtsen channel = 0x0E; /* Ask about the current channel */ 6792aa5d8c9SZdenek Styblik } else if (argc == 2) { 680140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 681c18ec02fSPetter Reinholdtsen return (-1); 682c18ec02fSPetter Reinholdtsen } 6833c34aa0eSZdenek Styblik } else { 684c18ec02fSPetter Reinholdtsen print_user_usage(); 685f8ce85eeSZdenek Styblik return (-1); 686c18ec02fSPetter Reinholdtsen } 6874d3decc4SZdenek Styblik return ipmi_print_user_summary(intf, channel); 6884d3decc4SZdenek Styblik } 6894d3decc4SZdenek Styblik 6904d3decc4SZdenek Styblik int 6914d3decc4SZdenek Styblik ipmi_user_list(struct ipmi_intf *intf, int argc, char **argv) 6924d3decc4SZdenek Styblik { 6933c34aa0eSZdenek Styblik /* List */ 694c18ec02fSPetter Reinholdtsen uint8_t channel; 6953c34aa0eSZdenek Styblik if (argc == 1) { 696c18ec02fSPetter Reinholdtsen channel = 0x0E; /* Ask about the current channel */ 6973c34aa0eSZdenek Styblik } else if (argc == 2) { 698140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[1], &channel) != 0) { 699c18ec02fSPetter Reinholdtsen return (-1); 700c18ec02fSPetter Reinholdtsen } 7013c34aa0eSZdenek Styblik } else { 702c18ec02fSPetter Reinholdtsen print_user_usage(); 703f8ce85eeSZdenek Styblik return (-1); 704c18ec02fSPetter Reinholdtsen } 7054d3decc4SZdenek Styblik return ipmi_print_user_list(intf, channel); 7064d3decc4SZdenek Styblik } 7074d3decc4SZdenek Styblik 7084d3decc4SZdenek Styblik int 7094d3decc4SZdenek Styblik ipmi_user_test(struct ipmi_intf *intf, int argc, char **argv) 7104d3decc4SZdenek Styblik { 7113c34aa0eSZdenek Styblik /* Test */ 712c18ec02fSPetter Reinholdtsen char *password = NULL; 713c18ec02fSPetter Reinholdtsen int password_length = 0; 714c18ec02fSPetter Reinholdtsen uint8_t user_id = 0; 7152aa5d8c9SZdenek Styblik /* a little irritating, isn't it */ 7162aa5d8c9SZdenek Styblik if (argc != 3 && argc != 4) { 7172aa5d8c9SZdenek Styblik print_user_usage(); 718f8ce85eeSZdenek Styblik return (-1); 7192aa5d8c9SZdenek Styblik } 720c18ec02fSPetter Reinholdtsen if (is_ipmi_user_id(argv[1], &user_id)) { 721c18ec02fSPetter Reinholdtsen return (-1); 722c18ec02fSPetter Reinholdtsen } 723c18ec02fSPetter Reinholdtsen if (str2int(argv[2], &password_length) != 0 724c18ec02fSPetter Reinholdtsen || (password_length != 16 && password_length != 20)) { 725c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, 726c18ec02fSPetter Reinholdtsen "Given password length '%s' is invalid.", 727c18ec02fSPetter Reinholdtsen argv[2]); 728c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Expected value is either 16 or 20."); 729c18ec02fSPetter Reinholdtsen return (-1); 730c18ec02fSPetter Reinholdtsen } 7313c34aa0eSZdenek Styblik if (argc == 3) { 732c18ec02fSPetter Reinholdtsen /* We need to prompt for a password */ 733befb2149SZdenek Styblik password = ask_password(user_id); 734c18ec02fSPetter Reinholdtsen if (password == NULL) { 735c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure"); 736f8ce85eeSZdenek Styblik return (-1); 737c18ec02fSPetter Reinholdtsen } 7383c34aa0eSZdenek Styblik } else { 739befb2149SZdenek Styblik password = argv[3]; 740c18ec02fSPetter Reinholdtsen } 741befb2149SZdenek Styblik return ipmi_user_test_password(intf, 742c18ec02fSPetter Reinholdtsen user_id, 743c18ec02fSPetter Reinholdtsen password, 744c18ec02fSPetter Reinholdtsen password_length == 20); 7454d3decc4SZdenek Styblik } 7464d3decc4SZdenek Styblik 7474d3decc4SZdenek Styblik int 7484d3decc4SZdenek Styblik ipmi_user_priv(struct ipmi_intf *intf, int argc, char **argv) 7494d3decc4SZdenek Styblik { 7504d3decc4SZdenek Styblik uint8_t channel = 0x0e; /* Use channel running on */ 751c97dbd34SZdenek Styblik uint8_t priv_level = 0; 752c97dbd34SZdenek Styblik uint8_t user_id = 0; 7534d3decc4SZdenek Styblik 7544d3decc4SZdenek Styblik if (argc != 3 && argc != 4) { 7554d3decc4SZdenek Styblik print_user_usage(); 7564d3decc4SZdenek Styblik return (-1); 7574d3decc4SZdenek Styblik } 7584d3decc4SZdenek Styblik if (argc == 4) { 759140add9dSZdenek Styblik if (is_ipmi_channel_num(argv[3], &channel) != 0) { 7604d3decc4SZdenek Styblik return (-1); 7614d3decc4SZdenek Styblik } 7624d3decc4SZdenek Styblik channel = (channel & 0x0f); 7634d3decc4SZdenek Styblik } 764140add9dSZdenek Styblik if (is_ipmi_user_priv_limit(argv[2], &priv_level) != 0 765c97dbd34SZdenek Styblik || is_ipmi_user_id(argv[1], &user_id) != 0) { 7664d3decc4SZdenek Styblik return (-1); 7674d3decc4SZdenek Styblik } 7684d3decc4SZdenek Styblik priv_level = (priv_level & 0x0f); 7694d3decc4SZdenek Styblik return ipmi_user_set_userpriv(intf,channel,user_id,priv_level); 7704d3decc4SZdenek Styblik } 7714d3decc4SZdenek Styblik 7724d3decc4SZdenek Styblik int 7734d3decc4SZdenek Styblik ipmi_user_mod(struct ipmi_intf *intf, int argc, char **argv) 7744d3decc4SZdenek Styblik { 7754d3decc4SZdenek Styblik /* Disable / Enable */ 7764d3decc4SZdenek Styblik uint8_t user_id; 7774d3decc4SZdenek Styblik uint8_t operation; 7784d3decc4SZdenek Styblik char null_password[16]; /* Not used, but required */ 7794d3decc4SZdenek Styblik 7804d3decc4SZdenek Styblik if (argc != 2) { 7814d3decc4SZdenek Styblik print_user_usage(); 7824d3decc4SZdenek Styblik return (-1); 7834d3decc4SZdenek Styblik } 7844d3decc4SZdenek Styblik if (is_ipmi_user_id(argv[1], &user_id)) { 7854d3decc4SZdenek Styblik return (-1); 7864d3decc4SZdenek Styblik } 7874d3decc4SZdenek Styblik memset(null_password, 0, sizeof(null_password)); 7884d3decc4SZdenek Styblik operation = (strncmp(argv[0], "disable", 7) == 0) ? 7894d3decc4SZdenek Styblik IPMI_PASSWORD_DISABLE_USER : IPMI_PASSWORD_ENABLE_USER; 7904d3decc4SZdenek Styblik 7914d3decc4SZdenek Styblik /* Last parameter is ignored */ 7924d3decc4SZdenek Styblik return ipmi_user_set_password(intf, user_id, operation, null_password, 0); 7934d3decc4SZdenek Styblik } 7944d3decc4SZdenek Styblik 7954d3decc4SZdenek Styblik int 7964d3decc4SZdenek Styblik ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv) 7974d3decc4SZdenek Styblik { 798c18ec02fSPetter Reinholdtsen char *password = NULL; 799ad77da20SZdenek Styblik uint8_t password_type = 16; 800c18ec02fSPetter Reinholdtsen uint8_t user_id = 0; 801c18ec02fSPetter Reinholdtsen if (is_ipmi_user_id(argv[2], &user_id)) { 802c18ec02fSPetter Reinholdtsen return (-1); 803c18ec02fSPetter Reinholdtsen } 804c18ec02fSPetter Reinholdtsen 8053c34aa0eSZdenek Styblik if (argc == 3) { 806c18ec02fSPetter Reinholdtsen /* We need to prompt for a password */ 807c18ec02fSPetter Reinholdtsen char *tmp; 808befb2149SZdenek Styblik password = ask_password(user_id); 809c18ec02fSPetter Reinholdtsen if (password == NULL) { 810c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure"); 811f8ce85eeSZdenek Styblik return (-1); 812c18ec02fSPetter Reinholdtsen } 813befb2149SZdenek Styblik tmp = ask_password(user_id); 814c18ec02fSPetter Reinholdtsen if (tmp == NULL) { 815c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "ipmitool: malloc failure"); 816c18ec02fSPetter Reinholdtsen return (-1); 817c18ec02fSPetter Reinholdtsen } 818c18ec02fSPetter Reinholdtsen if (strlen(password) != strlen(tmp) 819c18ec02fSPetter Reinholdtsen || strncmp(password, tmp, strlen(tmp))) { 820c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Passwords do not match."); 821f8ce85eeSZdenek Styblik return (-1); 822c18ec02fSPetter Reinholdtsen } 823c18ec02fSPetter Reinholdtsen } else { 824befb2149SZdenek Styblik password = argv[3]; 825ad77da20SZdenek Styblik if (argc > 4) { 826ad77da20SZdenek Styblik if ((str2uchar(argv[4], &password_type) != 0) 827ad77da20SZdenek Styblik || (password_type != 16 && password_type != 20)) { 828ad77da20SZdenek Styblik lprintf(LOG_ERR, "Invalid password length '%s'", argv[4]); 829ad77da20SZdenek Styblik return (-1); 830ad77da20SZdenek Styblik } 831ad77da20SZdenek Styblik } else { 832ad77da20SZdenek Styblik password_type = 16; 833ad77da20SZdenek Styblik } 834c18ec02fSPetter Reinholdtsen } 835c18ec02fSPetter Reinholdtsen 836c18ec02fSPetter Reinholdtsen if (password == NULL) { 837c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Unable to parse password argument."); 838f8ce85eeSZdenek Styblik return (-1); 8393c34aa0eSZdenek Styblik } else if (strlen(password) > 20) { 840c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Password is too long (> 20 bytes)"); 841f8ce85eeSZdenek Styblik return (-1); 842c18ec02fSPetter Reinholdtsen } 843c18ec02fSPetter Reinholdtsen 844befb2149SZdenek Styblik return ipmi_user_set_password(intf, 845c18ec02fSPetter Reinholdtsen user_id, 846c18ec02fSPetter Reinholdtsen IPMI_PASSWORD_SET_PASSWORD, 847c18ec02fSPetter Reinholdtsen password, 848ad77da20SZdenek Styblik password_type > 16); 8494d3decc4SZdenek Styblik } 8504d3decc4SZdenek Styblik 8514d3decc4SZdenek Styblik int 8524d3decc4SZdenek Styblik ipmi_user_name(struct ipmi_intf *intf, int argc, char **argv) 8534d3decc4SZdenek Styblik { 8543c34aa0eSZdenek Styblik /* Set Name */ 855c18ec02fSPetter Reinholdtsen uint8_t user_id = 0; 8563c34aa0eSZdenek Styblik if (argc != 4) { 857c18ec02fSPetter Reinholdtsen print_user_usage(); 858f8ce85eeSZdenek Styblik return (-1); 859c18ec02fSPetter Reinholdtsen } 860c18ec02fSPetter Reinholdtsen if (is_ipmi_user_id(argv[2], &user_id)) { 861c18ec02fSPetter Reinholdtsen return (-1); 862c18ec02fSPetter Reinholdtsen } 8633c34aa0eSZdenek Styblik if (strlen(argv[3]) > 16) { 864c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Username is too long (> 16 bytes)"); 865f8ce85eeSZdenek Styblik return (-1); 866c18ec02fSPetter Reinholdtsen } 867c18ec02fSPetter Reinholdtsen 8684d3decc4SZdenek Styblik return ipmi_user_set_username(intf, user_id, argv[3]); 8694d3decc4SZdenek Styblik } 8704d3decc4SZdenek Styblik 8714d3decc4SZdenek Styblik /* 8724d3decc4SZdenek Styblik * ipmi_user_main 8734d3decc4SZdenek Styblik * 8744d3decc4SZdenek Styblik * Upon entry to this function argv should contain our arguments 8754d3decc4SZdenek Styblik * specific to this subcommand 8764d3decc4SZdenek Styblik */ 8774d3decc4SZdenek Styblik int 8784d3decc4SZdenek Styblik ipmi_user_main(struct ipmi_intf *intf, int argc, char **argv) 8794d3decc4SZdenek Styblik { 8804d3decc4SZdenek Styblik if (argc == 0) { 8814d3decc4SZdenek Styblik lprintf(LOG_ERR, "Not enough parameters given."); 8824d3decc4SZdenek Styblik print_user_usage(); 8834d3decc4SZdenek Styblik return (-1); 8844d3decc4SZdenek Styblik } 8854d3decc4SZdenek Styblik if (strncmp(argv[0], "help", 4) == 0) { 8864d3decc4SZdenek Styblik /* Help */ 8874d3decc4SZdenek Styblik print_user_usage(); 8884d3decc4SZdenek Styblik return 0; 8894d3decc4SZdenek Styblik } else if (strncmp(argv[0], "summary", 7) == 0) { 8904d3decc4SZdenek Styblik return ipmi_user_summary(intf, argc, argv); 8914d3decc4SZdenek Styblik } else if (strncmp(argv[0], "list", 4) == 0) { 8924d3decc4SZdenek Styblik return ipmi_user_list(intf, argc, argv); 8934d3decc4SZdenek Styblik } else if (strncmp(argv[0], "test", 4) == 0) { 8944d3decc4SZdenek Styblik return ipmi_user_test(intf, argc, argv); 8954d3decc4SZdenek Styblik } else if (strncmp(argv[0], "set", 3) == 0) { 8964d3decc4SZdenek Styblik /* Set */ 8974d3decc4SZdenek Styblik if ((argc >= 3) 8984d3decc4SZdenek Styblik && (strncmp("password", argv[1], 8) == 0)) { 8994d3decc4SZdenek Styblik return ipmi_user_password(intf, argc, argv); 9004d3decc4SZdenek Styblik } else if ((argc >= 2) 9014d3decc4SZdenek Styblik && (strncmp("name", argv[1], 4) == 0)) { 9024d3decc4SZdenek Styblik return ipmi_user_name(intf, argc, argv); 9033c34aa0eSZdenek Styblik } else { 904c18ec02fSPetter Reinholdtsen print_user_usage(); 905f8ce85eeSZdenek Styblik return (-1); 906c18ec02fSPetter Reinholdtsen } 9073c34aa0eSZdenek Styblik } else if (strncmp(argv[0], "priv", 4) == 0) { 9084d3decc4SZdenek Styblik return ipmi_user_priv(intf, argc, argv); 9093c34aa0eSZdenek Styblik } else if ((strncmp(argv[0], "disable", 7) == 0) 9103c34aa0eSZdenek Styblik || (strncmp(argv[0], "enable", 6) == 0)) { 9114d3decc4SZdenek Styblik return ipmi_user_mod(intf, argc, argv); 9123c34aa0eSZdenek Styblik } else { 913c18ec02fSPetter Reinholdtsen lprintf(LOG_ERR, "Invalid user command: '%s'\n", argv[0]); 914c18ec02fSPetter Reinholdtsen print_user_usage(); 9154d3decc4SZdenek Styblik return (-1); 916c18ec02fSPetter Reinholdtsen } 917c18ec02fSPetter Reinholdtsen } 918