aboutsummaryrefslogtreecommitdiff
path: root/src/ctl.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 12:50:28 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 12:50:28 +0200
commit8334b598f85317eb4d44000f6ec580c54734b15d (patch)
tree04dd1b84443287aec625ab019b02fc170ae524a1 /src/ctl.c
parent8426fc4411c9679a10863d7aa3ced077155e0016 (diff)
downloadpies-8334b598f85317eb4d44000f6ec580c54734b15d.tar.gz
pies-8334b598f85317eb4d44000f6ec580c54734b15d.tar.bz2
Implement user privileges
* src/pies.h (component): New members: list_acl and adm_acl. (control): Removed id_acl. New members: adm_acl and usr_acl. * src/pies.c (component_keywords): New keywords list-acl and admin-acl. Removed identity-acl. * ident/ident.c (pies_identity_user_name): New function. * ident/identity.h (pies_identity_user_name): New proto. * src/ctl.c (CTL_USER_STATE,CTL_ADMIN_STATE): New states. (cmdtab): Mark administrative commands as valid in CTL_ADMIN_STATE (ctlio_create): Assume CTL_ADMIN_STATE in the absense of identity providers. (auth_data): New struct. (cmd_auth): Select appropriate state depending on the user permissions. (list_matches): New function. (eval_env): Keep the list of selected progs. (count_prog): Removed. (selector): New function. (cmd_list): Rewrite to take into account access rights. (cmd_start,cmd_stop) (cmd_restart): Only allowed for users with administrative privileges.
Diffstat (limited to 'src/ctl.c')
-rw-r--r--src/ctl.c291
1 files changed, 198 insertions, 93 deletions
diff --git a/src/ctl.c b/src/ctl.c
index 20c16e1..f422e4b 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -104,8 +104,11 @@ ctlbuf_chomp (struct ctlbuf *buf)
104 104
105#define CTL_END_STATE 0 105#define CTL_END_STATE 0
106#define CTL_INITIAL_STATE 0x01 106#define CTL_INITIAL_STATE 0x01
107#define CTL_AUTHENTICATED_STATE 0x02 107#define CTL_USER_STATE 0x02
108#define CTL_ACTION_STATE 0x04 108#define CTL_ADMIN_STATE 0x04
109#define CTL_ACTION_STATE 0x08
110
111#define CTL_AUTHENTICATED_STATE (CTL_USER_STATE|CTL_ADMIN_STATE)
109#define CTL_ALL_STATES (CTL_INITIAL_STATE|CTL_AUTHENTICATED_STATE) 112#define CTL_ALL_STATES (CTL_INITIAL_STATE|CTL_AUTHENTICATED_STATE)
110 113
111struct ctlio; 114struct ctlio;
@@ -152,9 +155,9 @@ static struct ctlio_command cmdtab[] = {
152 { "restart", "restart component", 155 { "restart", "restart component",
153 CTL_AUTHENTICATED_STATE, 2, 2, cmd_restart }, 156 CTL_AUTHENTICATED_STATE, 2, 2, cmd_restart },
154 { "reboot", "restart pies", 157 { "reboot", "restart pies",
155 CTL_AUTHENTICATED_STATE, 1, 1, cmd_reboot }, 158 CTL_ADMIN_STATE, 1, 1, cmd_reboot },
156 { "shutdown", "stop pies", 159 { "shutdown", "stop pies",
157 CTL_AUTHENTICATED_STATE, 1, 1, cmd_shutdown }, 160 CTL_ADMIN_STATE, 1, 1, cmd_shutdown },
158 { NULL } 161 { NULL }
159}; 162};
160 163
@@ -190,7 +193,7 @@ ctlio_create (void)
190 193
191 io = xmalloc (sizeof (*io)); 194 io = xmalloc (sizeof (*io));
192 io->state = identity_provider_list 195 io->state = identity_provider_list
193 ? CTL_INITIAL_STATE : CTL_AUTHENTICATED_STATE; 196 ? CTL_INITIAL_STATE : CTL_ADMIN_STATE;
194 io->action = ACTION_CONT; 197 io->action = ACTION_CONT;
195 ctlbuf_init (&io->ibuf); 198 ctlbuf_init (&io->ibuf);
196 ctlbuf_init (&io->obuf); 199 ctlbuf_init (&io->obuf);
@@ -321,12 +324,42 @@ ctlio_initial_reply (struct ctlio *io)
321 ctlio_eol (io); 324 ctlio_eol (io);
322} 325}
323 326
327struct auth_data
328{
329 union pies_sockaddr_storage addr;
330 socklen_t addrlen;
331 pies_identity_t id;
332 struct component const *comp;
333};
334
335static int
336try_auth (struct prog *prog, void *data)
337{
338 struct auth_data *auth = data;
339 if (IS_COMPONENT (prog))
340 {
341 if ((prog->v.p.comp->adm_acl
342 && check_acl (prog->v.p.comp->adm_acl,
343 (struct sockaddr *)&auth->addr, auth->addrlen,
344 auth->id) == 0)
345 || (prog->v.p.comp->list_acl
346 && check_acl (prog->v.p.comp->list_acl,
347 (struct sockaddr *)&auth->addr, auth->addrlen,
348 auth->id) == 0))
349 {
350 auth->comp = prog->v.p.comp;
351 return 1;
352 }
353 }
354 return 0;
355}
356
324static void 357static void
325cmd_auth (struct ctlio *io, size_t argc, char **argv) 358cmd_auth (struct ctlio *io, size_t argc, char **argv)
326{ 359{
327 struct grecs_list_entry *ep; 360 struct grecs_list_entry *ep;
328 pies_identity_t id = pies_identity_create (argv[1]); 361 pies_identity_t id = pies_identity_create (argv[1]);
329 int auth = 0; 362 int new_state = CTL_INITIAL_STATE;
330 363
331 for (ep = identity_provider_list->head; ep; ep = ep->next) 364 for (ep = identity_provider_list->head; ep; ep = ep->next)
332 { 365 {
@@ -336,33 +369,54 @@ cmd_auth (struct ctlio *io, size_t argc, char **argv)
336 debug(1, ("trying %s...", pname)); 369 debug(1, ("trying %s...", pname));
337 if (pies_authenticate (provider, id, argv[2]) == 0) 370 if (pies_authenticate (provider, id, argv[2]) == 0)
338 { 371 {
339 if (check_acl (control.id_acl, 372 if (control.adm_acl
340 (struct sockaddr *)&io->addr, io->addrlen, id)) 373 && check_acl (control.adm_acl,
374 (struct sockaddr *)&io->addr, io->addrlen,
375 id) == 0)
341 { 376 {
342 logmsg (LOG_AUTH, "%s authenticated via %s, but failed ACL check", 377 new_state = CTL_ADMIN_STATE;
378 logmsg (LOG_AUTH, "%s granted admin access via %s",
343 argv[1], pname); 379 argv[1], pname);
344 auth = 0;
345 } 380 }
346 else 381 else if (control.usr_acl
382 && check_acl (control.usr_acl,
383 (struct sockaddr *)&io->addr, io->addrlen,
384 id) == 0)
347 { 385 {
386 new_state = CTL_USER_STATE;
348 logmsg (LOG_AUTH, "%s authenticated via %s", 387 logmsg (LOG_AUTH, "%s authenticated via %s",
349 argv[1], pname); 388 argv[1], pname);
350 auth = 1; 389 }
390 else
391 {
392 struct auth_data ad = { io->addr, io->addrlen, id, NULL };
393 progman_foreach (try_auth, &ad);
394 if (ad.comp)
395 {
396 new_state = CTL_USER_STATE;
397 logmsg (LOG_AUTH, "%s authenticated via %s, component %s",
398 argv[1], pname, ad.comp->tag);
399 }
400 else
401 {
402 logmsg (LOG_AUTH, "%s authenticated via %s, but failed ACL check",
403 argv[1], pname);
404 }
351 } 405 }
352 break; 406 break;
353 } 407 }
354 } 408 }
355 409
356 if (auth) 410 if (new_state == CTL_INITIAL_STATE)
357 { 411 {
358 ctlio_reply (io, "230", "authentication successful"); 412 pies_identity_destroy (id);
359 identity = id; 413 ctlio_reply (io, "531", "access denied");
360 io->state = CTL_AUTHENTICATED_STATE;
361 } 414 }
362 else 415 else
363 { 416 {
364 pies_identity_destroy (id); 417 ctlio_reply (io, "230", "authentication successful");
365 ctlio_reply (io, "531", "access denied"); 418 identity = id;
419 io->state = new_state;
366 } 420 }
367} 421}
368 422
@@ -801,67 +855,100 @@ pcond_parse (struct ctlio *io, size_t argc, char **argv,
801 return 0; 855 return 0;
802} 856}
803 857
858static int
859list_matches (struct ctlio *io, struct grecs_list *matches)
860{
861 struct grecs_list_entry *ep;
862 size_t i;
863
864 for (ep = matches->head; ep; ep = ep->next)
865 {
866 struct prog *prog = ep->data;
867
868 ctlio_reply (io, "151", "%s", prog->tag);
869 FORMAT_IDX (io, "Type", pies_type_str, prog->type);
870 switch (prog->type)
871 {
872 case TYPE_COMPONENT:
873 FORMAT_IDX (io, "Mode", pies_comp_mode_str, prog->v.p.comp->mode);
874 FORMAT_IDX (io, "Status", status_str, prog->v.p.status);
875
876 if (prog->pid)
877 ctlio_printf (io, "PID: %lu%s", (unsigned long) prog->pid, CRLF);
878 else if (prog->v.p.status == status_listener
879 && prog->v.p.comp->socket_url)
880 ctlio_printf (io, "URL: %10s%s",
881 prog->v.p.comp->socket_url->string,
882 CRLF);
883
884 if (prog->v.p.status == status_sleeping)
885 {
886 ctlio_printf (io, "Wakeup-Time: %lu%s",
887 (unsigned long) (prog->v.p.timestamp + SLEEPTIME),
888 CRLF);
889 }
890
891 ctlio_printf (io, "Command:");
892 for (i = 0; i < prog->v.p.comp->argc; i++)
893 ctlio_printf (io, " %s", quotearg (prog->v.p.comp->argv[i]));
894 ctlio_eol (io);
895 break;
896
897 case TYPE_REDIRECTOR:
898 ctlio_printf (io, "PID: %10lu%s", (unsigned long) prog->pid, CRLF);
899 break;
900
901 case TYPE_COMMAND:
902 ctlio_printf (io, "Command: %s%s", prog->v.c.command, CRLF);
903 }
904 ctlio_eot (io);
905 }
906 return 0;
907}
908
804struct eval_env 909struct eval_env
805{ 910{
806 struct ctlio *io; 911 struct ctlio *io;
807 struct pcond_node *cond; 912 struct pcond_node *cond;
808 size_t count; 913 struct grecs_list *list;
809}; 914};
810 915
916/* Authenticate access to PROG. Return 0, CTL_USER_STATE or
917 CTL_ADMIN_STATE depending on whether and what kind of access is
918 allowed for the current identity */
811static int 919static int
812list_prog (struct prog *prog, void *data) 920auth_prog (struct prog *prog, struct ctlio *io)
813{ 921{
814 struct eval_env *env = data; 922 if (io->state == CTL_ADMIN_STATE)
815 struct ctlio *io = env->io; 923 return CTL_ADMIN_STATE|CTL_USER_STATE;
816 size_t i;