mgmt_mmsdb.c revision cee0fb94c0d4227de0a00efc162fb2739844b641
/*
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <ctype.h>
#include <libnvpair.h>
#include "mms_mgmt.h"
#include "mgmt_util.h"
#include "mms_cfg.h"
#include "net_cfg_service.h"
typedef struct {
char port[10];
char user[256];
char bindir[MAXPATHLEN];
char path[MAXPATHLEN];
char logdir[MAXPATHLEN];
char dbname[MAXPATHLEN];
char dbhost[MAXHOSTNAMELEN];
} mmsdb_opts_t;
/* If this path changes, make sure similar changes are made to mmsexplorer */
static char db_cli_env[1024];
/*
* Functions to manage the MMS Database
*/
int
{
int st = 0;
int doconf = 0;
char *val;
if (!mgmt_chk_auth("solaris.mms.modify")) {
return (EACCES);
}
/*
* check to see if any options have been set for the DB yet. Only
* a few are user-configurable. Changing the DB user is handled
* by the admin with SMF and chown -R. (i.e., outside of our CLI,
* at least for now)
*/
if (st != 0) {
return (st);
}
/* TODO - should we allow change after set? Need to copy -R if so */
if (st == 0) {
if (st != 0) {
return (st);
}
}
if (st == 0) {
/* update the conf file */
doconf = 1;
}
if (st == 0) {
/* update the conf file */
doconf = 1;
/* create dblogdir if it doesn't exist */
}
}
return (st);
}
static int
{
int st;
int i;
char buf[2048];
if (!dbpath) {
return (MMS_MGMT_NOARG);
}
return (st);
}
if (st != 0) {
return (st);
}
dbsubdirs[i]);
if (st != 0) {
break;
}
}
return (st);
}
int
mgmt_db_init(void)
{
int st;
char buf[2048];
char dbbuf[2048];
char *cmd[4];
if (!mgmt_chk_auth("solaris.mms.create")) {
return (EACCES);
}
if (st != 0) {
return (st);
}
/* see if we've been initialized already, bail if so */
if (st == 0) {
return (0);
}
return (st);
}
static int
{
int st;
int scf_size = MMS_CFG_MAX_VALUE;
char *bufp;
return (MMS_MGMT_NOARG);
}
if (st == 0) {
/*
* The *data* dir is stored in SMF. We need the
* parent thereof.
*/
if (bufp) {
*bufp = '\0';
}
}
if (st == 0) {
}
if (st == 0) {
}
if (st == 0) {
}
if (st == 0) {
}
#ifdef MMS_VAR_CFG
if (st == 0) {
}
#else
if (st == 0) {
}
#endif /* MMS_VAR_CFG */
if (st != 0) {
return (st);
}
return (MMS_MGMT_DB_USER_NOTFOUND);
}
/* set the envvar for PGPASSFILE */
db_cli);
return (st);
}
static int
{
int st;
return (MMS_MGMT_NOARG);
}
if (st != 0) {
return (st);
}
return (MMS_MGMT_DB_USER_NOTFOUND);
}
}
return (0);
}
int
{
int st;
int oldver = -1;
int ver = -1;
char buf[MAXPATHLEN];
char *cmd[7];
char dbbuf[2048];
if (!mgmt_chk_auth("solaris.mms.modify")) {
return (EACCES);
}
if (st != 0) {
return (st);
}
if (initialize) {
st = mgmt_db_check();
if (st == 0) {
/* db is alive, already inited */
return (EALREADY);
}
/* check to see if files exist, even if svc is stopped */
"base");
return (EALREADY);
} else {
/* create the dirs we need */
NULL);
if (st != 0) {
return (st);
}
}
st = mgmt_db_init();
if (st == 0) {
}
if (st != 0) {
return (st);
}
}
/*
* some callers may wish to populate the DB themselves, as in
* upgrade or downgrade.
*/
if (populate) {
if (st != 0) {
return (st);
}
if (st != 0) {
return (st);
}
st = 0;
}
if (oldver != -1) {
/* save the old mod file */
char newf[MAXPATHLEN];
}
if (st != 0) {
return (st);
}
}
}
/* make sure the DB is running */
if (st != 0) {
return (st);
}
/* import all the sql cmds */
}
if (st == 0) {
}
if (cmdfile) {
}
if (st == 0) {
char *passp;
if (st == 0) {
"%s_dbadmin", passp);
}
}
}
return (st);
}
int
mgmt_db_drop(void)
{
int st;
char *cmd[5];
char dbbuf[2048];
if (!mgmt_chk_auth("solaris.mms.modify")) {
return (EACCES);
}
if (st != 0) {
return (st);
}
if (st != 0) {
/* restart the service to force users to disconnect */
}
return (st);
}
int
mgmt_db_check(void)
{
int st;
char buf[1024];
char *cmd[9];
char dbbuf[2048];
if (!mgmt_chk_auth("solaris.mms.modify")) {
return (EACCES);
}
if (st != 0) {
return (st);
}
"SELECT datname FROM pg_database where datname = '%s'",
if (st == 0) {
buf[0] = '\0';
if (buf[0] == '\0') {
st = -1;
}
}
return (st);
}
int
{
int st;
char datebuf[256];
char filbuf[MAXPATHLEN];
char *cmd[11];
char dbbuf[2048];
return (MMS_MGMT_NOARG);
}
if (!mgmt_chk_auth("solaris.mms.modify")) {
return (EACCES);
}
if (st != 0) {
return (st);
}
datebuf);
}
if (st != 0) {
return (st);
}
return (st);
}
/*
* TODO: Ensure this is done on the MM server host only when client
* configs are supported.
*/
int
mgmt_db_restore(char *dumpfile)
{
int st;
if (!mgmt_chk_auth("solaris.mms.modify")) {
return (EACCES);
}
if (st != 0) {
return (st);
}
if (st != 0) {
return (MMS_MGMT_DBDUMP_MISSING);
}
return (MMS_MGMT_NOT_DBFILE);
}
/* shutdown MM */
if (st != 0) {
if (mmstate) {
}
return (st);
}
if (st != 0) {
return (st);
}
}
return (st);
}
typedef struct {
char *optnam;
char *val;
} pgconf_t;
static pgconf_t pgconf_opts[] = {
{"port", NULL},
{"log_directory", NULL},
{"external_pid_file", "'(none)'"},
{"log_destination", "stderr"},
{"redirect_stderr", "on"},
{"log_filename", "'log.%a'"},
{"log_rotation_size", "10000"},
{"log_truncate_on_rotation", "on"},
{"log_line_prefix", "'%m %p '"},
{"client_min_messages", "WARNING"},
{"log_min_messages", "INFO"},
{"log_disconnections", "on"},
{"autovacuum", "on"},
{"autovacuum_naptime", "1200"},
{"stats_start_collector", "on"},
{"stats_row_level", "on"}
};
static int
char *port,
char *logdir)
{
int st = 0;
char nambuf[256];
char buf[MAXPATHLEN];
char dbpath[MAXPATHLEN];
char logpath[MAXPATHLEN];
char *bufp;
int infd;
int outfd;
char filbuf[2048];
int i;
char *cptr;
int changed = 0;
int matched = 0;
return (MMS_MGMT_NOARG);
}
/* add quotes around the path */
if (st == 0) {
}
if (st != 0) {
return (st);
}
if (st != 0) {
}
if (st != 0) {
return (st);
}
} else {
return (ENOTDIR);
}
}
return (ENAMETOOLONG);
}
if (st != 0) {
return (errno);
} else {
/*
* DB not initialized yet, bail without
* error as this function will be called
* later from db_create.
*/
return (0);
}
}
/* construct the name of the new version of this file */
/* open the original */
if (infd == -1) {
return (st);
}
return (st);
}
/* open the target file */
if (outfd == -1) {
return (st);
}
return (st);
}
/* preserve, as much as possible, the existing format of the file */
matched = 0;
/* options are initially commented out */
if (*bufp == '#') {
continue;
}
break;
}
}
if (*bufp == '\0') {
continue;
}
for (i = 0; i < numpgopts; i++) {
continue;
}
bufp++;
sz++;
}
if (*bufp == '=') {
/* found a match - update it */
matched++;
/* TODO: check really needed to change */
if (cptr) {
cptr);
}
changed++;
break;
} else {
/* superstring or substring of another option */
}
}
if (!matched) {
}
}
/* if we didn't change anything, we're done */
if (!changed) {
return (0);
}
/* construct the name of the backup copy of this file */
/* finally, swap em */
if (st != 0) {
} else {
if (st != 0) {
}
}
return (st);
}
static int
{
int st = 0;
char buf[1024];
char *bufp;
int vers = -1;
int last = -1;
return (ENOENT);
}
if (st != 0) {
return (st);
}
return (errno);
}
continue;
}
do {
bufp++;
if (*bufp != 'u') {
continue;
}
*bufp = '\0';
}
}
return (st);
}
static int
{
int st = 0;
int fd = -1;
char buf[MAXPATHLEN];
char *bufp;
int started = 0;
char *pass;
return (MMS_MGMT_NOARG);
}
if (st != 0) {
return (st);
}
return (errno);
}
/* create our cmdfile */
0600);
if (fd == -1) {
goto done;
}
/* set this so the pguser can read it */
goto done;
}
if (*bufp == '#') {
continue;
}
if (started) {
}
continue;
}
bufp++;
}
started = 1;
bufp++;
}
} else {
started = 0;
}
}
if (dopd) {
/* override the junk password in the dbopts file */
"UPDATE \"MMPASSWORD\" SET \"Password\" = '%s';\n",
pass);
}
}
/* Set the version and add commit statement */
"UPDATE \"MM\" SET \"DBVersion\" = '%d';\nCOMMIT;\n", vers);
done:
if (st != 0) {
if (*cmdfile) {
}
}
return (st);
}
static int
{
int st;
char buf[MAXPATHLEN];
char *cmd[10];
char dbbuf[2048];
return (MMS_MGMT_NOARG);
}
if (st == 0) {
st = 1;
break;
}
}
}
return (st);
}
/*
* this should probably move to a header somewhere, but for
* now, leave it where it's directly mapped
*/
typedef struct {
char *mm;
char *ui;
/*
* map of MgmtUI-specified opts to MM options. NULL indicates
* not exposed by MgmtUI
*/
static mgmt_dbopt_map_t mm_sys_opts[] = {
{"AttendanceMode", O_ATTENDED},
{"SystemLogLevel", O_LOGLEVEL},
{"SystemLogFile", O_LOGFILE},
{"MessageLevel", O_MSGLEVEL},
{"TraceLevel", O_TRACELEVEL},
{"TraceFileSize", O_TRACESZ},
{"SocketFdLimit", O_NUMSOCKET},
{"SystemDiskMountTimeout", O_DKTIMEOUT},
{"WatcherStartsLimit", O_NUMRESTART},
{"SystemAcceptLevel", NULL},
{"SystemMessageLimit", NULL},
{"SystemMessageCount", NULL},
{"SystemRequestLimit", NULL},
{"SystemRequestCount", NULL},
{"SystemSyncLimit", NULL},
{"SystemDCALimit", NULL},
{"SystemDCACount", NULL},
{"ClearDriveAtLMConfig", NULL},
{"AskClearDriveAtLMConfig", NULL},
{"PreemptReservation", NULL},
{"SystemLogFileSize", NULL},
{"SystemName", NULL},
{"SystemInstance", NULL},
{"UnloadDelayTime", NULL},
{"DefaultBlocksize", NULL},
{"WatcherTimeLimit", NULL},
{"DriveRecordRetention", NULL},
};
/* add the MM options to the database before creation, if we know them */
static int
{
int st;
int i;
int fd = -1;
int changed = 0;
if (!opts) {
return (0);
}
if (!cmdfile) {
return (MMS_MGMT_NOARG);
}
if (fd == -1) {
return (errno);
}
if (st != 0) {
return (st);
}
return (st);
}
continue;
}
if (!changed) {
}
"UPDATE \"SYSTEM\" SET \"%s\" = '%s';\n",
changed++;
}
}
if (changed) {
}
return (0);
}
int
{
int st;
char buf[2048];
int fd = -1;
int wr = 0;
/* no provided password means use 'trust' */
if (dbpass) {
}
if (st != 0) {
return (st);
}
/* tell Postgres to use the new password */
if (fd == -1) {
return (st);
}
"alter user postgres with password '%s' valid until 'infinity';",
dbpass);
if (wr == -1) {
return (EIO);
}
if (st != 0) {
return (st);
}
/* next, set up the conf file */
if (st != 0) {
return (st);
}
/* write the PGPASSFILE */
if (fd == -1) {
return (st);
}
if (wr == -1) {
return (EIO);
}
if (st != 0) {
return (st);
}
/* restart the db */
return (st);
}
static int
{
int st;
char buf[2048];
char *bufp;
int infd = -1;
int outfd = -1;
char confpath[2048];
char newconfpath[2048];
char timebuf[256];
if (!dbopts) {
return (MMS_MGMT_NOARG);
}
"pg_hba.conf");
if (st != 0) {
return (st);
}
/* construct the name of the new version of this file */
timebuf);
/* open the original */
if (infd == -1) {
return (st);
}
return (st);
}
/* open the target file */
if (outfd == -1) {
return (st);
}
return (st);
}
/* preserve, as much as possible, the existing format of the file */
bufp++;
}
continue;
}
/* look for 'trust' or 'md5' */
if (ismd5) {
/* changing to password-protected */
if (bufp) {
}
} else {
/* removing password protection */
if (bufp) {
}
}
}
/* if we didn't change anything, we're done */
if (!changed) {
(void) unlink(newconfpath);
return (0);
}
/* construct the name of the backup copy of this file */
/* finally, swap em */
if (st != 0) {
} else {
if (st != 0) {
}
}
return (st);
}