284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina Pavel Březina <pbrezina@redhat.com>
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina Copyright (C) 2015 Red Hat
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina This program is free software; you can redistribute it and/or modify
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina it under the terms of the GNU General Public License as published by
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina the Free Software Foundation; either version 3 of the License, or
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina (at your option) any later version.
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina This program is distributed in the hope that it will be useful,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina GNU General Public License for more details.
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina You should have received a copy of the GNU General Public License
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
81cde110402e088508053aea79670b38d450cb83Pavel Březinastatic void sss_tool_print_common_opts(int min_len)
81cde110402e088508053aea79670b38d450cb83Pavel Březina fprintf(stderr, " %-*s\t %s\n", min_len, "--debug=INT",
a6cd927f298ff5c9a603db5acb6c1b0ebea178c0Pavel Březina _("The debug level to run with"));
81cde110402e088508053aea79670b38d450cb83Pavel Březina fprintf(stderr, " %-*s\t %s\n", min_len, "-?, --help",
b963ed8079a4a284611d50d1b79695116c40295dPavel Březina _("Show this for a command"));
81cde110402e088508053aea79670b38d450cb83Pavel Březina fprintf(stderr, " %-*s\t %s\n", min_len, "--usage",
b963ed8079a4a284611d50d1b79695116c40295dPavel Březina _("Show brief usage message for a command"));
bda8039465a0084fb380e878c8f9ea3e900505eaPavel Březinastatic struct poptOption *sss_tool_common_opts_table(void)
bda8039465a0084fb380e878c8f9ea3e900505eaPavel Březina common_opts[0].descrip = _("The debug level to run with");
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březinastatic void sss_tool_common_opts(struct sss_tool_ctx *tool_ctx,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina {"debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_STRIP, &debug,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina pc = poptGetContext(argv[0], orig_argc, argv, options, 0);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* do nothing */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* Strip common options from arguments. We will discard_const here,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina * since it is not worth the trouble to convert it back and forth. */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina *argc = poptStrippedArgv(pc, orig_argc, discard_const_p(char *, argv));
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březinastatic errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina path = talloc_asprintf(mem_ctx, "%s/%s", DB_PATH, CONFDB_FILE);
d2d8f342cd5e90bb9fd947c448492225f959aa86Pavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Unable to setup ConfDB [%d]: %s\n",
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březinastatic errno_t sss_tool_domains_init(TALLOC_CTX *mem_ctx,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n",
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina "Could not initialize connection to the sysdb\n");
3a8b5ccf7c27b72054e1d8b3ab355cb1e28efda9Sumit Bose /* Get flat name and domain ID (SID) from the cache
3a8b5ccf7c27b72054e1d8b3ab355cb1e28efda9Sumit Bose * if available */
3a8b5ccf7c27b72054e1d8b3ab355cb1e28efda9Sumit Bose DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update domain %s.\n",
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* Update list of subdomains for this domain */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina "Failed to update subdomains for domain %s.\n",
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina ret = sss_names_init(mem_ctx, confdb, dom->name, &dom->names);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n");
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina tool_ctx = talloc_zero(mem_ctx, struct sss_tool_ctx);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n");
b03ccb2764a4ccdadb77599cb624b6a17b633438Pavel Březinastatic bool sss_tool_is_delimiter(struct sss_route_cmd *command)
b03ccb2764a4ccdadb77599cb624b6a17b633438Pavel Březina if (command->command != NULL && command->command[0] == '\0') {
b03ccb2764a4ccdadb77599cb624b6a17b633438Pavel Březina return false;
a0b824ac01c6b58fe6055d48aa6e29e94219646dJakub Hrozekstatic bool sss_tools_handles_init_error(struct sss_route_cmd *command,
a0b824ac01c6b58fe6055d48aa6e29e94219646dJakub Hrozek return true;
81cde110402e088508053aea79670b38d450cb83Pavel Březinastatic size_t sss_tool_max_length(struct sss_route_cmd *commands)
81cde110402e088508053aea79670b38d450cb83Pavel Březina for (i = 0; commands[i].command != NULL; i++) {
e98ccef2609811186711b79d8ef5d0a4450ab6e0Pavel Březinavoid sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands)
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina fprintf(stderr, _("Usage:\n%s COMMAND COMMAND-ARGS\n\n"), tool_name);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina for (i = 0; commands[i].command != NULL; i++) {
b03ccb2764a4ccdadb77599cb624b6a17b633438Pavel Březina fprintf(stderr, "\n%s\n", commands[i].description);
81cde110402e088508053aea79670b38d450cb83Pavel Březina fprintf(stderr, "* %40s\n", commands[i].command);
81cde110402e088508053aea79670b38d450cb83Pavel Březina min_len, commands[i].command, commands[i].description);
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židekstatic int tool_cmd_init(struct sss_tool_ctx *tool_ctx,
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek if (command->flags & SSS_TOOL_FLAG_SKIP_CMD_INIT) {
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek /* Connect to confdb. */
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek ret = sss_tool_confdb_init(tool_ctx, &tool_ctx->confdb);
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open confdb [%d]: %s\n",
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek /* Setup domains. */
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek ret = sss_tool_domains_init(tool_ctx, tool_ctx->confdb, &tool_ctx->domains);
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n",
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek ret = confdb_get_string(tool_ctx->confdb, tool_ctx,
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek DEBUG(SSSDBG_OP_FAILURE, "Cannot get the default domain [%d]: %s\n",
e98ccef2609811186711b79d8ef5d0a4450ab6e0Pavel Březinaerrno_t sss_tool_route(int argc, const char **argv,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Bug: commands can't be NULL!\n");
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina for (i = 0; commands[i].command != NULL; i++) {
a0b824ac01c6b58fe6055d48aa6e29e94219646dJakub Hrozek if (!sss_tools_handles_init_error(&commands[i], tool_ctx->init_err)) {
a0b824ac01c6b58fe6055d48aa6e29e94219646dJakub Hrozek "Command %s does not handle initialization error [%d] %s\n",
cbee11e912bb391ba254b0bac8c1159c1f634533Michal Židek "Command initialization failed [%d] %s\n",
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina return commands[i].fn(&cmdline, tool_ctx, pvt);
16065cc731687eb8779d31b79436bbf79c5e3ed3Pavel Březinastatic struct poptOption *nonnull_popt_table(struct poptOption *options)
e98ccef2609811186711b79d8ef5d0a4450ab6e0Pavel Březinaerrno_t sss_tool_popt_ex(struct sss_cmdline *cmdline,
e98ccef2609811186711b79d8ef5d0a4450ab6e0Pavel Březina const char **_fopt,
16065cc731687eb8779d31b79436bbf79c5e3ed3Pavel Březina {NULL, '\0', POPT_ARG_INCLUDE_TABLE, nonnull_popt_table(options), \
bda8039465a0084fb380e878c8f9ea3e900505eaPavel Březina {NULL, '\0', POPT_ARG_INCLUDE_TABLE, sss_tool_common_opts_table(), \
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* Create help option string. We always need to append command name since
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina * we use POPT_CONTEXT_KEEP_FIRST. */
bda8039465a0084fb380e878c8f9ea3e900505eaPavel Březina help = talloc_asprintf(NULL, "%s %s %s", cmdline->exec,
bda8039465a0084fb380e878c8f9ea3e900505eaPavel Březina help = talloc_asprintf(NULL, "%s %s %s %s", cmdline->exec,
bda8039465a0084fb380e878c8f9ea3e900505eaPavel Březina cmdline->command, fopt_name, _("[OPTIONS...]"));
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* Create popt context. This function is supposed to be called on
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina * command argv which does not contain executable (argv[0]), therefore
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina * we need to use KEEP_FIRST that ensures argv[0] is also processed. */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina pc = poptGetContext(cmdline->exec, cmdline->argc, cmdline->argv,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* Parse options. Invoke custom function if provided. If no parsing
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina * function is provided, print error on unknown option. */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina fprintf(stderr, _("Invalid option %s: %s\n\n"),
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* Parse free option which is always required if requested. */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina fprintf(stderr, _("Missing option: %s\n\n"), fopt_help);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina /* No more arguments expected. If something follows it is an error. */
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina fprintf(stderr, _("Only one free argument is expected!\n\n"));
4940ba14100ad11b0ed1f2a8a4fea5daa34d56eePavel Březina /* Unexpected free argument. */
4940ba14100ad11b0ed1f2a8a4fea5daa34d56eePavel Březina fprintf(stderr, _("Unexpected parameter: %s\n\n"), fopt);
3bc651a611a3e5be508875f3ae58bfb5ece2525cPavel Březina if ((_fopt != NULL && cmdline->argc < 2) || cmdline->argc < 1) {
3bc651a611a3e5be508875f3ae58bfb5ece2525cPavel Březina /* If at least one option is required and not provided, print error. */
3bc651a611a3e5be508875f3ae58bfb5ece2525cPavel Březina if (require_option == SSS_TOOL_OPT_REQUIRED) {
3bc651a611a3e5be508875f3ae58bfb5ece2525cPavel Březina fprintf(stderr, _("At least one option is required!\n\n"));
e98ccef2609811186711b79d8ef5d0a4450ab6e0Pavel Březinaerrno_t sss_tool_popt(struct sss_cmdline *cmdline,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina return sss_tool_popt_ex(cmdline, options, require_option,
3bc651a611a3e5be508875f3ae58bfb5ece2525cPavel Březina popt_fn, popt_fn_pvt, NULL, NULL, NULL, NULL);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Running under %d, must be root\n", uid);
a0b824ac01c6b58fe6055d48aa6e29e94219646dJakub Hrozek ret = sss_tool_init(NULL, &argc, argv, &tool_ctx);
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tool context\n");
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina ret = sss_tool_route(argc, argv, tool_ctx, commands, pvt);
e98ccef2609811186711b79d8ef5d0a4450ab6e0Pavel Březinaerrno_t sss_tool_parse_name(TALLOC_CTX *mem_ctx,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina ret = sss_parse_name_for_domains(mem_ctx, tool_ctx->domains,
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find domain. The domain name may "
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina "be a subdomain that was not yet found.\n");
284937e6b5b0c9d7a1d3382d0d2820d1168842fbPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name [%d]: %s\n",