1a6d42e7dSPeter Dunlap /* 2a6d42e7dSPeter Dunlap * CDDL HEADER START 3a6d42e7dSPeter Dunlap * 4a6d42e7dSPeter Dunlap * The contents of this file are subject to the terms of the 5a6d42e7dSPeter Dunlap * Common Development and Distribution License (the "License"). 6a6d42e7dSPeter Dunlap * You may not use this file except in compliance with the License. 7a6d42e7dSPeter Dunlap * 8a6d42e7dSPeter Dunlap * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9a6d42e7dSPeter Dunlap * or http://www.opensolaris.org/os/licensing. 10a6d42e7dSPeter Dunlap * See the License for the specific language governing permissions 11a6d42e7dSPeter Dunlap * and limitations under the License. 12a6d42e7dSPeter Dunlap * 13a6d42e7dSPeter Dunlap * When distributing Covered Code, include this CDDL HEADER in each 14a6d42e7dSPeter Dunlap * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15a6d42e7dSPeter Dunlap * If applicable, add the following below this CDDL HEADER, with the 16a6d42e7dSPeter Dunlap * fields enclosed by brackets "[]" replaced with your own identifying 17a6d42e7dSPeter Dunlap * information: Portions Copyright [yyyy] [name of copyright owner] 18a6d42e7dSPeter Dunlap * 19a6d42e7dSPeter Dunlap * CDDL HEADER END 20a6d42e7dSPeter Dunlap */ 21a6d42e7dSPeter Dunlap /* 22836fc322SSam Cramer * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23a6d42e7dSPeter Dunlap * Use is subject to license terms. 24a6d42e7dSPeter Dunlap */ 25a6d42e7dSPeter Dunlap #include <stdlib.h> 26a6d42e7dSPeter Dunlap #include <stdio.h> 27a6d42e7dSPeter Dunlap #include <sys/types.h> 28a6d42e7dSPeter Dunlap #include <sys/stat.h> 29a6d42e7dSPeter Dunlap #include <fcntl.h> 30a6d42e7dSPeter Dunlap #include <unistd.h> 31a6d42e7dSPeter Dunlap #include <errno.h> 32a6d42e7dSPeter Dunlap #include <string.h> 33a6d42e7dSPeter Dunlap #include <getopt.h> 34a6d42e7dSPeter Dunlap #include <strings.h> 35a6d42e7dSPeter Dunlap #include <ctype.h> 36a6d42e7dSPeter Dunlap #include <libnvpair.h> 37a6d42e7dSPeter Dunlap #include <libintl.h> 38a6d42e7dSPeter Dunlap #include <libgen.h> 39a6d42e7dSPeter Dunlap #include <pwd.h> 40a6d42e7dSPeter Dunlap #include <auth_attr.h> 41a6d42e7dSPeter Dunlap #include <secdb.h> 42a6d42e7dSPeter Dunlap #include <libscf.h> 43a6d42e7dSPeter Dunlap #include <limits.h> 44a6d42e7dSPeter Dunlap #include <locale.h> 45a6d42e7dSPeter Dunlap 46a6d42e7dSPeter Dunlap #include <libstmf.h> 47a6d42e7dSPeter Dunlap #include <libiscsit.h> 48a6d42e7dSPeter Dunlap 49a6d42e7dSPeter Dunlap /* what's this used for?? */ 50a6d42e7dSPeter Dunlap #define ITADM_VERSION "1.0" 51a6d42e7dSPeter Dunlap 52a6d42e7dSPeter Dunlap /* SMF service info */ 53a6d42e7dSPeter Dunlap #define ISCSIT_SVC "svc:/network/iscsi/target:default" 54a6d42e7dSPeter Dunlap 55a6d42e7dSPeter Dunlap #define STMF_STALE(ret) {\ 56a6d42e7dSPeter Dunlap if (ret == STMF_ERROR_PROV_DATA_STALE) {\ 57a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n",\ 58a6d42e7dSPeter Dunlap gettext("Configuration changed during processing. "\ 59a6d42e7dSPeter Dunlap "Check the configuration, then retry this command "\ 60a6d42e7dSPeter Dunlap "if appropriate."));\ 61a6d42e7dSPeter Dunlap }\ 62a6d42e7dSPeter Dunlap } 63a6d42e7dSPeter Dunlap 64a6d42e7dSPeter Dunlap #define ITADM_CHKAUTH(sec) {\ 65a6d42e7dSPeter Dunlap if (!chkauthattr(sec, itadm_uname)) {\ 66a6d42e7dSPeter Dunlap (void) fprintf(stderr,\ 67a6d42e7dSPeter Dunlap gettext("Error, operation requires authorization %s"),\ 68a6d42e7dSPeter Dunlap sec);\ 69a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n");\ 70a6d42e7dSPeter Dunlap return (1);\ 71a6d42e7dSPeter Dunlap }\ 72a6d42e7dSPeter Dunlap } 73a6d42e7dSPeter Dunlap 74*a4f92191SSam Cramer #define IS_IQN_NAME(s) (strncmp((s), "iqn.", 4) == 0) 75*a4f92191SSam Cramer 76*a4f92191SSam Cramer 77a6d42e7dSPeter Dunlap static struct option itadm_long[] = { 78a6d42e7dSPeter Dunlap {"alias", required_argument, NULL, 'l'}, 79a6d42e7dSPeter Dunlap {"auth-method", required_argument, NULL, 'a'}, 80a6d42e7dSPeter Dunlap {"chap-secret", no_argument, NULL, 's'}, 81a6d42e7dSPeter Dunlap {"chap-secret-file", required_argument, NULL, 'S'}, 82a6d42e7dSPeter Dunlap {"chap-user", required_argument, NULL, 'u'}, 83a6d42e7dSPeter Dunlap {"force", no_argument, NULL, 'f'}, 84a6d42e7dSPeter Dunlap {"help", no_argument, NULL, 'h'}, 85a6d42e7dSPeter Dunlap {"help", no_argument, NULL, '?'}, 86a6d42e7dSPeter Dunlap {"isns", required_argument, NULL, 'i'}, 87a6d42e7dSPeter Dunlap {"isns-server", required_argument, NULL, 'I'}, 88a6d42e7dSPeter Dunlap {"node-name", required_argument, NULL, 'n'}, 89a6d42e7dSPeter Dunlap {"radius-secret", no_argument, NULL, 'd'}, 90a6d42e7dSPeter Dunlap {"radius-secret-file", required_argument, NULL, 'D'}, 91a6d42e7dSPeter Dunlap {"radius-server", required_argument, NULL, 'r'}, 92a6d42e7dSPeter Dunlap {"tpg-tag", required_argument, NULL, 't'}, 93a6d42e7dSPeter Dunlap {"verbose", no_argument, NULL, 'v'}, 94a6d42e7dSPeter Dunlap {"version", no_argument, NULL, 'V'}, 95a6d42e7dSPeter Dunlap {NULL, 0, NULL, 0} 96a6d42e7dSPeter Dunlap }; 97a6d42e7dSPeter Dunlap 98a6d42e7dSPeter Dunlap char c_tgt[] = "itadm create-target [-a radius|chap|none|default] [-s] \ 99a6d42e7dSPeter Dunlap [-S chap-secret-path] [-u chap-username] [-n target-node-name] \ 100a6d42e7dSPeter Dunlap [-l alias] [-t tpg-name[,tpg-name,...]]"; 101a6d42e7dSPeter Dunlap 102a6d42e7dSPeter Dunlap static char m_tgt[] = "itadm modify-target [-a radius|chap|none|default] [-s] \ 103a6d42e7dSPeter Dunlap [-S chap-secret-path] [-u chap-username] [-n new-target-node-name] \ 104a6d42e7dSPeter Dunlap [-l alias] [-t tpg-name[,tpg-name,...]] target-node-name"; 105a6d42e7dSPeter Dunlap 106a6d42e7dSPeter Dunlap static char d_tgt[] = "itadm delete-target [-f] target-node-name"; 107a6d42e7dSPeter Dunlap 108a6d42e7dSPeter Dunlap static char l_tgt[] = "itadm list-target [-v] [target-node-name"; 109a6d42e7dSPeter Dunlap 110a6d42e7dSPeter Dunlap static char c_tpg[] = "itadm create-tpg tpg-name IP-address[:port] \ 111a6d42e7dSPeter Dunlap [IP-address[:port]] [...]"; 112a6d42e7dSPeter Dunlap 113a6d42e7dSPeter Dunlap static char l_tpg[] = "itadm list-tpg [-v] [tpg-name]"; 114a6d42e7dSPeter Dunlap 115a6d42e7dSPeter Dunlap static char d_tpg[] = "itadm delete-tpg [-f] tpg-name"; 116a6d42e7dSPeter Dunlap 117a6d42e7dSPeter Dunlap static char c_ini[] = "itadm create-initiator [-s] [-S chap-secret-path] \ 118a6d42e7dSPeter Dunlap [-u chap-username] initiator-node-name"; 119a6d42e7dSPeter Dunlap 120a6d42e7dSPeter Dunlap static char m_ini[] = "itadm modify-initiator [-s] [-S chap-secret-path] \ 121a6d42e7dSPeter Dunlap [-u chap-username] initiator-node-name"; 122a6d42e7dSPeter Dunlap 123a6d42e7dSPeter Dunlap static char l_ini[] = "itadm list-initiator [-v] initiator-node-name"; 124a6d42e7dSPeter Dunlap 125a6d42e7dSPeter Dunlap static char d_ini[] = "itadm delete-inititator initiator-node-name"; 126a6d42e7dSPeter Dunlap 127a6d42e7dSPeter Dunlap static char m_def[] = "itadm modify-defaults [-a radius|chap|none] \ 128a6d42e7dSPeter Dunlap [-r IP-address[:port]] [-d] [-D radius-secret-path] [-i enable|disable] \ 129a6d42e7dSPeter Dunlap [-I IP-address[:port][,IP-adddress[:port]]]"; 130a6d42e7dSPeter Dunlap 131a6d42e7dSPeter Dunlap static char l_def[] = "itadm list-defaults"; 132a6d42e7dSPeter Dunlap 133a6d42e7dSPeter Dunlap 134a6d42e7dSPeter Dunlap /* keep the order of this enum in the same order as the 'subcmds' struct */ 135a6d42e7dSPeter Dunlap typedef enum { 136a6d42e7dSPeter Dunlap CREATE_TGT, 137a6d42e7dSPeter Dunlap MODIFY_TGT, 138a6d42e7dSPeter Dunlap DELETE_TGT, 139a6d42e7dSPeter Dunlap LIST_TGT, 140a6d42e7dSPeter Dunlap CREATE_TPG, 141a6d42e7dSPeter Dunlap DELETE_TPG, 142a6d42e7dSPeter Dunlap LIST_TPG, 143a6d42e7dSPeter Dunlap CREATE_INI, 144a6d42e7dSPeter Dunlap MODIFY_INI, 145a6d42e7dSPeter Dunlap LIST_INI, 146a6d42e7dSPeter Dunlap DELETE_INI, 147a6d42e7dSPeter Dunlap MODIFY_DEF, 148a6d42e7dSPeter Dunlap LIST_DEF, 149a6d42e7dSPeter Dunlap NULL_SUBCMD /* must always be last! */ 150a6d42e7dSPeter Dunlap } itadm_sub_t; 151a6d42e7dSPeter Dunlap 152a6d42e7dSPeter Dunlap typedef struct { 153a6d42e7dSPeter Dunlap char *name; 154a6d42e7dSPeter Dunlap char *shortopts; 155a6d42e7dSPeter Dunlap char *usemsg; 156a6d42e7dSPeter Dunlap } itadm_subcmds_t; 157a6d42e7dSPeter Dunlap 158a6d42e7dSPeter Dunlap static itadm_subcmds_t subcmds[] = { 159a6d42e7dSPeter Dunlap {"create-target", ":a:sS:u:n:l:t:h?", c_tgt}, 160a6d42e7dSPeter Dunlap {"modify-target", ":a:sS:u:n:l:t:h?", m_tgt}, 161a6d42e7dSPeter Dunlap {"delete-target", ":fh?", d_tgt}, 162a6d42e7dSPeter Dunlap {"list-target", ":vh?", l_tgt}, 163a6d42e7dSPeter Dunlap {"create-tpg", ":h?", c_tpg}, 164a6d42e7dSPeter Dunlap {"delete-tpg", ":fh?", d_tpg}, 165a6d42e7dSPeter Dunlap {"list-tpg", ":vh?", l_tpg}, 166a6d42e7dSPeter Dunlap {"create-initiator", ":sS:u:h?", c_ini}, 167a6d42e7dSPeter Dunlap {"modify-initiator", ":sS:u:h?", m_ini}, 168a6d42e7dSPeter Dunlap {"list-initiator", ":vh?", l_ini}, 169a6d42e7dSPeter Dunlap {"delete-initiator", ":h?", d_ini}, 170a6d42e7dSPeter Dunlap {"modify-defaults", ":a:r:dD:i:I:h?", m_def}, 171a6d42e7dSPeter Dunlap {"list-defaults", ":h?", l_def}, 172a6d42e7dSPeter Dunlap {NULL, ":h?", NULL}, 173a6d42e7dSPeter Dunlap }; 174a6d42e7dSPeter Dunlap 175a6d42e7dSPeter Dunlap /* used for checking if user is authorized */ 176a6d42e7dSPeter Dunlap static char *itadm_uname = NULL; 177a6d42e7dSPeter Dunlap 178a6d42e7dSPeter Dunlap /* prototypes */ 179a6d42e7dSPeter Dunlap static int 180a6d42e7dSPeter Dunlap itadm_get_password(nvlist_t *nvl, char *key, char *passfile, 181a6d42e7dSPeter Dunlap char *phrase); 182a6d42e7dSPeter Dunlap 183a6d42e7dSPeter Dunlap static int 184a6d42e7dSPeter Dunlap itadm_opt_to_arr(nvlist_t *nvl, char *key, char *opt, uint32_t *num); 185a6d42e7dSPeter Dunlap 186a6d42e7dSPeter Dunlap static int 187a6d42e7dSPeter Dunlap create_target(char *tgt, nvlist_t *proplist); 188a6d42e7dSPeter Dunlap 189a6d42e7dSPeter Dunlap static int 190a6d42e7dSPeter Dunlap modify_target(char *tgt, char *new, nvlist_t *proplist); 191a6d42e7dSPeter Dunlap 192a6d42e7dSPeter Dunlap static int 193a6d42e7dSPeter Dunlap delete_target(char *tgt, boolean_t force); 194a6d42e7dSPeter Dunlap 195a6d42e7dSPeter Dunlap static int 196a6d42e7dSPeter Dunlap list_target(char *tgt, boolean_t verbose, boolean_t script); 197a6d42e7dSPeter Dunlap 198a6d42e7dSPeter Dunlap static int 199a6d42e7dSPeter Dunlap create_tpg(char *tpg, int addrc, char **addrs); 200a6d42e7dSPeter Dunlap 201a6d42e7dSPeter Dunlap static int 202a6d42e7dSPeter Dunlap list_tpg(char *tpg, boolean_t verbose, boolean_t script); 203a6d42e7dSPeter Dunlap 204a6d42e7dSPeter Dunlap static int 205a6d42e7dSPeter Dunlap delete_tpg(char *tpg, boolean_t force); 206a6d42e7dSPeter Dunlap 207a6d42e7dSPeter Dunlap static int 208a6d42e7dSPeter Dunlap modify_initiator(char *ini, nvlist_t *proplist, boolean_t create); 209a6d42e7dSPeter Dunlap 210a6d42e7dSPeter Dunlap static int 211a6d42e7dSPeter Dunlap list_initiator(char *ini, boolean_t verbose, boolean_t script); 212a6d42e7dSPeter Dunlap 213a6d42e7dSPeter Dunlap static int 214a6d42e7dSPeter Dunlap delete_initiator(char *ini); 215a6d42e7dSPeter Dunlap 216a6d42e7dSPeter Dunlap static int 217a6d42e7dSPeter Dunlap modify_defaults(nvlist_t *proplist); 218a6d42e7dSPeter Dunlap 219a6d42e7dSPeter Dunlap static int 220a6d42e7dSPeter Dunlap list_defaults(boolean_t script); 221a6d42e7dSPeter Dunlap 222a6d42e7dSPeter Dunlap static void 223a6d42e7dSPeter Dunlap tag_name_to_num(char *tagname, uint16_t *tagnum); 224a6d42e7dSPeter Dunlap 225*a4f92191SSam Cramer static char * 226*a4f92191SSam Cramer canonical_target_name(char *tgt); 227*a4f92191SSam Cramer 228*a4f92191SSam Cramer static char * 229*a4f92191SSam Cramer strduplc(char *s); 230*a4f92191SSam Cramer 231a6d42e7dSPeter Dunlap /* prototype from iscsit_common.h */ 232a6d42e7dSPeter Dunlap extern int 233a6d42e7dSPeter Dunlap sockaddr_to_str(struct sockaddr_storage *sa, char **addr); 234a6d42e7dSPeter Dunlap 235a6d42e7dSPeter Dunlap int 236a6d42e7dSPeter Dunlap main(int argc, char *argv[]) 237a6d42e7dSPeter Dunlap { 238a6d42e7dSPeter Dunlap int ret = 0; 239a6d42e7dSPeter Dunlap int idx = NULL_SUBCMD; 240a6d42e7dSPeter Dunlap char c; 241a6d42e7dSPeter Dunlap int newargc = argc; 242a6d42e7dSPeter Dunlap char **newargv = NULL; 243a6d42e7dSPeter Dunlap char *objp; 244a6d42e7dSPeter Dunlap int itind = 0; 245a6d42e7dSPeter Dunlap nvlist_t *proplist = NULL; 246a6d42e7dSPeter Dunlap boolean_t verbose = B_FALSE; 247a6d42e7dSPeter Dunlap boolean_t scripting = B_FALSE; 248a6d42e7dSPeter Dunlap boolean_t tbool; 249a6d42e7dSPeter Dunlap char *targetname = NULL; 250a6d42e7dSPeter Dunlap char *propname; 251a6d42e7dSPeter Dunlap boolean_t force = B_FALSE; 252a6d42e7dSPeter Dunlap struct passwd *pwd = NULL; 253a6d42e7dSPeter Dunlap uint32_t count = 0; 254a6d42e7dSPeter Dunlap char *smfstate = NULL; 255a6d42e7dSPeter Dunlap 256a6d42e7dSPeter Dunlap (void) setlocale(LC_ALL, ""); 257a6d42e7dSPeter Dunlap (void) textdomain(TEXT_DOMAIN); 258a6d42e7dSPeter Dunlap 259a6d42e7dSPeter Dunlap if (argc < 2) { 260a6d42e7dSPeter Dunlap ret = 1; 261a6d42e7dSPeter Dunlap goto usage_error; 262a6d42e7dSPeter Dunlap } 263a6d42e7dSPeter Dunlap 264a6d42e7dSPeter Dunlap for (idx = 0; subcmds[idx].name != NULL; idx++) { 265a6d42e7dSPeter Dunlap if (strcmp(argv[1], subcmds[idx].name) == 0) { 266a6d42e7dSPeter Dunlap break; 267a6d42e7dSPeter Dunlap } 268a6d42e7dSPeter Dunlap } 269a6d42e7dSPeter Dunlap 270a6d42e7dSPeter Dunlap 271a6d42e7dSPeter Dunlap /* get the caller's user name for subsequent chkauthattr() calls */ 272a6d42e7dSPeter Dunlap pwd = getpwuid(getuid()); 273a6d42e7dSPeter Dunlap if (pwd == NULL) { 274a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 275a6d42e7dSPeter Dunlap gettext("Could not determine callers user name.")); 276a6d42e7dSPeter Dunlap return (1); 277a6d42e7dSPeter Dunlap } 278a6d42e7dSPeter Dunlap 279a6d42e7dSPeter Dunlap itadm_uname = strdup(pwd->pw_name); 280a6d42e7dSPeter Dunlap 281a6d42e7dSPeter Dunlap /* increment past command & subcommand */ 282a6d42e7dSPeter Dunlap newargc--; 283a6d42e7dSPeter Dunlap newargv = &(argv[1]); 284a6d42e7dSPeter Dunlap 285a6d42e7dSPeter Dunlap ret = nvlist_alloc(&proplist, NV_UNIQUE_NAME, 0); 286a6d42e7dSPeter Dunlap if (ret != 0) { 287a6d42e7dSPeter Dunlap ret = errno; 288a6d42e7dSPeter Dunlap (void) fprintf(stderr, 289a6d42e7dSPeter Dunlap gettext("Could not allocate nvlist, errno = %d"), 290a6d42e7dSPeter Dunlap ret); 291a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 292a6d42e7dSPeter Dunlap ret = 1; 293a6d42e7dSPeter Dunlap goto usage_error; 294a6d42e7dSPeter Dunlap } 295a6d42e7dSPeter Dunlap 296a6d42e7dSPeter Dunlap while ((ret == 0) && (newargv)) { 297a6d42e7dSPeter Dunlap c = getopt_long(newargc, newargv, subcmds[idx].shortopts, 298a6d42e7dSPeter Dunlap itadm_long, &itind); 299a6d42e7dSPeter Dunlap if (c == -1) { 300a6d42e7dSPeter Dunlap break; 301a6d42e7dSPeter Dunlap } 302a6d42e7dSPeter Dunlap 303a6d42e7dSPeter Dunlap switch (c) { 304a6d42e7dSPeter Dunlap case 0: 305a6d42e7dSPeter Dunlap /* flag set by getopt */ 306a6d42e7dSPeter Dunlap break; 307a6d42e7dSPeter Dunlap case 'a': 308a6d42e7dSPeter Dunlap ret = nvlist_add_string(proplist, 309a6d42e7dSPeter Dunlap "auth", optarg); 310a6d42e7dSPeter Dunlap break; 311a6d42e7dSPeter Dunlap case 'd': 312a6d42e7dSPeter Dunlap ret = itadm_get_password(proplist, 313a6d42e7dSPeter Dunlap "radiussecret", NULL, 314a6d42e7dSPeter Dunlap gettext("Enter RADIUS secret: ")); 315a6d42e7dSPeter Dunlap break; 316a6d42e7dSPeter Dunlap case 'D': 317a6d42e7dSPeter Dunlap ret = itadm_get_password(proplist, 318a6d42e7dSPeter Dunlap "radiussecret", optarg, NULL); 319a6d42e7dSPeter Dunlap break; 320a6d42e7dSPeter Dunlap case 'f': 321a6d42e7dSPeter Dunlap force = B_TRUE; 322a6d42e7dSPeter Dunlap break; 323a6d42e7dSPeter Dunlap case '?': 324a6d42e7dSPeter Dunlap /* 325a6d42e7dSPeter Dunlap * '?' is returned for both unrecognized 326a6d42e7dSPeter Dunlap * options and if explicitly provided on 327a6d42e7dSPeter Dunlap * the command line. The latter should 328a6d42e7dSPeter Dunlap * be handled the same as -h. 329a6d42e7dSPeter Dunlap */ 330a6d42e7dSPeter Dunlap if (strcmp(newargv[optind-1], "-?") != 0) { 331a6d42e7dSPeter Dunlap (void) fprintf(stderr, 332a6d42e7dSPeter Dunlap gettext("Unrecognized option %s"), 333a6d42e7dSPeter Dunlap newargv[optind-1]); 334a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 335a6d42e7dSPeter Dunlap ret = 1; 336a6d42e7dSPeter Dunlap } 337a6d42e7dSPeter Dunlap goto usage_error; 338a6d42e7dSPeter Dunlap case 'h': 339a6d42e7dSPeter Dunlap goto usage_error; 340a6d42e7dSPeter Dunlap case 'i': 341a6d42e7dSPeter Dunlap if (strncmp(optarg, "enable", strlen(optarg)) 342a6d42e7dSPeter Dunlap == 0) { 343a6d42e7dSPeter Dunlap tbool = B_TRUE; 344a6d42e7dSPeter Dunlap } else if (strncmp(optarg, "disable", 345a6d42e7dSPeter Dunlap strlen(optarg)) == 0) { 346a6d42e7dSPeter Dunlap tbool = B_FALSE; 347a6d42e7dSPeter Dunlap } else { 348a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 349a6d42e7dSPeter Dunlap gettext("invalid value for -i")); 350a6d42e7dSPeter Dunlap ret = 1; 351a6d42e7dSPeter Dunlap break; 352a6d42e7dSPeter Dunlap } 353a6d42e7dSPeter Dunlap ret = nvlist_add_boolean_value(proplist, 354a6d42e7dSPeter Dunlap "isns", tbool); 355a6d42e7dSPeter Dunlap break; 356a6d42e7dSPeter Dunlap case 'I': 357a6d42e7dSPeter Dunlap /* possibly multi-valued */ 358a6d42e7dSPeter Dunlap ret = itadm_opt_to_arr(proplist, 359a6d42e7dSPeter Dunlap "isnsserver", optarg, &count); 360a6d42e7dSPeter Dunlap if ((ret == 0) && (count > 8)) { 361a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 362a6d42e7dSPeter Dunlap gettext( 363a6d42e7dSPeter Dunlap "Too many iSNS servers specified, " 364a6d42e7dSPeter Dunlap "maximum of 8 allowed")); 365a6d42e7dSPeter Dunlap ret = 1; 366a6d42e7dSPeter Dunlap } 367a6d42e7dSPeter Dunlap break; 368a6d42e7dSPeter Dunlap case 'l': 369a6d42e7dSPeter Dunlap ret = nvlist_add_string(proplist, 370a6d42e7dSPeter Dunlap "alias", optarg); 371a6d42e7dSPeter Dunlap break; 372a6d42e7dSPeter Dunlap case 'n': 373a6d42e7dSPeter Dunlap targetname = strdup(optarg); 374a6d42e7dSPeter Dunlap if (targetname == NULL) { 375a6d42e7dSPeter Dunlap ret = ENOMEM; 376a6d42e7dSPeter Dunlap } 377a6d42e7dSPeter Dunlap break; 378a6d42e7dSPeter Dunlap case 'r': 379a6d42e7dSPeter Dunlap ret = nvlist_add_string(proplist, 380a6d42e7dSPeter Dunlap "radiusserver", optarg); 381a6d42e7dSPeter Dunlap break; 382a6d42e7dSPeter Dunlap case 's': 383a6d42e7dSPeter Dunlap if ((idx == CREATE_TGT) || 384a6d42e7dSPeter Dunlap (idx == MODIFY_TGT)) { 385a6d42e7dSPeter Dunlap propname = "targetchapsecret"; 386a6d42e7dSPeter Dunlap } else { 387a6d42e7dSPeter Dunlap propname = "chapsecret"; 388a6d42e7dSPeter Dunlap } 389a6d42e7dSPeter Dunlap ret = itadm_get_password(proplist, 390a6d42e7dSPeter Dunlap propname, NULL, 391a6d42e7dSPeter Dunlap gettext("Enter CHAP secret: ")); 392a6d42e7dSPeter Dunlap break; 393a6d42e7dSPeter Dunlap case 'S': 394a6d42e7dSPeter Dunlap if ((idx == CREATE_TGT) || 395a6d42e7dSPeter Dunlap (idx == MODIFY_TGT)) { 396a6d42e7dSPeter Dunlap propname = "targetchapsecret"; 397a6d42e7dSPeter Dunlap } else { 398a6d42e7dSPeter Dunlap propname = "chapsecret"; 399a6d42e7dSPeter Dunlap } 400a6d42e7dSPeter Dunlap ret = itadm_get_password(proplist, 401a6d42e7dSPeter Dunlap propname, optarg, NULL); 402a6d42e7dSPeter Dunlap break; 403a6d42e7dSPeter Dunlap case 't': 404a6d42e7dSPeter Dunlap /* possibly multi-valued */ 405a6d42e7dSPeter Dunlap ret = itadm_opt_to_arr(proplist, 406a6d42e7dSPeter Dunlap "tpg-tag", optarg, NULL); 407a6d42e7dSPeter Dunlap break; 408a6d42e7dSPeter Dunlap case 'u': 409a6d42e7dSPeter Dunlap if ((idx == CREATE_TGT) || 410a6d42e7dSPeter Dunlap (idx == MODIFY_TGT)) { 411a6d42e7dSPeter Dunlap propname = "targetchapuser"; 412a6d42e7dSPeter Dunlap } else { 413a6d42e7dSPeter Dunlap propname = "chapuser"; 414a6d42e7dSPeter Dunlap } 415a6d42e7dSPeter Dunlap ret = nvlist_add_string(proplist, 416a6d42e7dSPeter Dunlap propname, optarg); 417a6d42e7dSPeter Dunlap break; 418a6d42e7dSPeter Dunlap case 'v': 419a6d42e7dSPeter Dunlap verbose = B_TRUE; 420a6d42e7dSPeter Dunlap break; 421a6d42e7dSPeter Dunlap case ':': 422a6d42e7dSPeter Dunlap (void) fprintf(stderr, 423a6d42e7dSPeter Dunlap gettext("Option %s requires an operand."), 424a6d42e7dSPeter Dunlap newargv[optind-1]); 425a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 426a6d42e7dSPeter Dunlap 427a6d42e7dSPeter Dunlap /* fall through to default */ 428a6d42e7dSPeter Dunlap default: 429a6d42e7dSPeter Dunlap ret = 1; 430a6d42e7dSPeter Dunlap break; 431a6d42e7dSPeter Dunlap } 432a6d42e7dSPeter Dunlap } 433a6d42e7dSPeter Dunlap 434a6d42e7dSPeter Dunlap if (ret != 0) { 435a6d42e7dSPeter Dunlap goto usage_error; 436a6d42e7dSPeter Dunlap } 437a6d42e7dSPeter Dunlap 438a6d42e7dSPeter Dunlap /* after getopt() to allow handling of -h option */ 439a6d42e7dSPeter Dunlap if ((itadm_sub_t)idx == NULL_SUBCMD) { 440a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 441a6d42e7dSPeter Dunlap gettext("Error, no subcommand specified")); 442a6d42e7dSPeter Dunlap ret = 1; 443a6d42e7dSPeter Dunlap goto usage_error; 444a6d42e7dSPeter Dunlap } 445a6d42e7dSPeter Dunlap 446a6d42e7dSPeter Dunlap /* 447a6d42e7dSPeter Dunlap * some subcommands take multiple operands, so adjust now that 448a6d42e7dSPeter Dunlap * getopt is complete 449a6d42e7dSPeter Dunlap */ 450a6d42e7dSPeter Dunlap newargc -= optind; 451a6d42e7dSPeter Dunlap if (newargc == 0) { 452a6d42e7dSPeter Dunlap newargv = NULL; 453a6d42e7dSPeter Dunlap objp = NULL; 454a6d42e7dSPeter Dunlap } else { 455a6d42e7dSPeter Dunlap newargv = &(newargv[optind]); 456a6d42e7dSPeter Dunlap objp = newargv[0]; 457a6d42e7dSPeter Dunlap } 458a6d42e7dSPeter Dunlap 459a6d42e7dSPeter Dunlap if (objp == NULL) { 460a6d42e7dSPeter Dunlap switch ((itadm_sub_t)idx) { 461a6d42e7dSPeter Dunlap case MODIFY_TGT: 462a6d42e7dSPeter Dunlap case DELETE_TGT: 463a6d42e7dSPeter Dunlap case CREATE_TPG: 464a6d42e7dSPeter Dunlap case DELETE_TPG: 465a6d42e7dSPeter Dunlap case CREATE_INI: 466a6d42e7dSPeter Dunlap case MODIFY_INI: 467a6d42e7dSPeter Dunlap case DELETE_INI: 468a6d42e7dSPeter Dunlap /* These subcommands need operands */ 469a6d42e7dSPeter Dunlap ret = 1; 470a6d42e7dSPeter Dunlap goto usage_error; 471a6d42e7dSPeter Dunlap default: 472a6d42e7dSPeter Dunlap break; 473a6d42e7dSPeter Dunlap } 474a6d42e7dSPeter Dunlap } 475a6d42e7dSPeter Dunlap 476836fc322SSam Cramer if (newargc > 1) { 477836fc322SSam Cramer switch ((itadm_sub_t)idx) { 478836fc322SSam Cramer case MODIFY_TGT: 479836fc322SSam Cramer case DELETE_TGT: 480836fc322SSam Cramer case LIST_TGT: 481836fc322SSam Cramer case DELETE_TPG: 482836fc322SSam Cramer case LIST_TPG: 483836fc322SSam Cramer case CREATE_INI: 484836fc322SSam Cramer case MODIFY_INI: 485836fc322SSam Cramer case LIST_INI: 486836fc322SSam Cramer case DELETE_INI: 487836fc322SSam Cramer /* These subcommands should have at most one operand */ 488836fc322SSam Cramer ret = 1; 489836fc322SSam Cramer goto usage_error; 490836fc322SSam Cramer 491836fc322SSam Cramer default: 492836fc322SSam Cramer break; 493836fc322SSam Cramer } 494836fc322SSam Cramer } 495836fc322SSam Cramer 496a6d42e7dSPeter Dunlap /* 497a6d42e7dSPeter Dunlap * XXX - this should probably get pushed down to the library 498a6d42e7dSPeter Dunlap * depending on the decision to allow/disallow configuratoin 499a6d42e7dSPeter Dunlap * without the service running. 500a6d42e7dSPeter Dunlap */ 501a6d42e7dSPeter Dunlap /* 502a6d42e7dSPeter Dunlap * Make sure iSCSI target service is enabled before 503a6d42e7dSPeter Dunlap * proceeding. 504a6d42e7dSPeter Dunlap */ 505a6d42e7dSPeter Dunlap smfstate = smf_get_state(ISCSIT_SVC); 506a6d42e7dSPeter Dunlap if (!smfstate || 507a6d42e7dSPeter Dunlap (strcmp(smfstate, SCF_STATE_STRING_ONLINE) != 0)) { 508a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 509a6d42e7dSPeter Dunlap gettext("The iSCSI target service must be online " 510a6d42e7dSPeter Dunlap "before running this command.")); 511a6d42e7dSPeter Dunlap (void) fprintf(stderr, 512a6d42e7dSPeter Dunlap gettext("Use 'svcadm enable -r %s'"), ISCSIT_SVC); 513a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 514a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 515a6d42e7dSPeter Dunlap gettext("to enable the service and its prerequisite " 516a6d42e7dSPeter Dunlap "services and/or")); 517a6d42e7dSPeter Dunlap (void) fprintf(stderr, 518a6d42e7dSPeter Dunlap gettext("'svcs -x %s' to determine why it is not online."), 519a6d42e7dSPeter Dunlap ISCSIT_SVC); 520a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 521a6d42e7dSPeter Dunlap 522a6d42e7dSPeter Dunlap return (1); 523a6d42e7dSPeter Dunlap } 524a6d42e7dSPeter Dunlap 525a6d42e7dSPeter Dunlap switch ((itadm_sub_t)idx) { 526a6d42e7dSPeter Dunlap case CREATE_TGT: 527a6d42e7dSPeter Dunlap if (targetname) { 528a6d42e7dSPeter Dunlap ret = create_target(targetname, proplist); 529a6d42e7dSPeter Dunlap } else { 530a6d42e7dSPeter Dunlap /* 531a6d42e7dSPeter Dunlap * OK for objp to be NULL here. If the 532a6d42e7dSPeter Dunlap * user did not specify a target name, 533a6d42e7dSPeter Dunlap * one will be generated. 534a6d42e7dSPeter Dunlap */ 535a6d42e7dSPeter Dunlap ret = create_target(objp, proplist); 536a6d42e7dSPeter Dunlap } 537a6d42e7dSPeter Dunlap break; 538a6d42e7dSPeter Dunlap case MODIFY_TGT: 539a6d42e7dSPeter Dunlap ret = modify_target(objp, targetname, proplist); 540a6d42e7dSPeter Dunlap break; 541a6d42e7dSPeter Dunlap case DELETE_TGT: 542a6d42e7dSPeter Dunlap ret = delete_target(objp, force); 543a6d42e7dSPeter Dunlap break; 544a6d42e7dSPeter Dunlap case LIST_TGT: 545a6d42e7dSPeter Dunlap ret = list_target(objp, verbose, scripting); 546a6d42e7dSPeter Dunlap break; 547a6d42e7dSPeter Dunlap case CREATE_TPG: 548a6d42e7dSPeter Dunlap ret = create_tpg(objp, newargc - 1, &(newargv[1])); 549a6d42e7dSPeter Dunlap break; 550a6d42e7dSPeter Dunlap case DELETE_TPG: 551a6d42e7dSPeter Dunlap ret = delete_tpg(objp, force); 552a6d42e7dSPeter Dunlap break; 553a6d42e7dSPeter Dunlap case LIST_TPG: 554a6d42e7dSPeter Dunlap ret = list_tpg(objp, verbose, scripting); 555a6d42e7dSPeter Dunlap break; 556a6d42e7dSPeter Dunlap case CREATE_INI: 557a6d42e7dSPeter Dunlap ret = modify_initiator(objp, proplist, B_TRUE); 558a6d42e7dSPeter Dunlap break; 559a6d42e7dSPeter Dunlap case MODIFY_INI: 560a6d42e7dSPeter Dunlap ret = modify_initiator(objp, proplist, B_FALSE); 561a6d42e7dSPeter Dunlap break; 562a6d42e7dSPeter Dunlap case LIST_INI: 563a6d42e7dSPeter Dunlap ret = list_initiator(objp, verbose, scripting); 564a6d42e7dSPeter Dunlap break; 565a6d42e7dSPeter Dunlap case DELETE_INI: 566a6d42e7dSPeter Dunlap ret = delete_initiator(objp); 567a6d42e7dSPeter Dunlap break; 568a6d42e7dSPeter Dunlap case MODIFY_DEF: 569a6d42e7dSPeter Dunlap ret = modify_defaults(proplist); 570a6d42e7dSPeter Dunlap break; 571a6d42e7dSPeter Dunlap case LIST_DEF: 572a6d42e7dSPeter Dunlap ret = list_defaults(scripting); 573a6d42e7dSPeter Dunlap break; 574a6d42e7dSPeter Dunlap default: 575a6d42e7dSPeter Dunlap ret = 1; 576a6d42e7dSPeter Dunlap goto usage_error; 577a6d42e7dSPeter Dunlap } 578a6d42e7dSPeter Dunlap 579a6d42e7dSPeter Dunlap if (ret != 0) { 580a6d42e7dSPeter Dunlap (void) fprintf(stderr, 581a6d42e7dSPeter Dunlap gettext("itadm %s failed with error %d"), 582a6d42e7dSPeter Dunlap subcmds[idx].name, ret); 583a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 584a6d42e7dSPeter Dunlap } 585a6d42e7dSPeter Dunlap return (ret); 586a6d42e7dSPeter Dunlap 587a6d42e7dSPeter Dunlap usage_error: 588a6d42e7dSPeter Dunlap if (subcmds[idx].name) { 589a6d42e7dSPeter Dunlap (void) printf("%s\n", gettext(subcmds[idx].usemsg)); 590a6d42e7dSPeter Dunlap } else { 591a6d42e7dSPeter Dunlap /* overall usage */ 592a6d42e7dSPeter Dunlap (void) printf("%s\n\n", gettext("itadm usage:")); 593a6d42e7dSPeter Dunlap for (idx = 0; subcmds[idx].name != NULL; idx++) { 594a6d42e7dSPeter Dunlap if (!subcmds[idx].usemsg) { 595a6d42e7dSPeter Dunlap continue; 596a6d42e7dSPeter Dunlap } 597a6d42e7dSPeter Dunlap (void) printf("\t%s\n", gettext(subcmds[idx].usemsg)); 598a6d42e7dSPeter Dunlap } 599a6d42e7dSPeter Dunlap } 600a6d42e7dSPeter Dunlap 601a6d42e7dSPeter Dunlap return (ret); 602a6d42e7dSPeter Dunlap } 603a6d42e7dSPeter Dunlap 604a6d42e7dSPeter Dunlap static int 605a6d42e7dSPeter Dunlap create_target(char *tgt, nvlist_t *proplist) 606a6d42e7dSPeter Dunlap { 607a6d42e7dSPeter Dunlap int ret; 608a6d42e7dSPeter Dunlap it_config_t *cfg = NULL; 609a6d42e7dSPeter Dunlap it_tgt_t *tgtp; 610a6d42e7dSPeter Dunlap char **tags = NULL; 611a6d42e7dSPeter Dunlap uint32_t count = 0; 612a6d42e7dSPeter Dunlap nvlist_t *errlist = NULL; 613a6d42e7dSPeter Dunlap int i; 614a6d42e7dSPeter Dunlap it_tpg_t *tpg = NULL; 615a6d42e7dSPeter Dunlap uint16_t tagid = 0; 616a6d42e7dSPeter Dunlap it_tpgt_t *tpgt; 617a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 618*a4f92191SSam Cramer char *canonical_tgt = NULL; 619*a4f92191SSam Cramer boolean_t did_it_config_load = B_FALSE; 620a6d42e7dSPeter Dunlap 621a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 622a6d42e7dSPeter Dunlap 623a6d42e7dSPeter Dunlap if (tgt) { 624a6d42e7dSPeter Dunlap /* 625*a4f92191SSam Cramer * Validate target name. 626a6d42e7dSPeter Dunlap */ 627a6d42e7dSPeter Dunlap if ((strncmp(tgt, "eui.", 4) != 0) && 628a6d42e7dSPeter Dunlap (strncmp(tgt, "iqn.", 4) != 0)) { 629a6d42e7dSPeter Dunlap (void) fprintf(stderr, gettext("Invalid name %s"), 630a6d42e7dSPeter Dunlap tgt); 631a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 632a6d42e7dSPeter Dunlap return (EINVAL); 633a6d42e7dSPeter Dunlap } 634*a4f92191SSam Cramer 635*a4f92191SSam Cramer canonical_tgt = canonical_target_name(tgt); 636a6d42e7dSPeter Dunlap } 637a6d42e7dSPeter Dunlap 638a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 639a6d42e7dSPeter Dunlap if (ret != 0) { 640a6d42e7dSPeter Dunlap (void) fprintf(stderr, 641a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 642a6d42e7dSPeter Dunlap ret); 643a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 644*a4f92191SSam Cramer goto done; 645a6d42e7dSPeter Dunlap } 646a6d42e7dSPeter Dunlap 647*a4f92191SSam Cramer did_it_config_load = B_TRUE; 648*a4f92191SSam Cramer 649*a4f92191SSam Cramer ret = it_tgt_create(cfg, &tgtp, canonical_tgt); 650a6d42e7dSPeter Dunlap if (ret != 0) { 651a6d42e7dSPeter Dunlap if (ret == EFAULT) { 652a6d42e7dSPeter Dunlap (void) fprintf(stderr, 653a6d42e7dSPeter Dunlap gettext("Invalid iSCSI name %s"), tgt); 654a6d42e7dSPeter Dunlap } else if (ret == EEXIST) { 655a6d42e7dSPeter Dunlap (void) fprintf(stderr, 656a6d42e7dSPeter Dunlap gettext("iSCSI target %s already configured"), 657a6d42e7dSPeter Dunlap tgt); 658836fc322SSam Cramer } else if (ret == E2BIG) { 659836fc322SSam Cramer (void) fprintf(stderr, 660836fc322SSam Cramer gettext("Maximum of %d iSCSI targets"), 661836fc322SSam Cramer MAX_TARGETS); 662a6d42e7dSPeter Dunlap } else { 663a6d42e7dSPeter Dunlap (void) fprintf(stderr, 664a6d42e7dSPeter Dunlap gettext("Error creating target: %d"), ret); 665a6d42e7dSPeter Dunlap } 666a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 667a6d42e7dSPeter Dunlap goto done; 668a6d42e7dSPeter Dunlap } 669a6d42e7dSPeter Dunlap 670a6d42e7dSPeter Dunlap /* set the target portal group tags */ 671a6d42e7dSPeter Dunlap ret = nvlist_lookup_string_array(proplist, "tpg-tag", &tags, 672a6d42e7dSPeter Dunlap &count); 673a6d42e7dSPeter Dunlap 674a6d42e7dSPeter Dunlap if (ret == ENOENT) { 675a6d42e7dSPeter Dunlap /* none specified. is this ok? */ 676a6d42e7dSPeter Dunlap ret = 0; 677a6d42e7dSPeter Dunlap } else if (ret != 0) { 678a6d42e7dSPeter Dunlap (void) fprintf(stderr, 679a6d42e7dSPeter Dunlap gettext("internal error: %d"), ret); 680a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 681a6d42e7dSPeter Dunlap goto done; 682a6d42e7dSPeter Dunlap } 683a6d42e7dSPeter Dunlap 684a6d42e7dSPeter Dunlap /* special case, don't set any TPGs */ 685a6d42e7dSPeter Dunlap if (tags && (strcmp("default", tags[0]) == 0)) { 686a6d42e7dSPeter Dunlap count = 0; 687a6d42e7dSPeter Dunlap } 688a6d42e7dSPeter Dunlap 689a6d42e7dSPeter Dunlap for (i = 0; i < count; i++) { 690a6d42e7dSPeter Dunlap if (!tags[i]) { 691a6d42e7dSPeter Dunlap continue; 692a6d42e7dSPeter Dunlap } 693a6d42e7dSPeter Dunlap 694a6d42e7dSPeter Dunlap /* see that all referenced groups are already defined */ 695a6d42e7dSPeter Dunlap tpg = cfg->config_tpg_list; 696a6d42e7dSPeter Dunlap while (tpg != NULL) { 697a6d42e7dSPeter Dunlap if (strcmp(tags[i], tpg->tpg_name) == 0) { 698a6d42e7dSPeter Dunlap break; 699a6d42e7dSPeter Dunlap } 700a6d42e7dSPeter Dunlap 701a6d42e7dSPeter Dunlap tpg = tpg->tpg_next; 702a6d42e7dSPeter Dunlap } 703a6d42e7dSPeter Dunlap if (tpg == NULL) { 704a6d42e7dSPeter Dunlap (void) fprintf(stderr, 705a6d42e7dSPeter Dunlap gettext("Invalid tpg-tag %s, tag not defined"), 706a6d42e7dSPeter Dunlap tags[i]); 707a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 708a6d42e7dSPeter Dunlap ret = 1; 709a6d42e7dSPeter Dunlap goto done; 710a6d42e7dSPeter Dunlap } 711a6d42e7dSPeter Dunlap 712a6d42e7dSPeter Dunlap /* generate the tag number to use */ 713a6d42e7dSPeter Dunlap tag_name_to_num(tags[i], &tagid); 714a6d42e7dSPeter Dunlap 715a6d42e7dSPeter Dunlap ret = it_tpgt_create(cfg, tgtp, &tpgt, tags[i], tagid); 716a6d42e7dSPeter Dunlap if (ret != 0) { 717a6d42e7dSPeter Dunlap (void) fprintf(stderr, 718a6d42e7dSPeter Dunlap gettext("Could not add target portal group" 719a6d42e7dSPeter Dunlap "tag %s, error %d"), tags[i], ret); 720a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 721a6d42e7dSPeter Dunlap goto done; 722a6d42e7dSPeter Dunlap } 723a6d42e7dSPeter Dunlap tagid++; 724a6d42e7dSPeter Dunlap } 725a6d42e7dSPeter Dunlap 726a6d42e7dSPeter Dunlap /* remove the tags from the proplist before continuing */ 727a6d42e7dSPeter Dunlap if (tags) { 728a6d42e7dSPeter Dunlap (void) nvlist_remove_all(proplist, "tpg-tag"); 729a6d42e7dSPeter Dunlap } 730a6d42e7dSPeter Dunlap 731a6d42e7dSPeter Dunlap ret = it_tgt_setprop(cfg, tgtp, proplist, &errlist); 732a6d42e7dSPeter Dunlap if (ret != 0) { 733a6d42e7dSPeter Dunlap (void) fprintf(stderr, 734a6d42e7dSPeter Dunlap gettext("Error setting target properties, %d"), ret); 735a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 736a6d42e7dSPeter Dunlap if (errlist) { 737a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 738a6d42e7dSPeter Dunlap char *nn; 739a6d42e7dSPeter Dunlap char *nv; 740a6d42e7dSPeter Dunlap 741a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(errlist, nvp)) 742a6d42e7dSPeter Dunlap != NULL) { 743a6d42e7dSPeter Dunlap nv = NULL; 744a6d42e7dSPeter Dunlap 745a6d42e7dSPeter Dunlap nn = nvpair_name(nvp); 746a6d42e7dSPeter Dunlap (void) nvpair_value_string(nvp, &nv); 747a6d42e7dSPeter Dunlap 748a6d42e7dSPeter Dunlap if (nv != NULL) { 749a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\t%s: %s\n", 750a6d42e7dSPeter Dunlap nn, nv); 751a6d42e7dSPeter Dunlap } 752a6d42e7dSPeter Dunlap } 753a6d42e7dSPeter Dunlap 754a6d42e7dSPeter Dunlap nvlist_free(errlist); 755a6d42e7dSPeter Dunlap } 756a6d42e7dSPeter Dunlap goto done; 757a6d42e7dSPeter Dunlap } 758a6d42e7dSPeter Dunlap 759a6d42e7dSPeter Dunlap if (ret == 0) { 760a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 761a6d42e7dSPeter Dunlap STMF_STALE(ret); 762a6d42e7dSPeter Dunlap } 763a6d42e7dSPeter Dunlap 764a6d42e7dSPeter Dunlap done: 765a6d42e7dSPeter Dunlap if (ret == 0) { 766a6d42e7dSPeter Dunlap (void) printf(gettext("Target %s successfully created"), 767a6d42e7dSPeter Dunlap tgtp->tgt_name); 768a6d42e7dSPeter Dunlap (void) printf("\n"); 769a6d42e7dSPeter Dunlap } 770a6d42e7dSPeter Dunlap 771*a4f92191SSam Cramer if (did_it_config_load) 772a6d42e7dSPeter Dunlap it_config_free(cfg); 773a6d42e7dSPeter Dunlap 774*a4f92191SSam Cramer if (canonical_tgt != NULL) 775*a4f92191SSam Cramer free(canonical_tgt); 776*a4f92191SSam Cramer 777a6d42e7dSPeter Dunlap return (ret); 778a6d42e7dSPeter Dunlap } 779a6d42e7dSPeter Dunlap 780a6d42e7dSPeter Dunlap int 781a6d42e7dSPeter Dunlap list_target(char *tgt, boolean_t verbose, boolean_t script) 782a6d42e7dSPeter Dunlap { 783a6d42e7dSPeter Dunlap int ret; 784a6d42e7dSPeter Dunlap it_config_t *cfg; 785a6d42e7dSPeter Dunlap it_tgt_t *ptr; 786a6d42e7dSPeter Dunlap boolean_t found = B_FALSE; 787a6d42e7dSPeter Dunlap boolean_t first = B_TRUE; 788a6d42e7dSPeter Dunlap boolean_t first_tag = B_TRUE; 789a6d42e7dSPeter Dunlap char *gauth = "none"; 790a6d42e7dSPeter Dunlap char *galias = "-"; 791a6d42e7dSPeter Dunlap char *auth; 792a6d42e7dSPeter Dunlap char *alias; 793a6d42e7dSPeter Dunlap char *chapu; 794a6d42e7dSPeter Dunlap char *chaps; 795a6d42e7dSPeter Dunlap it_tpgt_t *tagp; 796a6d42e7dSPeter Dunlap char *sec = "solaris.smf.read.stmf"; 797a6d42e7dSPeter Dunlap stmfDevid devid; 798a6d42e7dSPeter Dunlap stmfSessionList *sess = NULL; 799a6d42e7dSPeter Dunlap stmfTargetProperties props; 800a6d42e7dSPeter Dunlap char *state; 801a6d42e7dSPeter Dunlap int num_sessions; 802a6d42e7dSPeter Dunlap 803a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 804a6d42e7dSPeter Dunlap 805a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 806a6d42e7dSPeter Dunlap if (ret != 0) { 807a6d42e7dSPeter Dunlap (void) fprintf(stderr, 808a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 809a6d42e7dSPeter Dunlap ret); 810a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 811a6d42e7dSPeter Dunlap return (ret); 812a6d42e7dSPeter Dunlap } 813a6d42e7dSPeter Dunlap 814a6d42e7dSPeter Dunlap ptr = cfg->config_tgt_list; 815a6d42e7dSPeter Dunlap 816a6d42e7dSPeter Dunlap /* grab global defaults for auth, alias */ 817a6d42e7dSPeter Dunlap if (cfg->config_global_properties) { 818a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(cfg->config_global_properties, 819a6d42e7dSPeter Dunlap "alias", &galias); 820a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(cfg->config_global_properties, 821a6d42e7dSPeter Dunlap "auth", &gauth); 822a6d42e7dSPeter Dunlap } 823a6d42e7dSPeter Dunlap 824a6d42e7dSPeter Dunlap for (; ptr != NULL; ptr = ptr->tgt_next) { 825a6d42e7dSPeter Dunlap if (found) { 826a6d42e7dSPeter Dunlap break; 827a6d42e7dSPeter Dunlap } 828a6d42e7dSPeter Dunlap 829a6d42e7dSPeter Dunlap if (tgt) { 830*a4f92191SSam Cramer /* 831*a4f92191SSam Cramer * We do a case-insensitive match in case 832*a4f92191SSam Cramer * a non-lower case value got stored. 833*a4f92191SSam Cramer */ 834*a4f92191SSam Cramer if (strcasecmp(tgt, ptr->tgt_name) != 0) { 835a6d42e7dSPeter Dunlap continue; 836a6d42e7dSPeter Dunlap } else { 837a6d42e7dSPeter Dunlap found = B_TRUE; 838a6d42e7dSPeter Dunlap } 839a6d42e7dSPeter Dunlap } 840a6d42e7dSPeter Dunlap 841a6d42e7dSPeter Dunlap state = "-"; 842a6d42e7dSPeter Dunlap num_sessions = 0; 843a6d42e7dSPeter Dunlap sess = NULL; 844a6d42e7dSPeter Dunlap 845a6d42e7dSPeter Dunlap /* 846a6d42e7dSPeter Dunlap * make a best effort to retrieve target status and 847a6d42e7dSPeter Dunlap * number of active sessions from STMF. 848a6d42e7dSPeter Dunlap */ 849a6d42e7dSPeter Dunlap ret = stmfDevidFromIscsiName(ptr->tgt_name, &devid); 850a6d42e7dSPeter Dunlap if (ret == STMF_STATUS_SUCCESS) { 851a6d42e7dSPeter Dunlap ret = stmfGetTargetProperties(&devid, &props); 852a6d42e7dSPeter Dunlap if (ret == STMF_STATUS_SUCCESS) { 853a6d42e7dSPeter Dunlap if (props.status == STMF_TARGET_PORT_ONLINE) { 854a6d42e7dSPeter Dunlap state = "online"; 855a6d42e7dSPeter Dunlap } else { 856a6d42e7dSPeter Dunlap state = "offline"; 857a6d42e7dSPeter Dunlap } 858a6d42e7dSPeter Dunlap } 859a6d42e7dSPeter Dunlap } 860a6d42e7dSPeter Dunlap if (ret == STMF_STATUS_SUCCESS) { 861a6d42e7dSPeter Dunlap ret = stmfGetSessionList(&devid, &sess); 862a6d42e7dSPeter Dunlap if (ret == STMF_STATUS_SUCCESS) { 863a6d42e7dSPeter Dunlap num_sessions = sess->cnt; 864a6d42e7dSPeter Dunlap free(sess); 865a6d42e7dSPeter Dunlap } 866a6d42e7dSPeter Dunlap } 867a6d42e7dSPeter Dunlap 868a6d42e7dSPeter Dunlap /* reset ret so we don't return an error */ 869a6d42e7dSPeter Dunlap ret = 0; 870a6d42e7dSPeter Dunlap 871a6d42e7dSPeter Dunlap if (!script && first) { 872a6d42e7dSPeter Dunlap (void) printf("%-61s%-9s%-9s\n", "TARGET NAME", 873a6d42e7dSPeter Dunlap "STATE", "SESSIONS"); 874a6d42e7dSPeter Dunlap first = B_FALSE; 875a6d42e7dSPeter Dunlap } 876a6d42e7dSPeter Dunlap 877a6d42e7dSPeter Dunlap if (!script) { 878a6d42e7dSPeter Dunlap /* 879a6d42e7dSPeter Dunlap * try not to let columns run into each other. 880a6d42e7dSPeter Dunlap * Stick a tab after too-long fields. 881a6d42e7dSPeter Dunlap * Lengths chosen are for the 'common' cases. 882a6d42e7dSPeter Dunlap */ 883a6d42e7dSPeter Dunlap (void) printf("%-61s", ptr->tgt_name); 884a6d42e7dSPeter Dunlap if (strlen(ptr->tgt_name) > 60) { 885a6d42e7dSPeter Dunlap (void) printf("\t"); 886a6d42e7dSPeter Dunlap } 887a6d42e7dSPeter Dunlap (void) printf("%-9s%-9d", state, num_sessions); 888a6d42e7dSPeter Dunlap } else { 889a6d42e7dSPeter Dunlap (void) printf("%s\t%s\t%d", ptr->tgt_name, 890a6d42e7dSPeter Dunlap state, num_sessions); 891a6d42e7dSPeter Dunlap } 892a6d42e7dSPeter Dunlap 893a6d42e7dSPeter Dunlap if (!verbose) { 894a6d42e7dSPeter Dunlap (void) printf("\n"); 895a6d42e7dSPeter Dunlap continue; 896a6d42e7dSPeter Dunlap } 897a6d42e7dSPeter Dunlap 898a6d42e7dSPeter Dunlap auth = gauth; 899a6d42e7dSPeter Dunlap alias = galias; 900a6d42e7dSPeter Dunlap chapu = "-"; 901a6d42e7dSPeter Dunlap chaps = "unset"; 902a6d42e7dSPeter Dunlap 903a6d42e7dSPeter Dunlap if (ptr->tgt_properties) { 904a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(ptr->tgt_properties, 905a6d42e7dSPeter Dunlap "auth", &auth); 906a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(ptr->tgt_properties, 907a6d42e7dSPeter Dunlap "alias", &alias); 908a6d42e7dSPeter Dunlap if (nvlist_exists(ptr->tgt_properties, 909a6d42e7dSPeter Dunlap "targetchapsecret")) { 910a6d42e7dSPeter Dunlap chaps = "set"; 911a6d42e7dSPeter Dunlap } 912a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(ptr->tgt_properties, 913a6d42e7dSPeter Dunlap "targetchapuser", &chapu); 914a6d42e7dSPeter Dunlap } 915a6d42e7dSPeter Dunlap 916a6d42e7dSPeter Dunlap if (!script) { 917263f58aaSPriya Krishnan (void) printf("\n\t%-20s\t%s\n\t%-20s\t%s %s\n" 918a6d42e7dSPeter Dunlap "\t%-20s\t%s\n\t%-20s\t%s\n\t%-20s\t", 919263f58aaSPriya Krishnan "alias:", alias, "auth:", auth, 920263f58aaSPriya Krishnan ((auth == gauth) ? "(defaults)" : ""), 921263f58aaSPriya Krishnan "targetchapuser:", 922a6d42e7dSPeter Dunlap chapu, "targetchapsecret:", chaps, "tpg-tags:"); 923a6d42e7dSPeter Dunlap } else { 924263f58aaSPriya Krishnan (void) printf("\t%s\t%s %s\t%s\t%s\t", 925263f58aaSPriya Krishnan alias, auth, 926263f58aaSPriya Krishnan ((auth == gauth) ? "(defaults)" : ""), 927263f58aaSPriya Krishnan chapu, chaps); 928a6d42e7dSPeter Dunlap } 929a6d42e7dSPeter Dunlap 930a6d42e7dSPeter Dunlap first_tag = B_TRUE; 931a6d42e7dSPeter Dunlap tagp = ptr->tgt_tpgt_list; 932a6d42e7dSPeter Dunlap for (; tagp != NULL; tagp = tagp->tpgt_next) { 933a6d42e7dSPeter Dunlap if (!first_tag) { 934a6d42e7dSPeter Dunlap (void) printf(","); 935a6d42e7dSPeter Dunlap } else { 936a6d42e7dSPeter Dunlap first_tag = B_FALSE; 937a6d42e7dSPeter Dunlap } 938263f58aaSPriya Krishnan (void) printf("%s = %d", 939263f58aaSPriya Krishnan tagp->tpgt_tpg_name, tagp->tpgt_tag); 940a6d42e7dSPeter Dunlap } 941a6d42e7dSPeter Dunlap 942a6d42e7dSPeter Dunlap if (first_tag) { 943a6d42e7dSPeter Dunlap /* didn't find any */ 944a6d42e7dSPeter Dunlap (void) printf("default"); 945a6d42e7dSPeter Dunlap } 946a6d42e7dSPeter Dunlap 947a6d42e7dSPeter Dunlap (void) printf("\n"); 948a6d42e7dSPeter Dunlap } 949a6d42e7dSPeter Dunlap 950a6d42e7dSPeter Dunlap if (tgt && (!found)) { 951a6d42e7dSPeter Dunlap (void) fprintf(stderr, 952a6d42e7dSPeter Dunlap gettext("Target %s not found!\n"), tgt); 953a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 954a6d42e7dSPeter Dunlap ret = 1; 955a6d42e7dSPeter Dunlap } 956a6d42e7dSPeter Dunlap 957a6d42e7dSPeter Dunlap it_config_free(cfg); 958a6d42e7dSPeter Dunlap 959a6d42e7dSPeter Dunlap return (ret); 960a6d42e7dSPeter Dunlap } 961a6d42e7dSPeter Dunlap 962a6d42e7dSPeter Dunlap int 963a6d42e7dSPeter Dunlap delete_target(char *tgt, boolean_t force) 964a6d42e7dSPeter Dunlap { 965a6d42e7dSPeter Dunlap int ret; 966a6d42e7dSPeter Dunlap it_config_t *cfg; 967a6d42e7dSPeter Dunlap it_tgt_t *ptr; 968a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 969a6d42e7dSPeter Dunlap 970a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 971a6d42e7dSPeter Dunlap 972a6d42e7dSPeter Dunlap if (!tgt) { 973a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 974a6d42e7dSPeter Dunlap gettext("Error, no target specified")); 975a6d42e7dSPeter Dunlap return (EINVAL); 976a6d42e7dSPeter Dunlap } 977a6d42e7dSPeter Dunlap 978a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 979a6d42e7dSPeter Dunlap if (ret != 0) { 980a6d42e7dSPeter Dunlap (void) fprintf(stderr, 981a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 982a6d42e7dSPeter Dunlap ret); 983a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 984a6d42e7dSPeter Dunlap return (ret); 985a6d42e7dSPeter Dunlap } 986a6d42e7dSPeter Dunlap 987a6d42e7dSPeter Dunlap ptr = cfg->config_tgt_list; 988a6d42e7dSPeter Dunlap while (ptr) { 989*a4f92191SSam Cramer /* 990*a4f92191SSam Cramer * We do a case-insensitive match in case 991*a4f92191SSam Cramer * a non-lower case value got stored. 992*a4f92191SSam Cramer */ 993*a4f92191SSam Cramer if (strcasecmp(ptr->tgt_name, tgt) == 0) { 994a6d42e7dSPeter Dunlap break; 995a6d42e7dSPeter Dunlap } 996a6d42e7dSPeter Dunlap 997a6d42e7dSPeter Dunlap ptr = ptr->tgt_next; 998a6d42e7dSPeter Dunlap } 999a6d42e7dSPeter Dunlap 1000a6d42e7dSPeter Dunlap if (ptr) { 1001a6d42e7dSPeter Dunlap ret = it_tgt_delete(cfg, ptr, force); 1002a6d42e7dSPeter Dunlap 1003a6d42e7dSPeter Dunlap if (ret != 0) { 1004a6d42e7dSPeter Dunlap if (ret == EBUSY) { 1005a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1006a6d42e7dSPeter Dunlap gettext("The target is online or busy. " 1007a6d42e7dSPeter Dunlap "Use the -f (force) option, or " 1008a6d42e7dSPeter Dunlap "'stmfadm offline-target %s'"), tgt); 1009a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1010a6d42e7dSPeter Dunlap } 1011a6d42e7dSPeter Dunlap } 1012a6d42e7dSPeter Dunlap 1013a6d42e7dSPeter Dunlap if (ret == 0) { 1014a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1015a6d42e7dSPeter Dunlap STMF_STALE(ret); 1016a6d42e7dSPeter Dunlap } 1017a6d42e7dSPeter Dunlap } else { 1018a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1019a6d42e7dSPeter Dunlap gettext("Target %s not found"), tgt); 1020a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1021a6d42e7dSPeter Dunlap ret = 1; 1022a6d42e7dSPeter Dunlap } 1023a6d42e7dSPeter Dunlap 1024a6d42e7dSPeter Dunlap it_config_free(cfg); 1025a6d42e7dSPeter Dunlap 1026a6d42e7dSPeter Dunlap return (ret); 1027a6d42e7dSPeter Dunlap } 1028a6d42e7dSPeter Dunlap 1029a6d42e7dSPeter Dunlap static int 1030a6d42e7dSPeter Dunlap modify_target(char *tgt, char *newname, nvlist_t *proplist) 1031a6d42e7dSPeter Dunlap { 1032a6d42e7dSPeter Dunlap int ret; 1033a6d42e7dSPeter Dunlap it_config_t *cfg = NULL; 1034a6d42e7dSPeter Dunlap it_tgt_t *ptr = NULL; 1035836fc322SSam Cramer it_tgt_t *tgtp = NULL; 1036a6d42e7dSPeter Dunlap char **tags = NULL; 1037a6d42e7dSPeter Dunlap uint32_t count = 0; 1038a6d42e7dSPeter Dunlap nvlist_t *errlist = NULL; 1039a6d42e7dSPeter Dunlap int i; 1040a6d42e7dSPeter Dunlap it_tpg_t *tpg = NULL; 1041a6d42e7dSPeter Dunlap uint16_t tagid; 1042836fc322SSam Cramer it_tpgt_t *tpgt = NULL; 1043a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 1044*a4f92191SSam Cramer char *canonical_newname = NULL; 1045*a4f92191SSam Cramer boolean_t did_it_config_load = B_FALSE; 1046a6d42e7dSPeter Dunlap 1047a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1048a6d42e7dSPeter Dunlap 1049a6d42e7dSPeter Dunlap /* XXX: Do we need to offline anything here too? */ 1050a6d42e7dSPeter Dunlap 1051a6d42e7dSPeter Dunlap if (!tgt) { 1052a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1053a6d42e7dSPeter Dunlap gettext("Error, no target specified")); 1054*a4f92191SSam Cramer ret = EINVAL; 1055*a4f92191SSam Cramer goto done; 1056a6d42e7dSPeter Dunlap } 1057a6d42e7dSPeter Dunlap 1058a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1059a6d42e7dSPeter Dunlap if (ret != 0) { 1060a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1061a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1062a6d42e7dSPeter Dunlap ret); 1063a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1064*a4f92191SSam Cramer goto done; 1065a6d42e7dSPeter Dunlap } 1066a6d42e7dSPeter Dunlap 1067*a4f92191SSam Cramer did_it_config_load = B_TRUE; 1068*a4f92191SSam Cramer 1069a6d42e7dSPeter Dunlap /* 1070*a4f92191SSam Cramer * If newname is specified, ensure it is a valid name, 1071*a4f92191SSam Cramer * and generate its canonical form. 1072a6d42e7dSPeter Dunlap */ 1073a6d42e7dSPeter Dunlap if (newname) { 1074a6d42e7dSPeter Dunlap if (!validate_iscsi_name(newname)) { 1075a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1076a6d42e7dSPeter Dunlap gettext("Invalid iSCSI name %s"), newname); 1077a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1078*a4f92191SSam Cramer ret = 1; 1079*a4f92191SSam Cramer goto done; 1080a6d42e7dSPeter Dunlap } 1081*a4f92191SSam Cramer 1082*a4f92191SSam Cramer canonical_newname = canonical_target_name(newname); 1083a6d42e7dSPeter Dunlap } 1084a6d42e7dSPeter Dunlap 1085a6d42e7dSPeter Dunlap /* 1086a6d42e7dSPeter Dunlap * Loop through to verify that the target to be modified truly 1087a6d42e7dSPeter Dunlap * exists. If this target is to be renamed, ensure the new 1088a6d42e7dSPeter Dunlap * name is not already in use. 1089a6d42e7dSPeter Dunlap */ 1090a6d42e7dSPeter Dunlap ptr = cfg->config_tgt_list; 1091a6d42e7dSPeter Dunlap while (ptr) { 1092*a4f92191SSam Cramer /* 1093*a4f92191SSam Cramer * Does a target with the new name already exist? 1094*a4f92191SSam Cramer */ 1095*a4f92191SSam Cramer if (newname && 1096*a4f92191SSam Cramer (strcmp(canonical_newname, ptr->tgt_name) == 0)) { 1097a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1098a6d42e7dSPeter Dunlap gettext("A target with name %s already exists"), 1099a6d42e7dSPeter Dunlap newname); 1100a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1101a6d42e7dSPeter Dunlap ret = 1; 1102a6d42e7dSPeter Dunlap goto done; 1103a6d42e7dSPeter Dunlap } 1104a6d42e7dSPeter Dunlap 1105*a4f92191SSam Cramer if (strcasecmp(ptr->tgt_name, tgt) == 0) { 1106a6d42e7dSPeter Dunlap tgtp = ptr; 1107a6d42e7dSPeter Dunlap } 1108a6d42e7dSPeter Dunlap 1109a6d42e7dSPeter Dunlap ptr = ptr ->tgt_next; 1110a6d42e7dSPeter Dunlap } 1111a6d42e7dSPeter Dunlap 1112a6d42e7dSPeter Dunlap if (!tgtp) { 1113a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1114a6d42e7dSPeter Dunlap gettext("Target %s not found"), tgt); 1115a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1116*a4f92191SSam Cramer ret = EINVAL; 1117*a4f92191SSam Cramer goto done; 1118a6d42e7dSPeter Dunlap } 1119a6d42e7dSPeter Dunlap 1120a6d42e7dSPeter Dunlap /* set the target portal group tags */ 1121a6d42e7dSPeter Dunlap ret = nvlist_lookup_string_array(proplist, "tpg-tag", &tags, 1122a6d42e7dSPeter Dunlap &count); 1123a6d42e7dSPeter Dunlap 1124a6d42e7dSPeter Dunlap if (ret == ENOENT) { 1125a6d42e7dSPeter Dunlap /* none specified. is this ok? */ 1126a6d42e7dSPeter Dunlap ret = 0; 1127a6d42e7dSPeter Dunlap } else if (ret != 0) { 1128a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1129a6d42e7dSPeter Dunlap gettext("internal error: %d"), ret); 1130a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1131a6d42e7dSPeter Dunlap goto done; 1132a6d42e7dSPeter Dunlap } 1133a6d42e7dSPeter Dunlap 1134a6d42e7dSPeter Dunlap /* special case, remove all explicit TPGs, and don't add any */ 1135a6d42e7dSPeter Dunlap if (tags && (strcmp("default", tags[0]) == 0)) { 1136a6d42e7dSPeter Dunlap count = 0; 1137a6d42e7dSPeter Dunlap } 1138a6d42e7dSPeter Dunlap 1139a6d42e7dSPeter Dunlap for (i = 0; i < count; i++) { 1140*a4f92191SSam Cramer if (!tags || !tags[i]) { 1141a6d42e7dSPeter Dunlap continue; 1142a6d42e7dSPeter Dunlap } 1143a6d42e7dSPeter Dunlap 1144a6d42e7dSPeter Dunlap /* see that all referenced groups are already defined */ 1145a6d42e7dSPeter Dunlap tpg = cfg->config_tpg_list; 1146a6d42e7dSPeter Dunlap while (tpg != NULL) { 1147a6d42e7dSPeter Dunlap if (strcmp(tags[i], tpg->tpg_name) == 0) { 1148a6d42e7dSPeter Dunlap break; 1149a6d42e7dSPeter Dunlap } 1150a6d42e7dSPeter Dunlap tpg = tpg->tpg_next; 1151a6d42e7dSPeter Dunlap } 1152a6d42e7dSPeter Dunlap if (tpg == NULL) { 1153a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1154a6d42e7dSPeter Dunlap gettext("Invalid tpg-name %s: not defined"), 1155a6d42e7dSPeter Dunlap tags[i]); 1156a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1157a6d42e7dSPeter Dunlap ret = 1; 1158a6d42e7dSPeter Dunlap goto done; 1159a6d42e7dSPeter Dunlap } 1160a6d42e7dSPeter Dunlap } 1161a6d42e7dSPeter Dunlap 1162a6d42e7dSPeter Dunlap /* 1163a6d42e7dSPeter Dunlap * don't recreate tags that are already associated, 1164a6d42e7dSPeter Dunlap * remove tags not requested. 1165a6d42e7dSPeter Dunlap */ 1166a6d42e7dSPeter Dunlap if (tags) { 1167a6d42e7dSPeter Dunlap tpgt = tgtp->tgt_tpgt_list; 1168a6d42e7dSPeter Dunlap while (tpgt) { 1169a6d42e7dSPeter Dunlap for (i = 0; i < count; i++) { 1170a6d42e7dSPeter Dunlap if (!tags[i]) { 1171a6d42e7dSPeter Dunlap continue; 1172a6d42e7dSPeter Dunlap } 1173a6d42e7dSPeter Dunlap 1174a6d42e7dSPeter Dunlap if (strcmp(tpgt->tpgt_tpg_name, tags[i]) 1175a6d42e7dSPeter Dunlap == 0) { 1176a6d42e7dSPeter Dunlap /* non-null tags will be created */ 1177a6d42e7dSPeter Dunlap tags[i] = NULL; 1178a6d42e7dSPeter Dunlap break; 1179a6d42e7dSPeter Dunlap } 1180a6d42e7dSPeter Dunlap } 1181a6d42e7dSPeter Dunlap if (i == count) { 1182a6d42e7dSPeter Dunlap /* one to remove */ 1183a6d42e7dSPeter Dunlap it_tpgt_t *ptr = tpgt; 1184a6d42e7dSPeter Dunlap 1185a6d42e7dSPeter Dunlap tpgt = ptr->tpgt_next; 1186a6d42e7dSPeter Dunlap it_tpgt_delete(cfg, tgtp, ptr); 1187a6d42e7dSPeter Dunlap } else { 1188a6d42e7dSPeter Dunlap tpgt = tpgt->tpgt_next; 1189a6d42e7dSPeter Dunlap } 1190a6d42e7dSPeter Dunlap } 1191a6d42e7dSPeter Dunlap } 1192a6d42e7dSPeter Dunlap 1193a6d42e7dSPeter Dunlap /* see if there are any left to add */ 1194a6d42e7dSPeter Dunlap for (i = 0; i < count; i++) { 1195*a4f92191SSam Cramer if (!tags || !tags[i]) { 1196a6d42e7dSPeter Dunlap continue; 1197a6d42e7dSPeter Dunlap } 1198a6d42e7dSPeter Dunlap 1199a6d42e7dSPeter Dunlap /* generate the tag number to use */ 1200a6d42e7dSPeter Dunlap tag_name_to_num(tags[i], &tagid); 1201a6d42e7dSPeter Dunlap 1202a6d42e7dSPeter Dunlap ret = it_tpgt_create(cfg, tgtp, &tpgt, tags[i], tagid); 1203a6d42e7dSPeter Dunlap if (ret != 0) { 1204a6d42e7dSPeter Dunlap if (ret == E2BIG) { 1205a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1206a6d42e7dSPeter Dunlap gettext("Error, no portal tag available")); 1207a6d42e7dSPeter Dunlap } else { 1208a6d42e7dSPeter Dunlap (void) fprintf(stderr, gettext( 1209a6d42e7dSPeter Dunlap "Could not add target portal group" 1210a6d42e7dSPeter Dunlap " tag %s, error %d"), tags[i], ret); 1211a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1212a6d42e7dSPeter Dunlap } 1213a6d42e7dSPeter Dunlap goto done; 1214a6d42e7dSPeter Dunlap } 1215a6d42e7dSPeter Dunlap } 1216a6d42e7dSPeter Dunlap 1217a6d42e7dSPeter Dunlap /* remove the tags from the proplist before continuing */ 1218a6d42e7dSPeter Dunlap (void) nvlist_remove_all(proplist, "tpg-tag"); 1219a6d42e7dSPeter Dunlap 1220a6d42e7dSPeter Dunlap /* 1221a6d42e7dSPeter Dunlap * Rename this target, if requested. Save the old name in 1222a6d42e7dSPeter Dunlap * the property list, so the kernel knows this is a renamed 1223a6d42e7dSPeter Dunlap * target, and not a new one. 1224a6d42e7dSPeter Dunlap */ 1225a6d42e7dSPeter Dunlap if (newname && (strlen(newname) > 0)) { 1226a6d42e7dSPeter Dunlap ret = nvlist_add_string(proplist, "oldtargetname", 1227a6d42e7dSPeter Dunlap tgtp->tgt_name); 1228a6d42e7dSPeter Dunlap if (ret != 0) { 1229a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1230a6d42e7dSPeter Dunlap gettext("Error renaming target.")); 1231a6d42e7dSPeter Dunlap goto done; 1232a6d42e7dSPeter Dunlap } 1233*a4f92191SSam Cramer (void) strlcpy(tgtp->tgt_name, canonical_newname, 1234a6d42e7dSPeter Dunlap sizeof (tgtp->tgt_name)); 1235a6d42e7dSPeter Dunlap } 1236a6d42e7dSPeter Dunlap 1237a6d42e7dSPeter Dunlap ret = it_tgt_setprop(cfg, tgtp, proplist, &errlist); 1238a6d42e7dSPeter Dunlap if (ret != 0) { 1239a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1240a6d42e7dSPeter Dunlap gettext("Error setting target properties: %d"), ret); 1241a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1242a6d42e7dSPeter Dunlap if (errlist) { 1243a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1244a6d42e7dSPeter Dunlap char *nn; 1245a6d42e7dSPeter Dunlap char *nv; 1246a6d42e7dSPeter Dunlap 1247a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(errlist, nvp)) 1248a6d42e7dSPeter Dunlap != NULL) { 1249a6d42e7dSPeter Dunlap nv = NULL; 1250a6d42e7dSPeter Dunlap 1251a6d42e7dSPeter Dunlap nn = nvpair_name(nvp); 1252a6d42e7dSPeter Dunlap (void) nvpair_value_string(nvp, &nv); 1253a6d42e7dSPeter Dunlap 1254a6d42e7dSPeter Dunlap if (nv != NULL) { 1255a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\t%s: %s\n", 1256a6d42e7dSPeter Dunlap nn, nv); 1257a6d42e7dSPeter Dunlap } 1258a6d42e7dSPeter Dunlap } 1259a6d42e7dSPeter Dunlap 1260a6d42e7dSPeter Dunlap nvlist_free(errlist); 1261a6d42e7dSPeter Dunlap } 1262a6d42e7dSPeter Dunlap goto done; 1263a6d42e7dSPeter Dunlap } 1264a6d42e7dSPeter Dunlap 1265a6d42e7dSPeter Dunlap if (ret == 0) { 1266a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1267a6d42e7dSPeter Dunlap STMF_STALE(ret); 1268a6d42e7dSPeter Dunlap } 1269a6d42e7dSPeter Dunlap 1270a6d42e7dSPeter Dunlap done: 1271a6d42e7dSPeter Dunlap if (ret == 0) { 1272a6d42e7dSPeter Dunlap (void) printf(gettext("Target %s successfully modified"), 1273a6d42e7dSPeter Dunlap tgtp->tgt_name); 1274a6d42e7dSPeter Dunlap (void) printf("\n"); 1275a6d42e7dSPeter Dunlap } 1276a6d42e7dSPeter Dunlap 1277*a4f92191SSam Cramer if (did_it_config_load) 1278a6d42e7dSPeter Dunlap it_config_free(cfg); 1279a6d42e7dSPeter Dunlap 1280*a4f92191SSam Cramer if (canonical_newname != NULL) 1281*a4f92191SSam Cramer free(canonical_newname); 1282*a4f92191SSam Cramer 1283a6d42e7dSPeter Dunlap return (ret); 1284a6d42e7dSPeter Dunlap } 1285a6d42e7dSPeter Dunlap 1286a6d42e7dSPeter Dunlap int 1287a6d42e7dSPeter Dunlap create_tpg(char *tpg, int addrc, char **addrs) 1288a6d42e7dSPeter Dunlap { 1289a6d42e7dSPeter Dunlap int ret; 1290a6d42e7dSPeter Dunlap it_config_t *cfg; 1291a6d42e7dSPeter Dunlap it_tpg_t *tpgp; 1292a6d42e7dSPeter Dunlap int count = 0; 1293a6d42e7dSPeter Dunlap it_portal_t *ptl; 1294a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 1295836fc322SSam Cramer int i = 0; 1296a6d42e7dSPeter Dunlap 1297a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1298a6d42e7dSPeter Dunlap 1299a6d42e7dSPeter Dunlap if (!tpg) { 1300a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1301a6d42e7dSPeter Dunlap gettext("Error, no target portal group specified")); 1302a6d42e7dSPeter Dunlap return (EINVAL); 1303a6d42e7dSPeter Dunlap } 1304a6d42e7dSPeter Dunlap 1305a6d42e7dSPeter Dunlap if (strlen(tpg) > (MAX_TPG_NAMELEN - 1)) { 1306a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1307a6d42e7dSPeter Dunlap gettext("Target Portal Group name must be no longer " 1308a6d42e7dSPeter Dunlap "than %d characters."), (MAX_TPG_NAMELEN - 1)); 1309a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1310a6d42e7dSPeter Dunlap return (EINVAL); 1311a6d42e7dSPeter Dunlap } 1312a6d42e7dSPeter Dunlap 1313a6d42e7dSPeter Dunlap if (!addrs || (addrc <= 0)) { 1314a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1315a6d42e7dSPeter Dunlap gettext("Error, no portal addresses specified")); 1316a6d42e7dSPeter Dunlap return (EINVAL); 1317a6d42e7dSPeter Dunlap } 1318a6d42e7dSPeter Dunlap 1319a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1320a6d42e7dSPeter Dunlap if (ret != 0) { 1321a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1322a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1323a6d42e7dSPeter Dunlap ret); 1324a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1325a6d42e7dSPeter Dunlap return (ret); 1326a6d42e7dSPeter Dunlap } 1327a6d42e7dSPeter Dunlap 1328a6d42e7dSPeter Dunlap tpgp = cfg->config_tpg_list; 1329a6d42e7dSPeter Dunlap while (tpgp != NULL) { 1330a6d42e7dSPeter Dunlap if (strcmp(tpgp->tpg_name, tpg) == 0) { 1331a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1332a6d42e7dSPeter Dunlap gettext("Target Portal Group %s already exists"), 1333a6d42e7dSPeter Dunlap tpg); 1334a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1335a6d42e7dSPeter Dunlap it_config_free(cfg); 1336a6d42e7dSPeter Dunlap return (1); 1337a6d42e7dSPeter Dunlap } 1338a6d42e7dSPeter Dunlap tpgp = tpgp->tpg_next; 1339a6d42e7dSPeter Dunlap } 1340a6d42e7dSPeter Dunlap 1341a6d42e7dSPeter Dunlap /* 1342836fc322SSam Cramer * Ensure that the addrs don't contain commas. 1343836fc322SSam Cramer */ 1344836fc322SSam Cramer for (i = 0; i < addrc; i++) { 1345836fc322SSam Cramer if (strchr(addrs[i], ',')) { 1346836fc322SSam Cramer (void) fprintf(stderr, 1347836fc322SSam Cramer gettext("Bad portal name %s"), 1348836fc322SSam Cramer addrs[i]); 1349836fc322SSam Cramer (void) fprintf(stderr, "\n"); 1350836fc322SSam Cramer 1351836fc322SSam Cramer it_config_free(cfg); 1352836fc322SSam Cramer return (EINVAL); 1353836fc322SSam Cramer } 1354836fc322SSam Cramer } 1355836fc322SSam Cramer 1356836fc322SSam Cramer /* 1357a6d42e7dSPeter Dunlap * Create the portal group and first portal 1358a6d42e7dSPeter Dunlap */ 1359a6d42e7dSPeter Dunlap ret = it_tpg_create(cfg, &tpgp, tpg, addrs[count]); 1360a6d42e7dSPeter Dunlap if (ret != 0) { 1361a6d42e7dSPeter Dunlap if (ret == EEXIST) { 1362a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1363a6d42e7dSPeter Dunlap gettext("Portal %s already in use"), 1364a6d42e7dSPeter Dunlap addrs[count]); 1365a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1366a6d42e7dSPeter Dunlap } 1367a6d42e7dSPeter Dunlap it_config_free(cfg); 1368a6d42e7dSPeter Dunlap return (ret); 1369a6d42e7dSPeter Dunlap } 1370a6d42e7dSPeter Dunlap 1371a6d42e7dSPeter Dunlap /* 1372a6d42e7dSPeter Dunlap * Add the remaining portals 1373a6d42e7dSPeter Dunlap */ 1374a6d42e7dSPeter Dunlap for (count = 1; count < addrc; count++) { 1375a6d42e7dSPeter Dunlap if (!addrs[count]) { 1376a6d42e7dSPeter Dunlap continue; 1377a6d42e7dSPeter Dunlap } 1378a6d42e7dSPeter Dunlap 1379a6d42e7dSPeter Dunlap ret = it_portal_create(cfg, tpgp, &ptl, addrs[count]); 1380a6d42e7dSPeter Dunlap if (ret != 0) { 1381a6d42e7dSPeter Dunlap if (ret == EEXIST) { 1382a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1383a6d42e7dSPeter Dunlap gettext("Portal %s already in use"), 1384a6d42e7dSPeter Dunlap addrs[count]); 1385a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1386a6d42e7dSPeter Dunlap } else { 1387a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1388a6d42e7dSPeter Dunlap gettext("Error adding portal %s: %d"), 1389a6d42e7dSPeter Dunlap addrs[count], ret); 1390a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1391a6d42e7dSPeter Dunlap break; 1392a6d42e7dSPeter Dunlap } 1393a6d42e7dSPeter Dunlap } 1394a6d42e7dSPeter Dunlap } 1395a6d42e7dSPeter Dunlap 1396a6d42e7dSPeter Dunlap if (ret == 0) { 1397a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1398a6d42e7dSPeter Dunlap STMF_STALE(ret); 1399a6d42e7dSPeter Dunlap } 1400a6d42e7dSPeter Dunlap 1401a6d42e7dSPeter Dunlap it_config_free(cfg); 1402a6d42e7dSPeter Dunlap 1403a6d42e7dSPeter Dunlap return (ret); 1404a6d42e7dSPeter Dunlap } 1405a6d42e7dSPeter Dunlap 1406a6d42e7dSPeter Dunlap static int 1407a6d42e7dSPeter Dunlap list_tpg(char *tpg, boolean_t verbose, boolean_t script) 1408a6d42e7dSPeter Dunlap { 1409a6d42e7dSPeter Dunlap int ret; 1410a6d42e7dSPeter Dunlap it_config_t *cfg; 1411a6d42e7dSPeter Dunlap it_tpg_t *ptr; 1412a6d42e7dSPeter Dunlap boolean_t found = B_FALSE; 1413a6d42e7dSPeter Dunlap it_portal_t *portal; 1414a6d42e7dSPeter Dunlap boolean_t first = B_TRUE; 1415a6d42e7dSPeter Dunlap boolean_t first_portal; 1416a6d42e7dSPeter Dunlap char *pstr; 1417a6d42e7dSPeter Dunlap char *sec = "solaris.smf.read.stmf"; 1418a6d42e7dSPeter Dunlap 1419a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1420a6d42e7dSPeter Dunlap 1421a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1422a6d42e7dSPeter Dunlap if (ret != 0) { 1423a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1424a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1425a6d42e7dSPeter Dunlap ret); 1426a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1427a6d42e7dSPeter Dunlap return (ret); 1428a6d42e7dSPeter Dunlap } 1429a6d42e7dSPeter Dunlap 1430a6d42e7dSPeter Dunlap ptr = cfg->config_tpg_list; 1431a6d42e7dSPeter Dunlap 1432a6d42e7dSPeter Dunlap for (; ptr != NULL; ptr = ptr->tpg_next) { 1433a6d42e7dSPeter Dunlap if (found) { 1434a6d42e7dSPeter Dunlap break; 1435a6d42e7dSPeter Dunlap } 1436a6d42e7dSPeter Dunlap 1437a6d42e7dSPeter Dunlap if (tpg) { 1438a6d42e7dSPeter Dunlap if (strcmp(tpg, ptr->tpg_name) != 0) { 1439a6d42e7dSPeter Dunlap continue; 1440a6d42e7dSPeter Dunlap } else { 1441a6d42e7dSPeter Dunlap found = B_TRUE; 1442a6d42e7dSPeter Dunlap } 1443a6d42e7dSPeter Dunlap } 1444a6d42e7dSPeter Dunlap 1445a6d42e7dSPeter Dunlap if (!script && first) { 1446a6d42e7dSPeter Dunlap (void) printf("%-30s%-9s\n", "TARGET PORTAL GROUP", 1447a6d42e7dSPeter Dunlap "PORTAL COUNT"); 1448a6d42e7dSPeter Dunlap first = B_FALSE; 1449a6d42e7dSPeter Dunlap } 1450a6d42e7dSPeter Dunlap 1451a6d42e7dSPeter Dunlap if (!script) { 1452a6d42e7dSPeter Dunlap (void) printf("%-30s", ptr->tpg_name); 1453a6d42e7dSPeter Dunlap if (strlen(ptr->tpg_name) > 30) { 1454a6d42e7dSPeter Dunlap (void) printf("\t"); 1455a6d42e7dSPeter Dunlap } 1456a6d42e7dSPeter Dunlap (void) printf("%-9d", ptr->tpg_portal_count); 1457a6d42e7dSPeter Dunlap } else { 1458a6d42e7dSPeter Dunlap (void) printf("%s\t%d", ptr->tpg_name, 1459a6d42e7dSPeter Dunlap ptr->tpg_portal_count); 1460a6d42e7dSPeter Dunlap } 1461a6d42e7dSPeter Dunlap 1462a6d42e7dSPeter Dunlap if (!verbose) { 1463a6d42e7dSPeter Dunlap (void) printf("\n"); 1464a6d42e7dSPeter Dunlap continue; 1465a6d42e7dSPeter Dunlap } 1466a6d42e7dSPeter Dunlap 1467a6d42e7dSPeter Dunlap if (!script) { 1468a6d42e7dSPeter Dunlap (void) printf("\n portals:"); 1469a6d42e7dSPeter Dunlap } 1470a6d42e7dSPeter Dunlap 1471a6d42e7dSPeter Dunlap first_portal = B_TRUE; 1472a6d42e7dSPeter Dunlap 1473a6d42e7dSPeter Dunlap portal = ptr->tpg_portal_list; 1474a6d42e7dSPeter Dunlap for (; portal != NULL; portal = portal->next) { 1475a6d42e7dSPeter Dunlap ret = sockaddr_to_str(&(portal->portal_addr), &pstr); 1476a6d42e7dSPeter Dunlap if (ret != 0) { 1477a6d42e7dSPeter Dunlap /* invalid addr? */ 1478a6d42e7dSPeter Dunlap continue; 1479a6d42e7dSPeter Dunlap } 1480a6d42e7dSPeter Dunlap if (!first_portal) { 1481a6d42e7dSPeter Dunlap (void) printf(","); 1482a6d42e7dSPeter Dunlap } else { 1483a6d42e7dSPeter Dunlap (void) printf("\t"); 1484a6d42e7dSPeter Dunlap first_portal = B_FALSE; 1485a6d42e7dSPeter Dunlap } 1486a6d42e7dSPeter Dunlap 1487a6d42e7dSPeter Dunlap (void) printf("%s", pstr); 1488a6d42e7dSPeter Dunlap free(pstr); 1489a6d42e7dSPeter Dunlap } 1490a6d42e7dSPeter Dunlap 1491a6d42e7dSPeter Dunlap if (first_portal) { 1492a6d42e7dSPeter Dunlap /* none found */ 1493a6d42e7dSPeter Dunlap (void) printf("\t<none>"); 1494a6d42e7dSPeter Dunlap } 1495a6d42e7dSPeter Dunlap 1496a6d42e7dSPeter Dunlap (void) printf("\n"); 1497a6d42e7dSPeter Dunlap } 1498a6d42e7dSPeter Dunlap 1499a6d42e7dSPeter Dunlap if (tpg && (!found)) { 1500a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1501a6d42e7dSPeter Dunlap gettext("Target Portal Group %s not found!\n"), tpg); 1502a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1503a6d42e7dSPeter Dunlap ret = 1; 1504a6d42e7dSPeter Dunlap } 1505a6d42e7dSPeter Dunlap 1506a6d42e7dSPeter Dunlap it_config_free(cfg); 1507a6d42e7dSPeter Dunlap 1508a6d42e7dSPeter Dunlap return (ret); 1509a6d42e7dSPeter Dunlap } 1510a6d42e7dSPeter Dunlap 1511a6d42e7dSPeter Dunlap static int 1512a6d42e7dSPeter Dunlap delete_tpg(char *tpg, boolean_t force) 1513a6d42e7dSPeter Dunlap { 1514a6d42e7dSPeter Dunlap int ret; 1515a6d42e7dSPeter Dunlap it_config_t *cfg; 1516a6d42e7dSPeter Dunlap it_tpg_t *ptpg = NULL; 1517a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 1518a6d42e7dSPeter Dunlap 1519a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1520a6d42e7dSPeter Dunlap 1521a6d42e7dSPeter Dunlap if (!tpg) { 1522a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1523a6d42e7dSPeter Dunlap gettext("Error, no target portal group specified")); 1524a6d42e7dSPeter Dunlap return (EINVAL); 1525a6d42e7dSPeter Dunlap } 1526a6d42e7dSPeter Dunlap 1527a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1528a6d42e7dSPeter Dunlap if (ret != 0) { 1529a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1530a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1531a6d42e7dSPeter Dunlap ret); 1532a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1533a6d42e7dSPeter Dunlap return (ret); 1534a6d42e7dSPeter Dunlap } 1535a6d42e7dSPeter Dunlap 1536a6d42e7dSPeter Dunlap ptpg = cfg->config_tpg_list; 1537a6d42e7dSPeter Dunlap for (; ptpg != NULL; ptpg = ptpg->tpg_next) { 1538a6d42e7dSPeter Dunlap if (strcmp(tpg, ptpg->tpg_name) == 0) { 1539a6d42e7dSPeter Dunlap break; 1540a6d42e7dSPeter Dunlap } 1541a6d42e7dSPeter Dunlap } 1542a6d42e7dSPeter Dunlap 1543a6d42e7dSPeter Dunlap if (!ptpg) { 1544a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1545a6d42e7dSPeter Dunlap gettext("Target portal group %s does not exist."), 1546a6d42e7dSPeter Dunlap tpg); 1547a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1548a6d42e7dSPeter Dunlap ret = 1; 1549a6d42e7dSPeter Dunlap } else { 1550a6d42e7dSPeter Dunlap ret = it_tpg_delete(cfg, ptpg, force); 1551a6d42e7dSPeter Dunlap if (ret == EBUSY) { 1552a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1553a6d42e7dSPeter Dunlap gettext( 1554a6d42e7dSPeter Dunlap "Target portal group associated with one or more " 1555a6d42e7dSPeter Dunlap "targets. Cannot delete.")); 1556a6d42e7dSPeter Dunlap } 1557a6d42e7dSPeter Dunlap 1558a6d42e7dSPeter Dunlap if (ret == 0) { 1559a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1560a6d42e7dSPeter Dunlap STMF_STALE(ret); 1561a6d42e7dSPeter Dunlap } 1562a6d42e7dSPeter Dunlap } 1563a6d42e7dSPeter Dunlap 1564a6d42e7dSPeter Dunlap it_config_free(cfg); 1565a6d42e7dSPeter Dunlap 1566a6d42e7dSPeter Dunlap return (ret); 1567a6d42e7dSPeter Dunlap } 1568a6d42e7dSPeter Dunlap 1569a6d42e7dSPeter Dunlap static int 1570a6d42e7dSPeter Dunlap modify_initiator(char *ini, nvlist_t *proplist, boolean_t create) 1571a6d42e7dSPeter Dunlap { 1572a6d42e7dSPeter Dunlap int ret; 1573a6d42e7dSPeter Dunlap it_config_t *cfg; 1574a6d42e7dSPeter Dunlap it_ini_t *inip; 1575a6d42e7dSPeter Dunlap nvlist_t *errlist = NULL; 1576a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1577a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 1578a6d42e7dSPeter Dunlap boolean_t changed = B_TRUE; 1579a6d42e7dSPeter Dunlap 1580a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1581a6d42e7dSPeter Dunlap 1582a6d42e7dSPeter Dunlap if (!ini) { 1583a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1584a6d42e7dSPeter Dunlap gettext("Error, no initiator specified")); 1585a6d42e7dSPeter Dunlap return (EINVAL); 1586a6d42e7dSPeter Dunlap } else if (create) { 1587a6d42e7dSPeter Dunlap /* 1588a6d42e7dSPeter Dunlap * validate input name - what are the rules for EUI 1589a6d42e7dSPeter Dunlap * and IQN values? 1590a6d42e7dSPeter Dunlap */ 1591a6d42e7dSPeter Dunlap if ((strncmp(ini, "eui.", 4) != 0) && 1592a6d42e7dSPeter Dunlap (strncmp(ini, "iqn.", 4) != 0)) { 1593a6d42e7dSPeter Dunlap (void) fprintf(stderr, gettext("Invalid name %s"), 1594a6d42e7dSPeter Dunlap ini); 1595a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1596a6d42e7dSPeter Dunlap return (EINVAL); 1597a6d42e7dSPeter Dunlap } 1598a6d42e7dSPeter Dunlap } 1599a6d42e7dSPeter Dunlap 1600a6d42e7dSPeter Dunlap /* 1601a6d42e7dSPeter Dunlap * See if any properties were actually specified. 1602a6d42e7dSPeter Dunlap */ 1603a6d42e7dSPeter Dunlap if (proplist) { 1604a6d42e7dSPeter Dunlap nvp = nvlist_next_nvpair(proplist, nvp); 1605a6d42e7dSPeter Dunlap } 1606a6d42e7dSPeter Dunlap 1607a6d42e7dSPeter Dunlap if ((nvp == NULL) && !create) { 1608a6d42e7dSPeter Dunlap changed = B_FALSE; 1609a6d42e7dSPeter Dunlap } 1610a6d42e7dSPeter Dunlap 1611a6d42e7dSPeter Dunlap /* 1612a6d42e7dSPeter Dunlap * If no properties, and this is really a modify op, verify 1613a6d42e7dSPeter Dunlap * that the requested initiator exists, but then don't do anything. 1614a6d42e7dSPeter Dunlap * Modifying non-existent is an error; doing nothing to a defined 1615a6d42e7dSPeter Dunlap * initiator is not. 1616a6d42e7dSPeter Dunlap */ 1617a6d42e7dSPeter Dunlap 1618a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1619a6d42e7dSPeter Dunlap if (ret != 0) { 1620a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1621a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1622a6d42e7dSPeter Dunlap ret); 1623a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1624a6d42e7dSPeter Dunlap return (ret); 1625a6d42e7dSPeter Dunlap } 1626a6d42e7dSPeter Dunlap 1627a6d42e7dSPeter Dunlap inip = cfg->config_ini_list; 1628a6d42e7dSPeter Dunlap while (inip) { 1629a6d42e7dSPeter Dunlap if (strcmp(inip->ini_name, ini) == 0) { 1630a6d42e7dSPeter Dunlap break; 1631a6d42e7dSPeter Dunlap } 1632a6d42e7dSPeter Dunlap 1633a6d42e7dSPeter Dunlap inip = inip->ini_next; 1634a6d42e7dSPeter Dunlap } 1635a6d42e7dSPeter Dunlap 1636a6d42e7dSPeter Dunlap if (create) { 1637a6d42e7dSPeter Dunlap if (inip) { 1638a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1639a6d42e7dSPeter Dunlap gettext("Initiator %s already exists"), 1640a6d42e7dSPeter Dunlap inip->ini_name); 1641a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1642a6d42e7dSPeter Dunlap ret = EINVAL; 1643a6d42e7dSPeter Dunlap } else { 1644a6d42e7dSPeter Dunlap ret = it_ini_create(cfg, &inip, ini); 1645a6d42e7dSPeter Dunlap if (ret != 0) { 1646a6d42e7dSPeter Dunlap if (ret == EFAULT) { 1647a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1648a6d42e7dSPeter Dunlap gettext("Invalid iSCSI name %s"), 1649a6d42e7dSPeter Dunlap ini); 1650a6d42e7dSPeter Dunlap } else { 1651a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1652a6d42e7dSPeter Dunlap gettext( 1653a6d42e7dSPeter Dunlap "Error creating initiator: %d"), 1654a6d42e7dSPeter Dunlap ret); 1655a6d42e7dSPeter Dunlap } 1656a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1657a6d42e7dSPeter Dunlap } 1658a6d42e7dSPeter Dunlap } 1659a6d42e7dSPeter Dunlap } else if (!inip) { 1660a6d42e7dSPeter Dunlap ret = ENOENT; 1661a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1662a6d42e7dSPeter Dunlap gettext("Error, initiator %s not found."), 1663a6d42e7dSPeter Dunlap ini); 1664a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1665a6d42e7dSPeter Dunlap } 1666a6d42e7dSPeter Dunlap 1667a6d42e7dSPeter Dunlap if ((ret == 0) && nvp) { 1668a6d42e7dSPeter Dunlap ret = it_ini_setprop(inip, proplist, &errlist); 1669a6d42e7dSPeter Dunlap 1670a6d42e7dSPeter Dunlap if (ret != 0) { 1671a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1672a6d42e7dSPeter Dunlap gettext("Error setting initiator properties: %d"), 1673a6d42e7dSPeter Dunlap ret); 1674a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1675a6d42e7dSPeter Dunlap if (errlist) { 1676a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1677a6d42e7dSPeter Dunlap char *nn; 1678a6d42e7dSPeter Dunlap char *nv; 1679a6d42e7dSPeter Dunlap 1680a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(errlist, nvp)) 1681a6d42e7dSPeter Dunlap != NULL) { 1682a6d42e7dSPeter Dunlap nv = NULL; 1683a6d42e7dSPeter Dunlap 1684a6d42e7dSPeter Dunlap nn = nvpair_name(nvp); 1685a6d42e7dSPeter Dunlap (void) nvpair_value_string(nvp, &nv); 1686a6d42e7dSPeter Dunlap 1687a6d42e7dSPeter Dunlap if (nv != NULL) { 1688a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1689a6d42e7dSPeter Dunlap "\t%s: %s\n", nn, nv); 1690a6d42e7dSPeter Dunlap } 1691a6d42e7dSPeter Dunlap } 1692a6d42e7dSPeter Dunlap 1693a6d42e7dSPeter Dunlap nvlist_free(errlist); 1694a6d42e7dSPeter Dunlap } 1695a6d42e7dSPeter Dunlap } 1696a6d42e7dSPeter Dunlap } 1697a6d42e7dSPeter Dunlap 1698a6d42e7dSPeter Dunlap if ((ret == 0) && changed) { 1699a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1700a6d42e7dSPeter Dunlap STMF_STALE(ret); 1701a6d42e7dSPeter Dunlap } 1702a6d42e7dSPeter Dunlap 1703a6d42e7dSPeter Dunlap it_config_free(cfg); 1704a6d42e7dSPeter Dunlap 1705a6d42e7dSPeter Dunlap return (ret); 1706a6d42e7dSPeter Dunlap } 1707a6d42e7dSPeter Dunlap 1708a6d42e7dSPeter Dunlap static int 1709a6d42e7dSPeter Dunlap list_initiator(char *ini, boolean_t verbose, boolean_t script) /* ARGSUSED */ 1710a6d42e7dSPeter Dunlap { 1711a6d42e7dSPeter Dunlap int ret; 1712a6d42e7dSPeter Dunlap it_config_t *cfg; 1713a6d42e7dSPeter Dunlap it_ini_t *ptr; 1714a6d42e7dSPeter Dunlap boolean_t found = B_FALSE; 1715a6d42e7dSPeter Dunlap boolean_t first = B_TRUE; 1716a6d42e7dSPeter Dunlap char *isecret; 1717a6d42e7dSPeter Dunlap char *iuser; 1718a6d42e7dSPeter Dunlap char *sec = "solaris.smf.read.stmf"; 1719a6d42e7dSPeter Dunlap 1720a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1721a6d42e7dSPeter Dunlap 1722a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1723a6d42e7dSPeter Dunlap if (ret != 0) { 1724a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1725a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1726a6d42e7dSPeter Dunlap ret); 1727a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1728a6d42e7dSPeter Dunlap return (ret); 1729a6d42e7dSPeter Dunlap } 1730a6d42e7dSPeter Dunlap 1731a6d42e7dSPeter Dunlap ptr = cfg->config_ini_list; 1732a6d42e7dSPeter Dunlap 1733a6d42e7dSPeter Dunlap for (; ptr != NULL; ptr = ptr->ini_next) { 1734a6d42e7dSPeter Dunlap isecret = "unset"; 1735a6d42e7dSPeter Dunlap iuser = "<none>"; 1736a6d42e7dSPeter Dunlap 1737a6d42e7dSPeter Dunlap if (found) { 1738a6d42e7dSPeter Dunlap break; 1739a6d42e7dSPeter Dunlap } 1740a6d42e7dSPeter Dunlap 1741a6d42e7dSPeter Dunlap if (ini) { 1742a6d42e7dSPeter Dunlap if (strcmp(ini, ptr->ini_name) != 0) { 1743a6d42e7dSPeter Dunlap continue; 1744a6d42e7dSPeter Dunlap } else { 1745a6d42e7dSPeter Dunlap found = B_TRUE; 1746a6d42e7dSPeter Dunlap } 1747a6d42e7dSPeter Dunlap } 1748a6d42e7dSPeter Dunlap 1749a6d42e7dSPeter Dunlap if (ptr->ini_properties) { 1750a6d42e7dSPeter Dunlap if (nvlist_exists(ptr->ini_properties, "chapsecret")) { 1751a6d42e7dSPeter Dunlap isecret = "set"; 1752a6d42e7dSPeter Dunlap } 1753a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(ptr->ini_properties, 1754a6d42e7dSPeter Dunlap "chapuser", &iuser); 1755a6d42e7dSPeter Dunlap 1756a6d42e7dSPeter Dunlap } 1757a6d42e7dSPeter Dunlap 1758a6d42e7dSPeter Dunlap /* there's nothing to print for verbose yet */ 1759a6d42e7dSPeter Dunlap if (!script && first) { 1760a6d42e7dSPeter Dunlap (void) printf("%-61s%-10s%-7s\n", "INITIATOR NAME", 1761a6d42e7dSPeter Dunlap "CHAPUSER", "SECRET"); 1762a6d42e7dSPeter Dunlap first = B_FALSE; 1763a6d42e7dSPeter Dunlap } 1764a6d42e7dSPeter Dunlap 1765a6d42e7dSPeter Dunlap if (!script) { 1766a6d42e7dSPeter Dunlap /* 1767a6d42e7dSPeter Dunlap * try not to let columns run into each other. 1768a6d42e7dSPeter Dunlap * Stick a tab after too-long fields. 1769a6d42e7dSPeter Dunlap * Lengths chosen are for the 'common' cases. 1770a6d42e7dSPeter Dunlap */ 1771a6d42e7dSPeter Dunlap (void) printf("%-61s", ptr->ini_name); 1772a6d42e7dSPeter Dunlap 1773a6d42e7dSPeter Dunlap if (strlen(ptr->ini_name) > 60) { 1774a6d42e7dSPeter Dunlap (void) printf("\t"); 1775a6d42e7dSPeter Dunlap } 1776a6d42e7dSPeter Dunlap 1777a6d42e7dSPeter Dunlap (void) printf("%-15s", iuser); 1778a6d42e7dSPeter Dunlap if (strlen(iuser) >= 15) { 1779a6d42e7dSPeter Dunlap (void) printf("\t"); 1780a6d42e7dSPeter Dunlap } 1781a6d42e7dSPeter Dunlap 1782a6d42e7dSPeter Dunlap (void) printf("%-4s", isecret); 1783a6d42e7dSPeter Dunlap } else { 1784a6d42e7dSPeter Dunlap (void) printf("%s\t%s\t%s", ptr->ini_name, 1785a6d42e7dSPeter Dunlap iuser, isecret); 1786a6d42e7dSPeter Dunlap } 1787a6d42e7dSPeter Dunlap 1788a6d42e7dSPeter Dunlap (void) printf("\n"); 1789a6d42e7dSPeter Dunlap } 1790a6d42e7dSPeter Dunlap 1791a6d42e7dSPeter Dunlap if (ini && (!found)) { 1792a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1793a6d42e7dSPeter Dunlap gettext("Initiator %s not found!"), ini); 1794a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1795a6d42e7dSPeter Dunlap ret = 1; 1796a6d42e7dSPeter Dunlap } 1797a6d42e7dSPeter Dunlap 1798a6d42e7dSPeter Dunlap it_config_free(cfg); 1799a6d42e7dSPeter Dunlap 1800a6d42e7dSPeter Dunlap return (ret); 1801a6d42e7dSPeter Dunlap } 1802a6d42e7dSPeter Dunlap 1803a6d42e7dSPeter Dunlap int 1804a6d42e7dSPeter Dunlap delete_initiator(char *ini) 1805a6d42e7dSPeter Dunlap { 1806a6d42e7dSPeter Dunlap int ret; 1807a6d42e7dSPeter Dunlap it_config_t *cfg; 1808a6d42e7dSPeter Dunlap it_ini_t *ptr; 1809a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 1810a6d42e7dSPeter Dunlap 1811a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1812a6d42e7dSPeter Dunlap 1813a6d42e7dSPeter Dunlap if (!ini) { 1814a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1815a6d42e7dSPeter Dunlap gettext("Error, no initiator specified")); 1816a6d42e7dSPeter Dunlap return (EINVAL); 1817a6d42e7dSPeter Dunlap } 1818a6d42e7dSPeter Dunlap 1819a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1820a6d42e7dSPeter Dunlap if (ret != 0) { 1821a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1822a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1823a6d42e7dSPeter Dunlap ret); 1824a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1825a6d42e7dSPeter Dunlap return (ret); 1826a6d42e7dSPeter Dunlap } 1827a6d42e7dSPeter Dunlap 1828a6d42e7dSPeter Dunlap ptr = cfg->config_ini_list; 1829a6d42e7dSPeter Dunlap while (ptr) { 1830a6d42e7dSPeter Dunlap if (strcmp(ptr->ini_name, ini) == 0) { 1831a6d42e7dSPeter Dunlap break; 1832a6d42e7dSPeter Dunlap } 1833a6d42e7dSPeter Dunlap 1834a6d42e7dSPeter Dunlap ptr = ptr->ini_next; 1835a6d42e7dSPeter Dunlap } 1836a6d42e7dSPeter Dunlap 1837a6d42e7dSPeter Dunlap if (ptr) { 1838a6d42e7dSPeter Dunlap it_ini_delete(cfg, ptr); 1839a6d42e7dSPeter Dunlap 1840a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1841a6d42e7dSPeter Dunlap STMF_STALE(ret); 1842a6d42e7dSPeter Dunlap } else { 1843a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1844a6d42e7dSPeter Dunlap gettext("Initiator %s not found"), ini); 1845a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1846a6d42e7dSPeter Dunlap ret = 1; 1847a6d42e7dSPeter Dunlap } 1848a6d42e7dSPeter Dunlap 1849a6d42e7dSPeter Dunlap return (ret); 1850a6d42e7dSPeter Dunlap } 1851a6d42e7dSPeter Dunlap 1852a6d42e7dSPeter Dunlap static int 1853a6d42e7dSPeter Dunlap modify_defaults(nvlist_t *proplist) 1854a6d42e7dSPeter Dunlap { 1855a6d42e7dSPeter Dunlap int ret; 1856a6d42e7dSPeter Dunlap it_config_t *cfg; 1857a6d42e7dSPeter Dunlap nvlist_t *errlist = NULL; 1858a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1859a6d42e7dSPeter Dunlap char *sec = "solaris.smf.modify.stmf"; 1860a6d42e7dSPeter Dunlap 1861a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1862a6d42e7dSPeter Dunlap 1863a6d42e7dSPeter Dunlap if (proplist) { 1864a6d42e7dSPeter Dunlap /* make sure at least one property is specified */ 1865a6d42e7dSPeter Dunlap nvp = nvlist_next_nvpair(proplist, nvp); 1866a6d42e7dSPeter Dunlap } 1867a6d42e7dSPeter Dunlap 1868a6d42e7dSPeter Dunlap if (nvp == NULL) { 1869a6d42e7dSPeter Dunlap /* empty list */ 1870a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 1871a6d42e7dSPeter Dunlap gettext("Error, no properties specified")); 1872a6d42e7dSPeter Dunlap return (EINVAL); 1873a6d42e7dSPeter Dunlap } 1874a6d42e7dSPeter Dunlap 1875a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1876a6d42e7dSPeter Dunlap if (ret != 0) { 1877a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1878a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1879a6d42e7dSPeter Dunlap ret); 1880a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1881a6d42e7dSPeter Dunlap return (ret); 1882a6d42e7dSPeter Dunlap } 1883a6d42e7dSPeter Dunlap 1884a6d42e7dSPeter Dunlap ret = it_config_setprop(cfg, proplist, &errlist); 1885a6d42e7dSPeter Dunlap if (ret != 0) { 1886a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1887a6d42e7dSPeter Dunlap gettext("Error setting global properties: %d"), 1888a6d42e7dSPeter Dunlap ret); 1889a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1890a6d42e7dSPeter Dunlap if (errlist) { 1891a6d42e7dSPeter Dunlap nvpair_t *nvp = NULL; 1892a6d42e7dSPeter Dunlap char *nn; 1893a6d42e7dSPeter Dunlap char *nv; 1894a6d42e7dSPeter Dunlap 1895a6d42e7dSPeter Dunlap while ((nvp = nvlist_next_nvpair(errlist, nvp)) 1896a6d42e7dSPeter Dunlap != NULL) { 1897a6d42e7dSPeter Dunlap nv = NULL; 1898a6d42e7dSPeter Dunlap 1899a6d42e7dSPeter Dunlap nn = nvpair_name(nvp); 1900a6d42e7dSPeter Dunlap (void) nvpair_value_string(nvp, &nv); 1901a6d42e7dSPeter Dunlap 1902a6d42e7dSPeter Dunlap if (nv != NULL) { 1903a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\t%s: %s\n", 1904a6d42e7dSPeter Dunlap nn, nv); 1905a6d42e7dSPeter Dunlap } 1906a6d42e7dSPeter Dunlap } 1907a6d42e7dSPeter Dunlap 1908a6d42e7dSPeter Dunlap nvlist_free(errlist); 1909a6d42e7dSPeter Dunlap } 1910a6d42e7dSPeter Dunlap } 1911a6d42e7dSPeter Dunlap 1912a6d42e7dSPeter Dunlap if (ret == 0) { 1913a6d42e7dSPeter Dunlap ret = it_config_commit(cfg); 1914a6d42e7dSPeter Dunlap STMF_STALE(ret); 1915a6d42e7dSPeter Dunlap } 1916a6d42e7dSPeter Dunlap 1917a6d42e7dSPeter Dunlap it_config_free(cfg); 1918a6d42e7dSPeter Dunlap 1919a6d42e7dSPeter Dunlap return (ret); 1920a6d42e7dSPeter Dunlap } 1921a6d42e7dSPeter Dunlap 1922a6d42e7dSPeter Dunlap static int 1923a6d42e7dSPeter Dunlap list_defaults(boolean_t script) 1924a6d42e7dSPeter Dunlap { 1925a6d42e7dSPeter Dunlap int ret; 1926a6d42e7dSPeter Dunlap it_config_t *cfg; 1927a6d42e7dSPeter Dunlap nvlist_t *nvl; 1928a6d42e7dSPeter Dunlap char *alias = "<none>"; 1929a6d42e7dSPeter Dunlap char *auth = "<none>"; 1930a6d42e7dSPeter Dunlap char *isns = "disabled"; 1931a6d42e7dSPeter Dunlap char **isvrs = NULL; 1932a6d42e7dSPeter Dunlap uint32_t scount = 0; 1933a6d42e7dSPeter Dunlap char *rsvr = "<none>"; 1934a6d42e7dSPeter Dunlap char *rsecret = "unset"; 1935a6d42e7dSPeter Dunlap boolean_t val = B_FALSE; 1936a6d42e7dSPeter Dunlap int i; 1937a6d42e7dSPeter Dunlap char *sec = "solaris.smf.read.stmf"; 1938a6d42e7dSPeter Dunlap 1939a6d42e7dSPeter Dunlap ITADM_CHKAUTH(sec); 1940a6d42e7dSPeter Dunlap 1941a6d42e7dSPeter Dunlap ret = it_config_load(&cfg); 1942a6d42e7dSPeter Dunlap if (ret != 0) { 1943a6d42e7dSPeter Dunlap (void) fprintf(stderr, 1944a6d42e7dSPeter Dunlap gettext("Error retrieving iSCSI target configuration: %d"), 1945a6d42e7dSPeter Dunlap ret); 1946a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 1947a6d42e7dSPeter Dunlap return (ret); 1948a6d42e7dSPeter Dunlap } 1949a6d42e7dSPeter Dunlap 1950a6d42e7dSPeter Dunlap nvl = cfg->config_global_properties; 1951a6d42e7dSPeter Dunlap 1952a6d42e7dSPeter Dunlap /* look up all possible options */ 1953a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(nvl, "alias", &alias); 1954a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(nvl, "auth", &auth); 1955a6d42e7dSPeter Dunlap (void) nvlist_lookup_boolean_value(nvl, "isns", &val); 1956a6d42e7dSPeter Dunlap if (val == B_TRUE) { 1957a6d42e7dSPeter Dunlap isns = "enabled"; 1958a6d42e7dSPeter Dunlap } 1959a6d42e7dSPeter Dunlap (void) nvlist_lookup_string_array(nvl, "isnsserver", &isvrs, 1960a6d42e7dSPeter Dunlap &scount); 1961a6d42e7dSPeter Dunlap (void) nvlist_lookup_string(nvl, "radiusserver", &rsvr); 1962a6d42e7dSPeter Dunlap if (nvlist_exists(nvl, "radiussecret")) { 1963a6d42e7dSPeter Dunlap rsecret = "set"; 1964a6d42e7dSPeter Dunlap } 1965a6d42e7dSPeter Dunlap 1966a6d42e7dSPeter Dunlap if (!script) { 1967a6d42e7dSPeter Dunlap (void) printf("%s:\n\n", 1968a6d42e7dSPeter Dunlap gettext("iSCSI Target Default Properties")); 1969a6d42e7dSPeter Dunlap } 1970a6d42e7dSPeter Dunlap 1971a6d42e7dSPeter Dunlap if (script) { 1972a6d42e7dSPeter Dunlap (void) printf("%s\t%s\t%s\t%s\t%s\t", 1973a6d42e7dSPeter Dunlap alias, auth, rsvr, rsecret, isns); 1974a6d42e7dSPeter Dunlap } else { 1975a6d42e7dSPeter Dunlap (void) printf("%-15s\t%s\n%-15s\t%s\n%-15s\t%s\n%-15s\t%s\n" 1976a6d42e7dSPeter Dunlap "%-15s\t%s\n%-15s\t", 1977a6d42e7dSPeter Dunlap "alias:", alias, "auth:", auth, "radiusserver:", 1978a6d42e7dSPeter Dunlap rsvr, "radiussecret:", rsecret, "isns:", isns, 1979a6d42e7dSPeter Dunlap "isnsserver:"); 1980a6d42e7dSPeter Dunlap } 1981a6d42e7dSPeter Dunlap 1982a6d42e7dSPeter Dunlap for (i = 0; i < scount; i++) { 1983a6d42e7dSPeter Dunlap if (!isvrs || !isvrs[i]) { 1984a6d42e7dSPeter Dunlap break; 1985a6d42e7dSPeter Dunlap } 1986a6d42e7dSPeter Dunlap if (i > 0) { 1987a6d42e7dSPeter Dunlap (void) printf(","); 1988a6d42e7dSPeter Dunlap } 1989a6d42e7dSPeter Dunlap (void) printf("%s", isvrs[i]); 1990a6d42e7dSPeter Dunlap } 1991a6d42e7dSPeter Dunlap 1992a6d42e7dSPeter Dunlap if (i == 0) { 1993a6d42e7dSPeter Dunlap (void) printf("%s", "<none>"); 1994a6d42e7dSPeter Dunlap } 1995a6d42e7dSPeter Dunlap 1996a6d42e7dSPeter Dunlap (void) printf("\n"); 1997a6d42e7dSPeter Dunlap 1998a6d42e7dSPeter Dunlap it_config_free(cfg); 1999a6d42e7dSPeter Dunlap 2000a6d42e7dSPeter Dunlap return (0); 2001a6d42e7dSPeter Dunlap } 2002a6d42e7dSPeter Dunlap 2003a6d42e7dSPeter Dunlap static int 2004a6d42e7dSPeter Dunlap itadm_get_password(nvlist_t *nvl, char *key, char *passfile, 2005a6d42e7dSPeter Dunlap char *phrase) 2006a6d42e7dSPeter Dunlap { 2007a6d42e7dSPeter Dunlap int ret = 0; 2008a6d42e7dSPeter Dunlap char *pass; 2009a6d42e7dSPeter Dunlap char buf[1024]; 2010a6d42e7dSPeter Dunlap int fd; 2011a6d42e7dSPeter Dunlap struct stat64 sbuf; 2012a6d42e7dSPeter Dunlap size_t rd; 2013a6d42e7dSPeter Dunlap 2014a6d42e7dSPeter Dunlap if (!nvl || !key) { 2015a6d42e7dSPeter Dunlap return (EINVAL); 2016a6d42e7dSPeter Dunlap } 2017a6d42e7dSPeter Dunlap 2018a6d42e7dSPeter Dunlap if (passfile) { 2019a6d42e7dSPeter Dunlap ret = stat64(passfile, &sbuf); 2020a6d42e7dSPeter Dunlap if ((ret != 0) || (!S_ISREG(sbuf.st_mode))) { 2021a6d42e7dSPeter Dunlap (void) fprintf(stderr, 2022a6d42e7dSPeter Dunlap gettext("Invalid secret file %s"), 2023a6d42e7dSPeter Dunlap passfile); 2024a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 2025a6d42e7dSPeter Dunlap return (EBADF); 2026a6d42e7dSPeter Dunlap } 2027a6d42e7dSPeter Dunlap 2028a6d42e7dSPeter Dunlap fd = open64(passfile, O_RDONLY); 2029a6d42e7dSPeter Dunlap if (fd == -1) { 2030a6d42e7dSPeter Dunlap ret = errno; 2031a6d42e7dSPeter Dunlap (void) fprintf(stderr, 2032a6d42e7dSPeter Dunlap gettext("Could not open secret file %s, %d"), 2033a6d42e7dSPeter Dunlap passfile, ret); 2034a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 2035a6d42e7dSPeter Dunlap return (ret); 2036a6d42e7dSPeter Dunlap } 2037a6d42e7dSPeter Dunlap 2038a6d42e7dSPeter Dunlap rd = read(fd, buf, sbuf.st_size); 2039a6d42e7dSPeter Dunlap (void) close(fd); 2040a6d42e7dSPeter Dunlap 2041a6d42e7dSPeter Dunlap if (rd != sbuf.st_size) { 2042a6d42e7dSPeter Dunlap ret = EIO; 2043a6d42e7dSPeter Dunlap (void) fprintf(stderr, 2044a6d42e7dSPeter Dunlap gettext("Could not read secret file %s, %d"), 2045a6d42e7dSPeter Dunlap passfile, ret); 2046a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 2047a6d42e7dSPeter Dunlap return (ret); 2048a6d42e7dSPeter Dunlap } 2049a6d42e7dSPeter Dunlap 2050a6d42e7dSPeter Dunlap /* ensure buf is properly terminated */ 2051a6d42e7dSPeter Dunlap buf[rd] = '\0'; 2052a6d42e7dSPeter Dunlap 2053a6d42e7dSPeter Dunlap /* if last char is a newline, strip it off */ 2054a6d42e7dSPeter Dunlap if (buf[rd - 1] == '\n') { 2055a6d42e7dSPeter Dunlap buf[rd - 1] = '\0'; 2056a6d42e7dSPeter Dunlap } 2057a6d42e7dSPeter Dunlap 2058a6d42e7dSPeter Dunlap /* validate length */ 2059a6d42e7dSPeter Dunlap if ((strlen(buf) > 255) || (strlen(buf) < 12)) { 2060a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 2061a6d42e7dSPeter Dunlap gettext( 2062a6d42e7dSPeter Dunlap "Secret must be between 12 and 255 characters")); 2063a6d42e7dSPeter Dunlap return (EINVAL); 2064a6d42e7dSPeter Dunlap } 2065a6d42e7dSPeter Dunlap } else { 2066a6d42e7dSPeter Dunlap /* prompt for secret */ 2067a6d42e7dSPeter Dunlap if (!phrase) { 2068a6d42e7dSPeter Dunlap return (EINVAL); 2069a6d42e7dSPeter Dunlap } 2070a6d42e7dSPeter Dunlap 2071a6d42e7dSPeter Dunlap pass = getpassphrase(phrase); 2072a6d42e7dSPeter Dunlap if (!pass) { 2073a6d42e7dSPeter Dunlap ret = errno; 2074a6d42e7dSPeter Dunlap (void) fprintf(stderr, 2075a6d42e7dSPeter Dunlap gettext("Could not read secret, %d"), 2076a6d42e7dSPeter Dunlap ret); 2077a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 2078a6d42e7dSPeter Dunlap return (ret); 2079a6d42e7dSPeter Dunlap } 2080a6d42e7dSPeter Dunlap 2081a6d42e7dSPeter Dunlap /* validate length */ 2082a6d42e7dSPeter Dunlap if ((strlen(pass) > 255) || (strlen(pass) < 12)) { 2083a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 2084a6d42e7dSPeter Dunlap gettext( 2085a6d42e7dSPeter Dunlap "Secret must be between 12 and 255 characters")); 2086a6d42e7dSPeter Dunlap return (EINVAL); 2087a6d42e7dSPeter Dunlap } 2088a6d42e7dSPeter Dunlap 2089a6d42e7dSPeter Dunlap (void) strlcpy(buf, pass, sizeof (buf)); 2090a6d42e7dSPeter Dunlap 2091a6d42e7dSPeter Dunlap /* confirm entered secret */ 2092a6d42e7dSPeter Dunlap pass = getpassphrase(gettext("Re-enter secret: ")); 2093a6d42e7dSPeter Dunlap if (!pass) { 2094a6d42e7dSPeter Dunlap ret = errno; 2095a6d42e7dSPeter Dunlap (void) fprintf(stderr, 2096a6d42e7dSPeter Dunlap gettext("Could not read secret, %d"), 2097a6d42e7dSPeter Dunlap ret); 2098a6d42e7dSPeter Dunlap (void) fprintf(stderr, "\n"); 2099a6d42e7dSPeter Dunlap return (ret); 2100a6d42e7dSPeter Dunlap } 2101a6d42e7dSPeter Dunlap 2102a6d42e7dSPeter Dunlap if (strcmp(buf, pass) != 0) { 2103a6d42e7dSPeter Dunlap ret = EINVAL; 2104a6d42e7dSPeter Dunlap (void) fprintf(stderr, "%s\n", 2105a6d42e7dSPeter Dunlap gettext("Secret validation failed")); 2106a6d42e7dSPeter Dunlap return (ret); 2107a6d42e7dSPeter Dunlap } 2108a6d42e7dSPeter Dunlap 2109a6d42e7dSPeter Dunlap } 2110a6d42e7dSPeter Dunlap 2111a6d42e7dSPeter Dunlap ret = nvlist_add_string(nvl, key, buf); 2112a6d42e7dSPeter Dunlap 2113a6d42e7dSPeter Dunlap return (ret); 2114a6d42e7dSPeter Dunlap } 2115a6d42e7dSPeter Dunlap 2116a6d42e7dSPeter Dunlap static int 2117a6d42e7dSPeter Dunlap itadm_opt_to_arr(nvlist_t *nvl, char *key, char *opt, uint32_t *num) 2118a6d42e7dSPeter Dunlap { 2119a6d42e7dSPeter Dunlap int count; 2120a6d42e7dSPeter Dunlap char *bufp; 2121a6d42e7dSPeter Dunlap char **arr; 2122a6d42e7dSPeter Dunlap 2123a6d42e7dSPeter Dunlap if (!opt || !key || !nvl) { 2124a6d42e7dSPeter Dunlap return (EINVAL); 2125a6d42e7dSPeter Dunlap } 2126a6d42e7dSPeter Dunlap 2127a6d42e7dSPeter Dunlap bufp = opt; 2128a6d42e7dSPeter Dunlap count = 1; 2129a6d42e7dSPeter Dunlap 2130a6d42e7dSPeter Dunlap for (;;) { 2131a6d42e7dSPeter Dunlap bufp = strchr(bufp, ','); 2132a6d42e7dSPeter Dunlap if (!bufp) { 2133a6d42e7dSPeter Dunlap break; 2134a6d42e7dSPeter Dunlap } 2135a6d42e7dSPeter Dunlap bufp++; 2136a6d42e7dSPeter Dunlap count++; 2137a6d42e7dSPeter Dunlap } 2138a6d42e7dSPeter Dunlap 2139a6d42e7dSPeter Dunlap arr = calloc(count, sizeof (char *)); 2140a6d42e7dSPeter Dunlap if (!arr) { 2141a6d42e7dSPeter Dunlap return (ENOMEM); 2142a6d42e7dSPeter Dunlap } 2143a6d42e7dSPeter Dunlap 2144a6d42e7dSPeter Dunlap bufp = opt; 2145a6d42e7dSPeter Dunlap /* set delimiter to comma */ 2146a6d42e7dSPeter Dunlap (void) bufsplit(",", 0, NULL); 2147a6d42e7dSPeter Dunlap 2148a6d42e7dSPeter Dunlap /* split up that buf! */ 2149a6d42e7dSPeter Dunlap (void) bufsplit(bufp, count, arr); 2150a6d42e7dSPeter Dunlap 2151a6d42e7dSPeter Dunlap /* if requested, return the number of array members found */ 2152a6d42e7dSPeter Dunlap if (num) { 2153a6d42e7dSPeter Dunlap *num = count; 2154a6d42e7dSPeter Dunlap } 2155a6d42e7dSPeter Dunlap 2156a6d42e7dSPeter Dunlap return (nvlist_add_string_array(nvl, key, arr, count)); 2157a6d42e7dSPeter Dunlap } 2158a6d42e7dSPeter Dunlap 2159a6d42e7dSPeter Dunlap static void 2160a6d42e7dSPeter Dunlap tag_name_to_num(char *tagname, uint16_t *tagnum) 2161a6d42e7dSPeter Dunlap { 2162a6d42e7dSPeter Dunlap ulong_t id; 2163a6d42e7dSPeter Dunlap char *ptr = NULL; 2164a6d42e7dSPeter Dunlap 2165a6d42e7dSPeter Dunlap if (!tagname || !tagnum) { 2166a6d42e7dSPeter Dunlap return; 2167a6d42e7dSPeter Dunlap } 2168a6d42e7dSPeter Dunlap 2169a6d42e7dSPeter Dunlap *tagnum = 0; 2170a6d42e7dSPeter Dunlap 2171a6d42e7dSPeter Dunlap id = strtoul(tagname, &ptr, 10); 2172a6d42e7dSPeter Dunlap 2173a6d42e7dSPeter Dunlap /* Must be entirely numeric and in-range */ 2174a6d42e7dSPeter Dunlap if (ptr && (*ptr != '\0')) { 2175a6d42e7dSPeter Dunlap return; 2176a6d42e7dSPeter Dunlap } 2177a6d42e7dSPeter Dunlap 2178a6d42e7dSPeter Dunlap if ((id <= UINT16_MAX) && (id > 1)) { 2179a6d42e7dSPeter Dunlap *tagnum = (uint16_t)id; 2180a6d42e7dSPeter Dunlap } 2181a6d42e7dSPeter Dunlap } 2182*a4f92191SSam Cramer 2183*a4f92191SSam Cramer /* 2184*a4f92191SSam Cramer * Return a new string containing the canonical (lower-case) 2185*a4f92191SSam Cramer * form of the target name. 2186*a4f92191SSam Cramer */ 2187*a4f92191SSam Cramer static char * 2188*a4f92191SSam Cramer canonical_target_name(char *tgt) 2189*a4f92191SSam Cramer { 2190*a4f92191SSam Cramer if (IS_IQN_NAME(tgt)) { 2191*a4f92191SSam Cramer /* lowercase iqn names */ 2192*a4f92191SSam Cramer return (strduplc(tgt)); 2193*a4f92191SSam Cramer } else { 2194*a4f92191SSam Cramer return (strdup(tgt)); 2195*a4f92191SSam Cramer } 2196*a4f92191SSam Cramer } 2197*a4f92191SSam Cramer 2198*a4f92191SSam Cramer /* 2199*a4f92191SSam Cramer * Duplicate a string, converting it to lower case in the process. 2200*a4f92191SSam Cramer * Returns NULL if no memory. 2201*a4f92191SSam Cramer */ 2202*a4f92191SSam Cramer static char * 2203*a4f92191SSam Cramer strduplc(char *s) 2204*a4f92191SSam Cramer { 2205*a4f92191SSam Cramer char *lc = strdup(s); 2206*a4f92191SSam Cramer 2207*a4f92191SSam Cramer if (lc != NULL) { 2208*a4f92191SSam Cramer char *l = lc; 2209*a4f92191SSam Cramer while (*s) { 2210*a4f92191SSam Cramer *l = tolower(*s); 2211*a4f92191SSam Cramer s++; l++; 2212*a4f92191SSam Cramer } 2213*a4f92191SSam Cramer } 2214*a4f92191SSam Cramer 2215*a4f92191SSam Cramer return (lc); 2216*a4f92191SSam Cramer } 2217