]> mj.ucw.cz Git - eval.git/blob - submit/commands.c
dc71e3039e61a700f299130bbcd5e404437613fe
[eval.git] / submit / commands.c
1 /*
2  *  The Submit Daemon: Processing of Commands
3  *
4  *  (c) 2007 Martin Mares <mj@ucw.cz>
5  */
6
7 #include "lib/lib.h"
8 #include "lib/mempool.h"
9 #include "lib/stkstring.h"
10 #include "sherlock/object.h"
11 #include "sherlock/objread.h"
12
13 #include <sys/stat.h>
14
15 #include "submitd.h"
16
17 static void NONRET
18 read_error_cb(struct obj_read_state *st UNUSED, byte *msg)
19 {
20   client_error("Request parse error: %s", msg);
21 }
22
23 static int
24 read_request(struct conn *c)
25 {
26   if (c->pool)
27     mp_flush(c->pool);
28   else
29     c->pool = mp_new(1024);
30   c->request = obj_new(c->pool);
31   c->reply = obj_new(c->pool);
32
33   struct obj_read_state st;
34   obj_read_start(&st, c->request);
35   st.error_callback = read_error_cb;
36   byte line[1024];
37   uns size = 0;
38   for (;;)
39     {
40       int l = bgets_nodie(&c->rx_fb, line, sizeof(line));
41       if (l < 0)
42         client_error("Request line too long");
43       if (!l)
44         {
45           if (!size)
46             return 0;
47           else
48             client_error("Truncated request");
49         }
50       if (l == 1)
51         break;
52       size += l;
53       if (size >= max_request_size)
54         client_error("Request too long");
55       obj_read_attr(&st, line[0], line+1);
56     }
57   obj_read_end(&st);
58   return 1;
59 }
60
61 static void
62 write_reply(struct conn *c)
63 {
64   if (trace_commands)
65     {
66       byte *msg;
67       if (msg = obj_find_aval(c->reply, '-'))
68         log(L_DEBUG, ">> -%s", msg);
69       else if (msg = obj_find_aval(c->reply, '+'))
70         log(L_DEBUG, ">> +%s", msg);
71       else
72         log(L_DEBUG, ">> ???");
73     }
74   put_attr_set_type(BUCKET_TYPE_PLAIN);
75   bput_object(&c->tx_fb, c->reply);
76   bputc(&c->tx_fb, '\n');
77   bflush(&c->tx_fb);
78 }
79
80 static void
81 execute_command(struct conn *c)
82 {
83   byte *cmd = obj_find_aval(c->request, '!');
84   if (!cmd)
85     {
86       obj_set_attr(c->reply, '-', "Missing command");
87       return;
88     }
89   if (trace_commands)
90     log(L_DEBUG, "<< %s", cmd);
91   obj_set_attr(c->reply, '-', "Unknown command");
92 }
93
94 int
95 process_command(struct conn *c)
96 {
97   if (!read_request(c))
98     return 0;
99   execute_command(c);
100   write_reply(c);
101   return 1;
102 }
103
104 static int
105 user_exists_p(byte *user)
106 {
107   byte *fn = stk_printf("solutions/%s/status", user);
108   struct stat st;
109   return !stat(fn, &st) && S_ISREG(st.st_mode);
110 }
111
112 static void
113 execute_init(struct conn *c)
114 {
115   byte *user = obj_find_aval(c->request, 'U');
116   if (!user)
117     {
118       obj_set_attr(c->reply, '-', "Missing user");
119       return;
120     }
121   if (!c->cert_name ||
122       !strcmp(user, c->cert_name) ||
123       c->rule->allow_admin && !strcmp(c->cert_name, "admin"))
124     {
125       if (!user_exists_p(user))
126         {
127           obj_set_attr(c->reply, '-', "Unknown user");
128           return;
129         }
130       log(L_INFO, "Logged in %s", user);
131     }
132   else
133     {
134       obj_set_attr(c->reply, '-', "Permission denied");
135       log(L_ERROR, "Unauthorized attempt to log in as %s", user);
136       return;
137     }
138   obj_set_attr(c->reply, '+', "OK");
139 }
140
141 int
142 process_init(struct conn *c)
143 {
144   if (!read_request(c))
145     return 0;
146   execute_init(c);
147   write_reply(c);
148   return !!obj_find_attr(c->reply, '+');
149 }