From ac931daa86ca9240e91386b4bf223a985389fcb6 Mon Sep 17 00:00:00 2001 From: Jeremy Ellington Date: Fri, 1 Oct 2004 15:24:45 +0000 Subject: [PATCH] Added a subcommand for testing password (as well as password length per v.2). Also re-tabified. --- ipmitool/lib/ipmi_user.c | 400 +++++++++++++++++++++++++-------------- 1 file changed, 254 insertions(+), 146 deletions(-) diff --git a/ipmitool/lib/ipmi_user.c b/ipmitool/lib/ipmi_user.c index 869e38e..57cc2af 100644 --- a/ipmitool/lib/ipmi_user.c +++ b/ipmitool/lib/ipmi_user.c @@ -65,29 +65,29 @@ extern int csv_output; /* * ipmi_get_user_access * - * param intf [in] + * param intf [in] * param channel_number [in] - * param user_id [in] - * param user_access [out] + * param user_id [in] + * param user_access [out] * * return 0 on succes - * 1 on failure + * 1 on failure */ static int ipmi_get_user_access( - struct ipmi_intf * intf, - unsigned char channel_number, - unsigned char user_id, - struct user_access_rsp * user_access) + struct ipmi_intf * intf, + unsigned char channel_number, + unsigned char user_id, + struct user_access_rsp * user_access) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - unsigned char msg_data[2]; + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char msg_data[2]; memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ - req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */ + req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ + req.msg.cmd = IPMI_GET_USER_ACCESS; /* 0x44 */ req.msg.data = msg_data; req.msg.data_len = 2; @@ -101,13 +101,13 @@ ipmi_get_user_access( if (!rsp || rsp->ccode) { printf("Error:%x Get User Access Command (user 0x%x)\n", - rsp ? rsp->ccode : 0, msg_data[1]); + rsp ? rsp->ccode : 0, msg_data[1]); return -1; } memcpy(user_access, - rsp->data, - sizeof(struct user_access_rsp)); + rsp->data, + sizeof(struct user_access_rsp)); return 0; } @@ -117,28 +117,28 @@ ipmi_get_user_access( /* * ipmi_get_user_name * - * param intf [in] + * param intf [in] * param channel_number [in] - * param user_id [in] - * param user_name [out] + * param user_id [in] + * param user_name [out] * * return 0 on succes - * 1 on failure + * 1 on failure */ static int ipmi_get_user_name( - struct ipmi_intf * intf, - unsigned char user_id, - char * user_name) + struct ipmi_intf * intf, + unsigned char user_id, + char * user_name) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - unsigned char msg_data[1]; + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char msg_data[1]; memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ - req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */ + req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ + req.msg.cmd = IPMI_GET_USER_NAME; /* 0x45 */ req.msg.data = msg_data; req.msg.data_len = 1; @@ -149,7 +149,7 @@ ipmi_get_user_name( if (!rsp || rsp->ccode) { printf("Error:%x Get User Name Command (user 0x%x)\n", - rsp ? rsp->ccode : 0, msg_data[0]); + rsp ? rsp->ccode : 0, msg_data[0]); return -1; } @@ -163,54 +163,54 @@ ipmi_get_user_name( static void dump_user_access( - unsigned char user_id, - const char * user_name, - struct user_access_rsp * user_access) + unsigned char user_id, + const char * user_name, + struct user_access_rsp * user_access) { static int printed_header = 0; if (! printed_header) { - printf("ID Name Callin Link Auth IPMI Msg " - "Channel Priv Limit\n"); + printf("ID Name Callin Link Auth IPMI Msg " + "Channel Priv Limit\n"); printed_header = 1; } printf("%-4d%-17s%-8s%-11s%-11s%-s\n", - user_id, - user_name, - user_access->no_callin_access? "false": "true ", - user_access->link_auth_access? "true ": "false", - user_access->ipmi_messaging_access? "true ": "false", - val2str(user_access->channel_privilege_limit, - ipmi_privlvl_vals)); + user_id, + user_name, + user_access->no_callin_access? "false": "true ", + user_access->link_auth_access? "true ": "false", + user_access->ipmi_messaging_access? "true ": "false", + val2str(user_access->channel_privilege_limit, + ipmi_privlvl_vals)); } static void dump_user_access_csv( - unsigned char user_id, - const char * user_name, - struct user_access_rsp * user_access) + unsigned char user_id, + const char * user_name, + struct user_access_rsp * user_access) { printf("%d,%s,%s,%s,%s,%s\n", - user_id, - user_name, - user_access->no_callin_access? "false": "true", - user_access->link_auth_access? "true": "false", - user_access->ipmi_messaging_access? "true": "false", - val2str(user_access->channel_privilege_limit, - ipmi_privlvl_vals)); + user_id, + user_name, + user_access->no_callin_access? "false": "true", + user_access->link_auth_access? "true": "false", + user_access->ipmi_messaging_access? "true": "false", + val2str(user_access->channel_privilege_limit, + ipmi_privlvl_vals)); } static int ipmi_print_user_list( - struct ipmi_intf * intf, - unsigned char channel_number) + struct ipmi_intf * intf, + unsigned char channel_number) { /* This is where you were! */ char user_name[17]; @@ -221,33 +221,36 @@ ipmi_print_user_list( do { if (ipmi_get_user_access(intf, - channel_number, - current_user_id, - &user_access)) + channel_number, + current_user_id, + &user_access)) return -1; if (ipmi_get_user_name(intf, - current_user_id, - user_name)) + current_user_id, + user_name)) return -1; - if ((current_user_id == 0) || - user_access.link_auth_access || - user_access.ipmi_messaging_access || - strcmp("", user_name)) + if ((current_user_id == 0) || + user_access.link_auth_access || + user_access.ipmi_messaging_access || + strcmp("", user_name)) { if (csv_output) - dump_user_access_csv(current_user_id, user_name, &user_access); + dump_user_access_csv(current_user_id, + user_name, &user_access); else - dump_user_access(current_user_id, user_name, &user_access); + dump_user_access(current_user_id, + user_name, + &user_access); } ++current_user_id; } while((current_user_id < user_access.maximum_ids) && - (current_user_id < 63)); /* Absolute maximum allowed by spec */ + (current_user_id < 63)); /* Absolute maximum allowed by spec */ return 0; @@ -257,32 +260,32 @@ ipmi_print_user_list( static int ipmi_print_user_summary( - struct ipmi_intf * intf, - unsigned char channel_number) + struct ipmi_intf * intf, + unsigned char channel_number) { struct user_access_rsp user_access; if (ipmi_get_user_access(intf, - channel_number, - 1, - &user_access)) + channel_number, + 1, + &user_access)) return -1; if (csv_output) { printf("%d,%d,%d\n", - user_access.maximum_ids, - user_access.enabled_user_count, - user_access.fixed_name_count); + user_access.maximum_ids, + user_access.enabled_user_count, + user_access.fixed_name_count); } else { - printf("Maximum IDs : %d\n", - user_access.maximum_ids); + printf("Maximum IDs : %d\n", + user_access.maximum_ids); printf("Enabled User Count : %d\n", - user_access.enabled_user_count); + user_access.enabled_user_count); printf("Fixed Name Count : %d\n", - user_access.fixed_name_count); + user_access.fixed_name_count); } return 0; @@ -295,17 +298,17 @@ ipmi_print_user_summary( */ static int ipmi_user_set_username( - struct ipmi_intf * intf, - unsigned char user_id, - const char * name) + struct ipmi_intf * intf, + unsigned char user_id, + const char * name) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - unsigned char msg_data[17]; + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char msg_data[17]; memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ - req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */ + req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ + req.msg.cmd = IPMI_SET_USER_NAME; /* 0x45 */ req.msg.data = msg_data; req.msg.data_len = 17; @@ -320,7 +323,7 @@ ipmi_user_set_username( if (!rsp || rsp->ccode) { printf("Error:%x Set User Name Command\n", - rsp ? rsp->ccode : 0); + rsp ? rsp->ccode : 0); return -1; } @@ -339,46 +342,91 @@ ipmi_user_set_username( */ static int ipmi_user_set_password( - struct ipmi_intf * intf, - unsigned char user_id, - unsigned char operation, - const char * password) + struct ipmi_intf * intf, + unsigned char user_id, + unsigned char operation, + const char * password, + int is_twenty_byte_password) { - struct ipmi_rs * rsp; - struct ipmi_rq req; - unsigned char msg_data[18]; + struct ipmi_rs * rsp; + struct ipmi_rq req; + char * msg_data; + int ret = 0; + + int password_length = (is_twenty_byte_password? 20 : 16); + + msg_data = (char*)malloc(password_length + 2); + memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ - req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */ + req.msg.netfn = IPMI_NETFN_APP; /* 0x06 */ + req.msg.cmd = IPMI_SET_USER_PASSWORD; /* 0x47 */ req.msg.data = msg_data; - req.msg.data_len = 18; + req.msg.data_len = password_length + 2; /* The channel number will remain constant throughout this function */ msg_data[0] = user_id; + + if (is_twenty_byte_password) + msg_data[0] |= 0x80; + msg_data[1] = operation; - memset(msg_data + 2, 0, 16); + memset(msg_data + 2, 0, password_length); if (password) - strcpy(msg_data + 2, password); + strncpy(msg_data + 2, password, password_length); rsp = intf->sendrecv(intf, &req); if (!rsp || rsp->ccode) { printf("Error:%x Set User Password Command\n", - rsp ? rsp->ccode : 0); - return -1; + rsp ? rsp->ccode : 0); + ret = (rsp? rsp->ccode : -1); } - return 0; + return ret; } +/* + * ipmi_user_test_password + * + * Call ipmi_user_set_password, and interpret the result + */ +static int +ipmi_user_test_password( + struct ipmi_intf * intf, + unsigned char user_id, + const char * password, + int is_twenty_byte_password) +{ + int ret; + + ret = ipmi_user_set_password(intf, + user_id, + IPMI_PASSWORD_TEST_PASSWORD, + password, + is_twenty_byte_password); + + if (! ret) + printf("Success\n"); + else if (ret == 0x80) + printf("Failure: password incorrect\n"); + else if (ret == 0x81) + printf("Failure: wrong password size\n"); + else + printf("Unknown error\n"); + + return (ret ? -1 : 0); +} + + + /* * print_user_usage */ @@ -387,29 +435,17 @@ print_user_usage() { printf("\n"); printf("User Commands: summary []\n"); - printf(" list []\n"); - printf(" set name \n"); - printf(" set password []\n"); - printf(" disable []\n"); - printf(" enable []\n"); - + printf(" list []\n"); + printf(" set name \n"); + printf(" set password []\n"); + printf(" disable []\n"); + printf(" enable []\n"); + printf(" test <16|20> [\n"); printf("\n"); } -/* - * - */ -void -print_user_set_usage() -{ - printf("\nUser set parameters and values: \n\n"); - printf(" name \n"); - printf(" password \n"); - printf("\n"); -} - const char * ipmi_user_build_password_prompt(unsigned char user_id) @@ -462,7 +498,7 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) /* * List */ - else if (!strncmp(argv[0], "list", 4)) { + else if (!strncmp(argv[0], "list", 4)) { unsigned char channel; if (argc == 1) @@ -478,6 +514,67 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) retval = ipmi_print_user_list(intf, channel); } + + + /* + * Test + */ + else if (!strncmp(argv[0], "test", 4)) + { + // a little fucking irritating, isn't it + if ((argc == 3 || argc == 4) && + ((!strncmp(argv[2], "16", 2)) || + (!strncmp(argv[2], "20", 2)))) + { + char * password = NULL; + int password_length = atoi(argv[2]); + unsigned char user_id = (unsigned char)strtol(argv[1], + NULL, + 0); + if (! user_id) + { + printf("Error. Invalid user ID: %d\n", user_id); + return -1; + } + + + if (argc == 3) + { + /* We need to prompt for a password */ + + char * tmp; + const char * password_prompt = + ipmi_user_build_password_prompt(user_id); + +#ifdef HAVE_GETPASSPHRASE + if ((tmp = getpassphrase (password_prompt))) +#else + if ((tmp = (char*)getpass(password_prompt))) +#endif + { + password = strdup(tmp); + + } + + } + else + password = argv[3]; + + + retval = ipmi_user_test_password(intf, + user_id, + password, + password_length == 20); + + + } + else + { + print_user_usage(); + return -1; + } + } + /* * Set @@ -487,13 +584,13 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) /* * Set Password */ - if ((argc >= 3) && - (! strcmp("password", argv[1]))) + if ((argc >= 3) && + (! strcmp("password", argv[1]))) { char * password = NULL; unsigned char user_id = (unsigned char)strtol(argv[2], - NULL, - 0); + NULL, + 0); if (! user_id) { printf("Error. Invalid user ID: %d\n", user_id); @@ -520,23 +617,32 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) #ifdef HAVE_GETPASSPHRASE if ((tmp = getpassphrase (password_prompt))) #else - if ((tmp = (char*)getpass (password_prompt))) + if ((tmp = (char*)getpass (password_prompt))) #endif - { - if (strcmp(password, tmp)) { - printf("Error. Passwords to not match.\n"); - return -1; + if (strcmp(password, tmp)) + { + printf("Error. Passwords to not match.\n"); + return -1; + } } - } } } + else + password = argv[3]; + + if (strlen(password) > 20) + { + printf("Error. Password is too long (> 20 bytes).\n"); + return -1; + } retval = ipmi_user_set_password(intf, - user_id, - IPMI_PASSWORD_SET_PASSWORD, - argc == 4? argv[3]: password); + user_id, + IPMI_PASSWORD_SET_PASSWORD, + password, + strlen(password) > 16); } @@ -544,23 +650,23 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) * Set Name */ else if ((argc >= 2) && - (! strcmp("name", argv[1]))) + (! strcmp("name", argv[1]))) { if (argc != 4) { - print_user_set_usage(); + print_user_usage(); return -1; } retval = ipmi_user_set_username(intf, - (unsigned char)strtol(argv[2], - NULL, - 0), - argv[3]); + (unsigned char)strtol(argv[2], + NULL, + 0), + argv[3]); } else { - print_user_set_usage(); + print_user_usage(); return -1; } } @@ -570,7 +676,7 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) * Disable / Enable */ else if ((!strncmp(argv[0], "disable", 7)) || - (!strncmp(argv[0], "enable", 6))) + (!strncmp(argv[0], "enable", 6))) { unsigned char user_id; unsigned char operation; @@ -585,8 +691,8 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) } user_id = (unsigned char)strtol(argv[1], - NULL, - 0); + NULL, + 0); if (! user_id) { printf("Error. Invalid user ID: %d\n", user_id); @@ -598,12 +704,14 @@ ipmi_user_main(struct ipmi_intf * intf, int argc, char ** argv) IPMI_PASSWORD_DISABLE_USER: IPMI_PASSWORD_ENABLE_USER; retval = ipmi_user_set_password(intf, - user_id, - operation, - null_password); + user_id, + operation, + null_password, + 0); /* This field is ignored */ } + else { print_user_usage();