113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "selinux_internal.h" 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "context_internal.h" 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <selinux/get_context_list.h> 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* context_menu - given a list of contexts, presents a menu of security contexts 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to the user. Returns the number (position in the list) of 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * the user selected context. 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 129eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleystatic int context_menu(char ** list) 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; /* array index */ 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int choice = 0; /* index of the user's choice */ 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char response[10]; /* string to hold the user's response */ 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("\n\n"); 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; list[i]; i++) 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("[%d] %s\n", i + 1, list[i]); 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while ((choice < 1) || (choice > i)) { 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("Enter number of choice: "); 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fflush(stdin); 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fgets(response, sizeof(response), stdin) == NULL) 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fflush(stdin); 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle choice = strtol(response, NULL, 10); 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return (choice - 1); 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* query_user_context - given a list of context, allow the user to choose one. The 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * default is the first context in the list. Returns 0 on 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * success, -1 on failure 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 389eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint query_user_context(char ** list, char ** usercon) 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char response[10]; /* The user's response */ 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int choice; /* The index in the list of the sid chosen by 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle the user */ 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!list[0]) 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("\nYour default context is %s.\n", list[0]); 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (list[1]) { 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("Do you want to choose a different one? [n]"); 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fflush(stdin); 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fgets(response, sizeof(response), stdin) == NULL) 5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fflush(stdin); 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if ((response[0] == 'y') || (response[0] == 'Y')) { 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle choice = context_menu(list); 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *usercon = strdup(list[choice]); 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(*usercon)) 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *usercon = strdup(list[0]); 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(*usercon)) 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *usercon = strdup(list[0]); 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(*usercon)) 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* get_field - given fieldstr - the "name" of a field, query the user 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * and set the new value of the field 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void get_field(const char *fieldstr, char *newfield, int newfieldlen) 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int done = 0; /* true if a non-empty field has been obtained */ 8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (!done) { /* Keep going until we get a value for the field */ 8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("\tEnter %s ", fieldstr); 8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fflush(stdin); 8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fgets(newfield, newfieldlen, stdin) == NULL) 8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fflush(stdin); 8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (newfield[strlen(newfield) - 1] == '\n') 8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle newfield[strlen(newfield) - 1] = '\0'; 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strlen(newfield) == 0) { 9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("You must enter a %s\n", fieldstr); 9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle done = 1; 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* manual_user_enter_context - provides a way for a user to manually enter a 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * context in case the policy doesn't allow a list 10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * to be obtained. 10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * given the userid, queries the user and places the 10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * context chosen by the user into usercon. Returns 0 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * on success. 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 1069eb9c9327563014ad6a807814e7975424642d5b9Stephen Smalleyint manual_user_enter_context(const char *user, char ** newcon) 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char response[10]; /* Used to get yes or no answers from user */ 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char role[100]; /* The role requested by the user */ 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int rolelen = 100; 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char type[100]; /* The type requested by the user */ 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int typelen = 100; 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char level[100]; /* The level requested by the user */ 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int levellen = 100; 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int mls_enabled = is_selinux_mls_enabled(); 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_t new_context; /* The new context chosen by the user */ 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *user_context = NULL; /* String value of the user's context */ 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int done = 0; /* true if a valid sid has been obtained */ 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Initialize the context. How this is done depends on whether 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle or not MLS is enabled */ 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_enabled) 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_context = context_new("user:role:type:level"); 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle new_context = context_new("user:role:type"); 12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!new_context) 12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while (!done) { 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("Would you like to enter a security context? [y]"); 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fgets(response, sizeof(response), stdin) == NULL 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || (response[0] == 'n') || (response[0] == 'N')) { 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Allow the user to enter each field of the context individually */ 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_user_set(new_context, user)) { 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle get_field("role", role, rolelen); 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_role_set(new_context, role)) { 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle get_field("type", type, typelen); 15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_type_set(new_context, type)) { 15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (mls_enabled) { 15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle get_field("level", level, levellen); 15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (context_range_set(new_context, level)) { 15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Get the string value of the context and see if it is valid. */ 16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_context = context_str(new_context); 16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!user_context) { 16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!security_check_context(user_context)) 17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle done = 1; 17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle printf("Not a valid security context\n"); 17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *newcon = strdup(user_context); 17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle context_free(new_context); 17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(*newcon)) 17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return -1; 17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 181