Code

Merged branch 'master' of git://github.com/sysdb/sysdb.git.
authorSebastian Harl <sh@tokkee.org>
Fri, 27 Feb 2015 17:34:02 +0000 (18:34 +0100)
committerSebastian Harl <sh@tokkee.org>
Fri, 27 Feb 2015 17:34:02 +0000 (18:34 +0100)
12 files changed:
src/frontend/connection.c
src/frontend/query.c
src/include/frontend/connection.h
src/include/frontend/proto.h
src/include/utils/proto.h
src/tools/sysdb/command.c
src/tools/sysdb/command.h
src/tools/sysdb/input.c
src/tools/sysdb/main.c
src/utils/proto.c
t/integration/query.sh
t/integration/test_lib.sh

index 64f2cb2000322dcb83557c932282e0125a797ca2..ebc3b99332d92d0e929f51467edbc549f0088630 100644 (file)
@@ -170,7 +170,18 @@ connection_destroy(sdb_object_t *obj)
                                        "(%zu byte%s left in buffer)", len, len == 1 ? "" : "s");
        }
 
-       sdb_log(SDB_LOG_DEBUG, "frontend: Closing connection %s", obj->name);
+       if (conn->client_addr.ss_family == AF_UNIX) {
+               sdb_log(SDB_LOG_DEBUG, "frontend: Closing connection %s from peer %s",
+                               obj->name, conn->username);
+       }
+       else {
+               char host[1024] = "<unknown>", port[32] = "";
+               getnameinfo((struct sockaddr *)&conn->client_addr,
+                               conn->client_addr_len, host, sizeof(host), port, sizeof(port),
+                               NI_NUMERICHOST | NI_NUMERICSERV);
+               sdb_log(SDB_LOG_DEBUG, "frontend: Closing connection %s from peer %s "
+                               "at %s:%s", obj->name, conn->username, host, port);
+       }
        sdb_connection_close(conn);
 
        if (conn->username)
@@ -284,6 +295,7 @@ command_handle(sdb_conn_t *conn)
                status = sdb_connection_ping(conn);
        else if (conn->cmd == SDB_CONNECTION_STARTUP)
                status = sdb_fe_session_start(conn);
+
        else if (conn->cmd == SDB_CONNECTION_QUERY)
                status = sdb_fe_query(conn);
        else if (conn->cmd == SDB_CONNECTION_FETCH)
@@ -294,6 +306,10 @@ command_handle(sdb_conn_t *conn)
                status = sdb_fe_lookup(conn);
        else if (conn->cmd == SDB_CONNECTION_STORE)
                status = sdb_fe_store(conn);
+
+       else if (conn->cmd == SDB_CONNECTION_SERVER_VERSION)
+               status = sdb_connection_server_version(conn);
+
        else {
                sdb_log(SDB_LOG_WARNING, "frontend: Ignoring invalid command %#x",
                                conn->cmd);
@@ -532,5 +548,20 @@ sdb_connection_ping(sdb_conn_t *conn)
        return 0;
 } /* sdb_connection_ping */
 
+int
+sdb_connection_server_version(sdb_conn_t *conn)
+{
+       char msg[sizeof(uint32_t) + strlen(SDB_VERSION_EXTRA) + 1];
+
+       if ((! conn) || (conn->cmd != SDB_CONNECTION_SERVER_VERSION))
+               return -1;
+
+       sdb_proto_marshal_int32(msg, sizeof(msg), (uint32_t)SDB_VERSION);
+       strncpy(msg + sizeof(uint32_t), SDB_VERSION_EXTRA,
+                       sizeof(msg) - sizeof(uint32_t));
+       sdb_connection_send(conn, SDB_CONNECTION_OK, (uint32_t)sizeof(msg), msg);
+       return 0;
+} /* sdb_connection_server_version */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */
 
index cc107c6ed46f7f1eb38a1ae3efea3ea94d8d4e2a..2c80be76f84f5ee8ca98560cebf293219c238e31 100644 (file)
@@ -312,6 +312,8 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, int type,
                                SDB_STORE_TYPE_TO_NAME(type), hostname, name);
                return -1;
        }
+       if (type == SDB_HOST)
+               name = hostname;
 
        host = sdb_store_get_host(hostname);
        if ((! host) || (filter
@@ -319,6 +321,7 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, int type,
                sdb_strbuf_sprintf(conn->errbuf, "Failed to fetch %s %s: "
                                "host %s not found", SDB_STORE_TYPE_TO_NAME(type),
                                name, hostname);
+               sdb_object_deref(SDB_OBJ(host));
                return -1;
        }
        if (type == SDB_HOST) {
@@ -331,10 +334,14 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, int type,
                        sdb_strbuf_sprintf(conn->errbuf, "Failed to fetch %s %s.%s: "
                                        "%s not found", SDB_STORE_TYPE_TO_NAME(type),
                                        hostname, name, name);
+                       if (obj)
+                               sdb_object_deref(SDB_OBJ(obj));
+                       sdb_object_deref(SDB_OBJ(host));
                        return -1;
                }
                sdb_object_deref(SDB_OBJ(host));
        }
+       host = NULL;
 
        buf = sdb_strbuf_create(1024);
        if (! buf) {
index c4f2bc716a75de34b31e5160cecb12fcc6e19a5b..0397e508d2eeab6f5d0fc58a9d5dbadc4496ec27 100644 (file)
@@ -135,6 +135,17 @@ sdb_connection_send(sdb_conn_t *conn, uint32_t code,
 int
 sdb_connection_ping(sdb_conn_t *conn);
 
+/*
+ * sdb_connection_server_version:
+ * Send back the backend server version to the connected client.
+ *
+ * Returns:
+ *  - 0 on success
+ *  - a negative value else
+ */
+int
+sdb_connection_server_version(sdb_conn_t *conn);
+
 /*
  * sdb_fe_parse:
  * Parse the query text specified in 'query' of length 'len' and return a list
index 833762d76a3644a9237c19ccb9c29f9a26e36f51..ade3a7cb192eaa7fc1ccf0fa5c01c050723c69e8 100644 (file)
@@ -298,6 +298,25 @@ typedef enum {
         * A parsed expression. Only used internally.
         */
        SDB_CONNECTION_EXPR,
+
+       /*
+        * Server status queries.
+        */
+
+       /*
+        * SDB_CONNECTION_SERVER_VERSION:
+        * Retrieve the server version. The server replies with SDB_CONNECTION_OK
+        * on success and the server version as an unsigned 32-bit integer,
+        * optionally followed by a string describing extra version components.
+        * The integer server version is encoded as 100000 * major + 100 * minor +
+        * patch.
+        *
+        * 0               32              64
+        * +---------------+---------------+
+        * | SERVER_VERSION| 0             |
+        * +---------------+---------------+
+        */
+       SDB_CONNECTION_SERVER_VERSION = 1000,
 } sdb_conn_state_t;
 
 #define SDB_CONN_MSGTYPE_TO_STRING(t) \
index b626781f9a1f70652bd0de5fa7a51455ff57c346..56715630524594a71e524932def3f1a01a9f7670 100644 (file)
@@ -91,6 +91,20 @@ ssize_t
 sdb_proto_marshal(char *buf, size_t buf_len, uint32_t code,
                uint32_t msg_len, const char *msg);
 
+/*
+ * sdb_proto_marshal_int32:
+ * Encode the 32-bit integer into the wire format and write it to buf.
+ *
+ * Returns:
+ *  - The number of bytes of the encoded value on success. The function does
+ *    not write more than 'buf_len' bytes. If the output was truncated then
+ *    the return value is the number of bytes which would have been written if
+ *    enough space had been available.
+ *  - a negative value else
+ */
+ssize_t
+sdb_proto_marshal_int32(char *buf, size_t buf_len, uint32_t v);
+
 /*
  * sdb_proto_marshal_data:
  * Encode a datum into the wire format and write it to buf.
index 440ba41e3b13832574ff0ca42472315023cd7f07..c7ca310a086230268272b46dcb7c268733b106b8 100644 (file)
@@ -215,5 +215,25 @@ sdb_command_exec(sdb_input_t *input)
        return data;
 } /* sdb_command_exec */
 
+void
+sdb_command_print_server_version(sdb_input_t *input)
+{
+       sdb_strbuf_t *buf = sdb_strbuf_create(32);
+       uint32_t code = 0, version = 0;
+       const char *extra;
+
+       if ((sdb_client_rpc(input->client, SDB_CONNECTION_SERVER_VERSION,
+                                       0, NULL, &code, buf) < 0) || (code != SDB_CONNECTION_OK))
+               return;
+       if (sdb_strbuf_len(buf) < sizeof(version))
+               return;
+
+       sdb_proto_unmarshal_int32(SDB_STRBUF_STR(buf), &version);
+       extra = sdb_strbuf_string(buf) + sizeof(version);
+       sdb_log(SDB_LOG_INFO, "SysDB server %d.%d.%d%s",
+                       SDB_VERSION_DECODE((int)version), extra);
+       sdb_strbuf_destroy(buf);
+} /* sdb_command_print_server_version */
+
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */
 
index bd9833828167de802c063c28e0878efdf06e3bf1..04ad5e156a7cd87992a9c8691adc2414eb4fe013 100644 (file)
@@ -58,6 +58,13 @@ sdb_command_print_reply(sdb_client_t *client);
 char *
 sdb_command_exec(sdb_input_t *input);
 
+/*
+ * sdb_command_print_server_version:
+ * Query and print the server version.
+ */
+void
+sdb_command_print_server_version(sdb_input_t *input);
+
 #endif /* SYSDB_COMMAND_H */
 
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */
index 0b0dbf719c20fee8acbd29218530d4d51838430c..f0f86ea2a9bff1e264013bf39c3ab31758919c63 100644 (file)
@@ -329,6 +329,7 @@ sdb_input_reconnect(void)
                return -1;
        }
        sdb_log(SDB_LOG_INFO, "Successfully reconnected to SysDBd");
+       sdb_command_print_server_version(sysdb_input);
        return 0;
 } /* sdb_input_reconnect */
 
index 792faf9d93a7ff62d407b23320729e35c83cd6d7..e4922e9b939587c914fd7d28ef172ce0fa4a59fb 100644 (file)
@@ -330,8 +330,10 @@ main(int argc, char **argv)
        }
 
        sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING
-                       SDB_CLIENT_VERSION_EXTRA" (libsysdbclient %s%s)\n",
+                       SDB_CLIENT_VERSION_EXTRA" (libsysdbclient %s%s)",
                        sdb_client_version_string(), sdb_client_version_extra());
+       sdb_command_print_server_version(&input);
+       printf("\n");
 
        using_history();
 
index 13d91293d20a7c91da012c10e978c3295d8b4129..af47cdf11d51673684808bc206af14524dbec370 100644 (file)
@@ -80,16 +80,6 @@ memdup(const unsigned char *d, size_t length)
  * return the number of bytes that would have been written if enough space had
  * been available. */
 
-static ssize_t
-marshal_int32(char *buf, size_t buf_len, uint32_t v)
-{
-       if (buf_len >= sizeof(v)) {
-               v = htonl(v);
-               memcpy(buf, &v, sizeof(v));
-       }
-       return sizeof(v);
-} /* marshal_int32 */
-
 static ssize_t
 marshal_int64(char *buf, size_t buf_len, int64_t v)
 {
@@ -229,7 +219,7 @@ marshal_obj_header(char *buf, size_t buf_len,
        if (buf_len < OBJ_HEADER_LEN)
                return OBJ_HEADER_LEN;
 
-       n = marshal_int32(buf, buf_len, (uint32_t)type);
+       n = sdb_proto_marshal_int32(buf, buf_len, (uint32_t)type);
        buf += n; buf_len -= n;
        marshal_datetime(buf, buf_len, last_update);
        return OBJ_HEADER_LEN;
@@ -277,6 +267,16 @@ sdb_proto_marshal(char *buf, size_t buf_len, uint32_t code,
        return len;
 } /* sdb_proto_marshal */
 
+ssize_t
+sdb_proto_marshal_int32(char *buf, size_t buf_len, uint32_t v)
+{
+       if (buf_len >= sizeof(v)) {
+               v = htonl(v);
+               memcpy(buf, &v, sizeof(v));
+       }
+       return sizeof(v);
+} /* sdb_proto_marshal_int32 */
+
 ssize_t
 sdb_proto_marshal_data(char *buf, size_t buf_len, const sdb_data_t *datum)
 {
index c9b21b6063d001ae29bd92d302259dc41671c043..72a0b88426adae7496deee4c9b4d8f6d7e845c02 100755 (executable)
@@ -125,6 +125,10 @@ echo "$output" | grep -F 'not found'
 (echo 'LIST hosts;'; sleep 1; echo "FETCH host 'host1.example.com'") \
        | run_sysdb -H "$SOCKET_FILE"
 
+output="$( run_sysdb -H "$SOCKET_FILE" \
+       -c "FETCH host 'host1.example.com' FILTER age < 0" 2>&1 )" && exit 1
+echo "$output" | grep -F 'not found'
+
 # When requesting information for unknown hosts, expect a non-zero exit code.
 output="$( run_sysdb -H "$SOCKET_FILE" \
        -c "FETCH host 'does.not.exist'" 2>&1 )" && exit 1
index e3a2092b2ee3d2a74701b460cd3e3137e8e35a98..1fb3324ca332081fddc9dac43392913cad21e966 100644 (file)
@@ -137,7 +137,8 @@ function setup_ssl() {
        openssl req -batch -subj '/CN=localhost' \
                -new -out "${SERVER_CERT}.csr" -key "$SERVER_KEY"
        openssl x509 -req -in "${SERVER_CERT}.csr" -out "$SERVER_CERT" -days 1 \
-               -CAkey "$CA_KEY" -CA "$CA_CERT" -CAcreateserial -CAserial serial
+               -CAkey "$CA_KEY" -CA "$CA_CERT" -CAcreateserial \
+               -CAserial ${TESTDIR}/serial
 
        CLIENT_KEY="$TESTDIR/client.key"
        CLIENT_CERT="$TESTDIR/client.cert"
@@ -145,7 +146,8 @@ function setup_ssl() {
        openssl req -batch -subj "/CN=$SYSDB_USER" \
                -new -out "${CLIENT_CERT}.csr" -key "$CLIENT_KEY"
        openssl x509 -req -in "${CLIENT_CERT}.csr" -out "$CLIENT_CERT" -days 1 \
-               -CAkey "$CA_KEY" -CA "$CA_CERT" -CAcreateserial -CAserial serial
+               -CAkey "$CA_KEY" -CA "$CA_CERT" -CAcreateserial \
+               -CAserial ${TESTDIR}/serial
 }
 
 # vim: set tw=78 sw=4 ts=4 noexpandtab :