/*
* 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
*/
/*
*/
/*
* ldapclient command. To make (initiailize) or uninitialize a machines as
* and LDAP client. This command MUST be run as root (or it will simply exit).
*
* -I Install. No file_backup/recover for installing only (no doc).
*
* init Initialze (create) an LDAP client from a profile stored
* in a directory-server.
* manual Initialze (create) an LDAP client by hand (-file option
* reads from file).
* mod Modify the LDAP client configuration on this machine by hand.
* list List the contents of the LDAP client cache files.
* uninit Uninitialize this machine.
*
* -v Verbose flag.
* -q Quiet flag (mutually exclusive with -v).
*
* -a attrName=attrVal
* <attrName> can be one of the following:
*
* attributeMap
* Attribute map. Can be multiple instances of this option.
* (no former option)
* authenticationMethod
* Authentication method (formerly -a)
* bindTimeLimit
* Bind time limit. (no former option)
* certificatePath
* Path to certificates used for secure bind (no former option)
* credentialLevel
* Client credential level (no former option)
* defaultServerList
* Default server (no former option) Refer to DUA Config
* Schema draft.
* defaultSearchBase
* Search Base DN. e.g. dc=eng,dc=sun,dc=com (formerly -b)
* defaultSearchScope
* Search scope. (formerly -s)
* domainName
* Hosts lookup domain (DNS) Ex. eng.sun.com (formerly -d)
* followReferrals
* Search dereference. followref or noref (default followref)
* (formerly -r)
* objectclassMap
* Objectclass map. Can be multiple instances of this option.
* (no former option)
* preferredServerList
* Server preference list. Comma ',' separated list of IPaddr.
* (formerly -p)
* profileName
* Profile name to use for init (ldapclient) or
* generate (gen_profile). (formerly -P)
* profileTTL
* Client info TTL. If set to 0 this information will not be
* automatically updated by the ldap_cachemgr(1M).
* (formerly -e)
* proxyDN
* Binding DN. Ex. cn=client,ou=people,cd=eng,dc=sun,dc=com
* (formerly -D)
* proxyPassword
* Client password not needed for authentication "none".
* (formerly -w)
* adminDN
* Administrator DN for updating naming data.
* adminPassword
* Administrator password
* enableShadowUpdate
* Allow Administrator to change shadow data in LDAP
* searchTimeLimit
* Timeout value. (formerly -o)
* serviceSearchDescriptor
* Service search scope. (no former option)
* serviceAuthenticationMethod
* Service authenticaion method (no former option)
* serviceCredentialLevel
* Service credential level (no former option)
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/systeminfo.h>
#include <fcntl.h>
#include <xti.h>
#include <strings.h>
#include <limits.h>
#include <locale.h>
#include <syslog.h>
#include <libscf.h>
#include <assert.h>
#include "standalone.h"
#if !defined(TEXT_DOMAIN)
#endif
/* error codes */
/* The manpage doc only allows for SUCCESS(0), FAIL(1) and CRED(2) on exit */
#define CLIENT_SUCCESS 0
/* Reset flag for start_services() */
/* Reset flag for stop_services() */
#define STATE_NOSAVE 0
/* files to (possibiliy) restore */
/* Define the service FMRIs */
/* Define flags for checking if services were enabled */
/* Command to copy files */
/* Files that need to be just removed */
/* Output defines to suppress if quiet mode set */
/*
* There isn't a domainName defined as a param, so we set a value here
* (1001) should be big enough
*/
/* Used to turn off profile checking */
/* Globals */
static char *cmd;
static int mode_verbose = 0;
static int mode_quiet = 0;
static int gen = 0;
static int gStartLdap = 0;
static int gStartYp = 0;
static int enableFlag = 0;
/* multival_t is used to hold params that can have more than one value */
typedef struct {
int count;
char **optlist;
} multival_t;
static multival_t *multival_new();
/*
* clientopts_t is used to hold and pass around the param values from
* the cmd line
*/
typedef struct {
char *authenticationMethod;
char *bindTimeLimit;
char *certificatePath;
char *credentialLevel;
char *defaultSearchBase;
char *defaultServerList;
char *domainName;
char *followReferrals;
char *preferredServerList;
char *profileName;
char *profileTTL;
char *proxyDN;
char *proxyPassword;
char *enableShadowUpdate;
char *adminDN;
char *adminPassword;
char *bindDN;
char *bindPasswd;
char *defaultSearchScope;
char *searchTimeLimit;
} clientopts_t;
static clientopts_t *clientopts_new();
extern ns_ldap_error_t *__ns_ldap_print_config(int);
extern void __ns_ldap_default_config();
extern int __ns_ldap_download(const char *, char *, char *, ns_ldap_error_t **);
/* Function prototypes (these could be static) */
static void usage(void);
static int file_backup(void);
static int mod_backup(void);
static int mod_recover(void);
static void mod_cleanup(void);
static int start_services(int flag);
static int stop_services(int saveState);
const char *state);
int
{
int retcode;
int paramFlag;
char *attrVal;
int sysinfostatus;
extern char *optarg;
extern int optind;
int option;
if (ret_locale == NULL) {
}
if (ret_textdomain == NULL) {
}
/* get name that invoked us */
++cmd;
else
if (0 < sysinfostatus)
optlist = clientopts_new();
gettext("Error getting optlist (malloc fail)\n"),
stderr);
}
optind = 1;
switch (option) {
case 'v':
mode_verbose = 1;
break;
case 'q':
mode_quiet = 1;
break;
case 'a':
if (paramFlag == CLIENT_ERR_PARSE) {
gettext("Unrecognized "
"parameter \"%s\"\n"),
optarg);
usage();
}
if (paramFlag == NS_LDAP_BINDPASSWD_P &&
gettext("The -a proxyPassword option is "
"mutually exclusive of -y. "
"-a proxyPassword is ignored.\n"));
break;
}
if (paramFlag == NS_LDAP_ADMIN_BINDPASSWD_P &&
gettext("The -a adminPassword option is "
"mutually exclusive of -z. "
"-a adminPassword is ignored.\n"));
break;
}
if (retcode != CLIENT_SUCCESS) {
gettext("Error (%d) setting "
"param \"%s\"\n"),
usage();
}
break;
case 'D':
break;
case 'w':
gettext("The -w option is mutually "
"exclusive of -j. -w is ignored."));
break;
}
/* Ask for a password later */
break;
}
break;
case 'j':
gettext("The -w option is mutually "
"exclusive of -j. -w is ignored.\n"));
}
}
break;
case 'y':
gettext("The -a proxyPassword option is "
"mutually exclusive of -y. "
"-a proxyPassword is ignored.\n"));
}
}
break;
case 'z':
gettext("The -a adminPassword option is "
"mutually exclusive of -z. "
"-a adminPassword is ignored.\n"));
}
}
break;
case EOF:
op_init = 1;
op_manual = 1;
op_mod = 1;
op_list = 1;
op_uninit = 1;
gen = 1;
op_genprofile = 1;
if (retcode != CLIENT_SUCCESS) {
gettext("Error (%d) setting "
"serverList param.\n"),
retcode);
usage();
}
} else {
gettext("Error parsing "
"command line\n"),
stderr);
usage();
}
optind++; /* get past the verb and keep trying */
break;
/* Backwards compatibility to support system install */
case 'I':
op_init = 1;
mode_quiet = 1;
break;
case '?':
usage();
gen = 1;
usage();
break;
}
}
if ((getuid() != 0) && (!op_genprofile)) {
(void) puts(
"You must be root (SuperUser) to run this command.");
usage();
}
/*
* All command line arguments are finished being parsed now
*/
/* *** Do semantic checking here *** */
/* if gen and no no searchBase then err */
gettext("ldapclient: Missing required attrName "
"defaultSearchBase\n"),
stderr);
usage();
}
/*
* if init or manual, and if adminDN is specified then enableShadowUpdate
* must be set to TRUE.
*/
(!optlist->enableShadowUpdate ||
gettext("ldapclient: adminDN and adminPassword must not "
"be specified if enableShadowUpdate is not set to TRUE \n"),
stderr);
usage();
}
/* Only one verb can be specified */
usage();
}
/* *** We passed semantic checking, so now do the operation *** */
if (mode_verbose) {
}
/* handle "ldapclient list" here. err checking done in func */
if (op_list) {
if (mode_verbose)
gettext("Handling list option\n"),
stderr);
}
/* handle "ldapclient uninit" here */
if (op_uninit) {
if (mode_verbose)
gettext("Handling uninit option\n"),
stderr);
}
/* handle "ldapclient init" (profile) */
if (op_init) {
if (mode_verbose)
gettext("Handling init option\n"),
stderr);
}
/* handle "genprofile" here */
if (op_genprofile) {
if (mode_verbose)
gettext("Handling genProfile\n"),
stderr);
}
/* handle "ldapclient manual" here */
if (op_manual) {
if (mode_verbose)
gettext("Handling manual option\n"),
stderr);
}
/* handle "ldapclient mod" here */
if (op_mod) {
if (mode_verbose)
gettext("Handling mod option\n"),
stderr);
}
if ((retcode == CLIENT_SUCCESS) ||
(retcode == CLIENT_ERR_FAIL) ||
(retcode == CLIENT_ERR_CREDENTIAL))
return (retcode);
else
return (CLIENT_ERR_FAIL);
}
static int
{
gettext("No args supported with \"list\" option\n"),
stderr);
usage();
return (CLIENT_ERR_FAIL); /* exit code here ? */
}
gettext("Cannot get print configuration\n"),
stderr);
(void) __ns_ldap_freeError(&errorp);
}
return (retcode);
}
static int
{
if (mode_verbose) {
gettext("Restoring machine to previous "
"configuration state\n"),
stderr);
}
gettext("No args supported with \"uninit\" option\n"),
stderr);
usage();
return (CLIENT_ERR_FAIL);
}
(void) __ns_ldap_self_gssapi_config(&config);
if (retcode != CLIENT_SUCCESS) {
/* restart whatever services we can */
(void) start_services(START_RESET);
return (CLIENT_ERR_FAIL);
}
if (retcode != CLIENT_SUCCESS) {
gettext("Cannot recover the configuration on "
"this machine.\n"),
stderr);
(void) start_services(START_RESET);
} else {
if (retcode != CLIENT_SUCCESS) {
gettext("Config restored but problems "
"encountered resetting network "
"services.\n"),
stderr);
}
}
if (retcode == CLIENT_SUCCESS) {
gettext("System successfully recovered\n"),
stderr);
}
return (retcode);
}
/*
* The following macro is used to do a __ns_ldap_setParam().
* On every call, the return code is checked, and if there was
* a problem then the error message is printed, the ldaperr
* is freed and we return from the function with the offending
* error return code. This macro keeps us from having to
* repeat this code for every call to setParam as was done
* in the previous incarnation of ldapclient.
*
* assumes a "retcode" variable is available for status
*/
retcode = 0; \
if (retcode != NS_LDAP_SUCCESS) { \
(void) __ns_ldap_freeError(&ldaperr); \
} \
} \
}
/*
* The following macro is used to check if an arg has already been set
* and issues an error message, a usage message and then returns an error.
* This was made into a macro to avoid the duplication of this code many
* times in the function below.
*/
if (arg) { \
"specified\n"), param); \
usage(); \
return (CLIENT_ERR_FAIL); \
}
static int
{
int counter;
int domain_fp;
int ret_copy;
int reset_ret;
gettext("Manual failed: System domain not set and "
"no domainName specified.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
gettext("Manual failed: Missing required "
"defaultSearchBase attribute.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
gettext("Manual failed: Missing required "
"defaultServerList or preferredServerList "
"attribute.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
gettext("Manual aborted: profileTTL is not supported "
"in manual mode.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
gettext("Manual aborted: profileName is not supported "
"in manual mode.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
/* Set version to latest (not version 1) */
/* Set profileTTL to 0 since NO profile on manual */
/* Set additional valid params from command line */
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
}
for (counter = 0;
counter++) {
}
if (retcode == CLIENT_SUCCESS)
if (retcode != CLIENT_SUCCESS) {
gettext("Error in setting up credentials\n"),
stderr);
return (retcode);
}
if (mode_verbose)
gettext("About to modify this machines "
"configuration by writing the files\n"),
stderr);
/* get ready to start playing with files */
if (retcode != CLIENT_SUCCESS) {
return (CLIENT_ERR_FAIL);
}
/* Save orig versions of files */
retcode = file_backup();
if (retcode == CLIENT_ERR_RESTORE) {
gettext("System not in state to enable ldap client.\n"),
stderr);
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (retcode);
} else if (retcode != CLIENT_SUCCESS) {
gettext("Save of system configuration failed! "
"Attempting recovery.\n"),
stderr);
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (retcode);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (retcode);
}
/* Dump new files */
gettext("%s manual: errorp is not NULL; %s\n"),
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (retcode);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
(void) __ns_ldap_freeError(&errorp);
return (CLIENT_ERR_FAIL);
}
/* if (credargs(arglist)) */
gettext("%s init: errorp is not NULL; %s\n"),
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (retcode);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
(void) __ns_ldap_freeError(&errorp);
return (CLIENT_ERR_FAIL);
}
if (ret_copy != 0) {
gettext("Error %d copying (%s) -> (%s)\n"),
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
if (retcode == CLIENT_SUCCESS) {
stderr);
} else {
"Recovering old system settings.\n"), stderr),
/* stop any started services for recover */
/* don't stomp on history of saved services state */
if (reset_ret != CLIENT_SUCCESS) {
"stopping services during reset\n"),
/* Coninue and try to recover what we can */
}
if (reset_ret != CLIENT_SUCCESS) {
"recovering service files during "
"reset\n"), reset_ret);
/* Continue and start what we can */
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
}
return (retcode);
}
static int
{
int counter;
int domain_fp;
int reset_ret;
stderr);
(void) __ns_ldap_freeError(&errorp);
return (CLIENT_ERR_FAIL);
}
gettext("Mod aborted: profileTTL modification is "
"not allowed in mod mode.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
gettext("Mod aborted: profileName modification is "
"not allowed. If you want to use profiles "
"generate one with genProfile and load it "
"on the server with ldapadd.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
/* Set additional valid params from command line */
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
if (retcode == CLIENT_SUCCESS)
if (retcode != CLIENT_SUCCESS) {
gettext("Error in setting up credentials\n"),
stderr);
return (retcode);
}
if (mode_verbose)
gettext("About to modify this machines configuration "
"by writing the files\n"),
stderr);
/* get ready to start playing with files */
if (retcode != CLIENT_SUCCESS) {
return (CLIENT_ERR_FAIL);
}
/* Temporarily save orig versions of files */
retcode = mod_backup();
if (retcode != CLIENT_SUCCESS) {
gettext("Unable to backup the ldap client files!\n"),
stderr);
return (retcode);
}
/* Dump new files */
gettext("%s mod: errorp is not NULL; %s\n"),
retcode = mod_recover();
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
}
(void) __ns_ldap_freeError(&errorp);
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
/* if (credargs(arglist)) */
gettext("%s mod: errorp is not NULL; %s\n"),
retcode = mod_recover();
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
}
(void) __ns_ldap_freeError(&errorp);
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
retcode = mod_recover();
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed! Machine needs to be "
"fixed!\n"),
stderr);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
if (retcode == CLIENT_SUCCESS) {
stderr);
} else {
"Recovering old system settings.\n"), stderr),
/* stop any started services for recover */
/* don't stomp on history of saved services state */
if (reset_ret != CLIENT_SUCCESS) {
"stopping services during reset\n"),
/* Coninue and try to recover what we can */
}
reset_ret = mod_recover();
if (reset_ret != CLIENT_SUCCESS) {
"recovering service files during "
"reset\n"), reset_ret);
/* Continue and start what we can */
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
}
/* Cleanup temporary files created by mod_backup() */
mod_cleanup();
return (retcode);
}
static int
{
int counter;
if (mode_verbose)
/* *** Check for invalid args *** */
"enableShadowUpdate");
/* *** End check for invalid args *** */
if (mode_verbose)
gettext("No profile specified. "
"Using \"default\"\n"),
stderr);
}
/* Set version to latest (not version 1) */
/* Set additional valid params from command line */
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
for (counter = 0;
counter++) {
}
(void) __ns_ldap_freeError(&errorp);
return (CLIENT_ERR_FAIL);
}
return (CLIENT_SUCCESS);
}
/* INET6_ADDRSTRLEN + ":" + <5-digit port> + some round-up */
static int
{
int profile_fp;
int reset_ret;
int ret_copy;
int **credLevel, i;
char *cred;
if (mode_verbose)
gettext("About to configure machine by downloading "
"a profile\n"),
stderr);
gettext("Init failed: System domain not set and "
"no domainName specified.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
if (!arglist->defaultServerList) {
return (CLIENT_ERR_FAIL);
}
/* *** Check for invalid args *** */
"defaultSearchBase");
"profileTTL");
"searchTimeLimit");
"preferredServerList");
"followReferrals");
"defaultSearchScope");
"bindTimeLimit");
"objectclassMap");
"attributeMap");
"serviceAuthenticationMethod");
"serviceCredentialLevel");
"serviceSearchDescriptor");
/* *** End check for invalid args *** */
if (mode_verbose)
gettext("No profile specified. "
"Using \"default\"\n"),
stderr);
}
return (CLIENT_ERR_FAIL);
}
/*
* We don't want to force users to always specify authentication
* have to specify appropriate -a though.
*/
getpassphrase("Bind Password:");
stderr);
if (gStartLdap == START_RESET) {
(void) start_service(YPDOM_FMRI,
B_TRUE);
(void) start_service(LDAP_FMRI,
B_TRUE);
}
return (CLIENT_ERR_CREDENTIAL);
}
}
}
(void) __ns_ldap_freeError(&errorp);
}
if (gStartLdap == START_RESET) {
}
return (CLIENT_ERR_FAIL);
}
}
(void) __ns_ldap_freeError(&errorp);
}
if (gStartLdap == START_RESET) {
}
return (CLIENT_ERR_FAIL);
}
if (gStartLdap == START_RESET) {
}
return (CLIENT_ERR_CREDENTIAL);
}
}
(void) __ns_ldap_freeError(&errorp);
}
return (CLIENT_ERR_CREDENTIAL);
}
(void) __ns_ldap_freeError(&errorp);
}
return (CLIENT_ERR_CREDENTIAL);
}
}
}
if (arglist->enableShadowUpdate &&
if (gStartLdap == START_RESET) {
}
return (CLIENT_ERR_CREDENTIAL);
}
}
(void) __ns_ldap_freeError(&errorp);
}
return (CLIENT_ERR_CREDENTIAL);
}
(void) __ns_ldap_freeError(&errorp);
}
return (CLIENT_ERR_CREDENTIAL);
}
}
(void) __ns_ldap_freeError(&errorp);
}
return (CLIENT_ERR_CREDENTIAL);
}
if (authMethod != NULL) {
for (i = 0; authMethod[i] != NULL; ++i) {
break;
}
}
if (authMethod[i] == NULL) {
"Warning: init authentication method "
"not found in DUAConfigProfile.\n"));
} else {
if (i != 0) {
"Warning: init authentication"
"method using secondary "
"authentication method from "
"DUAConfigProfile.\n"));
}
}
(void) __ns_ldap_freeParam((void ***) &authMethod);
}
}
(void) __ns_ldap_freeError(&errorp);
}
return (CLIENT_ERR_CREDENTIAL);
}
switch (*credLevel[i]) {
case NS_LDAP_CRED_ANON :
cred = "none";
break;
case NS_LDAP_CRED_PROXY :
cred = "proxy";
break;
case NS_LDAP_CRED_SELF :
cred = "self";
break;
default:
continue;
/* NOTREACHED */
break;
}
arglist->credentialLevel) == 0) {
break;
}
}
"Warning: init credential level not found "
"in DUAConfigProfile.\n"));
} else {
if (i != 0) {
gettext("Warning: "
"init credential level using "
"secondary credential level from "
"DUAConfigProfile.\n"));
}
}
(void) __ns_ldap_freeParam((void ***) &credLevel);
}
}
if (retcode == CLIENT_SUCCESS)
if (retcode != CLIENT_SUCCESS) {
if (gStartLdap == START_RESET) {
}
return (retcode);
}
if (mode_verbose)
gettext("About to modify this machines configuration "
"by writing the files\n"),
stderr);
/* get ready to start playing with files */
if (retcode != CLIENT_SUCCESS) {
if (gStartLdap == START_RESET) {
}
return (CLIENT_ERR_FAIL);
}
/* Save orig versions of files */
retcode = file_backup();
if (retcode == CLIENT_ERR_RESTORE) {
gettext("System not in state to enable ldap client.\n"),
stderr);
return (retcode);
} else if (retcode != CLIENT_SUCCESS) {
gettext("Save of system configuration failed. "
"Attempting recovery.\n"),
stderr);
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (retcode);
}
/* Dump new files */
gettext("%s init: errorp is not NULL; %s\n"),
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
(void) __ns_ldap_freeError(&errorp);
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
/* if (credargs(arglist)) */
gettext("%s init: errorp is not NULL; %s\n"),
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
(void) __ns_ldap_freeError(&errorp);
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
if (ret_copy != 0) {
gettext("Error %d copying (%s) -> (%s)\n"),
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
if (retcode != CLIENT_SUCCESS) {
gettext("Recovery of systems configuration "
"failed. Manual intervention of "
"config files is required.\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
return (CLIENT_ERR_FAIL);
}
(void) close(profile_fp);
if (retcode == CLIENT_SUCCESS) {
stderr);
} else {
"Recovering old system settings.\n"), stderr),
/* stop any started services for recover */
/* don't stomp on history of saved services state */
if (reset_ret != CLIENT_SUCCESS) {
"stopping services during reset\n"),
/* Coninue and try to recover what we can */
}
if (reset_ret != CLIENT_SUCCESS) {
"recovering service files during "
"reset\n"), reset_ret);
/* Continue and start what we can */
}
if (reset_ret != CLIENT_SUCCESS) {
"starting services during reset\n"),
}
}
return (retcode);
}
static void
usage(void)
{
if (mode_quiet)
return;
if (gen == 0) {
gettext("Usage: %s [-v | -q] init | manual | mod | "
"list | uninit [<args>]\n"),
cmd);
gettext("\n %s [-v | -q] [-a authenticationMethod]"
" [-D bindDN]\n\t[-w bindPassword] [-j passswdFile]"
" [-y proxyPasswordFile]\n\t"
"[-z adminPasswordFile] init [<args>]\n"),
cmd);
gettext("\nSet up a server or workstation as a "
"client of an LDAP namespace.\n"),
stderr);
} else { /* genprofile */
gettext("Usage: %s [-v | -q] genprofile "
"-a profileName=<name> "
"-a defaultSearchBase=<base> <args>\n"),
cmd);
gettext("\nGenerate a profile used to set up clients "
"of an LDAP namespace.\n"),
stderr);
}
gettext("<args> take the form of \'-a attrName=attrVal\' as "
"described in the\n"),
stderr);
}
/*
* import_service is called to perform an "nscfg import -f" of a given
* service. In theory this code should be performed using direct libscf
* calls. Currently it has nscfg do all the work.
*/
static int
{
int sysret;
valid_fmri = B_TRUE;
if (valid_fmri == B_FALSE)
return (CLIENT_SUCCESS);
/*
* This shouldn't happen since the fixed sized strings
* are all defined in this program and all total < BUFSIZ
*/
return (CLIENT_ERR_FAIL);
}
if (mode_verbose)
if (sysret != 0) {
gettext("import failed \"%s\" returned: %d\n"),
return (CLIENT_ERR_FAIL);
}
if (mode_verbose)
return (CLIENT_SUCCESS);
}
/*
* stop_services is called to stop network services prior to their
* (an error occurs during config), we detect whether the service is
* running and store that info so that a reset will only start services
* that were stopped here.
*
* In terms of SMF, this translates to disabling the services. So we
* try to disable them if they are in any other state
*
* Stop order :
* sendmail, nscd, autofs, ldap.client, nisd (rpc), inetinit(domainname)
*/
static int
{
int ret;
if (mode_verbose) {
}
if (mode_verbose)
if (ret != CLIENT_SUCCESS) {
/* Not serious, but tell user what to do */
"failed with (%d). You may need to restart "
"it manually for changes to take effect.\n"),
ret);
} else enableFlag |= SENDMAIL_ON;
} else {
if (mode_verbose)
}
if (mode_verbose)
if (ret != CLIENT_SUCCESS) {
"failed with (%d)\n"), ret);
return (CLIENT_ERR_FAIL);
} else enableFlag |= NSCD_ON;
} else {
if (mode_verbose)
}
if (mode_verbose)
if (ret != CLIENT_SUCCESS) {
/* Not serious, but tell user what to do */
"failed with (%d). You may need to restart "
"it manually for changes to take effect.\n"),
ret);
} else enableFlag |= AUTOFS_ON;
} else {
if (mode_verbose)
}
if (saveState)
if (mode_verbose)
if (ret != CLIENT_SUCCESS) {
"failed with (%d)\n"), ret);
return (CLIENT_ERR_FAIL);
}
} else {
if (mode_verbose)
stderr);
}
if (saveState)
if (mode_verbose)
if (ret != 0) {
"failed with (%d)\n"), ret);
return (CLIENT_ERR_FAIL);
}
} else {
if (mode_verbose)
stderr);
}
if (mode_verbose)
if (ret != 0) {
"failed with (%d)\n"), ret);
return (CLIENT_ERR_FAIL);
}
}
return (CLIENT_SUCCESS);
}
/*
* start_services is called to start up network services after config
* files have all been setup or recovered. In the case of an error, the
* files will be recovered and start_services will be called with the
* "reset" flag set so that only those services that were earlier stopped
* will be started. If it is not a reset, then the services associated
* with files "recovered" will attempt to be started.
*/
static int
{
if (mode_verbose) {
}
/* Read in current defaultdomain so we can set it */
"(%d)\n"), errno);
/* if we did an ldap init, we must have domain */
if (flag == START_INIT)
return (CLIENT_ERR_FAIL);
} else {
stderr);
return (CLIENT_ERR_FAIL);
}
gettext("Error closing defaultdomain (%d)\n"),
errno);
return (CLIENT_ERR_FAIL);
}
}
/*
* We can be starting services after an init in which case
* we want to start ldap and not start yp.
*/
if (flag == START_INIT) {
rc);
}
if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE) {
if (errorp)
(void) __ns_ldap_freeError(&errorp);
if (rc != NS_LDAP_SUCCESS)
}
if (rc == NS_LDAP_SUCCESS &&
if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE &&
&errorp);
if (errorp)
(void) __ns_ldap_freeError(&errorp);
if (rc != NS_LDAP_SUCCESS)
}
/* No YP after init */
/*
* Or we can be starting services after an uninit or error
* recovery. We want to start whatever services were running
* before. In the case of error recovery, it is the services
* that were running before we stopped them (flags set in
* stop_services). If it is an uninit then we determine
* which services to start based on the files we recovered
* (flags set in recover).
*/
} else {
/* uninit and recover should set flags of what to start */
if (domain_fp) {
}
if (gStartLdap == flag) {
!= CLIENT_SUCCESS)
}
}
}
/* no matter what, re-import nsswitch.conf, and restart the service */
if ((enableFlag & AUTOFS_ON) &&
if ((enableFlag & NSCD_ON) &&
#if 0
retcode == CLIENT_SUCCESS &&
" but nscd is not online"));
}
#endif
if ((enableFlag & SENDMAIL_ON) &&
/*
* Restart name-service milestone so that any consumer
* which depends on it will be restarted.
*/
return (retcode);
}
/*
* credCheck is called to check if credentials are required for this
* configuration. Currently, this means that if any credentialLevel is
* proxy and any authenticationMethod is something other than none, then
* credential info is required (proxyDN and proxyPassword).
*/
static int
{
int counter;
int **credLevel;
int retcode;
/* If credentialLevel is proxy, make sure we have proxyDN and proxyPassword */
if (retcode != 0) {
gettext("Error %d while trying to retrieve "
"credLevel\n"),
retcode);
return (CLIENT_ERR_FAIL);
}
(void ***)&authMethod, &errorp);
if (retcode != 0) {
gettext("Error %d while trying to retrieve "
"authMethod\n"), retcode);
return (CLIENT_ERR_FAIL);
}
if (retcode != 0) {
gettext("Error %d while trying to retrieve proxyDN\n"),
retcode);
return (CLIENT_ERR_FAIL);
}
(void ***)&proxyPassword, &errorp);
if (retcode != 0) {
gettext("Error %d while trying to retrieve "
"proxyPassword\n"), retcode);
return (CLIENT_ERR_FAIL);
}
if (mode_verbose) {
gettext("Proxy DN: %s\n"),
gettext("Proxy password: %s\n"),
(proxyPassword && proxyPassword[0]) ?
proxyPassword[0] : "NULL");
}
credProxy = 0; /* flag to indicate if we have a credLevel of proxy */
if (mode_verbose)
gettext("Credential level: %d\n"),
credProxy = 1;
break;
}
}
authNotNone = 0; /* flag for authMethod other than none */
for (counter = 0;
counter++) {
if (mode_verbose)
gettext("Authentication method: %d\n"),
authNotNone = 1;
break;
}
}
if (!(credProxy && authNotNone)) {
if (mode_verbose)
gettext("No proxyDN/proxyPassword required\n"),
stderr);
return (CLIENT_SUCCESS);
}
/* Now let's check if we have the cred stuff we need */
gettext("credentialLevel is proxy and no proxyDN "
"specified\n"),
stderr);
return (CLIENT_ERR_CREDENTIAL);
}
/* If we need proxyPassword (prompt) */
if (!proxyPassword || !proxyPassword[0]) {
gettext("credentialLevel requires proxyPassword\n"),
stderr);
return (CLIENT_ERR_CREDENTIAL);
}
if (retcode != 0) {
gettext("setParam proxyPassword failed.\n"),
stderr);
return (CLIENT_ERR_CREDENTIAL);
}
}
return (CLIENT_SUCCESS);
}
/*
* adminCredCheck is called to check if the admin credential is required
* for this configuration. This means that if enableShadowUpdate is set
* to TRUE then credential info is required (adminDN and adminPassword).
* One exception is that if there is a 'self' credentialLevel and
* host credential) then adminDN and adminPassword are not required.
*/
static int
{
int counter;
/* If shadow update not enabled, then no need to check */
if (retcode != 0) {
gettext("Error %d while trying to retrieve "
"enableShadowUpdate\n"), retcode);
goto out;
}
*enabled[0] != NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE) {
if (mode_verbose)
gettext("Shadow Update is not enabled, "
"no adminDN/adminPassword is required.\n"), stderr);
rc = CLIENT_SUCCESS;
goto out;
}
/* get credentialLevel */
if (retcode != 0) {
gettext("Error %d while trying to retrieve credLevel\n"),
retcode);
goto out;
}
/* get AuthenticationMethod */
(void ***)&authMethod, &errorp);
if (retcode != 0) {
gettext("Error %d while trying to retrieve authMethod\n"),
retcode);
goto out;
}
/* get adminDN */
if (retcode != 0) {
gettext("Error %d while trying to retrieve adminDN\n"),
retcode);
goto out;
}
/* get adminPassword */
(void ***)&adminPassword, &errorp);
if (retcode != 0) {
gettext("Error %d while trying to retrieve "
"adminPassword\n"), retcode);
goto out;
}
if (mode_verbose) {
gettext("admin DN: %s\n"),
gettext("admin password: %s\n"),
(adminPassword && adminPassword[0]) ?
adminPassword[0] : "NULL");
}
credSelf = 0; /* flag to indicate if we have a credLevel of self */
if (mode_verbose)
gettext("Credential level: %d\n"),
credSelf = 1;
break;
}
}
authSASLgss = 0; /* flag for authMethod of SASL/gssapi */
for (counter = 0;
counter++) {
if (mode_verbose)
gettext("Authentication sasl mechanism: %d\n"),
authSASLgss = 1;
break;
}
}
/* First, if we don't need adminDN/adminPassword then just return ok */
if (credSelf && authSASLgss) {
if (mode_verbose)
gettext("A credential Level of self and an "
"configured, no adminDN/adminPassword "
"is required.\n"), stderr);
rc = CLIENT_SUCCESS;
goto out;
}
/* Now let's check if we have the cred stuff we need */
gettext("Shadow Update is enabled, but "
"no adminDN is configured.\n"), stderr);
goto out;
}
/* If we need adminPassword (prompt) */
gettext("Shadow Update requires adminPassword\n"),
stderr);
stderr);
goto out;
}
if (retcode != 0) {
gettext("setParam adminPassword failed.\n"),
stderr);
goto out;
}
}
rc = CLIENT_SUCCESS;
out:
(void) __ns_ldap_freeParam((void ***)&enabled);
(void) __ns_ldap_freeParam((void ***)&credLevel);
if (authMethod != NULL)
(void) __ns_ldap_freeParam((void ***)&authMethod);
(void) __ns_ldap_freeParam((void ***)&adminDN);
if (adminPassword != NULL)
(void) __ns_ldap_freeParam((void ***)&adminPassword);
return (rc);
}
/*
* try to restore the previous name space on this machine
*/
static int
{
/* If running as Sysid Install become a no-op */
if (sysid_install == B_TRUE)
return (CLIENT_SUCCESS);
if (stat_ret != 0) {
gettext("Cannot recover. No backup files "
"found.\n"),
stderr);
gettext("\t Either this machine was not initialized\n"),
stderr);
gettext("\t by ldapclient or the backup files "
"have been\n"),
stderr);
gettext("\t removed manually or with an \"uninit\"\n"),
stderr);
return (CLIENT_ERR_RESTORE); /* invalid backup */
}
/*
* Get domainname. Allow no domainname for the case where "files"
* config was backed up.
*/
if (mode_verbose)
gettext("recover: stat(%s)=%d\n"),
if (stat_ret == 0) {
if (mode_verbose)
gettext("recover: open(%s)\n"),
if (mode_verbose)
gettext("recover: read(%s)\n"),
if (domainlen < 0) {
gettext("Cannot recover. Cannot determine "
"previous domain name.\n"),
stderr);
return (CLIENT_ERR_RESTORE); /* invalid backup */
} else {
char *ptr;
*ptr = '\0';
else
if (mode_verbose)
gettext("recover: old domainname "
"\"%s\"\n"), name);
domain = 0;
else
}
}
/*
* we can recover at this point
* remove LDAP config files before restore
*/
(void) unlink(NSCONFIGFILE);
(void) unlink(NSCREDFILE);
if (mode_verbose)
gettext("recover: stat(%s)=%d\n"),
if (stat_ret == 0) {
if (saveState)
if (mode_verbose)
gettext("recover: file_move(%s, %s)=%d\n"),
if (retcode != 0)
gettext("recover: file_move(%s, %s) failed\n"),
}
if (mode_verbose)
gettext("recover: stat(%s)=%d\n"),
if (stat_ret == 0) {
if (mode_verbose)
gettext("recover: file_move(%s, %s)=%d\n"),
if (retcode != 0)
gettext("recover: file_move(%s, %s) failed\n"),
}
/* Check for recovery of NIS(YP) if we have a domainname */
if (domain) {
/* "name" would have to be huge for this, but just in case */
return (CLIENT_ERR_FAIL);
return (CLIENT_ERR_FAIL);
if (mode_verbose)
gettext("recover: stat(%s)=%d\n"),
if (stat_ret == 0) {
if (mode_verbose)
gettext("recover: file_move(%s, "
"%s)=%d\n"),
if (retcode != 0) {
gettext("recover: file_move(%s, "
"%s) failed!\n"),
} else {
if (saveState)
}
}
}
/* restore machine configuration */
if (mode_verbose)
gettext("recover: stat(%s)=%d\n"),
if (stat_ret == 0) {
if (mode_verbose)
gettext("recover: file_move(%s, %s)=%d\n"),
if (retcode != 0)
gettext("recover: file_move(%s, %s) failed\n"),
}
if (mode_verbose)
gettext("recover: stat(%s)=%d\n"),
if (stat_ret == 0) {
if (mode_verbose)
gettext("recover: file_move(%s, %s)=%d\n"),
if (retcode != 0)
gettext("recover: file_move(%s, %s) failed\n"),
}
if (retcode != 0) {
gettext("Error removing \"%s\" directory.\n"),
}
return (CLIENT_SUCCESS);
}
/*
* try to save the current state of this machine.
* this just overwrites any old saved configration files.
*
* This function should only be called after network services have been stopped.
*
* Returns 0 on successful save
* Otherwise returns -1
*/
static int
file_backup(void)
{
/* If running as Sysid Install become a no-op */
if (sysid_install == B_TRUE)
return (CLIENT_SUCCESS);
/* If existing backup files, clear for this run */
if (restore_stat == 0) {
if (mode_verbose) {
gettext("Removing existing restore "
"directory\n"),
stderr);
}
if (restore_stat == 0) {
gettext("Unable to remove backup "
"directory (%s)\n"),
return (CLIENT_ERR_RESTORE);
}
}
if (retcode != 0) {
gettext("file_backup: Failed to make %s backup "
"directory. mkdir=%d\n"),
return (CLIENT_ERR_FAIL);
}
if (mode_verbose)
gettext("file_backup: stat(%s)=%d\n"),
if (conf_stat == 0) {
if (mode_verbose)
gettext("file_backup: (%s -> %s)\n"),
if (retcode != 0) {
gettext("file_backup: file_move(%s, %s) failed "
"with %d\n"),
}
} else {
if (mode_verbose)
gettext("file_backup: No %s file.\n"),
}
if (mode_verbose)
gettext("file_backup: stat(%s)=%d\n"),
if (mode_verbose)
gettext("file_backup: (%s -> %s)\n"),
if (retcode != 0) {
gettext("file_backup: file_move(%s, %s) failed "
"with %d\n"),
}
} else {
if (mode_verbose)
if (domain_stat != 0) {
gettext("file_backup: No %s file.\n"),
} else {
gettext("file_backup: Empty %s "
"file.\n"),
}
}
if (mode_verbose)
gettext("file_backup: nis domain is \"%s\"\n"),
/* check for domain name if not set cannot save NIS(YP) state */
if (namelen > 0) {
if (mode_verbose)
gettext("file_backup: stat(%s)=%d\n"),
if (yp_stat == 0) {
BUFSIZE);
if (mode_verbose)
gettext("file_backup: (%s -> %s)\n"),
if (retcode != 0) {
gettext("file_backup: file_move(%s, %s)"
" failed with %d\n"),
}
} else {
if (mode_verbose)
gettext("file_backup: No %s "
"directory.\n"), yp_dir);
}
}
/* point to file name, not path delim (/) */
if (mode_verbose)
gettext("file_backup: stat(%s)=%d\n"),
if (ldap_stat == 0) {
if (mode_verbose)
gettext("file_backup: (%s -> %s)\n"),
if (retcode != 0) {
gettext("file_backup: file_move(%s, %s) failed "
"with %d\n"),
}
if (mode_verbose)
gettext("file_backup: (%s -> %s)\n"),
if (retcode != 0) {
gettext("file_backup: file_move(%s, %s) failed "
"with %d\n"),
}
} else {
if (mode_verbose)
gettext("file_backup: No %s file.\n"),
}
return (ret);
}
/*
* mod_backup()
*
* that the "mod" operation needs to update. If an error occurs then the
* function mod_recover() can be invoke to recover the unmodified files.
*/
static int
mod_backup(void)
{
int rc;
if (mode_verbose)
gettext("mod_backup: backup %s for %s\n"),
if (mode_verbose)
gettext("mod_backup: backup %s for %s\n"),
if (mode_verbose)
gettext("mod_backup: backup %s for %s\n"),
if (retcode != CLIENT_SUCCESS)
return (retcode);
}
/*
* mod_recover()
*
* This function is used to recover the temporily backed up files by
* the mod_backup() function if an error occurs during the "mod"
* operation.
*/
static int
mod_recover(void)
{
int rc;
if (mode_verbose)
gettext("mod_recover: recovery %s for %s\n"),
if (mode_verbose)
gettext("mod_recover: recovery %s for %s\n"),
if (mode_verbose)
gettext("mod_recover: recovery %s for %s\n"),
if (retcode != CLIENT_SUCCESS)
return (retcode);
}
/*
* mod_cleanup()
*
*/
static void
mod_cleanup(void)
{
}
static multival_t *
{
gettext("multival_new: Memory allocation error\n"),
stderr);
}
return (hold); /* NULL -> error */
}
static int
{
gettext("Empty value passed to multival_add\n"),
stderr);
return (CLIENT_ERR_FAIL);
}
} else {
}
return (CLIENT_ERR_MEMORY); /* 0 is success */
}
return (CLIENT_SUCCESS);
}
static void
{
return;
}
static clientopts_t *
{
"clientopts structure\n"), stderr);
return (hold); /* NULL -> error */
}
"serviceAuthenticationMethod\n"), stderr);
return (NULL); /* NULL -> error */
}
"serviceCredentialLevel\n"), stderr);
return (NULL); /* NULL -> error */
}
"objectclassMap\n"), stderr);
return (NULL); /* NULL -> error */
}
"attributeMap\n"), stderr);
return (NULL); /* NULL -> error */
}
"serviceSearchDescriptor\n"), stderr);
return (NULL); /* NULL -> error */
}
return (hold);
}
static void
{
return;
}
static void
{
int i;
return;
}
}
/* return the number of arguments specified in the command line */
static int
{
int arg_count = 0;
return (arg_count);
}
static void
{
multival_list("\tserviceAuthenticationMethod: ",
multival_list("\tserviceCredentialLevel: ",
multival_list("\tserviceSearchDescriptor: ",
}
/* These definitions are only used in parseParam() below. */
struct param {
char *name;
int index;
};
{"proxyDN", NS_LDAP_BINDDN_P},
{"proxyPassword", NS_LDAP_BINDPASSWD_P},
{"defaultServerList", NS_LDAP_SERVERS_P},
{"defaultSearchBase", NS_LDAP_SEARCH_BASEDN_P},
{"authenticationMethod", NS_LDAP_AUTH_P},
{"followReferrals", NS_LDAP_SEARCH_REF_P},
{"profileTTL", NS_LDAP_CACHETTL_P},
{"certificatePath", NS_LDAP_HOST_CERTPATH_P},
{"defaultSearchScope", NS_LDAP_SEARCH_SCOPE_P},
{"bindTimeLimit", NS_LDAP_BIND_TIME_P},
{"searchTimeLimit", NS_LDAP_SEARCH_TIME_P},
{"preferredServerList", NS_LDAP_SERVER_PREF_P},
{"profileName", NS_LDAP_PROFILE_P},
{"credentialLevel", NS_LDAP_CREDENTIAL_LEVEL_P},
{"serviceSearchDescriptor", NS_LDAP_SERVICE_SEARCH_DESC_P},
{"attributeMap", NS_LDAP_ATTRIBUTEMAP_P},
{"objectclassMap", NS_LDAP_OBJECTCLASSMAP_P},
{"serviceAuthenticationMethod", NS_LDAP_SERVICE_AUTH_METHOD_P},
{"serviceCredentialLevel", NS_LDAP_SERVICE_CRED_LEVEL_P},
{"domainName", LOCAL_DOMAIN_P},
{"enableShadowUpdate", NS_LDAP_ENABLE_SHADOW_UPDATE_P},
{"adminDN", NS_LDAP_ADMIN_BINDDN_P},
{"adminPassword", NS_LDAP_ADMIN_BINDPASSWD_P},
{NULL, 0}
};
static int
{
int counter;
if (mode_verbose) {
}
gettext("Didn\'t find \'=\' character in string\n"),
stderr);
return (CLIENT_ERR_PARSE);
}
*val = '\0';
}
}
/* Not found */
return (CLIENT_ERR_PARSE);
}
/*
* The following macro checks if an option has already been specified
* and errs out with usage if so
*/
if (optarg) { \
usage(); \
return (CLIENT_ERR_FAIL); \
}
static int
{
int retcode = 0;
int counter;
switch (paramFlag) {
case NS_LDAP_AUTH_P:
break;
case NS_LDAP_SERVICE_AUTH_METHOD_P: /* multiple allowed */
attrVal);
if (retcode != CLIENT_SUCCESS) {
gettext("Error processing attrVal %s\n"),
usage();
return (CLIENT_ERR_FAIL);
}
break;
case NS_LDAP_SEARCH_BASEDN_P:
break;
break;
case NS_LDAP_SERVICE_CRED_LEVEL_P: /* multiple allowed */
attrVal);
if (retcode != CLIENT_SUCCESS) {
gettext("Error processing attrVal %s\n"),
usage();
return (CLIENT_ERR_FAIL);
}
break;
case LOCAL_DOMAIN_P:
break;
case NS_LDAP_BINDDN_P:
break;
break;
case NS_LDAP_ADMIN_BINDDN_P:
break;
case NS_LDAP_CACHETTL_P:
break;
case NS_LDAP_OBJECTCLASSMAP_P: /* multiple allowed */
if (retcode != CLIENT_SUCCESS) {
gettext("Error processing attrVal %s\n"),
usage();
return (CLIENT_ERR_FAIL);
}
break;
case NS_LDAP_SEARCH_TIME_P:
break;
case NS_LDAP_SERVER_PREF_P:
/* replace ',' chars with ' ' for proper syntax */
for (counter = 0;
counter++) {
}
break;
case NS_LDAP_PROFILE_P:
break;
case NS_LDAP_SEARCH_REF_P:
else
break;
case NS_LDAP_ATTRIBUTEMAP_P: /* multiple allowed */
if (retcode != CLIENT_SUCCESS) {
gettext("Error processing attrVal %s\n"),
usage();
return (CLIENT_ERR_FAIL);
}
break;
case NS_LDAP_SEARCH_SCOPE_P:
break;
case NS_LDAP_SERVICE_SEARCH_DESC_P: /* multiple allowed */
attrVal);
if (retcode != CLIENT_SUCCESS) {
gettext("Error processing attrVal %s\n"),
usage();
return (CLIENT_ERR_FAIL);
}
break;
case NS_LDAP_BIND_TIME_P:
break;
case NS_LDAP_BINDPASSWD_P:
break;
break;
case NS_LDAP_HOST_CERTPATH_P:
break;
case NS_LDAP_SERVERS_P:
break;
default:
usage();
return (CLIENT_ERR_FAIL);
/* break; lint doesn't like break before end of switch */
}
return (retcode);
}
/*
*
* case where the backup directory (/var) is on a different file
* system than the config file (typically /etc).
*/
static int
{
int retcode;
/*
* to so that the mv command that follows doesn't move a dir
* into an existing dir or other non-obvious problem. As
* mentioned below, this call is also run as root.
* if an error occurs (aka nothing to remove) ignore it.
*/
(void) system(cmd_buffer);
/*
* This function should only be used internally to move
* reasons (this is run as root), don't use this function
* with arguments passed into the program.
*/
return (retcode);
}
/*
* Manipulate the service as instructed by "dowhat"
*/
static int
const char *state) {
int status;
/* Check if we are in maintenance */
/* re-import SMF on start or re-start */
/* do no additional harm */
return (CLIENT_ERR_FAIL);
}
switch (dowhat) {
case START_SERVICE:
break;
case STOP_SERVICE:
break;
case RESTART_SERVICE:
break;
default:
/* coding error; will not happen */
assert(0);
}
/*
* If the service was previously in maintenance then we need to
* clear it immediately. The "dowhat" action will set the
* enabled property of the service as intended by the caller while
* We assume that the caller has called us after taking some
* recovery action. Even if it's not the case, we don't lose
* anything.
*/
if (mode_verbose)
"%s: %s... %s\n",
what,
fmri,
gettext("restoring from maintenance state"));
}
if (status == 0) {
/* Check if we need to wait ? */
if (mode_verbose)
"%s: %s... %s\n",
what,
fmri,
gettext("success"));
return (CLIENT_SUCCESS);
}
/* Otherwise wait for max seconds (from the manifest) */
if (status == CLIENT_SUCCESS)
return (CLIENT_SUCCESS);
/* For error fall through for corrective action */
} else {
/* Well, service failed ... */
if (mode_verbose)
what,
fmri,
gettext("failed"),
scf_strerror(scf_error()));
/* For error fall through for corrective action */
}
/*
* failed and guess is restarter failed to apply the timeout as well.
* So instead of leaving it offline, let's just disable it until we have
* some other mechanism available from smf to handle such situation.
*/
if (dowhat != STOP_SERVICE)
if (mode_verbose)
"%s: %s... %s\n",
what,
fmri,
gettext("offline to disable"));
}
return (status);
}
/*
* Wait for "max" usecs for the service described by "fmri" to change
* to "state". If check_maint is true then return immediately if
* service goes into maintenance
*/
static int
char *st;
/* incremental wait */
usecs *= 2;
if (mode_verbose)
"%s: %s %u %s\n",
gettext("microseconds"));
/* Check state after the wait */
if (mode_verbose)
"%s: %s... %s\n",
what,
fmri,
gettext("success"));
return (CLIENT_SUCCESS);
}
/*
* If service has gone into maintenance then
* we will time out anyway, so we are better
* off returning now
*/
if (check_maint &&
if (mode_verbose)
"%s: %s... %s\n",
what,
fmri,
gettext("maintenance"));
return (CLIENT_ERR_MAINTENANCE);
}
} else {
if (mode_verbose)
"%s: %s... %s: %s\n",
what,
fmri,
gettext("failed"),
scf_strerror(scf_error()));
return (CLIENT_ERR_FAIL);
}
}
/* Timed out waiting */
if (mode_verbose)
"%s: %s... %s\n",
what,
fmri,
gettext("timed out"));
return (CLIENT_ERR_TIMEDOUT);
}
static boolean_t
char *st;
}
return (result);
}
/*
*
* get_timeout_val : returns the timeout value set in fmri manifest
* fmri(defined fmri string)
* Returns default if error, the timeout val otherwise
*
*/
static useconds_t
{
switch (dowhat) {
case START_SERVICE:
case RESTART_SERVICE:
action = "start";
break;
case STOP_SERVICE:
action = "stop";
break;
default:
assert(0);
}
if (mode_verbose)
fmri,
gettext("failed to retrieve timeout property"),
scf_strerror(scf_error()));
return (default_val);
}
if (mode_verbose)
fmri,
gettext("failed to retrieve timeout value"),
scf_strerror(scf_error()));
return (default_val);
}
if (*cp != 0)
return (timeout * 1000000);
}