source: web/old/remctl-2.14/server/server-v1.c @ f6f3e91

web
Last change on this file since f6f3e91 was f6f3e91, checked in by Jessica B. Hamrick <jhamrick@…>, 15 years ago

Preserve directory hierarchy (not sure what happened to it)

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/*
2 * Protocol v1, server implementation.
3 *
4 * This is the server implementation of the old v1 protocol, which doesn't
5 * support streaming, keep-alive, or many of the other features of the
6 * current protocol.
7 *
8 * Written by Russ Allbery <rra@stanford.edu>
9 * Based on work by Anton Ushakov
10 * Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
11 *     Board of Trustees, Leland Stanford Jr. University
12 *
13 * See LICENSE for licensing terms.
14 */
15
16#include <config.h>
17#include <portable/system.h>
18#include <portable/gssapi.h>
19#include <portable/socket.h>
20#include <portable/uio.h>
21
22#include <server/internal.h>
23#include <util/util.h>
24
25
26/*
27 * Given the client struct, a buffer of data to send, and the exit status of a
28 * command, send a protocol v1 output token back to the client.  Returns true
29 * on success and false on failure (and logs a message on failure).
30 */
31bool
32server_v1_send_output(struct client *client, int exit_status)
33{
34    gss_buffer_desc token;
35    char *p;
36    OM_uint32 tmp, major, minor;
37    int status;
38
39    /* Allocate room for the total message. */
40    token.length = 4 + 4 + client->outlen;
41    token.value = xmalloc(token.length);
42
43    /* Fill in the token. */
44    p = token.value;
45    tmp = htonl(exit_status);
46    memcpy(p, &tmp, 4);
47    p += 4;
48    tmp = htonl(client->outlen);
49    memcpy(p, &tmp, 4);
50    p += 4;
51    memcpy(p, client->output, client->outlen);
52   
53    /* Send the token. */
54    status = token_send_priv(client->fd, client->context, TOKEN_DATA, &token,
55                             &major, &minor);
56    if (status != TOKEN_OK) {
57        warn_token("sending output token", status, major, minor);
58        free(token.value);
59        return false;
60    }
61    free(token.value);
62    return true;
63}
64
65
66/*
67 * Takes the client struct and the server configuration and handles a client
68 * request.  Reads a command from the client, checks the ACL, runs the command
69 * if appropriate, and sends any output back to the client.
70*/
71void
72server_v1_handle_commands(struct client *client, struct config *config)
73{
74    gss_buffer_desc token;
75    OM_uint32 major, minor;
76    struct iovec **argv = NULL;
77    int status, flags;
78
79    /* Receive the message. */
80    status = token_recv_priv(client->fd, client->context, &flags, &token,
81                             TOKEN_MAX_LENGTH, &major, &minor);
82    if (status != TOKEN_OK) {
83        warn_token("receiving command token", status, major, minor);
84        if (status == TOKEN_FAIL_LARGE)
85            server_send_error(client, ERROR_TOOMUCH_DATA, "Too much data");
86        else if (status != TOKEN_FAIL_EOF)
87            server_send_error(client, ERROR_BAD_TOKEN, "Invalid token");
88        return;
89    }
90
91    /* Check the data size. */
92    if (token.length > TOKEN_MAX_DATA) {
93        warn("command data length %lu exceeds 64KB",
94             (unsigned long) token.length);
95        server_send_error(client, ERROR_TOOMUCH_DATA, "Too much data");
96        gss_release_buffer(&minor, &token);
97        return;
98    }
99
100    /*
101     * Do the shared parsing of the message.  This code is identical to the
102     * code for v2 (v2 just pulls more data off the front of the token first).
103     */
104    argv = server_parse_command(client, token.value, token.length);
105    gss_release_buffer(&minor, &token);
106    if (argv == NULL)
107        return;
108
109    /*
110     * Check the ACL and existence of the command, run the command if
111     * possible, and accumulate the output in the client struct.
112     */
113    server_run_command(client, config, argv);
114    server_free_command(argv);
115}
Note: See TracBrowser for help on using the repository browser.