Mercurial > illumos > illumos-gate
changeset 10516:73cc1414bac0
6878550 libipmi: ipmi_user_iter() uses stale response data
6878552 libipmi: ipmi_get_user_name() issues wrong command
6878554 libipmi: ipmi_user_iter() needs to work with Sun ILOM
author | Eric Schrock <Eric.Schrock@Sun.COM> |
---|---|
date | Mon, 14 Sep 2009 10:13:26 -0700 |
parents | 95e125dab827 |
children | 43ea36a8f8b6 |
files | usr/src/lib/libipmi/common/ipmi_user.c |
diffstat | 1 files changed, 46 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libipmi/common/ipmi_user.c Mon Sep 14 08:35:38 2009 -0700 +++ b/usr/src/lib/libipmi/common/ipmi_user.c Mon Sep 14 10:13:26 2009 -0700 @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libipmi.h> #include <string.h> @@ -146,7 +144,7 @@ ipmi_cmd_t cmd, *resp; cmd.ic_netfn = IPMI_NETFN_APP; - cmd.ic_cmd = IPMI_CMD_GET_USER_ACCESS; + cmd.ic_cmd = IPMI_CMD_GET_USER_NAME; cmd.ic_lun = 0; cmd.ic_data = &uid; cmd.ic_dlen = sizeof (uid); @@ -182,24 +180,43 @@ void *data) { ipmi_get_user_access_t *resp; - uint8_t i; + uint8_t i, uid_max; ipmi_user_impl_t *uip; ipmi_user_t *up; const char *name; + uint8_t channel; + ipmi_deviceid_t *devid; ipmi_user_clear(ihp); + channel = IPMI_USER_CHANNEL_CURRENT; + /* - * First get the number of active users on the system by requesting the - * reserved user ID (0). + * Get the number of active users on the system by requesting the first + * user ID (1). */ - if ((resp = ipmi_get_user_access(ihp, - IPMI_USER_CHANNEL_CURRENT, 0)) == NULL) - return (-1); + if ((resp = ipmi_get_user_access(ihp, channel, 1)) == NULL) { + /* + * Some versions of the Sun ILOM have a bug which prevent the + * GET USER ACCESS command from succeeding over the default + * channel. If this fails and we are on ILOM, then attempt to + * use the standard channel (1) instead. + */ + if ((devid = ipmi_get_deviceid(ihp)) == NULL) + return (-1); - for (i = 1; i <= resp->igua_max_uid; i++) { - if ((resp = ipmi_get_user_access(ihp, - IPMI_USER_CHANNEL_CURRENT, i)) == NULL) + if (!ipmi_is_sun_ilom(devid)) + return (-1); + + channel = 1; + if ((resp = ipmi_get_user_access(ihp, channel, 1)) == NULL) + return (-1); + } + + uid_max = resp->igua_max_uid; + for (i = 1; i <= uid_max; i++) { + if (i != 1 && (resp = ipmi_get_user_access(ihp, + channel, i)) == NULL) return (-1); if ((uip = ipmi_zalloc(ihp, sizeof (ipmi_user_impl_t))) == NULL) @@ -215,11 +232,23 @@ ipmi_list_append(&ihp->ih_users, uip); - if ((name = ipmi_get_user_name(ihp, i)) == NULL) - return (-1); + /* + * If we are requesting a username that doesn't have a + * supported username, we may get an INVALID REQUEST response. + * If this is the case, then continue as if there is no known + * username. + */ + if ((name = ipmi_get_user_name(ihp, i)) == NULL) { + if (ipmi_errno(ihp) == EIPMI_INVALID_REQUEST) + continue; + else + return (-1); + } - if (*name != '\0' && - (up->iu_name = ipmi_strdup(ihp, name)) == NULL) + if (*name == '\0') + continue; + + if ((up->iu_name = ipmi_strdup(ihp, name)) == NULL) return (-1); }