Skip to content

Commit

Permalink
sssctl: new tool
Browse files Browse the repository at this point in the history
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
  • Loading branch information
pbrezina authored and jhrozek committed Jun 27, 2016
1 parent 9e9ad4c commit e157b9f
Show file tree
Hide file tree
Showing 11 changed files with 1,665 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ sbin_PROGRAMS = \
sss_debuglevel \
sss_override \
sss_seed \
sssctl \
$(NULL)

sssdlibexec_PROGRAMS = \
Expand Down Expand Up @@ -728,6 +729,7 @@ dist_noinst_HEADERS = \
src/tools/common/sss_tools.h \
src/tools/common/sss_process.h \
src/tools/common/sss_colondb.h \
src/tools/sssctl/sssctl.h \
src/util/probes.h \
$(NULL)

Expand Down Expand Up @@ -1507,6 +1509,25 @@ sss_override_CFLAGS = \
$(AM_CFLAGS) \
$(NULL)

sssctl_SOURCES = \
src/tools/sssctl/sssctl.c \
src/tools/sssctl/sssctl_cache.c \
src/tools/sssctl/sssctl_data.c \
src/tools/sssctl/sssctl_logs.c \
src/tools/sssctl/sssctl_domains.c \
src/tools/sssctl/sssctl_sifp.c \
$(SSSD_TOOLS_OBJ) \
$(NULL)
sssctl_LDADD = \
$(TOOLS_LIBS) \
$(SSSD_INTERNAL_LTLIBS) \
libsss_simpleifp.la \
$(NULL)
sssctl_CFLAGS = \
$(AM_CFLAGS) \
-I$(top_srcdir)/src/lib/sifp
$(NULL)

if BUILD_SUDO
sss_sudo_cli_SOURCES = \
src/sss_client/common.c \
Expand Down
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ WITH_INITSCRIPT
if test x$initscript = xsystemd; then
WITH_SYSTEMD_UNIT_DIR
WITH_SYSTEMD_CONF_DIR
else
AC_CHECK_PROG(HAVE_SERVICE, service, yes, no)
AS_IF([test x$HAVE_SERVICE = xyes],
[AC_DEFINE(HAVE_SERVICE, 1,
[Whether the service command is available])])
fi

PKG_CHECK_MODULES([DBUS],[dbus-1])
Expand Down
2 changes: 2 additions & 0 deletions contrib/sssd.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ Also provides several other administrative tools:
* sss_debuglevel to change the debug level on the fly
* sss_seed which pre-creates a user entry for use in kickstarts
* sss_obfuscate for generating an obfuscated LDAP password
* sssctl -- an sssd status and control utility

%package -n python-sssdconfig
Summary: SSSD and IPA configuration file manipulation classes and functions
Expand Down Expand Up @@ -932,6 +933,7 @@ done
%{_sbindir}/sss_override
%{_sbindir}/sss_debuglevel
%{_sbindir}/sss_seed
%{_sbindir}/sssctl
%{_mandir}/man8/sss_groupadd.8*
%{_mandir}/man8/sss_groupdel.8*
%{_mandir}/man8/sss_groupmod.8*
Expand Down
4 changes: 4 additions & 0 deletions src/external/systemd.m4
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ AS_IF([test x$HAVE_LIBSYSTEMD = xyes],
[login_lib_name=libsystemd],
[login_lib_name=libsystemd-login])

AM_COND_IF([HAVE_SYSTEMD],
[AC_DEFINE_UNQUOTED([HAVE_SYSTEMD], 1, [Build with libsystemd support])],
[AC_MSG_NOTICE([Build without libsystemd support])])

AM_COND_IF([HAVE_SYSTEMD],
[PKG_CHECK_MODULES([SYSTEMD_LOGIN],
[$login_lib_name],
Expand Down
277 changes: 277 additions & 0 deletions src/tools/sssctl/sssctl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
/*
Authors:
Pavel Březina <pbrezina@redhat.com>
Copyright (C) 2016 Red Hat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>
#include <stdio.h>

#include "util/util.h"
#include "tools/sssctl/sssctl.h"
#include "tools/common/sss_tools.h"
#include "tools/common/sss_process.h"

#ifdef HAVE_SYSTEMD
#define SSSD_SVC_CMD(cmd) "systemctl " cmd " sssd.service"
#else
#define SSSD_SVC_CMD(cmd) "service sssd " cmd
#endif

static const char *
sssctl_prompt_str(enum sssctl_prompt_result result)
{
switch (result) {
case SSSCTL_PROMPT_YES:
return _("yes");
case SSSCTL_PROMPT_NO:
return _("no");
case SSSCTL_PROMPT_ERROR:
return _("error");
}

return _("Invalid result.");
}

enum sssctl_prompt_result
sssctl_prompt(const char *message,
enum sssctl_prompt_result defval)
{
char answer[255] = {0};
int c;
const char *yes = sssctl_prompt_str(SSSCTL_PROMPT_YES);
const char *no = sssctl_prompt_str(SSSCTL_PROMPT_NO);
int attempts = 0;
int ret;

do {
if (defval != SSSCTL_PROMPT_ERROR) {
printf("%s (%s/%s) [%s] ", message, yes, no,
sssctl_prompt_str(defval));

/* Detect empty line. */
c = getchar();
if (c == '\n') {
return defval;
} else {
ungetc(c, stdin);
}
} else {
printf("%s (%s/%s)", message, yes, no);
}

ret = scanf("%254s", answer);

/* Clear stdin. */
while ((c = getchar()) != '\n' && c != EOF);

if (ret != 1) {
fprintf(stderr, _("Unable to read user input\n"));
return SSSCTL_PROMPT_ERROR;
}


if (strcasecmp(yes, answer) == 0) {
return SSSCTL_PROMPT_YES;
}

if (strcasecmp(no, answer) == 0) {
return SSSCTL_PROMPT_NO;
}

fprintf(stderr, _("Invalid input, please provide either "
"'%s' or '%s'.\n"), yes, no);

attempts++;
} while (attempts < 3);

return SSSCTL_PROMPT_ERROR;
}

errno_t sssctl_run_command(const char *command)
{
int ret;

DEBUG(SSSDBG_TRACE_FUNC, "Running %s\n", command);

ret = system(command);
if (ret == -1) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to execute %s\n", command);
fprintf(stderr, _("Error while executing external command\n"));
return EFAULT;
} else if (WEXITSTATUS(ret) != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "Command %s failed with [%d]\n",
command, WEXITSTATUS(ret));
fprintf(stderr, _("Error while executing external command\n"));
return EIO;
}

return EOK;
}

static errno_t sssctl_manage_service(enum sssctl_svc_action action)
{
#if defined(HAVE_SYSTEMD) || defined(HAVE_SERVICE)
switch (action) {
case SSSCTL_SVC_START:
return sssctl_run_command(SSSD_SVC_CMD("start"));
case SSSCTL_SVC_STOP:
return sssctl_run_command(SSSD_SVC_CMD("stop"));
case SSSCTL_SVC_RESTART:
return sssctl_run_command(SSSD_SVC_CMD("restart"));
}
#endif

return ENOSYS;
}

bool sssctl_start_sssd(bool force)
{
enum sssctl_prompt_result prompt;
errno_t ret;

if (sss_deamon_running()) {
return true;
}

if (!force) {
prompt = sssctl_prompt(_("SSSD needs to be running. Start SSSD now?"),
SSSCTL_PROMPT_YES);
switch (prompt) {
case SSSCTL_PROMPT_YES:
/* continue */
break;
case SSSCTL_PROMPT_NO:
case SSSCTL_PROMPT_ERROR:
return false;
}
}

ret = sssctl_manage_service(SSSCTL_SVC_START);
switch(ret) {
case EOK:
return true;
case ENOSYS:
fprintf(stderr, "Starting SSSD automatically is not supported "
"on this platform, please start the service "
"manually\n");
return false;
default:
fprintf(stderr, "Unable to start SSSD!\n");
return false;
}

return true;
}

bool sssctl_stop_sssd(bool force)
{
enum sssctl_prompt_result prompt;
errno_t ret;

if (!sss_deamon_running()) {
return true;
}

if (!force) {
prompt = sssctl_prompt(_("SSSD must not be running. Stop SSSD now?"),
SSSCTL_PROMPT_YES);
switch (prompt) {
case SSSCTL_PROMPT_YES:
/* continue */
break;
case SSSCTL_PROMPT_NO:
case SSSCTL_PROMPT_ERROR:
return false;
}
}

ret = sssctl_manage_service(SSSCTL_SVC_STOP);
switch(ret) {
case EOK:
return true;
case ENOSYS:
fprintf(stderr, "Stopping SSSD automatically is not supported "
"on this platform, please stop the service "
"manually\n");
return false;
default:
fprintf(stderr, "Unable to stop SSSD!\n");
return false;
}


return true;
}

bool sssctl_restart_sssd(bool force)
{
enum sssctl_prompt_result prompt;
errno_t ret;

if (!force) {
prompt = sssctl_prompt(_("SSSD needs to be restarted. Restart SSSD now?"),
SSSCTL_PROMPT_YES);
switch (prompt) {
case SSSCTL_PROMPT_YES:
/* continue */
break;
case SSSCTL_PROMPT_NO:
case SSSCTL_PROMPT_ERROR:
return false;
}
}

ret = sssctl_manage_service(SSSCTL_SVC_RESTART);
switch(ret) {
case EOK:
return true;
case ENOSYS:
fprintf(stderr, "Restarting SSSD automatically is not supported "
"on this platform, please restart the service "
"manually\n");
return false;
default:
fprintf(stderr, "Unable to restart SSSD!\n");
return false;
}

return true;
}

int main(int argc, const char **argv)
{
struct sss_route_cmd commands[] = {
SSS_TOOL_DELIMITER("SSSD Status:"),
SSS_TOOL_COMMAND("list-domains", "List available domains", sssctl_list_domains),
SSS_TOOL_COMMAND("domain-status", "Print information about domain", sssctl_domain_status),
SSS_TOOL_DELIMITER("Information about cached content:"),
SSS_TOOL_COMMAND("user", "Information about cached user", sssctl_user),
SSS_TOOL_COMMAND("group", "Information about cached group", sssctl_group),
SSS_TOOL_COMMAND("netgroup", "Information about cached netgroup", sssctl_netgroup),
SSS_TOOL_DELIMITER("Local data tools:"),
SSS_TOOL_COMMAND("backup-local-data", "Backup local data", sssctl_backup_local_data),
SSS_TOOL_COMMAND("restore-local-data", "Restore local data from backup", sssctl_restore_local_data),
SSS_TOOL_COMMAND("remove-cache", "Backup local data and remove cached content", sssctl_remove_cache),
SSS_TOOL_DELIMITER("Log files tools:"),
SSS_TOOL_COMMAND("remove-logs", "Remove existing SSSD log files", sssctl_remove_logs),
SSS_TOOL_COMMAND("fetch-logs", "Archive SSSD log files in tarball", sssctl_fetch_logs),
{NULL, NULL, NULL}
};

return sss_tool_main(argc, argv, commands, NULL);
}
Loading

0 comments on commit e157b9f

Please sign in to comment.