X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ftools%2Fsysdb%2Fmain.c;h=a8dbf27fa55a7e0315d4fa95c88383cd957d5695;hb=960ba9b7b50bb2aff0bc1dbe02cccc89bb0a8b4a;hp=1174fa9fa0462ddb13603456b7de2bba19a4d33e;hpb=8c58d65dec8e046ec1d8b26eb1a6d913b971e5be;p=sysdb.git diff --git a/src/tools/sysdb/main.c b/src/tools/sysdb/main.c index 1174fa9..a8dbf27 100644 --- a/src/tools/sysdb/main.c +++ b/src/tools/sysdb/main.c @@ -37,6 +37,7 @@ #include "utils/error.h" #include "utils/llist.h" #include "utils/strbuf.h" +#include "utils/os.h" #include @@ -76,66 +77,46 @@ # endif #endif /* READLINEs */ +#include +#include + #ifndef DEFAULT_SOCKET # define DEFAULT_SOCKET "unix:"LOCALSTATEDIR"/run/sysdbd.sock" #endif -static const char * -get_current_user(void) -{ - struct passwd pw_entry; - struct passwd *result = NULL; - - uid_t uid; - - /* needs to be static because we return a pointer into this buffer - * to the caller */ - static char buf[1024]; +static sdb_ssl_options_t ssl_options = { + /* ca_file */ SDB_SSL_CAFILE, + /* key_file */ "~/.config/sysdb/ssl/key.pem", + /* cert_file */ "~/.config/sysdb/ssl/cert.pem", + /* crl_file */ "~/.config/sysdb/ssl/crl.pem", +}; - int status; - - uid = geteuid(); - - memset(&pw_entry, 0, sizeof(pw_entry)); - status = getpwuid_r(uid, &pw_entry, buf, sizeof(buf), &result); - - if (status || (! result)) { - char errbuf[1024]; - sdb_log(SDB_LOG_ERR, "Failed to determine current username: %s", - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return NULL; - } - return result->pw_name; -} /* get_current_user */ - -static const char * -get_homedir(const char *username) +static void +canonicalize_ssl_options(void) { - struct passwd pw_entry; - struct passwd *result = NULL; - - /* needs to be static because we return a pointer into this buffer - * to the caller */ - static char buf[1024]; - - int status; - - memset(&pw_entry, 0, sizeof(pw_entry)); - status = getpwnam_r(username, &pw_entry, buf, sizeof(buf), &result); - - if (status || (! result)) { - char errbuf[1024]; - sdb_log(SDB_LOG_WARNING, "Failed to determine home directory " - "for user %s: %s", username, - sdb_strerror(errno, errbuf, sizeof(errbuf))); - return NULL; + char *tmp; + if (ssl_options.ca_file) { + tmp = sdb_realpath(ssl_options.ca_file); + ssl_options.ca_file = tmp ? tmp : strdup(ssl_options.ca_file); + } + if (ssl_options.key_file) { + tmp = sdb_realpath(ssl_options.key_file); + ssl_options.key_file = tmp ? tmp : strdup(ssl_options.key_file); } - return result->pw_dir; -} /* get_homedir */ + if (ssl_options.cert_file) { + tmp = sdb_realpath(ssl_options.cert_file); + ssl_options.cert_file = tmp ? tmp : strdup(ssl_options.cert_file); + } + if (ssl_options.crl_file) { + tmp = sdb_realpath(ssl_options.crl_file); + ssl_options.crl_file = tmp ? tmp : strdup(ssl_options.crl_file); + } +} /* canonicalize_ssl_options */ static void exit_usage(char *name, int status) { + char *user = sdb_get_current_user(); printf( "Usage: %s \n" @@ -150,7 +131,8 @@ exit_usage(char *name, int status) " -V display the version number and copyright\n" "\nSysDB client "SDB_CLIENT_VERSION_STRING SDB_CLIENT_VERSION_EXTRA", " -PACKAGE_URL"\n", basename(name), get_current_user()); +PACKAGE_URL"\n", basename(name), user); + free(user); exit(status); } /* exit_usage */ @@ -185,7 +167,7 @@ execute_commands(sdb_client_t *client, sdb_llist_t *commands) while (sdb_llist_iter_has_next(iter)) { sdb_object_t *obj = sdb_llist_iter_get_next(iter); - if (sdb_client_send(client, CONNECTION_QUERY, + if (sdb_client_send(client, SDB_CONNECTION_QUERY, (uint32_t)strlen(obj->name), obj->name) <= 0) { sdb_log(SDB_LOG_ERR, "Failed to send command '%s' to server", obj->name); @@ -194,7 +176,7 @@ execute_commands(sdb_client_t *client, sdb_llist_t *commands) } /* Wait for server replies. We might get any number of log messages - * but eventually see the reply to the query, which is either OK or + * but eventually see the reply to the query, which is either DATA or * ERROR. */ while (42) { status = sdb_command_print_reply(client); @@ -203,12 +185,20 @@ execute_commands(sdb_client_t *client, sdb_llist_t *commands) break; } - if ((status == CONNECTION_OK) || (status == CONNECTION_ERROR)) + if ((status == SDB_CONNECTION_DATA) + || (status == SDB_CONNECTION_ERROR)) break; + if (status == SDB_CONNECTION_OK) { + /* pre 0.4 versions used OK instead of DATA */ + sdb_log(SDB_LOG_WARNING, "Received unexpected OK status from " + "server in response to a QUERY (expected DATA); " + "assuming we're talking to an old server"); + break; + } } - if (status) - break; + if ((status != SDB_CONNECTION_OK) && (status != SDB_CONNECTION_DATA)) + break; /* error */ } sdb_llist_iter_destroy(iter); @@ -219,9 +209,8 @@ int main(int argc, char **argv) { const char *host = NULL; - const char *user = NULL; - const char *homedir; + char *homedir; char hist_file[1024] = ""; sdb_input_t input = SDB_INPUT_INIT; @@ -238,7 +227,7 @@ main(int argc, char **argv) host = optarg; break; case 'U': - user = optarg; + input.user = optarg; break; case 'c': @@ -281,39 +270,57 @@ main(int argc, char **argv) if (! host) host = DEFAULT_SOCKET; - if (! user) { - user = get_current_user(); - if (! user) - exit(1); - } + if (! input.user) + input.user = sdb_get_current_user(); + else + input.user = strdup(input.user); + if (! input.user) + exit(1); + + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); input.client = sdb_client_create(host); if (! input.client) { sdb_log(SDB_LOG_ERR, "Failed to create client object"); + sdb_input_reset(&input); + exit(1); + } + canonicalize_ssl_options(); + if (sdb_client_set_ssl_options(input.client, &ssl_options)) { + sdb_log(SDB_LOG_ERR, "Failed to apply SSL options"); + sdb_input_reset(&input); + sdb_ssl_free_options(&ssl_options); exit(1); } - if (sdb_client_connect(input.client, user)) { + sdb_ssl_free_options(&ssl_options); + if (sdb_client_connect(input.client, input.user)) { sdb_log(SDB_LOG_ERR, "Failed to connect to SysDBd"); - sdb_client_destroy(input.client); + sdb_input_reset(&input); exit(1); } if (commands) { int status = execute_commands(input.client, commands); sdb_llist_destroy(commands); - sdb_client_destroy(input.client); - exit(status); + sdb_input_reset(&input); + if ((status != SDB_CONNECTION_OK) && (status != SDB_CONNECTION_DATA)) + exit(1); + exit(0); } sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING - SDB_CLIENT_VERSION_EXTRA"\n"); + SDB_CLIENT_VERSION_EXTRA" (libsysdbclient %s%s)\n", + sdb_client_version_string(), sdb_client_version_extra()); using_history(); - if ((homedir = get_homedir(user))) { + if ((homedir = sdb_get_homedir())) { snprintf(hist_file, sizeof(hist_file) - 1, "%s/.sysdb_history", homedir); hist_file[sizeof(hist_file) - 1] = '\0'; + free(homedir); + homedir = NULL; errno = 0; if (read_history(hist_file) && (errno != ENOENT)) { @@ -327,6 +334,12 @@ main(int argc, char **argv) sdb_input_init(&input); sdb_input_mainloop(); + sdb_client_shutdown(input.client, SHUT_WR); + while (! sdb_client_eof(input.client)) { + /* wait for remaining data to arrive */ + sdb_command_print_reply(input.client); + } + if (hist_file[0] != '\0') { errno = 0; if (write_history(hist_file)) { @@ -336,8 +349,9 @@ main(int argc, char **argv) } } - sdb_client_destroy(input.client); - sdb_strbuf_destroy(input.input); + sdb_input_reset(&input); + + ERR_free_strings(); return 0; } /* main */