Mercurial > illumos > illumos-gate
changeset 9266:133cda0d0b82
6803906 itadm does not fold iqn names to lower case
6792253 itadm.c uninitialized access
author | Sam Cramer <Sam.Cramer@Sun.COM> |
---|---|
date | Thu, 02 Apr 2009 16:46:36 -0600 |
parents | 0ddbce3734dc |
children | 35175e0c3043 |
files | usr/src/cmd/itadm/itadm.c |
diffstat | 1 files changed, 97 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/itadm/itadm.c Thu Apr 02 15:17:01 2009 -0600 +++ b/usr/src/cmd/itadm/itadm.c Thu Apr 02 16:46:36 2009 -0600 @@ -71,6 +71,9 @@ }\ } +#define IS_IQN_NAME(s) (strncmp((s), "iqn.", 4) == 0) + + static struct option itadm_long[] = { {"alias", required_argument, NULL, 'l'}, {"auth-method", required_argument, NULL, 'a'}, @@ -219,6 +222,12 @@ static void tag_name_to_num(char *tagname, uint16_t *tagnum); +static char * +canonical_target_name(char *tgt); + +static char * +strduplc(char *s); + /* prototype from iscsit_common.h */ extern int sockaddr_to_str(struct sockaddr_storage *sa, char **addr); @@ -606,13 +615,14 @@ uint16_t tagid = 0; it_tpgt_t *tpgt; char *sec = "solaris.smf.modify.stmf"; + char *canonical_tgt = NULL; + boolean_t did_it_config_load = B_FALSE; ITADM_CHKAUTH(sec); if (tgt) { /* - * validate input name - what are the rules for EUI - * and IQN values? + * Validate target name. */ if ((strncmp(tgt, "eui.", 4) != 0) && (strncmp(tgt, "iqn.", 4) != 0)) { @@ -621,6 +631,8 @@ (void) fprintf(stderr, "\n"); return (EINVAL); } + + canonical_tgt = canonical_target_name(tgt); } ret = it_config_load(&cfg); @@ -629,10 +641,12 @@ gettext("Error retrieving iSCSI target configuration: %d"), ret); (void) fprintf(stderr, "\n"); - return (ret); + goto done; } - ret = it_tgt_create(cfg, &tgtp, tgt); + did_it_config_load = B_TRUE; + + ret = it_tgt_create(cfg, &tgtp, canonical_tgt); if (ret != 0) { if (ret == EFAULT) { (void) fprintf(stderr, @@ -754,7 +768,11 @@ (void) printf("\n"); } - it_config_free(cfg); + if (did_it_config_load) + it_config_free(cfg); + + if (canonical_tgt != NULL) + free(canonical_tgt); return (ret); } @@ -809,7 +827,11 @@ } if (tgt) { - if (strcmp(tgt, ptr->tgt_name) != 0) { + /* + * We do a case-insensitive match in case + * a non-lower case value got stored. + */ + if (strcasecmp(tgt, ptr->tgt_name) != 0) { continue; } else { found = B_TRUE; @@ -964,7 +986,11 @@ ptr = cfg->config_tgt_list; while (ptr) { - if (strcmp(ptr->tgt_name, tgt) == 0) { + /* + * We do a case-insensitive match in case + * a non-lower case value got stored. + */ + if (strcasecmp(ptr->tgt_name, tgt) == 0) { break; } @@ -1015,6 +1041,8 @@ uint16_t tagid; it_tpgt_t *tpgt = NULL; char *sec = "solaris.smf.modify.stmf"; + char *canonical_newname = NULL; + boolean_t did_it_config_load = B_FALSE; ITADM_CHKAUTH(sec); @@ -1023,7 +1051,8 @@ if (!tgt) { (void) fprintf(stderr, "%s\n", gettext("Error, no target specified")); - return (EINVAL); + ret = EINVAL; + goto done; } ret = it_config_load(&cfg); @@ -1032,19 +1061,25 @@ gettext("Error retrieving iSCSI target configuration: %d"), ret); (void) fprintf(stderr, "\n"); - return (ret); + goto done; } + did_it_config_load = B_TRUE; + /* - * If newname is specified, ensure it is a valid name + * If newname is specified, ensure it is a valid name, + * and generate its canonical form. */ if (newname) { if (!validate_iscsi_name(newname)) { (void) fprintf(stderr, gettext("Invalid iSCSI name %s"), newname); (void) fprintf(stderr, "\n"); - return (1); + ret = 1; + goto done; } + + canonical_newname = canonical_target_name(newname); } /* @@ -1054,7 +1089,11 @@ */ ptr = cfg->config_tgt_list; while (ptr) { - if (newname && (strcmp(newname, ptr->tgt_name) == 0)) { + /* + * Does a target with the new name already exist? + */ + if (newname && + (strcmp(canonical_newname, ptr->tgt_name) == 0)) { (void) fprintf(stderr, gettext("A target with name %s already exists"), newname); @@ -1063,7 +1102,7 @@ goto done; } - if (strcmp(ptr->tgt_name, tgt) == 0) { + if (strcasecmp(ptr->tgt_name, tgt) == 0) { tgtp = ptr; } @@ -1074,8 +1113,8 @@ (void) fprintf(stderr, gettext("Target %s not found"), tgt); (void) fprintf(stderr, "\n"); - it_config_free(cfg); - return (EINVAL); + ret = EINVAL; + goto done; } /* set the target portal group tags */ @@ -1098,7 +1137,7 @@ } for (i = 0; i < count; i++) { - if (!tags[i]) { + if (!tags || !tags[i]) { continue; } @@ -1153,7 +1192,7 @@ /* see if there are any left to add */ for (i = 0; i < count; i++) { - if (!tags[i]) { + if (!tags || !tags[i]) { continue; } @@ -1191,7 +1230,7 @@ gettext("Error renaming target.")); goto done; } - (void) strlcpy(tgtp->tgt_name, newname, + (void) strlcpy(tgtp->tgt_name, canonical_newname, sizeof (tgtp->tgt_name)); } @@ -1235,7 +1274,11 @@ (void) printf("\n"); } - it_config_free(cfg); + if (did_it_config_load) + it_config_free(cfg); + + if (canonical_newname != NULL) + free(canonical_newname); return (ret); } @@ -2136,3 +2179,38 @@ *tagnum = (uint16_t)id; } } + +/* + * Return a new string containing the canonical (lower-case) + * form of the target name. + */ +static char * +canonical_target_name(char *tgt) +{ + if (IS_IQN_NAME(tgt)) { + /* lowercase iqn names */ + return (strduplc(tgt)); + } else { + return (strdup(tgt)); + } +} + +/* + * Duplicate a string, converting it to lower case in the process. + * Returns NULL if no memory. + */ +static char * +strduplc(char *s) +{ + char *lc = strdup(s); + + if (lc != NULL) { + char *l = lc; + while (*s) { + *l = tolower(*s); + s++; l++; + } + } + + return (lc); +}