|
Chris PeBenito |
473ea7 |
#include <stdio.h>
|
|
Chris PeBenito |
473ea7 |
#include <stdlib.h>
|
|
Chris PeBenito |
473ea7 |
#include <string.h>
|
|
Chris PeBenito |
473ea7 |
#include "selinux_internal.h"
|
|
Chris PeBenito |
473ea7 |
#include "context_internal.h"
|
|
Chris PeBenito |
473ea7 |
#include <selinux/get_context_list.h>
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* context_menu - given a list of contexts, presents a menu of security contexts
|
|
Chris PeBenito |
473ea7 |
* to the user. Returns the number (position in the list) of
|
|
Chris PeBenito |
473ea7 |
* the user selected context.
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
static int context_menu (security_context_t *list)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
int i; /* array index */
|
|
Chris PeBenito |
473ea7 |
int choice = 0; /* index of the user's choice */
|
|
Chris PeBenito |
473ea7 |
char response[10]; /* string to hold the user's response */
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
printf ("\n\n");
|
|
Chris PeBenito |
473ea7 |
for (i = 0; list[i]; i++)
|
|
Chris PeBenito |
473ea7 |
printf ("[%d] %s\n", i+1, list[i]);
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
while ((choice < 1) || (choice > i))
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
printf ("Enter number of choice: ");
|
|
Chris PeBenito |
473ea7 |
fflush (stdin);
|
|
Chris PeBenito |
473ea7 |
if (fgets (response, sizeof (response), stdin) == NULL)
|
|
Chris PeBenito |
473ea7 |
continue;
|
|
Chris PeBenito |
473ea7 |
fflush (stdin);
|
|
Chris PeBenito |
473ea7 |
choice = strtol (response, NULL, 10);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
return (choice-1);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* query_user_context - given a list of context, allow the user to choose one. The
|
|
Chris PeBenito |
473ea7 |
* default is the first context in the list. Returns 0 on
|
|
Chris PeBenito |
473ea7 |
* success, -1 on failure
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
int query_user_context (security_context_t *list,
|
|
Chris PeBenito |
473ea7 |
security_context_t *usercon)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
char response[10] ; /* The user's response */
|
|
Chris PeBenito |
473ea7 |
int choice; /* The index in the list of the sid chosen by
|
|
Chris PeBenito |
473ea7 |
the user */
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
if (!list[0])
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
printf ("\nYour default context is %s.\n", list[0]);
|
|
Chris PeBenito |
473ea7 |
if (list[1]) {
|
|
Chris PeBenito |
473ea7 |
printf ("Do you want to choose a different one? [n]");
|
|
Chris PeBenito |
473ea7 |
fflush (stdin);
|
|
Chris PeBenito |
473ea7 |
if (fgets (response, sizeof (response), stdin) == NULL)
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
fflush (stdin);
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
if ((response[0] == 'y') || (response[0] == 'Y'))
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
choice = context_menu (list);
|
|
Chris PeBenito |
473ea7 |
*usercon = strdup(list[choice]);
|
|
Chris PeBenito |
473ea7 |
if (!(*usercon))
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
return 0;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
*usercon = strdup(list[0]);
|
|
Chris PeBenito |
473ea7 |
if (!(*usercon))
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
} else {
|
|
Chris PeBenito |
473ea7 |
*usercon = strdup(list[0]);
|
|
Chris PeBenito |
473ea7 |
if (!(*usercon))
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
return 0;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* get_field - given fieldstr - the "name" of a field, query the user
|
|
Chris PeBenito |
473ea7 |
* and set the new value of the field
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
static void get_field (const char* fieldstr, char* newfield, int newfieldlen)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
int done = 0; /* true if a non-empty field has been obtained */
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
while (!done) /* Keep going until we get a value for the field */
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
printf ("\tEnter %s ", fieldstr);
|
|
Chris PeBenito |
473ea7 |
fflush (stdin);
|
|
Chris PeBenito |
473ea7 |
if (fgets (newfield, newfieldlen, stdin) == NULL)
|
|
Chris PeBenito |
473ea7 |
continue;
|
|
Chris PeBenito |
473ea7 |
fflush (stdin);
|
|
Chris PeBenito |
473ea7 |
if (newfield[strlen(newfield)-1] == '\n')
|
|
Chris PeBenito |
473ea7 |
newfield[strlen(newfield)-1] = '\0';
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
if (strlen(newfield) == 0)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
printf ("You must enter a %s\n", fieldstr);
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
else
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
done = 1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* manual_user_enter_context - provides a way for a user to manually enter a
|
|
Chris PeBenito |
473ea7 |
* context in case the policy doesn't allow a list
|
|
Chris PeBenito |
473ea7 |
* to be obtained.
|
|
Chris PeBenito |
473ea7 |
* given the userid, queries the user and places the
|
|
Chris PeBenito |
473ea7 |
* context chosen by the user into usercon. Returns 0
|
|
Chris PeBenito |
473ea7 |
* on success.
|
|
Chris PeBenito |
473ea7 |
*/
|
|
Chris PeBenito |
473ea7 |
int manual_user_enter_context (const char *user, security_context_t *newcon)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
char response[10]; /* Used to get yes or no answers from user */
|
|
Chris PeBenito |
473ea7 |
char role[100]; /* The role requested by the user */
|
|
Chris PeBenito |
473ea7 |
int rolelen = 100;
|
|
Chris PeBenito |
473ea7 |
char type[100]; /* The type requested by the user */
|
|
Chris PeBenito |
473ea7 |
int typelen = 100;
|
|
Chris PeBenito |
473ea7 |
char level[100]; /* The level requested by the user */
|
|
Chris PeBenito |
473ea7 |
int levellen = 100;
|
|
Chris PeBenito |
473ea7 |
int mls_enabled = is_selinux_mls_enabled();
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
context_t new_context; /* The new context chosen by the user */
|
|
Chris PeBenito |
473ea7 |
char *user_context = NULL; /* String value of the user's context */
|
|
Chris PeBenito |
473ea7 |
int done = 0; /* true if a valid sid has been obtained */
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* Initialize the context. How this is done depends on whether
|
|
Chris PeBenito |
473ea7 |
or not MLS is enabled */
|
|
Chris PeBenito |
473ea7 |
if (mls_enabled)
|
|
Chris PeBenito |
473ea7 |
new_context = context_new ("user:role:type:level");
|
|
Chris PeBenito |
473ea7 |
else
|
|
Chris PeBenito |
473ea7 |
new_context = context_new ("user:role:type");
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
if(!new_context)
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
while (!done)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
printf ("Would you like to enter a security context? [y]");
|
|
Chris PeBenito |
473ea7 |
if (fgets (response, sizeof(response), stdin) == NULL
|
|
Chris PeBenito |
473ea7 |
|| (response[0] == 'n') || (response[0] == 'N')) {
|
|
Chris PeBenito |
473ea7 |
context_free(new_context);
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* Allow the user to enter each field of the context individually */
|
|
Chris PeBenito |
473ea7 |
if (context_user_set (new_context, user))
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_free (new_context);
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
get_field ("role", role, rolelen);
|
|
Chris PeBenito |
473ea7 |
if (context_role_set (new_context, role))
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_free (new_context);
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
get_field ("type", type, typelen);
|
|
Chris PeBenito |
473ea7 |
if (context_type_set (new_context, type))
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_free (new_context);
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
if (mls_enabled) {
|
|
Chris PeBenito |
473ea7 |
get_field ("level", level, levellen);
|
|
Chris PeBenito |
473ea7 |
if (context_range_set (new_context, level))
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_free (new_context);
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
/* Get the string value of the context and see if it is valid. */
|
|
Chris PeBenito |
473ea7 |
user_context = context_str(new_context);
|
|
Chris PeBenito |
473ea7 |
if(!user_context)
|
|
Chris PeBenito |
473ea7 |
{
|
|
Chris PeBenito |
473ea7 |
context_free (new_context);
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
if (!security_check_context(user_context))
|
|
Chris PeBenito |
473ea7 |
done = 1;
|
|
Chris PeBenito |
473ea7 |
else
|
|
Chris PeBenito |
473ea7 |
printf ("Not a valid security context\n");
|
|
Chris PeBenito |
473ea7 |
}
|
|
Chris PeBenito |
473ea7 |
|
|
Chris PeBenito |
473ea7 |
*newcon = strdup(user_context);
|
|
Chris PeBenito |
473ea7 |
context_free (new_context);
|
|
Chris PeBenito |
473ea7 |
if(!(*newcon))
|
|
Chris PeBenito |
473ea7 |
return -1;
|
|
Chris PeBenito |
473ea7 |
return 0;
|
|
Chris PeBenito |
473ea7 |
}
|