Skip to content

Improve clarity of the "set password" length argument #153

Merged
merged 4 commits into from
Sep 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 11 additions & 6 deletions doc/ipmitool.1.in
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,15 @@ system. It is thus recommended that IPMI password management only be done
over IPMIv2.0 \fIlanplus\fP interface or the system interface on the
local station.

For IPMI v1.5, the maximum password length is 16 characters.
Passwords longer than 16 characters will be truncated.
For IPMI v1.5, the maximum password length is 16 characters; longer
passwords might be truncated or rejected by the server, or rejected
by
.BR ipmitool .

For IPMI v2.0, the maximum password length is 20 characters; longer
passwords will be rejected by
.BR ipmitool .

For IPMI v2.0, the maximum password length is 20 characters;
longer passwords are truncated.
.SH "COMMANDS"
.TP
\fIhelp\fP
Expand Down Expand Up @@ -3526,12 +3530,13 @@ Displays a list of user information for all defined userids.

Sets the username associated with the given userid.
.TP
\fIpassword\fP <\fBuserid\fR> [<\fBpassword\fR>]
\fIpassword\fP <\fBuserid\fR> [<\fBpassword\fR> [<\fB16|20\fR>]]
.br

Sets the password for the given userid. If no password is given,
the password is cleared (set to the NULL password). Be careful when
removing passwords from administrator\-level accounts.
removing passwords from administrator\-level accounts. If specified,
16 or 20 determines the maximum password length.
.RE
.TP
\fIdisable\fP <\fBuserid\fR>
Expand Down
56 changes: 36 additions & 20 deletions lib/ipmi_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ print_user_usage(void)
lprintf(LOG_NOTICE,
" set name <user id> <username>");
lprintf(LOG_NOTICE,
" set password <user id> [<password> <16|20>]");
" set password <user id> [<password> [<16|20>]]");
gdttn marked this conversation as resolved.
Show resolved Hide resolved
lprintf(LOG_NOTICE,
" disable <user id>");
lprintf(LOG_NOTICE,
Expand Down Expand Up @@ -626,12 +626,17 @@ ipmi_user_mod(struct ipmi_intf *intf, int argc, char **argv)
return 0;
}

#define USER_PW_IPMI15_LEN 16 /* IPMI 1.5 only allowed for 16 bytes */
#define USER_PW_IPMI20_LEN 20 /* IPMI 2.0 allows for 20 bytes */
#define USER_PW_MAX_LEN USER_PW_IPMI20_LEN

int
ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv)
{
char *password = NULL;
int ccode = 0;
uint8_t password_type = 16;
uint8_t password_type = USER_PW_IPMI15_LEN;
size_t password_len;
uint8_t user_id = 0;
if (is_ipmi_user_id(argv[2], &user_id)) {
return (-1);
Expand All @@ -640,52 +645,63 @@ ipmi_user_password(struct ipmi_intf *intf, int argc, char **argv)
if (argc == 3) {
/* We need to prompt for a password */
char *tmp;
size_t tmplen;
password = ask_password(user_id);
if (!password) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return (-1);
}
tmp = ask_password(user_id);
tmplen = strnlen(tmp, USER_PW_MAX_LEN + 1);
if (!tmp) {
lprintf(LOG_ERR, "ipmitool: malloc failure");
return (-1);
}
if (strlen(password) != strlen(tmp)
|| strncmp(password, tmp, strlen(tmp))) {
lprintf(LOG_ERR, "Passwords do not match.");
if (strncmp(password, tmp, tmplen)) {
lprintf(LOG_ERR, "Passwords do not match or are "
"longer than %d", USER_PW_MAX_LEN);
return (-1);
}
} else {
password = argv[3];
if (argc > 4) {
if ((str2uchar(argv[4], &password_type) != 0)
|| (password_type != 16 && password_type != 20)) {
lprintf(LOG_ERR, "Invalid password length '%s'", argv[4]);
return (-1);
}
} else {
password_type = 16;
}
}

if (!password) {
lprintf(LOG_ERR, "Unable to parse password argument.");
return (-1);
} else if (strlen(password) > 20) {
lprintf(LOG_ERR, "Password is too long (> 20 bytes)");
}

password_len = strnlen(password, USER_PW_MAX_LEN + 1);

if (argc > 4) {
if ((str2uchar(argv[4], &password_type) != 0)
|| (password_type != USER_PW_IPMI15_LEN
&& password_type != USER_PW_IPMI20_LEN))
{
lprintf(LOG_ERR, "Invalid password length '%s'",
argv[4]);
return (-1);
}
} else if (password_len > USER_PW_IPMI15_LEN) {
password_type = USER_PW_IPMI20_LEN;
}

if (password_len > password_type) {
lprintf(LOG_ERR, "Password is too long (> %d bytes)",
password_type);
return (-1);
}

ccode = _ipmi_set_user_password(intf, user_id,
IPMI_PASSWORD_SET_PASSWORD, password,
password_type > 16);
IPMI_PASSWORD_SET_PASSWORD, password,
password_type > USER_PW_IPMI15_LEN);
if (eval_ccode(ccode) != 0) {
lprintf(LOG_ERR, "Set User Password command failed (user %d)",
user_id);
user_id);
return (-1);
} else {
printf("Set User Password command successful (user %d)\n",
user_id);
user_id);
return 0;
}
}
Expand Down