aboutsummaryrefslogtreecommitdiff
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
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.
-rw-r--r--ident/ident.c8
-rw-r--r--ident/identity.h6
-rw-r--r--src/ctl.c291
-rw-r--r--src/pies.c34
-rw-r--r--src/pies.h14
5 files changed, 244 insertions, 109 deletions
diff --git a/ident/ident.c b/ident/ident.c
index 38ae1a8..dbf3f9b 100644
--- a/ident/ident.c
+++ b/ident/ident.c
@@ -41,6 +41,14 @@ pies_authenticate (pies_identity_provider_t pr, pies_identity_t id,
41 return 1; 41 return 1;
42} 42}
43 43
44char const *
45pies_identity_user_name (pies_identity_t id)
46{
47 if (!id)
48 return NULL;
49 return id->username;
50}
51
44int 52int
45pies_identity_is_user (pies_identity_t id, char * const * users) 53pies_identity_is_user (pies_identity_t id, char * const * users)
46{ 54{
diff --git a/ident/identity.h b/ident/identity.h
index 0ee129d..8a9e2ab 100644
--- a/ident/identity.h
+++ b/ident/identity.h
@@ -20,12 +20,12 @@ typedef struct pies_identity_mechanism *pies_identity_mechanism_t;
20 20
21pies_identity_t pies_identity_create (char const *user); 21pies_identity_t pies_identity_create (char const *user);
22void pies_identity_destroy (pies_identity_t id); 22void pies_identity_destroy (pies_identity_t id);
23
24int pies_authenticate (pies_identity_provider_t pr, pies_identity_t id,
25 char const *passwd);
26int pies_identity_is_user (pies_identity_t id, char * const * users); 23int pies_identity_is_user (pies_identity_t id, char * const * users);
27int pies_identity_is_group_member (pies_identity_t id, char * const * groups); 24int pies_identity_is_group_member (pies_identity_t id, char * const * groups);
25char const *pies_identity_user_name (pies_identity_t p);
28 26
27int pies_authenticate (pies_identity_provider_t pr, pies_identity_t id,
28 char const *passwd);
29char const *pies_identity_provider_name (pies_identity_provider_t p); 29char const *pies_identity_provider_name (pies_identity_provider_t p);
30 30
31int pies_identity_mechanism_register (pies_identity_mechanism_t mech); 31int pies_identity_mechanism_register (pies_identity_mechanism_t mech);
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 == statu