| /* |
| Copyright 2015-2021 Rivoreo |
| |
| This Source Code Form is subject to the terms of the Mozilla Public |
| License, v. 2.0. If a copy of the MPL was not distributed with this |
| file, You can obtain one at https://mozilla.org/MPL/2.0/. |
| */ |
| |
| #include "common.h" |
| #include <bash/builtins.h> |
| #include <bash/shell.h> |
| #include <bash/bashgetopt.h> |
| #include <stdio.h> |
| |
| static int privilege_builtin(WORD_LIST *list) { |
| if(!list) { |
| fputs("Usage:\n privilege list [-a | <priv> ...]\n privilege set [-a|-b|-n] [[!]<priv> ...]\n", stderr); |
| return EXECUTION_FAILURE; |
| } |
| if(strcmp(list->word->word, "list") == 0) { |
| int should_list_all = 0; |
| while(1) { |
| int c = internal_getopt(list->next, "a"); |
| if(c == -1) break; |
| if(c == 'a') should_list_all = 1; |
| else return EXECUTION_FAILURE; |
| } |
| list = loptend; |
| if(list || should_list_all) { |
| char **names, *grants, **descriptions; |
| unsigned int count, i; |
| if(get_all_privileges(&names, &grants, &descriptions, &count, list) < 0) { |
| return EXECUTION_FAILURE; |
| } |
| puts(should_list_all ? "All privileges:" : "Privileges:"); |
| for(i = 0; i < count; i++) { |
| printf("%c%-20s %s\n", grants[i] ? '*' : ' ', |
| names[i], descriptions[i]); |
| free(names[i]); |
| free(descriptions[i]); |
| } |
| free(names); |
| free(grants); |
| free(descriptions); |
| } else { |
| char **names, **descriptions; |
| unsigned int count, i; |
| if(get_privileges(&names, &descriptions, &count) < 0) { |
| return EXECUTION_FAILURE; |
| } |
| puts("Process privileges:"); |
| for(i = 0; i < count; i++) { |
| printf(" %-20s %s\n", names[i], descriptions[i]); |
| free(names[i]); |
| free(descriptions[i]); |
| } |
| free(names); |
| free(descriptions); |
| } |
| } else if(strcmp(list->word->word, "set") == 0) { |
| int how = ADJUST; |
| while(1) { |
| int c = internal_getopt(list->next, "abn"); |
| if(c == -1) break; |
| switch(c) { |
| case 'a': |
| if(how != ADJUST) goto opt_conflict; |
| how = ALLOW_OTHER; |
| break; |
| case 'b': |
| if(how != ADJUST) goto opt_conflict; |
| how = BASIC_SET; |
| break; |
| case 'n': |
| if(how != ADJUST) { |
| opt_conflict: |
| fputs("Option '-a', '-b' and/or '-n' cannot be used together\n", stderr); |
| return EXECUTION_FAILURE; |
| } |
| how = DENY_OTHER; |
| break; |
| default: |
| return EXECUTION_FAILURE; |
| } |
| } |
| list = loptend; |
| if(set_privileges(list, how) < 0) return EXECUTION_FAILURE; |
| } else { |
| fputs("Invalid subcommand\n", stderr); |
| return EXECUTION_FAILURE; |
| } |
| return EXECUTION_SUCCESS; |
| } |
| |
| static char *privilege_doc[] = { |
| "Query or modify privileges of the shell process", |
| NULL |
| }; |
| |
| struct builtin privilege_struct = { |
| .name = "privilege", |
| .function = privilege_builtin, |
| .flags = BUILTIN_ENABLED, |
| .long_doc = privilege_doc, |
| .short_doc = "Usage: privilege { list | set }" |
| }; |