/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <widec.h>
#include <netdb.h>
#include <unistd.h>
#include <libintl.h>
#include <limits.h>
#include <string.h>
#include <strings.h>
#include <syslog.h>
#include <errno.h>
#include <wctype.h>
#include <assert.h>
#include <ima.h>
#include <libsun_ima.h>
#include <sys/iscsi_protocol.h>
#include "cmdparse.h"
#include "sun_ima.h"
#include "iscsiadm.h"
/*
* Version number:
* MAJOR - This should only change when there is an incompatible change made
* to the interfaces or the output.
*
* MINOR - This should change whenever there is a new command or new feature
* with no incompatible change.
*/
/* For listNode */
if ((option) == PRINT_CONFIGURED_PARAMS) { \
gettext("no"), \
} else if ((option) == PRINT_NEGOTIATED_PARAMS) { \
}
if ((option) == PRINT_CONFIGURED_PARAMS) { \
} \
} else if ((option) == PRINT_NEGOTIATED_PARAMS) { \
} \
}
/* forward declarations */
#define PARSE_ADDR_OK 0
#define PARSE_TARGET_OK 0
typedef enum iSCSINameCheckStatus {
/* Utility functions */
int parseTarget(char *targetStr,
/* subcommand functions */
static int addFunc(int, char **, int, cmdOptions_t *, void *, int *);
static int listFunc(int, char **, int, cmdOptions_t *, void *, int *);
static int modifyFunc(int, char **, int, cmdOptions_t *, void *, int *);
static int removeFunc(int, char **, int, cmdOptions_t *, void *, int *);
/* helper functions */
static char *getExecBasename(char *);
static int getNodeProps(IMA_NODE_PROPERTIES *);
static int getSecret(char *, int *, int, int);
static int getTargetAddress(int, char *, IMA_TARGET_ADDRESS *);
static int printLoginParameters(char *, IMA_OID, int);
static void printDiscoveryMethod(char *, IMA_UINT32);
static void printTargetLuns(IMA_OID_LIST *);
static void printSendTargets(SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *);
static void printDigestAlgorithm(SUN_IMA_DIGEST_ALGORITHM_VALUE *, int);
static int setLoginParameter(IMA_OID, int, char *);
static int setLoginParameters(IMA_OID, char *);
static int setTunableParameters(IMA_OID, char *);
static void printLibError(IMA_STATUS);
/* LINTED E_STATIC_UNUSED */
static int sunInitiatorFind(IMA_OID *);
static int getAuthMethodValue(char *, IMA_AUTHMETHOD *);
static int getLoginParam(char *);
static int getTunableParam(char *);
static int printConfiguredSessions(IMA_OID);
/* object functions per subcommand */
static int addAddress(int, int, char *[], int *);
static int addStaticConfig(int, char *[], int *);
static int listDiscovery(int *);
static int listDiscoveryAddress(int, char *[], cmdOptions_t *, int *);
static int listISNSServerAddress(int, char *[], cmdOptions_t *, int *);
static int listNode(int *);
static int listStaticConfig(int, char *[], int *);
static int listTarget(int, char *[], cmdOptions_t *, int *);
static int listTargetParam(int, char *[], cmdOptions_t *, int *);
static int modifyDiscovery(cmdOptions_t *, int *);
static int modifyNodeAuthMethod(IMA_OID, char *, int *);
static int modifyNodeRadiusConfig(IMA_OID, char *, int *);
static int modifyNodeRadiusAccess(IMA_OID, char *, int *);
static int modifyNodeRadiusSharedSecret(IMA_OID, int *);
static int modifyNode(cmdOptions_t *, int *);
static int modifyTargetAuthMethod(IMA_OID, char *, int *);
static int modifyTargetParam(cmdOptions_t *, char *, int *);
static int removeAddress(int, int, char *[], int *);
static int removeStaticConfig(int, char *[], int *);
static int removeTargetParam(int, char *[], int *);
static int modifyTargetBidirAuthFlag(IMA_OID, char *, int *);
/* LINTED E_STATIC_UNUSED */
void *pProps,
/* LINTED E_STATIC_UNUSED */
void *pProps,
/* LINTED E_STATIC_UNUSED */
/* globals */
static char *cmdName;
/*
* Available option letters:
*
* befgijklmnoquwxyz
*
* DEFGHIJKLMOQUVWXYZ
*/
/*
* Add new options here
*/
{NULL, 0, 0, 0}
};
{"dataseqinorder", DATA_SEQ_IN_ORDER},
{"defaulttime2retain", DEFAULT_TIME_2_RETAIN},
{"defaulttime2wait", DEFAULT_TIME_2_WAIT},
{"firstburstlength", FIRST_BURST_LENGTH},
{"immediatedata", IMMEDIATE_DATA},
{"initialr2t", INITIAL_R2T},
{"maxburstlength", MAX_BURST_LENGTH},
{"datapduinorder", DATA_PDU_IN_ORDER},
{"maxoutstandingr2t", MAX_OUTSTANDING_R2T},
{"maxrecvdataseglen", MAX_RECV_DATA_SEG_LEN},
{"maxconnections", MAX_CONNECTIONS},
{"errorrecoverylevel", ERROR_RECOVERY_LEVEL},
{NULL, 0}
};
{"recv-login-rsp-timeout", RECV_LOGIN_RSP_TIMEOUT},
{"conn-login-max", CONN_LOGIN_MAX},
{"polling-login-delay", POLLING_LOGIN_DELAY},
{NULL, 0}
};
/*
* Add new subcommands here
*/
};
/*
* Add objects here
*/
{"discovery", DISCOVERY},
{"discovery-address", DISCOVERY_ADDRESS},
{"isns-server", ISNS_SERVER_ADDRESS},
{"initiator-node", NODE},
{"static-config", STATIC_CONFIG},
{"target", TARGET},
{"target-param", TARGET_PARAM},
{NULL, 0}
};
/*
* Rules for subcommands and objects
*/
"target-name"},
"target-name"},
"target-name,target-address[:port-number][,tpgt]"},
{0, 0, 0, 0, 0, NULL}
};
/*
* list of objects, subcommands, valid short options, required flag and
* exclusive option string
*
* If it's not here, there are no options for that object.
*/
{0, 0, 0, 0, 0}
};
static boolean_t
{
int i;
return (B_FALSE);
}
return (B_FALSE);
}
/*
* Convert names to lower case and compare
*/
return (B_FALSE);
}
}
return (B_TRUE);
}
static boolean_t
{
int compSize;
return (B_FALSE);
}
}
return (B_TRUE);
}
return (B_FALSE);
}
static int
{
int len;
}
}
return (-1);
}
static int
{
int len;
}
}
return (-1);
}
static void
{
char *errorString;
switch (status) {
case IMA_ERROR_NOT_SUPPORTED:
gettext("Operation currently not supported");
break;
break;
break;
case IMA_ERROR_UNKNOWN_ERROR:
break;
case IMA_ERROR_LU_IN_USE:
break;
break;
gettext("Internal library error: Invalid oid type specified");
break;
gettext("Internal library error: Incorrect oid type specified");
break;
break;
case IMA_ERROR_NAME_TOO_LONG:
break;
default:
}
}
/*
* input:
* execFullName - exec name of program (argv[0])
*
* Returns:
* command name portion of execFullName
*/
static char *
{
/* guard against '/' at end of command invocation */
for (;;) {
break;
} else {
if (*execBasename == '\0') {
*lastSlash = '\0';
continue;
}
break;
}
}
return (execBasename);
}
/*
* input:
* nodeProps - pointer to caller allocated IMA_NODE_PROPERTIES
*
* returns:
* zero on success
* non-zero otherwise
*/
static int
{
if (!(IMA_SUCCESS(status))) {
return (INF_ERROR);
}
if (!IMA_SUCCESS(status)) {
return (INF_ERROR);
}
return (0);
}
/*
* sunInitiatorFind
* Purpose:
* Finds the Sun iSCSI initiator (LHBA). This CLI currently supports only
* one initiator.
*
* output:
* oid of initiator
*
* Returns:
* zero on success with initiator found
* > 0 on success with no initiator found
* < 0 on failure
*/
static int
{
if (!IMA_SUCCESS(status)) {
return (-1);
}
(void) IMA_FreeMemory(lhbaList);
return (-1);
}
(void) IMA_FreeMemory(lhbaList);
return (0);
}
/*
* input:
* wcInput - wide character string containing discovery address
* output:
* address - IMA_TARGET_ADDRESS structure containing valid
* discovery address
* returns:
* zero on success
* non-zero on failure
*/
static int
{
char *colPos;
char *startPos;
unsigned long inputPort;
int rval;
/* Check if this is a ipv6 address */
if (!startPos) {
return (1);
}
} else {
/* set start position to beginning of input object */
}
/* wcschr for ':'. If not there, use default port */
if (!colPos) {
if (addrType == DISCOVERY_ADDRESS) {
} else if (addrType == ISNS_SERVER_ADDRESS) {
} else {
}
} else {
}
/* inet_pton returns 1 on success */
if (rval != 1) {
gettext("invalid IP address"));
return (1);
}
if (colPos) {
char *errchr;
colPos++;
gettext("port number missing"));
return (1);
}
/*
* convert port string to unsigned value
* Note: Don't remove errno = 0 as you may get false failures.
*/
errno = 0;
gettext("port number invalid"));
return (1);
}
/* make sure it's in the range */
gettext("port number out of range"));
return (1);
}
}
return (0);
}
/*
* Print results of send targets command
*/
static void
{
int inetSize;
int af;
int i;
} else {
}
}
}
/*
* Print all login parameters
*/
static int
{
switch (printOption) {
case PRINT_CONFIGURED_PARAMS:
gettext("Login Parameters (Default/Configured)"));
break;
case PRINT_NEGOTIATED_PARAMS:
gettext("Login Parameters (Negotiated)"));
&oid,
&pConnList);
if (!IMA_SUCCESS(status)) {
return (1);
}
&connProps);
break;
default:
return (1);
}
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Data Sequence In Order"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Data PDU In Order"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Default Time To Retain"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Default Time To Wait"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Error Recovery Level"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
&propMinMax);
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Initial Ready To Transfer (R2T)"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Max Outstanding R2T"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
&propMinMax);
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
gettext("Max Receive Data Segment Length"));
if (printOption == PRINT_NEGOTIATED_PARAMS) {
} else {
}
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(connProps);
return (1);
}
(void) IMA_FreeMemory(connProps);
return (0);
}
/*
* Print discovery information.
*/
static void
{
} else {
if (!((discoveryMethodFlags &
}
if (!((discoveryMethodFlags &
}
if (!((discoveryMethodFlags &
}
}
}
/*
* printConnectionList - Prints the conection list provided
*/
static void
{
int i;
union {
} tmp;
&connProps);
if (imaStatus != IMA_STATUS_SUCCESS) {
continue;
}
INET_ADDRSTRLEN)) {
"%s %s: %s:%u\n",
gettext("IP address (Local)"),
}
} else {
INET6_ADDRSTRLEN)) {
"%s %s: [%s]:%u\n",
gettext("IP address (Local)"),
}
}
INET_ADDRSTRLEN)) {
"%s %s: %s:%u\n",
gettext("IP address (Peer)"),
}
} else {
INET6_ADDRSTRLEN)) {
"%s %s: [%s]:%u\n",
gettext("IP address (Peer)"),
}
}
(void) IMA_FreeMemory(connProps);
}
}
/*
* Set login parameters on a target or initiator
*/
static int
{
char *endptr;
/*
* for clarity, there are two switch statements
* The first loads the variable and the second
* calls the appropriate API
*/
switch (optval) {
case DATA_SEQ_IN_ORDER:
case IMMEDIATE_DATA:
case INITIAL_R2T:
case DATA_PDU_IN_ORDER:
/* implement 'default'? */
} else {
gettext("invalid option argument"),
optarg);
return (1);
}
break;
case DEFAULT_TIME_2_RETAIN:
case DEFAULT_TIME_2_WAIT:
errno = 0;
gettext("invalid option argument"),
optarg);
return (1);
}
if (uintValue > 3600) {
gettext("value must be between 0 and 3600"));
return (1);
}
break;
case FIRST_BURST_LENGTH:
case MAX_BURST_LENGTH:
case MAX_RECV_DATA_SEG_LEN:
errno = 0;
/* implement 'default'? */
gettext("invalid option argument"),
optarg);
return (1);
}
gettext("value must be between 512 and 16777215"));
return (1);
}
break;
case MAX_OUTSTANDING_R2T:
errno = 0;
gettext("invalid option argument"),
optarg);
return (1);
}
gettext("value must be between 1 and 65535"));
return (1);
}
break;
case HEADER_DIGEST:
case DATA_DIGEST:
} else {
gettext("invalid option argument"),
optarg);
return (1);
}
break;
case MAX_CONNECTIONS:
errno = 0;
gettext("invalid option argument"),
optarg);
return (1);
}
gettext("value must be between 1 and 256"));
return (1);
}
break;
case ERROR_RECOVERY_LEVEL:
errno = 0;
gettext("invalid option argument"),
optarg);
return (1);
}
if (uintValue > 2) {
gettext("value must be between 0 and 2"));
return (1);
}
break;
default:
return (1);
}
switch (optval) {
case DATA_PDU_IN_ORDER:
break;
case DATA_SEQ_IN_ORDER:
break;
case DEFAULT_TIME_2_RETAIN:
break;
case DEFAULT_TIME_2_WAIT:
break;
case FIRST_BURST_LENGTH:
/*
* If this call fails check to see if it's because
* the requested value is > than maxBurstLength
*/
if (!IMA_SUCCESS(status)) {
&propMinMax);
if (!IMA_SUCCESS(status)) {
return (1);
}
"%s: %s\n", cmdName,
gettext("firstBurstLength must " \
"be less than or equal to than " \
"maxBurstLength"));
}
return (1);
}
break;
case IMMEDIATE_DATA:
break;
case INITIAL_R2T:
break;
case MAX_BURST_LENGTH:
/*
* If this call fails check to see if it's because
* the requested value is < than firstBurstLength
*/
if (!IMA_SUCCESS(status)) {
&propMinMax);
if (!IMA_SUCCESS(status)) {
return (1);
}
gettext("maxBurstLength must be " \
"greater than or equal to " \
"firstBurstLength"));
}
return (1);
}
break;
case MAX_OUTSTANDING_R2T:
break;
case MAX_RECV_DATA_SEG_LEN:
break;
case HEADER_DIGEST:
&digestAlgList[0]);
break;
case DATA_DIGEST:
&digestAlgList[0]);
break;
case MAX_CONNECTIONS:
break;
case ERROR_RECOVERY_LEVEL:
break;
}
if (!IMA_SUCCESS(status)) {
return (1);
}
return (0);
}
static void
int printOption)
{
int i;
if (printOption == PRINT_CONFIGURED_PARAMS) {
for (i = 0; i < digestAlgorithms->defaultAlgorithmCount; i++) {
if (i > 0) {
}
switch (digestAlgorithms->defaultAlgorithms[i]) {
case SUN_IMA_DIGEST_NONE:
gettext("NONE"));
break;
case SUN_IMA_DIGEST_CRC32:
gettext("CRC32"));
break;
default:
gettext("Unknown"));
break;
}
}
for (i = 0;
i < digestAlgorithms->currentAlgorithmCount; i++) {
if (i > 0) {
}
switch (digestAlgorithms->
currentAlgorithms[i]) {
case SUN_IMA_DIGEST_NONE:
gettext("NONE"));
break;
case SUN_IMA_DIGEST_CRC32:
gettext("CRC32"));
break;
default:
gettext("Unknown"));
break;
}
}
} else {
}
} else if (printOption == PRINT_NEGOTIATED_PARAMS) {
for (i = 0;
i++) {
if (i > 0) {
}
switch (digestAlgorithms->
negotiatedAlgorithms[i]) {
case SUN_IMA_DIGEST_NONE:
gettext("NONE"));
break;
case SUN_IMA_DIGEST_CRC32:
gettext("CRC32"));
break;
default:
gettext("Unknown"));
break;
}
}
} else {
}
}
}
static int
{
int key;
} else {
gettext("unknown error"));
}
return (1);
}
/*
* Retrieve all login params from option argument
* Syntax <key=value,...>
*/
while (indexp) {
delim[0] = '\0';
}
if (nameValueString) {
}
return (1);
}
if (nameValueString) {
}
return (1);
}
if (nameValueString) {
}
return (1);
}
if (delim) {
} else {
}
}
if (nameValueString) {
}
return (0);
}
/*
* Print logical unit information for a specific target
*/
static void
{
int j;
&lunProps);
if (!IMA_SUCCESS(status)) {
return;
}
/*
* The lun is valid though the os Device Name is not.
* Give this information to users for judgement.
*/
gettext("\t OS Device Name: %ws\n"),
} else {
gettext("\t OS Device Name: Not"
" Available\n"));
}
}
}
/*
* Retrieve CHAP secret from input
*/
static int
{
char *chapSecret;
/* get password */
if (chapSecret == NULL) {
gettext("Unable to get secret"));
return (1);
}
gettext("secret too long, maximum length is"),
return (1);
}
gettext("secret too short, minimum length is"),
return (1);
}
if (chapSecret == NULL) {
gettext("Unable to get secret"));
return (1);
}
gettext("secrets do not match, secret not changed"));
return (1);
}
return (0);
}
/*
* Lists the discovery attributes
*/
static int
{
int ret;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
/* Get discovery attributes from IMA */
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
return (0);
}
/*
* Print all initiator node attributes
*/
static int
{
int ret;
int i;
if (ret != 0) {
return (ret);
}
return (INVALID_NODE_NAME);
}
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
/* Begin output */
gettext("Initiator node name"),
} else {
}
gettext("Login Parameters (Default/Configured)"));
/* Get Digest configuration */
if (IMA_SUCCESS(status)) {
} else {
*funcRet = 1;
return (ret);
}
if (IMA_SUCCESS(status)) {
} else {
*funcRet = 1;
return (ret);
}
/* Get authentication type for this lhba */
&methodList[0]);
if (!IMA_SUCCESS(status)) {
/* No authentication method set - default is NONE */
} else {
for (i = 0; i < maxEntries; i++) {
if (i > 0) {
}
switch (methodList[i]) {
case IMA_AUTHMETHOD_NONE:
break;
case IMA_AUTHMETHOD_CHAP:
break;
default:
gettext("unknown type"));
break;
}
}
}
/* Get RADIUS configuration */
if (IMA_SUCCESS(status)) {
} else {
}
} else {
}
&radiusAccess);
if (IMA_SUCCESS(status)) {
if (radiusAccess == IMA_TRUE) {
} else {
}
} else if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
} else {
}
/* print tunable parameters information. */
/* print configured session information. */
return (ret);
}
/*
* Print discovery addresses
*/
static int
int *funcRet)
{
int ret;
int outerLoop;
int i, j;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
switch (optionList->optval) {
case 'v':
break;
default:
gettext("unknown option"));
return (1);
}
}
/*
* If there are multiple objects, execute outer 'for' loop that
* many times for each target detail, otherwise, execute it only
* once with summaries only
*/
if (objectLen > 0) {
} else {
outerLoop = 1;
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < outerLoop; i++) {
if (object) {
/* initialize */
(void) memset(&wcInputObject[0], 0,
sizeof (wcInputObject));
gettext("conversion error"));
ret = 1;
continue;
}
/*
* if one or more objects were input,
* get the values
*/
ret = 1;
continue;
}
}
j++) {
/*
* Compare the discovery address with the input if
* one was input
*/
if (object &&
}
/* Print summary - always */
ipv4Address) {
sizeof (sAddr));
"Discovery Address: %s:%u\n",
} else {
sizeof (sAddr));
"DiscoveryAddress: [%s]:%u\n",
}
}
if (getNodeProps(&nodeProps) != 0) {
break;
}
/*
* Issue sendTargets only when an addr is
* specified.
*/
if (!IMA_SUCCESS(status)) {
gettext("\tUnable to get "\
"targets."));
*funcRet = 1;
continue;
}
}
if (found) {
/* we found the discovery address - break */
break;
}
}
/*
* There was an object entered but we didn't
* find it.
*/
}
}
return (ret);
}
/*
* Print ISNS Server addresses
*/
static int
int *funcRet)
{
int ret;
int outerLoop;
int i, j;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
switch (optionList->optval) {
case 'v':
showTarget = B_TRUE;
break;
default:
gettext("unknown option"));
return (1);
}
}
/*
* If there are multiple objects, execute outer 'for' loop that
* many times for each target detail, otherwise, execute it only
* once with summaries only
*/
if (objectLen > 0) {
} else {
outerLoop = 1;
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < outerLoop; i++) {
if (object) {
/* initialize */
(void) memset(&wcInputObject[0], 0,
sizeof (wcInputObject));
gettext("conversion error"));
ret = 1;
continue;
}
/*
* if one or more objects were input,
* get the values
*/
ret = 1;
continue;
}
}
j++) {
/*
* Compare the discovery address with the input if
* one was input
*/
if (object &&
address) &&
address.portNumber)) {
}
/* Print summary - always */
ipv4Address) {
sizeof (sAddr));
} else {
sizeof (sAddr));
}
"iSNS Server IP Address: %s:%u\n",
}
if (getNodeProps(&nodeProps) != 0) {
break;
}
/*
* Issue sendTargets only when an addr is
* specified.
*/
&pList);
if (!IMA_SUCCESS(status)) {
/*
* Check if the discovery mode is
* disabled.
*/
if (status ==
gettext("\tiSNS "\
"discovery "\
"mode "\
"disabled. "\
"No targets "\
"to report."));
} else {
gettext("\tUnable "\
"to get "\
"targets."));
}
continue;
}
}
if (found) {
/* we found the discovery address - break */
break;
}
}
/*
* There was an object entered but we didn't
* find it.
*/
}
}
return (ret);
}
/*
* Print static configuration targets
*/
static int
{
int ret;
int outerLoop;
int i, j;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
/*
* If there are multiple objects, execute outer 'for' loop that
* many times for each static config detail, otherwise, execute it only
* once with summaries only
*/
if (operandLen > 0) {
} else {
outerLoop = 1;
}
/* convert ':' to wide char for wchar string search */
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < outerLoop; i++) {
if (object) {
if (parseTarget(operand[i],
&staticTargetName[0],
MAX_ISCSI_NAME_LEN + 1,
&staticTargetAddress[0],
&port,
&tpgt,
&isIpv6) != PARSE_TARGET_OK) {
ret = 1;
continue;
}
}
j++) {
(void) memset(&staticTargetProps, 0,
sizeof (staticTargetProps));
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(staticTargetList);
*funcRet = 1;
return (ret);
}
tpgt;
/*
* Compare the static target name with the input if
* one was input
*/
if (object &&
staticTargetName) == B_TRUE)) {
/* targetName found - found = B_TRUE */
if (targetAddressSpecified == B_FALSE) {
} else {
ipv4Address == IMA_TRUE) {
sizeof (tmpStr));
} else {
sizeof (tmpStr));
}
(size_t)-1) {
gettext("conversion error"));
ret = 1;
continue;
}
if (wcsncmp(tmpTargetAddress,
== 0 &&
/*
* Since an object is
* specified, it should also
* have a tpgt specified. If
* not, that means the object
* specified is associated with
* the default tpgt. In
* either case, a tpgt
* comparison should be done
* before claiming that a
* match is found.
*/
tpgtSpecified == B_TRUE &&
defaultTpgt == IMA_FALSE) ||
tpgtSpecified == B_FALSE &&
defaultTpgt == IMA_TRUE)) {
}
}
}
}
/* print summary - always */
"Static Configuration Target",
sizeof (sAddr));
} else {
sizeof (sAddr));
}
defaultTpgt == IMA_FALSE) {
} else {
}
}
}
/*
* No details to display, but if there were:
* if (object && found)...
*
*/
/*
* There was an object entered but we didn't
* find it.
*/
}
}
return (ret);
}
/*
* Print targets
*/
/*ARGSUSED*/
static int
{
int ret;
int outerLoop;
int i, j;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
switch (optionList->optval) {
case 'S':
break;
case 'v':
break;
default:
gettext("unknown option"));
return (1);
}
}
/*
* If there are multiple objects, execute outer 'for' loop that
* many times for each target detail, otherwise, execute it only
* once with summaries only
*/
if (objectLen > 0) {
} else {
outerLoop = 1;
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < outerLoop; i++) {
if (operandEntered) {
if (parseTarget(objects[i],
&targetName[0],
MAX_ISCSI_NAME_LEN + 1,
&targetAddress[0],
&port,
&tpgt,
&isIpv6) != PARSE_TARGET_OK) {
ret = 1;
continue;
}
}
targetList->oids[j],
&targetProps);
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
/*
* Compare the target name with the input if
* one was input, if they match, print the target's info
*
* if no target name was input, continue printing this
* target
*/
if (operandEntered) {
targetName) == B_TRUE) {
if (tpgtSpecified == B_TRUE) {
if (targetProps.
IMA_FALSE &&
} else {
/*
* tpgt does not match,
* move on to next
* target
*/
continue;
}
} else {
}
} else {
/*
* target name does not match, move on
* to next target
*/
continue;
}
}
/* print summary - always */
/* Alias */
} else {
}
}
"%s%s: %02x%02x%02x%02x%02x%02x\n",
&targetList->oids[j],
&pConnList);
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
"\t",
gettext("Connections"),
if (verbose) {
"\t\t ",
(void) printLoginParameters(
"\t\t ",
targetList->oids[j],
/* Get Digest configuration */
(void) getNegotiatedDigest(
if (IMA_SUCCESS(status)) {
gettext("Header Digest"));
} else {
(void) IMA_FreeMemory(pConnList);
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
(void) getNegotiatedDigest(
if (IMA_SUCCESS(status)) {
gettext("Data Digest"));
} else {
(void) IMA_FreeMemory(pConnList);
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
}
if (scsi_target) {
targetList->oids[j]);
if (!IMA_SUCCESS(status)) {
/*
* Proceeds the listing
* but indicates the
* error in return value
*/
ret = 1;
}
targetList->oids[j],
&lunList);
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
}
(void) IMA_FreeMemory(lunList);
}
}
/*
* did we find the object
*/
if (operandEntered && !found) {
}
}
(void) IMA_FreeMemory(targetList);
return (ret);
}
/*
* Print configured session information
*/
static int
{
const char *rtn;
int out;
/* Get configured session information */
if (IMA_SUCCESS(status)) {
gettext("Configured Sessions"));
/* default binding */
} else {
/* hardcoded binding */
for (out = 0;
} else {
}
}
}
}
} else {
return (1);
}
return (0);
}
/*
* Print target parameters
*/
static int
int *funcRet)
{
int ret;
int outerLoop;
int i, j;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
switch (optionList->optval) {
case 'v':
break;
default:
gettext("unknown option"));
return (1);
}
}
/*
* If there are multiple operands, execute outer 'for' loop that
* many times to find each target parameter operand entered, otherwise,
* execute it only once for all target parameters returned.
*/
if (operandLen > 0) {
} else {
outerLoop = 1;
}
/*
* Ideally there should be an interface available for obtaining
* the list of target-param objects. Since the driver currently
* creates a target OID and the associated session structure when
* a target-param object is created, we can leverage the target
* OID list and use it to manage the target-param objects. When
* we stop creating a session for target-param object in the
* driver, we will switch to using a different interface to
* obtain target-param objects.
*/
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < outerLoop; i++) {
if (operandEntered) {
if (parseTarget(operand[i],
&targetName[0],
MAX_ISCSI_NAME_LEN + 1,
&targetAddress[0],
&port,
&tpgt,
&isIpv6) != PARSE_TARGET_OK) {
ret = 1;
continue;
}
}
for (j = 0; j < targetList->oidCount; j++) {
targetList->oids[j],
&targetProps);
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
/*
* Compare the target name with the input if
* one was input
*/
if (operandEntered &&
targetName) == B_TRUE)) {
/*
* For now, regardless of whether a target
* address is specified, we return B_TRUE
* because IMA_TARGET_PROPERTIES does not
* have a field for specifying address.
*/
}
/*
* if no operand was entered OR
* an operand was entered and it was
* found, we want to print
*/
if (!operandEntered || found) {
}
if (printObject) {
gettext("Target"),
(size_t)0) {
gettext("%ws\n"),
} else {
}
}
if (printObject && verbose) {
/* Get bidirectional authentication flag */
gettext("Bi-directional Authentication"));
targetList->oids[j],
&bidirAuth);
if (IMA_SUCCESS(status)) {
gettext("enabled"));
} else {
gettext("disabled"));
}
} else {
gettext("disabled"));
}
/* Get authentication type for this target */
targetList->oids[j],
&methodList[0]);
gettext("Authentication Type"));
if (!IMA_SUCCESS(status)) {
/*
* No authentication method define
* NONE by default.
*/
} else {
for (i = 0; i < maxEntries; i++) {
if (i > 0) {
"|");
}
switch (methodList[i]) {
case IMA_AUTHMETHOD_NONE:
gettext("NONE"));
break;
case IMA_AUTHMETHOD_CHAP:
gettext("CHAP"));
oids[j]);
break;
default:
"unknown "
"type"));
break;
}
}
}
if (printLoginParameters("\t",
targetList->oids[j],
!= 0) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
/* Get Digest configuration */
targetList->oids[j],
if (IMA_SUCCESS(status)) {
gettext("Header Digest"));
} else {
*funcRet = 1;
return (ret);
}
targetList->oids[j],
if (IMA_SUCCESS(status)) {
gettext("Data Digest"));
} else {
*funcRet = 1;
return (ret);
}
/* print tunable parameters infomation */
targetList->oids[j]) != 0) {
*funcRet = 1;
return (ret);
}
/* print configured session information */
targetList->oids[j]) != 0) {
*funcRet = 1;
return (ret);
}
}
if (found) {
break;
}
}
if (operandEntered && !found) {
}
}
(void) IMA_FreeMemory(targetList);
return (ret);
}
/*
* Modify discovery attributes
*/
static int
{
int ret;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
/* check optarg and set bool accordingly */
== 0) {
} else {
return (1);
}
switch (optionList->optval) {
case 's':
/* Set static discovery */
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
break;
case 't':
/* Set send targets discovery */
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
break;
case 'i':
/* Set iSNS discovery */
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
break;
default:
gettext("unknown option"));
return (1);
}
}
return (ret);
}
/*
* Set the initiator node's authentication method
*/
static int
{
int ret;
int nameLen = 0;
/*
* Start with existing parameters and modify with the desired change
* before passing along. We ignore any failures as they probably
* are caused by non-existence of auth params for the given node.
*/
&authParams);
switch (param) {
case AUTH_NAME:
return (1);
}
if (nameLen == 0) {
return (1);
}
if (nameLen > ISCSI_MAX_C_USER_LEN) {
return (1);
}
break;
case AUTH_PASSWORD :
if (ret != 0) {
return (ret);
}
&chapSecret[0], secretLen);
break;
default:
return (1);
}
&authParams);
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (ret);
}
/*
* Set the target's authentication method
*/
static int
{
int ret;
int nameLen = 0;
/*
* Start with existing parameters and modify with the desired change
* before passing along. We ignore any get failures as they probably
* are caused by non-existence of auth params for the given target.
*/
&authParams);
switch (param) {
case AUTH_NAME:
return (1);
}
if (nameLen == 0) {
return (1);
}
if (nameLen > ISCSI_MAX_C_USER_LEN) {
return (1);
}
break;
case AUTH_PASSWORD :
1, MAX_CHAP_SECRET_LEN);
if (ret != 0) {
return (ret);
}
&chapSecret[0], secretLen);
break;
default:
return (1);
}
&authParams);
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (0);
}
static int
{
} else {
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (0);
}
static int
{
int sessions;
int size;
char *commaPos;
char *addressPos;
int rtn;
/*
* Strip the first int value from the string. If we sprintf
* this back to a string and it matches the original string
* then this command is using default binding. If not a
* match we have hard coded binding or a usage error.
*/
/* default binding */
/* allocate the required pConfigSessions */
size = sizeof (SUN_IMA_CONFIG_SESSIONS);
if (pConfigSessions == NULL) {
return (1);
}
/* setup pConfigSessions */
pConfigSessions->out = 0;
} else {
/* hardcoded binding */
/*
* First we need to determine how many bindings
* are available. This can be done by scanning
* for the number of ',' + 1.
*/
sessions = 1;
sessions++;
}
/* allocate the required pConfigSessions */
sizeof (IMA_ADDRESS_KEY));
if (pConfigSessions == NULL) {
return (1);
}
/* setup pConfigSessions */
pConfigSessions->out = 0;
/* Now fill in the binding information. */
sessions = 0;
addressPos = optarg;
/*
* Walk thru possible address strings
* stop once all strings are processed.
*/
while (addressPos != NULL) {
/*
* Check if there is another address after this
* one. If so terminate the current address and
* keep a pointer to the next one.
*/
*commaPos++ = 0x00;
}
/*
* Parse current address. If invalid abort
* processing of addresses and free memory.
*/
return (1);
}
/* Convert address into binary form */
} else {
}
if (rtn == 0) {
/* inet_pton found address invalid */
return (1);
}
/* update addressPos to next address */
sessions++;
}
}
/* issue SUN_IMA request */
if (!IMA_SUCCESS(status)) {
return (1);
}
return (0);
}
static int
{
return (0);
}
return (0);
}
return (1);
}
/*
* Set the authentication method
* Currently only supports CHAP and NONE
*/
static int
{
char *method;
char *commaPos;
/*
* optarg will be a , delimited set of auth methods, in order
* of preference
* if any values here are incorrect, return without setting
* anything.
*/
return (1);
}
commaPos++;
}
/* Should not find more method specified - if found, error */
if (commaPos) {
return (1);
}
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (0);
}
static int
{
char *method;
char *commaPos;
/*
* optarg will be a , delimited set of auth methods, in order
* of preference
* if any values here are incorrect, return without setting
* anything.
*/
return (1);
}
commaPos++;
}
/* Should not find more method specified - if found, error */
if (commaPos) {
return (1);
}
return (1);
}
&methodList[0]);
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (0);
}
/*
* Modify the RADIUS configuration of the initiator node.
*
* Return 0 on success.
*/
static int
{
return (1);
}
/* Not setting shared secret here. */
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (0);
}
/*
* Modify the RADIUS access flag of the initiator node.
*
* Return 0 on success.
*/
static int
{
int ret;
/* Check if Radius Config is there */
if (ret != 0) {
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
/* Check if Radius Shared is set */
gettext("RADIUS server secret not configured yet"));
return (1);
}
} else {
gettext("invalid option argument"),
optarg);
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (ret);
}
/*
* Modify the RADIUS shared secret.
*
* Returns:
* zero on success.
* > 0 on failure.
*/
static int
{
int ret;
if (ret != 0) {
return (1);
}
if (ret > 0) {
}
if (ret != 0) {
return (1);
}
/* First obtain existing RADIUS configuration (if any) */
if (!IMA_SUCCESS(status)) {
return (1);
}
/* Modify the shared secret only */
&radiusSharedSecret[0], secretLen);
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
return (0);
}
/*
* Set initiator node attributes.
*/
static int
{
int ret;
int i;
int lowerCase;
int prefixlen = 0;
/* Get boot session's info */
(void) SUN_IMA_GetBootIscsi(&iscsiBoot);
if (!IMA_SUCCESS(status)) {
" of root disk"));
*funcRet = 1;
return (1);
}
}
/* Find Sun initiator */
if (ret != 0) {
return (ret);
}
switch (optionList->optval) {
case 'N':
gettext("name too long, \
maximum length is:"),
}
/* Take the first operand as node name. */
sizeof (IMA_NODE_NAME));
gettext("conversion error"));
return (1);
}
return (1);
}
gettext("conversion error"));
(void) IMA_FreeMemory(mb_name);
return (1);
}
prefixlen) == 0) {
/*
* For iqn format, we should map
* the upper-case characters to
* their lower-case equivalents.
*/
for (i = 0; nodeName[i] != 0; i++) {
}
}
(void) IMA_FreeMemory(mb_name);
/* Perform string profile checks */
if (nameCheckStatus != iSCSINameCheckOK) {
return (1);
}
/*
* IMA_GetSharedNodeOid(&sharedNodeOid);
* if (!IMA_SUCCESS(status)) {
* printLibError(status);
* return (INF_ERROR);
* }
*/
" allowed to change"
" initiator's name"));
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
break;
case 'A':
" allowed to change"
" initiator's alias"));
return (1);
}
/* Take the first operand as node alias. */
gettext("alias too long, maximum \
length is:"),
}
sizeof (IMA_NODE_ALIAS));
gettext("conversion error"));
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
break;
case 'a':
" allowed to change authentication"
" method"));
return (1);
}
funcRet) != 0) {
return (1);
}
break;
case 'R':
funcRet) != 0) {
return (1);
}
break;
case 'r':
funcRet) != 0) {
return (1);
}
break;
case 'P':
!= 0) {
return (1);
}
break;
case 'C':
" allowed to change CHAP secret"));
return (1);
}
return (1);
}
break;
case 'c':
if (mpxioEnabled == IMA_FALSE) {
"%s: %s\n", cmdName,
gettext("iscsi"
" boot and MPxIO"
" is disabled, not allowed"
" to change number of"
" sessions to be"
" configured"));
return (1);
}
}
optionList->optarg) != 0) {
"%s: %s\n", cmdName,
gettext("iscsi boot,"
" fail to set configured"
" session"));
}
return (1);
}
break;
case 'H':
" allowed to change CHAP name"));
return (1);
}
return (1);
}
break;
case 'd':
if (mpxioEnabled == IMA_FALSE) {
"%s: %s\n", cmdName,
gettext("iscsi"
" boot and MPxIO"
" is disabled, not"
" allowed to"
" change initiator's"
" login params"));
return (1);
}
}
optionList->optarg) != 0) {
return (1);
}
break;
case 'h':
if (mpxioEnabled == IMA_FALSE) {
"%s: %s\n", cmdName,
gettext("iscsi"
" boot and MPxIO"
" is disabled, not"
" allowed to"
" change initiator's"
" login params"));
return (1);
}
}
optionList->optarg) != 0) {
return (1);
}
break;
case 'T':
if (setTunableParameters(oid,
optionList->optarg) != 0) {
return (1);
}
break;
default:
gettext("unknown option"));
break;
}
}
return (ret);
}
/*
* Modify target parameters
*/
static int
{
int ret;
int i;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
if (parseTarget(targetName,
&wcInputObject[0],
MAX_ISCSI_NAME_LEN + 1,
&targetAddress[0],
&port,
&tpgt,
&isIpv6) != PARSE_TARGET_OK) {
return (1);
}
/* Perform string profile checks */
if (nameCheckStatus != iSCSINameCheckOK) {
return (1);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (0);
}
(void) SUN_IMA_GetBootIscsi(&iscsiBoot);
if (!IMA_SUCCESS(status)) {
" of root disk"));
*funcRet = 1;
return (ret);
}
if (!IMA_SUCCESS(status)) {
" name"));
*funcRet = 1;
return (ret);
}
if (!IMA_SUCCESS(status)) {
" auth param"));
*funcRet = 1;
return (ret);
}
}
/* find target oid */
&targetProps);
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
/*
* Compare the target name with the input name
*/
== B_TRUE)) {
/*
* For now, regardless of whether a target address
* is specified, we return B_TRUE because
* IMA_TARGET_PROPERTIES does not have a field for
* specifying address.
*/
/*
* iscsi booting, need changed target param is
* booting target, for auth param, not allow
* to change, for others dependent on mpxio
*/
/*
* -C CHAP secret set
* -H CHAP name set
* -a authentication
* -B bi-directional-authentication
*/
" not allowed to modify"
" authentication parameters"
" of boot target"));
return (1);
}
if (mpxioEnabled == IMA_FALSE) {
" MPxIO is disabled, not allowed"
" to modify boot target's"
" parameters"));
return (1);
}
}
funcRet) != 0) {
return (ret);
}
/*
* Even after finding a matched target, keep going
* since there could be multiple target objects
* associated with one target name in the system
* because of different TPGTs.
*/
}
}
/* If the target OID cannot be found create one */
if (!found) {
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
funcRet) != 0) {
return (ret);
}
}
(void) IMA_FreeMemory(targetList);
return (ret);
}
/*
* Add one or more addresses
*/
static int
{
int ret;
int i;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
/*
* Format of discovery address operand:
*
* <IP address|hostname>:<port>
*/
for (i = 0; i < operandLen; i++) {
/* initialize */
ret = 1;
continue;
}
!= 0) {
ret = 1;
continue;
}
if (addrType == DISCOVERY_ADDRESS) {
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
} else if (addrType == ISNS_SERVER_ADDRESS) {
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
}
}
return (ret);
}
/*
* Add one or more static configuration targets
*/
static int
{
int i;
int ret;
int addrType;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
/*
* Format of static config operand:
* <target-name>,<IP address|hostname>[:port][,tpgt]
*/
for (i = 0; i < operandLen; i++) {
if (parseTarget(operand[i],
&staticTargetName[0],
MAX_ISCSI_NAME_LEN + 1,
&staticTargetAddress[0],
&port,
&tpgt,
&isIpv6) != PARSE_TARGET_OK) {
ret = 1;
continue;
}
if (targetAddressSpecified != B_TRUE) {
return (1);
}
/* Perform string profile checks */
if (nameCheckStatus != iSCSINameCheckOK) {
return (1);
}
MAX_ISCSI_NAME_LEN + 1);
} else {
}
ret = 1;
continue;
}
if (tpgtSpecified == B_TRUE) {
} else {
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (1);
}
}
if (ret != 0) {
*funcRet = 1;
}
return (ret);
}
/*
* Remove one or more addresses
*/
static int
{
int ret;
int i;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
for (i = 0; i < operandLen; i++) {
/* initialize */
ret = 1;
continue;
}
!= 0) {
ret = 1;
continue;
}
if (addrType == DISCOVERY_ADDRESS) {
if (!IMA_SUCCESS(status)) {
if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
} else {
}
*funcRet = 1;
}
} else {
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
}
}
}
return (ret);
}
/*
* Remove one or more static configuration targets
*/
static int
{
int ret;
int i, j;
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < operandLen; i++) {
if (parseTarget(operand[i],
&staticTargetName[0],
MAX_ISCSI_NAME_LEN + 1,
&staticTargetAddress[0],
&port,
&tpgt,
&isIpv6) != PARSE_TARGET_OK) {
ret = 1;
continue;
}
/* Perform string profile checks */
if (nameCheckStatus != iSCSINameCheckOK) {
return (1);
}
for (atLeastFoundOne = B_FALSE, j = 0;
j < staticTargetList->oidCount;
j++) {
if (!IMA_SUCCESS(status)) {
if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
/*
* When removing multiple static-config
* entries we need to expect get
* failures. These failures occur when
* we are trying to get entry
* information we have just removed.
* Ignore the failure and continue.
*/
ret = 1;
continue;
} else {
(void) IMA_FreeMemory(staticTargetList);
*funcRet = 1;
return (ret);
}
}
stpgt =
/*
* Compare the static target name with the input if
* one was input
*/
if ((targetNamesEqual(
staticTargetName) == B_TRUE)) {
if (targetAddressSpecified == B_FALSE) {
} else {
IMA_TRUE) {
sizeof (tmpStr));
} else {
sizeof (tmpStr));
}
(size_t)-1) {
"%s: %s\n",
"conversion error"));
ret = 1;
continue;
}
if ((wcsncmp(tmpTargetAddress,
0) && (staticTargetProps.
if (tpgtSpecified == B_FALSE) {
} else {
matched =
}
}
}
}
if (matched) {
status =
staticTargetList->oids[j]);
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
}
}
}
if (!atLeastFoundOne) {
gettext("not found"));
}
}
return (ret);
}
/*
* Remove one or more target params.
*/
static int
{
char *commaPos;
int ret;
int i, j;
/* Get boot session's info */
(void) SUN_IMA_GetBootIscsi(&iscsiBoot);
if (!IMA_SUCCESS(status)) {
" root disk"));
*funcRet = 1;
return (1);
}
if (!IMA_SUCCESS(status)) {
" target's name"));
*funcRet = 1;
return (1);
}
}
/* Find Sun initiator */
if (ret > 0) {
}
if (ret != 0) {
return (ret);
}
if (!IMA_SUCCESS(status)) {
*funcRet = 1;
return (ret);
}
for (i = 0; i < operandLen; i++) {
/* initialize */
if (commaPos) {
/* Ignore IP address. */
}
gettext("conversion error"));
ret = 1;
continue;
}
j++) {
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
/*
* Compare the target name with the input if
* one was input
*/
wcInputObject) == B_TRUE) {
wcInputObject) == B_TRUE) &&
/*
* iscsi booting, need changed target
* param is booting target, booting
* session mpxio disabled, not
* allow to update
*/
if (mpxioEnabled == IMA_FALSE) {
"%s: %s\n", cmdName,
gettext("iscsi boot"
" with MPxIO disabled,"
" not allowed to remove"
" boot sess param"));
ret = 1;
continue;
}
}
targetList->oids[j]);
if (!IMA_SUCCESS(status)) {
(void) IMA_FreeMemory(targetList);
*funcRet = 1;
return (ret);
}
}
}
if (!found) {
/* Silently ignoring it? */
}
}
(void) IMA_FreeMemory(targetList);
return (ret);
}
/*ARGSUSED*/
static int
{
int ret;
switch (object) {
case DISCOVERY_ADDRESS:
case ISNS_SERVER_ADDRESS:
break;
case STATIC_CONFIG:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*ARGSUSED*/
static int
{
int ret;
switch (object) {
case DISCOVERY:
break;
case DISCOVERY_ADDRESS:
funcRet);
break;
case ISNS_SERVER_ADDRESS:
funcRet);
break;
case NODE:
break;
case STATIC_CONFIG:
break;
case TARGET:
break;
case TARGET_PARAM:
break;
default:
ret = 1;
break;
}
return (ret);
}
/*ARGSUSED*/
static int
{
int ret, i;
switch (object) {
case DISCOVERY:
break;
case NODE:
break;
case TARGET_PARAM:
i = 0;
while (operand[i]) {
if (ret) {
operand[i]);
return (ret);
}
i++;
}
break;
default:
ret = 1;
break;
}
return (ret);
}
/*ARGSUSED*/
static int
{
int ret;
switch (object) {
case DISCOVERY_ADDRESS:
case ISNS_SERVER_ADDRESS:
funcRet);
break;
case STATIC_CONFIG:
break;
case TARGET_PARAM:
break;
default:
ret = 1;
break;
}
return (ret);
}
static void
{
switch (status) {
case iSCSINameLenZero:
break;
case iSCSINameLenExceededMax:
gettext("iSCSI name exceeded maximum length."));
break;
case iSCSINameUnknownType:
gettext("unknown iSCSI name type."));
break;
gettext("iSCSI name invalid character used"));
break;
case iSCSINameIqnFormatError:
gettext("iqn formatting error."));
break;
" format is: YYYY-MM"));
break;
break;
break;
break;
case iSCSINameIqnFQDNError:
" domain name"));
break;
case iSCSINameEUIFormatError:
gettext("eui formatting error."));
break;
}
}
/*
* A convenient function to modify the target parameters of an individual
* target.
*
* Return 0 if successful
* Return 1 if failed
*/
static int
int *funcRet)
{
switch (optionList->optval) {
case 'a':
return (1);
}
break;
case 'B':
return (1);
}
break;
case 'C':
return (1);
}
break;
case 'd':
optionList->optarg) != 0) {
return (1);
}
break;
case 'h':
optionList->optarg) != 0) {
return (1);
}
break;
case 'p':
/* Login parameter */
optionList->optarg) != 0) {
return (1);
}
break;
case 'c':
/* Modify configure sessions */
optionList->optarg) != 0) {
return (1);
}
break;
case 'H':
return (1);
}
break;
case 'T':
optionList->optarg) != 0) {
return (1);
}
break;
}
}
return (0);
}
/*
* This helper function could go into a utility module for general use.
*/
static int
char *address_str,
{
int tmp_port;
char *errchr;
if (address_port_str[0] == '[') {
/* IPv6 address */
char *close_bracket_pos;
if (!close_bracket_pos) {
"IP address format error: %s\n", address_str);
return (PARSE_ADDR_MISSING_CLOSING_BRACKET);
}
/* Extract the port number */
if (*close_bracket_pos == ':') {
if (*close_bracket_pos != NULL) {
gettext("port number invalid"));
return (PARSE_ADDR_PORT_OUT_OF_RANGE);
}
(tmp_port < 0)) {
/* Port number out of range */
"Specified port out of range: %d",
tmp_port);
return (PARSE_ADDR_PORT_OUT_OF_RANGE);
} else {
}
} else {
*port = defaultPort;
}
} else {
*port = defaultPort;
}
} else {
/* IPv4 address */
char *colon_pos;
if (!colon_pos) {
/* No port number specified. */
*port = defaultPort;
} else {
/* Extract the port number */
colon_pos++;
gettext("port number invalid"));
return (PARSE_ADDR_PORT_OUT_OF_RANGE);
}
(tmp_port < 0)) {
/* Port number out of range */
"Specified port out of range: %d",
tmp_port);
return (PARSE_ADDR_PORT_OUT_OF_RANGE);
} else {
}
} else {
*port = defaultPort;
}
}
}
return (PARSE_ADDR_OK);
}
/*
* This helper function could go into a utility module for general use.
*/
{
char *tmp;
return (iSCSINameLenZero);
} else if (name_len > MAX_ISCSI_NAME_LEN) {
return (iSCSINameLenExceededMax);
}
/*
* check for invalid characters
* According to RFC 3722 iSCSI name must be either a letter,
* a digit or one of the following '-' '.' ':'
*/
(*tmp != '-') &&
(*tmp != '.') &&
(*tmp != ':')) {
return (iSCSINameInvalidCharacter);
}
}
strlen(ISCSI_IQN_NAME_PREFIX)) == 0) {
/*
* If name is of type iqn, check date string and naming
* authority.
*/
/*
* Don't allow the string to end with a colon. If there is a
* colon then there must be a subdomain provided.
*/
return (iSCSINameIqnSubdomainFormatError);
}
/* Date string */
if (strp) {
/* Date string should be in YYYY-MM format */
return (iSCSINameIqnDateFormatError);
}
/*
* Validate year. Only validating that the
* year can be converted to a number. No
* validation will be done on year's actual
* value.
*/
errno = 0;
return (iSCSINameIqnInvalidYearError);
}
/*
* Validate month is valid.
*/
errno = 0;
return (iSCSINameIqnInvalidMonthError);
}
/*
* A reversed FQDN needs to be provided. We
* will only check for a "." followed by more
* than two or more characters. The list of domains is
* too large and changes too frequently to
* add validation for.
*/
return (iSCSINameIqnFQDNError);
}
/* Name authority string */
if (strp) {
return (iSCSINameCheckOK);
} else {
return (iSCSINameIqnFQDNError);
}
} else {
return (iSCSINameIqnFormatError);
}
strlen(ISCSI_EUI_NAME_PREFIX)) == 0) {
/* If name is of type EUI, change its length */
return (iSCSINameEUIFormatError);
}
continue;
}
return (iSCSINameEUIFormatError);
}
return (iSCSINameCheckOK);
} else {
return (iSCSINameUnknownType);
}
}
/*
* This helper function could go into a utility module for general use.
*
* Returns:
* B_TRUE is the numberStr is an unsigned natural number and within the
* specified bound.
* B_FALSE otherwise.
*/
{
int i;
int number_str_len;
return (B_FALSE);
}
for (i = 0; i < number_str_len; i++) {
return (B_FALSE);
}
}
return (B_FALSE);
}
return (B_TRUE);
}
/*
* This helper function could go into a utility module for general use.
* It parses a target string in the format of:
*
* <target_name>,[<ip_address>[:port][,tpgt]]
*
* and creates wchar strings for target name and target address. It
* also populates port and tpgt if found.
*
* Returns:
* PARSE_TARGET_OK if parsing is successful.
* PARSE_TARGET_INVALID_TPGT if the specified tpgt is
* invalid.
* PARSE_TARGET_INVALID_ADDR if the address specified is
* invalid.
*/
int
{
char *commaPos;
char *commaPos2;
int i;
int lowerCase;
(void) memset(targetNameStr, 0,
targetNameStrLen * sizeof (wchar_t));
(void) memset(targetAddressStr, 0,
targetAddressStrLen * sizeof (wchar_t));
commaPos++;
/*
* Checking of tpgt makes sense only when
*/
commaPos2++;
B_TRUE) {
*tpgtSpecified = B_TRUE;
} else {
gettext("parse target invalid TPGT"));
return (PARSE_TARGET_INVALID_TPGT);
}
}
return (PARSE_TARGET_INVALID_ADDR);
case PARSE_ADDR_OK:
break;
default:
return (PARSE_TARGET_INVALID_ADDR);
}
for (i = 0; targetAddressStr[i] != 0; i++) {
targetAddressStr[i] = lowerCase;
}
} else {
*tpgtSpecified = B_FALSE;
}
for (i = 0; targetNameStr[i] != 0; i++) {
targetNameStr[i] = lowerCase;
}
return (PARSE_TARGET_OK);
}
/*ARGSUSED*/
static void
{
/* Get Chap Name depending upon oid object type */
} else {
}
if (IMA_SUCCESS(status)) {
/*
* Default chap name will be the node name. The default will
* be set by the driver.
*/
} else {
}
} else {
}
}
static boolean_t
checkServiceStatus(void)
{
if (status != IMA_STATUS_SUCCESS) {
gettext("Unable to query the service status of"
" iSCSI initiator."),
gettext("For more information, please refer to"
" iscsi(7D)."));
return (B_FALSE);
}
if (enabled == 0) {
gettext("iSCSI Initiator Service is disabled,"
" enable the service."),
gettext("For more information, please refer to"
" iscsi(7D)."));
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Prints out see manual page.
* Called out through atexit(3C) so is always last thing displayed.
*/
void
seeMan(void)
{
static int sent = 0;
if (sent)
return;
sent = 1;
}
/*
* main calls a parser that checks syntax of the input command against
* various rules tables.
*
* The parser provides usage feedback based upon same tables by calling
* two usage functions, usage and subUsage, handling command and subcommand
* usage respectively.
*
* The parser handles all printing of usage syntactical errors
*
* When syntax is successfully validated, the parser calls the associated
* function using the subcommands table functions.
*
* Syntax is as follows:
* command subcommand [options] resource-type [<object>]
*
* The return value from the function is placed in funcRet
*/
int
{
int ret;
int funcRet = 0;
if (geteuid() != 0) {
return (1);
}
if (checkServiceStatus() == B_FALSE) {
return (1);
}
/* set global command name */
/* call the CLI parser */
if (ret == -1) {
ret = 1;
}
if (funcRet != 0) {
ret = 1;
}
return (ret);
}
static int
{
int key;
} else {
gettext("unknown error"));
}
return (1);
}
if (nameValueString) {
}
return (1);
}
if (nameValueString) {
}
return (1);
}
switch (key) {
case RECV_LOGIN_RSP_TIMEOUT:
case CONN_LOGIN_MAX:
case POLLING_LOGIN_DELAY:
errno = 0;
gettext("invalid option argument"),
optarg);
if (nameValueString) {
}
return (1);
}
if (uintValue > 3600) {
gettext("value must be between 0 and 3600"));
if (nameValueString) {
}
return (1);
}
if (nameValueString) {
}
return (1);
}
if (key == RECV_LOGIN_RSP_TIMEOUT) {
} else if (key == CONN_LOGIN_MAX) {
} else if (key == POLLING_LOGIN_DELAY) {
}
break;
default:
if (nameValueString) {
}
return (1);
}
if (!IMA_SUCCESS(status)) {
if (nameValueString) {
}
return (1);
}
if (nameValueString) {
}
return (0);
}
/*
* Print tunable parameters information
*/
static int
{
gettext("Tunable Parameters (Default/Configured)"));
if (!IMA_SUCCESS(status)) {
return (1);
}
if (value[0] == '\0') {
value[0] = '-';
}
gettext("Session Login Response Time"));
value[0] = '\0';
if (!IMA_SUCCESS(status)) {
return (1);
}
if (value[0] == '\0') {
value[0] = '-';
}
gettext("Maximum Connection Retry Time"));
value[0] = '\0';
if (!IMA_SUCCESS(status)) {
return (1);
}
if (value[0] == '\0') {
value[0] = '-';
}
gettext("Login Retry Time Interval"));
return (0);
}
/*
* This is helper function to check conn_login_max and polling_login_delay.
*/
static int
{
char *endptr;
if (key == CONN_LOGIN_MAX) {
} else if (key == POLLING_LOGIN_DELAY) {
} else {
return (0);
}
valuep[0] = '\0';
if (!IMA_SUCCESS(status)) {
return (1);
}
if (valuep[0] == '\0') {
if (key == CONN_LOGIN_MAX) {
} else {
}
}
errno = 0;
gettext("cannot convert tunable string"),
valuep);
return (1);
}
if (key == CONN_LOGIN_MAX) {
getValue);
return (1);
}
} else {
getValue);
return (1);
}
}
return (0);
}