env: Add support for access control to .flags
Add support for read-only, write-once, and change-default. Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>utp
parent
fffad71bc4
commit
267541f776
13
README
13
README
|
@ -3128,7 +3128,8 @@ Configuration Settings:
|
||||||
|
|
||||||
The format of the list is:
|
The format of the list is:
|
||||||
type_attribute = [s|d|x|b|i|m]
|
type_attribute = [s|d|x|b|i|m]
|
||||||
attributes = type_attribute
|
access_atribute = [a|r|o|c]
|
||||||
|
attributes = type_attribute[access_atribute]
|
||||||
entry = variable_name[:attributes]
|
entry = variable_name[:attributes]
|
||||||
list = entry[,list]
|
list = entry[,list]
|
||||||
|
|
||||||
|
@ -3140,6 +3141,12 @@ Configuration Settings:
|
||||||
i - IP address
|
i - IP address
|
||||||
m - MAC address
|
m - MAC address
|
||||||
|
|
||||||
|
The access attributes are:
|
||||||
|
a - Any (default)
|
||||||
|
r - Read-only
|
||||||
|
o - Write-once
|
||||||
|
c - Change-default
|
||||||
|
|
||||||
- CONFIG_ENV_FLAGS_LIST_DEFAULT
|
- CONFIG_ENV_FLAGS_LIST_DEFAULT
|
||||||
Define this to a list (string) to define the ".flags"
|
Define this to a list (string) to define the ".flags"
|
||||||
envirnoment variable in the default or embedded environment.
|
envirnoment variable in the default or embedded environment.
|
||||||
|
@ -3151,6 +3158,10 @@ Configuration Settings:
|
||||||
list, simply add an entry for the same variable name to the
|
list, simply add an entry for the same variable name to the
|
||||||
".flags" variable.
|
".flags" variable.
|
||||||
|
|
||||||
|
- CONFIG_ENV_ACCESS_IGNORE_FORCE
|
||||||
|
If defined, don't allow the -f switch to env set override variable
|
||||||
|
access flags.
|
||||||
|
|
||||||
The following definitions that deal with the placement and management
|
The following definitions that deal with the placement and management
|
||||||
of environment data (variable area); in general, we support the
|
of environment data (variable area); in general, we support the
|
||||||
following configurations:
|
following configurations:
|
||||||
|
|
|
@ -447,8 +447,11 @@ int do_env_callback(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
static int print_static_flags(const char *var_name, const char *flags)
|
static int print_static_flags(const char *var_name, const char *flags)
|
||||||
{
|
{
|
||||||
enum env_flags_vartype type = env_flags_parse_vartype(flags);
|
enum env_flags_vartype type = env_flags_parse_vartype(flags);
|
||||||
|
enum env_flags_varaccess access = env_flags_parse_varaccess(flags);
|
||||||
|
|
||||||
printf("\t%-20s %-20s\n", var_name, env_flags_get_vartype_name(type));
|
printf("\t%-20s %-20s %-20s\n", var_name,
|
||||||
|
env_flags_get_vartype_name(type),
|
||||||
|
env_flags_get_varaccess_name(access));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -456,13 +459,17 @@ static int print_static_flags(const char *var_name, const char *flags)
|
||||||
static int print_active_flags(ENTRY *entry)
|
static int print_active_flags(ENTRY *entry)
|
||||||
{
|
{
|
||||||
enum env_flags_vartype type;
|
enum env_flags_vartype type;
|
||||||
|
enum env_flags_varaccess access;
|
||||||
|
|
||||||
if (entry->flags == 0)
|
if (entry->flags == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
type = (enum env_flags_vartype)
|
type = (enum env_flags_vartype)
|
||||||
(entry->flags & ENV_FLAGS_VARTYPE_BIN_MASK);
|
(entry->flags & ENV_FLAGS_VARTYPE_BIN_MASK);
|
||||||
printf("\t%-20s %-20s\n", entry->key, env_flags_get_vartype_name(type));
|
access = env_flags_parse_varaccess_from_binflags(entry->flags);
|
||||||
|
printf("\t%-20s %-20s %-20s\n", entry->key,
|
||||||
|
env_flags_get_vartype_name(type),
|
||||||
|
env_flags_get_varaccess_name(access));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -480,17 +487,29 @@ int do_env_flags(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
env_flags_print_vartypes();
|
env_flags_print_vartypes();
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
|
||||||
|
/* Print the available variable access types */
|
||||||
|
printf("Available variable access flags (position %d):\n",
|
||||||
|
ENV_FLAGS_VARACCESS_LOC);
|
||||||
|
puts("\tFlag\tVariable Access Name\n");
|
||||||
|
puts("\t----\t--------------------\n");
|
||||||
|
env_flags_print_varaccess();
|
||||||
|
puts("\n");
|
||||||
|
|
||||||
/* Print the static flags that may exist */
|
/* Print the static flags that may exist */
|
||||||
puts("Static flags:\n");
|
puts("Static flags:\n");
|
||||||
printf("\t%-20s %-20s\n", "Variable Name", "Variable Type");
|
printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
|
||||||
printf("\t%-20s %-20s\n", "-------------", "-------------");
|
"Variable Access");
|
||||||
|
printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
|
||||||
|
"---------------");
|
||||||
env_attr_walk(ENV_FLAGS_LIST_STATIC, print_static_flags);
|
env_attr_walk(ENV_FLAGS_LIST_STATIC, print_static_flags);
|
||||||
puts("\n");
|
puts("\n");
|
||||||
|
|
||||||
/* walk through each variable and print the flags if non-default */
|
/* walk through each variable and print the flags if non-default */
|
||||||
puts("Active flags:\n");
|
puts("Active flags:\n");
|
||||||
printf("\t%-20s %-20s\n", "Variable Name", "Variable Type");
|
printf("\t%-20s %-20s %-20s\n", "Variable Name", "Variable Type",
|
||||||
printf("\t%-20s %-20s\n", "-------------", "-------------");
|
"Variable Access");
|
||||||
|
printf("\t%-20s %-20s %-20s\n", "-------------", "-------------",
|
||||||
|
"---------------");
|
||||||
hwalk_r(&env_htab, print_active_flags);
|
hwalk_r(&env_htab, print_active_flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,24 @@ int getenv_yesno(const char *var)
|
||||||
1 : 0;
|
1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the variable from the default environment
|
||||||
|
*/
|
||||||
|
char *getenv_default(const char *name)
|
||||||
|
{
|
||||||
|
char *ret_val;
|
||||||
|
unsigned long really_valid = gd->env_valid;
|
||||||
|
unsigned long real_gd_flags = gd->flags;
|
||||||
|
|
||||||
|
/* Pretend that the image is bad. */
|
||||||
|
gd->flags &= ~GD_FLG_ENV_READY;
|
||||||
|
gd->env_valid = 0;
|
||||||
|
ret_val = getenv(name);
|
||||||
|
gd->env_valid = really_valid;
|
||||||
|
gd->flags = real_gd_flags;
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
void set_default_env(const char *s)
|
void set_default_env(const char *s)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
|
@ -43,6 +43,17 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
|
static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS;
|
||||||
|
static const char env_flags_varaccess_rep[] = "aroc";
|
||||||
|
static const int env_flags_varaccess_mask[] = {
|
||||||
|
0,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_CREATE |
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_OVERWR,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_DELETE |
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR};
|
||||||
|
|
||||||
#ifdef CONFIG_CMD_ENV_FLAGS
|
#ifdef CONFIG_CMD_ENV_FLAGS
|
||||||
static const char * const env_flags_vartype_names[] = {
|
static const char * const env_flags_vartype_names[] = {
|
||||||
"string",
|
"string",
|
||||||
|
@ -54,6 +65,12 @@ static const char * const env_flags_vartype_names[] = {
|
||||||
"MAC address",
|
"MAC address",
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
static const char * const env_flags_varaccess_names[] = {
|
||||||
|
"any",
|
||||||
|
"read-only",
|
||||||
|
"write-once",
|
||||||
|
"change-default",
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print the whole list of available type flags.
|
* Print the whole list of available type flags.
|
||||||
|
@ -69,6 +86,20 @@ void env_flags_print_vartypes(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print the whole list of available access flags.
|
||||||
|
*/
|
||||||
|
void env_flags_print_varaccess(void)
|
||||||
|
{
|
||||||
|
enum env_flags_varaccess curaccess = (enum env_flags_varaccess)0;
|
||||||
|
|
||||||
|
while (curaccess != env_flags_varaccess_end) {
|
||||||
|
printf("\t%c -\t%s\n", env_flags_varaccess_rep[curaccess],
|
||||||
|
env_flags_varaccess_names[curaccess]);
|
||||||
|
curaccess++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the name of the type.
|
* Return the name of the type.
|
||||||
*/
|
*/
|
||||||
|
@ -76,6 +107,14 @@ const char *env_flags_get_vartype_name(enum env_flags_vartype type)
|
||||||
{
|
{
|
||||||
return env_flags_vartype_names[type];
|
return env_flags_vartype_names[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the name of the access.
|
||||||
|
*/
|
||||||
|
const char *env_flags_get_varaccess_name(enum env_flags_varaccess access)
|
||||||
|
{
|
||||||
|
return env_flags_varaccess_names[access];
|
||||||
|
}
|
||||||
#endif /* CONFIG_CMD_ENV_FLAGS */
|
#endif /* CONFIG_CMD_ENV_FLAGS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -100,6 +139,46 @@ enum env_flags_vartype env_flags_parse_vartype(const char *flags)
|
||||||
return env_flags_vartype_string;
|
return env_flags_vartype_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the flags string from a .flags attribute list into the varaccess enum.
|
||||||
|
*/
|
||||||
|
enum env_flags_varaccess env_flags_parse_varaccess(const char *flags)
|
||||||
|
{
|
||||||
|
char *access;
|
||||||
|
|
||||||
|
if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
|
||||||
|
return env_flags_varaccess_any;
|
||||||
|
|
||||||
|
access = strchr(env_flags_varaccess_rep,
|
||||||
|
flags[ENV_FLAGS_VARACCESS_LOC]);
|
||||||
|
|
||||||
|
if (access != NULL)
|
||||||
|
return (enum env_flags_varaccess)
|
||||||
|
(access - &env_flags_varaccess_rep[0]);
|
||||||
|
|
||||||
|
printf("## Warning: Unknown environment variable access method '%c'\n",
|
||||||
|
flags[ENV_FLAGS_VARACCESS_LOC]);
|
||||||
|
return env_flags_varaccess_any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the binary flags from a hash table entry into the varaccess enum.
|
||||||
|
*/
|
||||||
|
enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(env_flags_varaccess_mask); i++)
|
||||||
|
if (env_flags_varaccess_mask[i] ==
|
||||||
|
(binflags & ENV_FLAGS_VARACCESS_BIN_MASK))
|
||||||
|
return (enum env_flags_varaccess)i;
|
||||||
|
|
||||||
|
printf("Warning: Non-standard access flags. (0x%x)\n",
|
||||||
|
binflags & ENV_FLAGS_VARACCESS_BIN_MASK);
|
||||||
|
|
||||||
|
return env_flags_varaccess_any;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int is_hex_prefix(const char *value)
|
static inline int is_hex_prefix(const char *value)
|
||||||
{
|
{
|
||||||
return value[0] == '0' && (value[1] == 'x' || value[1] == 'X');
|
return value[0] == '0' && (value[1] == 'x' || value[1] == 'X');
|
||||||
|
@ -241,6 +320,23 @@ enum env_flags_vartype env_flags_get_type(const char *name)
|
||||||
return env_flags_parse_vartype(flags);
|
return env_flags_parse_vartype(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the access of a variable directly from the .flags var.
|
||||||
|
*/
|
||||||
|
enum env_flags_varaccess env_flags_get_varaccess(const char *name)
|
||||||
|
{
|
||||||
|
const char *flags_list = getenv(ENV_FLAGS_VAR);
|
||||||
|
char flags[ENV_FLAGS_ATTR_MAX_LEN + 1];
|
||||||
|
|
||||||
|
if (env_flags_lookup(flags_list, name, flags))
|
||||||
|
return env_flags_varaccess_any;
|
||||||
|
|
||||||
|
if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC)
|
||||||
|
return env_flags_varaccess_any;
|
||||||
|
|
||||||
|
return env_flags_parse_varaccess(flags);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate that the proposed new value for "name" is valid according to the
|
* Validate that the proposed new value for "name" is valid according to the
|
||||||
* defined flags for that variable, if any.
|
* defined flags for that variable, if any.
|
||||||
|
@ -261,6 +357,21 @@ int env_flags_validate_type(const char *name, const char *value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate that the proposed access to variable "name" is valid according to
|
||||||
|
* the defined flags for that variable, if any.
|
||||||
|
*/
|
||||||
|
int env_flags_validate_varaccess(const char *name, int check_mask)
|
||||||
|
{
|
||||||
|
enum env_flags_varaccess access;
|
||||||
|
int access_mask;
|
||||||
|
|
||||||
|
access = env_flags_get_varaccess(name);
|
||||||
|
access_mask = env_flags_varaccess_mask[access];
|
||||||
|
|
||||||
|
return (check_mask & access_mask) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate the parameters to "env set" directly
|
* Validate the parameters to "env set" directly
|
||||||
*/
|
*/
|
||||||
|
@ -292,7 +403,12 @@ int env_flags_validate_env_set_params(int argc, char * const argv[])
|
||||||
*/
|
*/
|
||||||
static int env_parse_flags_to_bin(const char *flags)
|
static int env_parse_flags_to_bin(const char *flags)
|
||||||
{
|
{
|
||||||
return env_flags_parse_vartype(flags) & ENV_FLAGS_VARTYPE_BIN_MASK;
|
int binflags;
|
||||||
|
|
||||||
|
binflags = env_flags_parse_vartype(flags) & ENV_FLAGS_VARTYPE_BIN_MASK;
|
||||||
|
binflags |= env_flags_varaccess_mask[env_flags_parse_varaccess(flags)];
|
||||||
|
|
||||||
|
return binflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -377,13 +493,10 @@ int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
#if !defined(CONFIG_ENV_OVERWRITE) && defined(CONFIG_OVERWRITE_ETHADDR_ONCE) \
|
|
||||||
&& defined(CONFIG_ETHADDR)
|
|
||||||
const char *oldval = NULL;
|
const char *oldval = NULL;
|
||||||
|
|
||||||
if (op != env_op_create)
|
if (op != env_op_create)
|
||||||
oldval = item->data;
|
oldval = item->data;
|
||||||
#endif
|
|
||||||
|
|
||||||
name = item->key;
|
name = item->key;
|
||||||
|
|
||||||
|
@ -422,6 +535,44 @@ int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for access permission */
|
||||||
|
#ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE
|
||||||
|
if (flag & H_FORCE)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
switch (op) {
|
||||||
|
case env_op_delete:
|
||||||
|
if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_DELETE) {
|
||||||
|
printf("## Error: Can't delete \"%s\"\n", name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case env_op_overwrite:
|
||||||
|
if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_OVERWR) {
|
||||||
|
printf("## Error: Can't overwrite \"%s\"\n", name);
|
||||||
|
return 1;
|
||||||
|
} else if (item->flags &
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR) {
|
||||||
|
const char *defval = getenv_default(name);
|
||||||
|
|
||||||
|
if (defval == NULL)
|
||||||
|
defval = "";
|
||||||
|
printf("oldval: %s defval: %s\n", oldval, defval);
|
||||||
|
if (strcmp(oldval, defval) != 0) {
|
||||||
|
printf("## Error: Can't overwrite \"%s\"\n",
|
||||||
|
name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case env_op_create:
|
||||||
|
if (item->flags & ENV_FLAGS_VARACCESS_PREVENT_CREATE) {
|
||||||
|
printf("## Error: Can't create \"%s\"\n", name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,18 @@ enum env_flags_vartype {
|
||||||
env_flags_vartype_end
|
env_flags_vartype_end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum env_flags_varaccess {
|
||||||
|
env_flags_varaccess_any,
|
||||||
|
env_flags_varaccess_readonly,
|
||||||
|
env_flags_varaccess_writeonce,
|
||||||
|
env_flags_varaccess_changedefault,
|
||||||
|
env_flags_varaccess_end
|
||||||
|
};
|
||||||
|
|
||||||
#define ENV_FLAGS_VAR ".flags"
|
#define ENV_FLAGS_VAR ".flags"
|
||||||
#define ENV_FLAGS_ATTR_MAX_LEN 2
|
#define ENV_FLAGS_ATTR_MAX_LEN 2
|
||||||
#define ENV_FLAGS_VARTYPE_LOC 0
|
#define ENV_FLAGS_VARTYPE_LOC 0
|
||||||
|
#define ENV_FLAGS_VARACCESS_LOC 1
|
||||||
|
|
||||||
#ifndef CONFIG_ENV_FLAGS_LIST_STATIC
|
#ifndef CONFIG_ENV_FLAGS_LIST_STATIC
|
||||||
#define CONFIG_ENV_FLAGS_LIST_STATIC ""
|
#define CONFIG_ENV_FLAGS_LIST_STATIC ""
|
||||||
|
@ -52,27 +61,57 @@ enum env_flags_vartype {
|
||||||
* Print the whole list of available type flags.
|
* Print the whole list of available type flags.
|
||||||
*/
|
*/
|
||||||
void env_flags_print_vartypes(void);
|
void env_flags_print_vartypes(void);
|
||||||
|
/*
|
||||||
|
* Print the whole list of available access flags.
|
||||||
|
*/
|
||||||
|
void env_flags_print_varaccess(void);
|
||||||
/*
|
/*
|
||||||
* Return the name of the type.
|
* Return the name of the type.
|
||||||
*/
|
*/
|
||||||
const char *env_flags_get_vartype_name(enum env_flags_vartype type);
|
const char *env_flags_get_vartype_name(enum env_flags_vartype type);
|
||||||
|
/*
|
||||||
|
* Return the name of the access.
|
||||||
|
*/
|
||||||
|
const char *env_flags_get_varaccess_name(enum env_flags_varaccess access);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the flags string from a .flags attribute list into the vartype enum.
|
* Parse the flags string from a .flags attribute list into the vartype enum.
|
||||||
*/
|
*/
|
||||||
enum env_flags_vartype env_flags_parse_vartype(const char *flags);
|
enum env_flags_vartype env_flags_parse_vartype(const char *flags);
|
||||||
|
/*
|
||||||
|
* Parse the flags string from a .flags attribute list into the varaccess enum.
|
||||||
|
*/
|
||||||
|
enum env_flags_varaccess env_flags_parse_varaccess(const char *flags);
|
||||||
|
/*
|
||||||
|
* Parse the binary flags from a hash table entry into the varaccess enum.
|
||||||
|
*/
|
||||||
|
enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags);
|
||||||
|
|
||||||
#ifdef USE_HOSTCC
|
#ifdef USE_HOSTCC
|
||||||
/*
|
/*
|
||||||
* Look up the type of a variable directly from the .flags var.
|
* Look up the type of a variable directly from the .flags var.
|
||||||
*/
|
*/
|
||||||
enum env_flags_vartype env_flags_get_type(const char *name);
|
enum env_flags_vartype env_flags_get_type(const char *name);
|
||||||
|
/*
|
||||||
|
* Look up the access of a variable directly from the .flags var.
|
||||||
|
*/
|
||||||
|
enum env_flags_varaccess env_flags_get_access(const char *name);
|
||||||
/*
|
/*
|
||||||
* Validate the newval for its type to conform with the requirements defined by
|
* Validate the newval for its type to conform with the requirements defined by
|
||||||
* its flags (directly looked at the .flags var).
|
* its flags (directly looked at the .flags var).
|
||||||
*/
|
*/
|
||||||
int env_flags_validate_type(const char *name, const char *newval);
|
int env_flags_validate_type(const char *name, const char *newval);
|
||||||
|
/*
|
||||||
|
* Validate the newval for its access to conform with the requirements defined
|
||||||
|
* by its flags (directly looked at the .flags var).
|
||||||
|
*/
|
||||||
|
int env_flags_validate_access(const char *name, int check_mask);
|
||||||
|
/*
|
||||||
|
* Validate that the proposed access to variable "name" is valid according to
|
||||||
|
* the defined flags for that variable, if any.
|
||||||
|
*/
|
||||||
|
int env_flags_validate_varaccess(const char *name, int check_mask);
|
||||||
/*
|
/*
|
||||||
* Validate the parameters passed to "env set" for type compliance
|
* Validate the parameters passed to "env set" for type compliance
|
||||||
*/
|
*/
|
||||||
|
@ -94,13 +133,18 @@ void env_flags_init(ENTRY *var_entry);
|
||||||
int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
|
int env_flags_validate(const ENTRY *item, const char *newval, enum env_op op,
|
||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
|
#endif /* USE_HOSTCC */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are the binary flags used in the environment entry->flags variable to
|
* These are the binary flags used in the environment entry->flags variable to
|
||||||
* decribe properties of veriables in the table
|
* decribe properties of veriables in the table
|
||||||
*/
|
*/
|
||||||
#define ENV_FLAGS_VARTYPE_BIN_MASK 0x00000007
|
#define ENV_FLAGS_VARTYPE_BIN_MASK 0x00000007
|
||||||
/* The actual variable type values use the enum value (within the mask) */
|
/* The actual variable type values use the enum value (within the mask) */
|
||||||
|
#define ENV_FLAGS_VARACCESS_PREVENT_DELETE 0x00000008
|
||||||
#endif /* USE_HOSTCC */
|
#define ENV_FLAGS_VARACCESS_PREVENT_CREATE 0x00000010
|
||||||
|
#define ENV_FLAGS_VARACCESS_PREVENT_OVERWR 0x00000020
|
||||||
|
#define ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR 0x00000040
|
||||||
|
#define ENV_FLAGS_VARACCESS_BIN_MASK 0x00000078
|
||||||
|
|
||||||
#endif /* __ENV_FLAGS_H__ */
|
#endif /* __ENV_FLAGS_H__ */
|
||||||
|
|
|
@ -181,6 +181,9 @@ unsigned char env_get_char_memory(int index);
|
||||||
/* Function that updates CRC of the enironment */
|
/* Function that updates CRC of the enironment */
|
||||||
void env_crc_update(void);
|
void env_crc_update(void);
|
||||||
|
|
||||||
|
/* Look up the variable from the default environment */
|
||||||
|
char *getenv_default(const char *name);
|
||||||
|
|
||||||
/* [re]set to the default environment */
|
/* [re]set to the default environment */
|
||||||
void set_default_env(const char *s);
|
void set_default_env(const char *s);
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,32 @@ char *fw_getenv (char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search the default environment for a variable.
|
||||||
|
* Return the value, if found, or NULL, if not found.
|
||||||
|
*/
|
||||||
|
char *fw_getdefenv(char *name)
|
||||||
|
{
|
||||||
|
char *env, *nxt;
|
||||||
|
|
||||||
|
for (env = default_environment; *env; env = nxt + 1) {
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
for (nxt = env; *nxt; ++nxt) {
|
||||||
|
if (nxt >= &default_environment[ENV_SIZE]) {
|
||||||
|
fprintf(stderr, "## Error: "
|
||||||
|
"default environment not terminated\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val = envmatch(name, env);
|
||||||
|
if (!val)
|
||||||
|
continue;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print the current definition of one, or more, or all
|
* Print the current definition of one, or more, or all
|
||||||
* environment variables
|
* environment variables
|
||||||
|
@ -282,6 +308,7 @@ int fw_env_write(char *name, char *value)
|
||||||
int len;
|
int len;
|
||||||
char *env, *nxt;
|
char *env, *nxt;
|
||||||
char *oldval = NULL;
|
char *oldval = NULL;
|
||||||
|
int deleting, creating, overwriting;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* search if variable with this name already exists
|
* search if variable with this name already exists
|
||||||
|
@ -299,10 +326,49 @@ int fw_env_write(char *name, char *value)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
deleting = (oldval && !(value && strlen(value)));
|
||||||
* Delete any existing definition
|
creating = (!oldval && (value && strlen(value)));
|
||||||
*/
|
overwriting = (oldval && (value && strlen(value)));
|
||||||
if (oldval) {
|
|
||||||
|
/* check for permission */
|
||||||
|
if (deleting) {
|
||||||
|
if (env_flags_validate_varaccess(name,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_DELETE)) {
|
||||||
|
printf("Can't delete \"%s\"\n", name);
|
||||||
|
errno = EROFS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (overwriting) {
|
||||||
|
if (env_flags_validate_varaccess(name,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_OVERWR)) {
|
||||||
|
printf("Can't overwrite \"%s\"\n", name);
|
||||||
|
errno = EROFS;
|
||||||
|
return -1;
|
||||||
|
} else if (env_flags_validate_varaccess(name,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR)) {
|
||||||
|
const char *defval = fw_getdefenv(name);
|
||||||
|
|
||||||
|
if (defval == NULL)
|
||||||
|
defval = "";
|
||||||
|
if (strcmp(oldval, defval)
|
||||||
|
!= 0) {
|
||||||
|
printf("Can't overwrite \"%s\"\n", name);
|
||||||
|
errno = EROFS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (creating) {
|
||||||
|
if (env_flags_validate_varaccess(name,
|
||||||
|
ENV_FLAGS_VARACCESS_PREVENT_CREATE)) {
|
||||||
|
printf("Can't create \"%s\"\n", name);
|
||||||
|
errno = EROFS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
/* Nothing to do */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (deleting || overwriting) {
|
||||||
#ifndef CONFIG_ENV_OVERWRITE
|
#ifndef CONFIG_ENV_OVERWRITE
|
||||||
/*
|
/*
|
||||||
* Ethernet Address and serial# can be set only once
|
* Ethernet Address and serial# can be set only once
|
||||||
|
|
Loading…
Reference in New Issue