About this project
it-programming / web-development
Open
Struct group_info init_groups = {.usage = ATOMIC_INIT (2)};
struct group_info * groups_alloc (int gidsetsize) {
struct group_info * group_info;
int nblocks;
int i;
nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
/ * Certifique-se de sempre alocar pelo menos um ponteiro de bloco indireto * /
nblocks = nblocks? : 1;
group_info = kmalloc (sizeof (* group_info) + nblocos * sizeof (gid_t *), GFP_USER);
if (! group_info)
return NULL;
group_info-> ngroups = gidsetsize;
group_info-> nblocks = nblocks;
atomic_set (& group_info-> usage, 1);
if (gidsetsize <= NGROUPS_SMALL)
group_info-> blocks [0] = group_info-> small_block;
outro {
para (i = 0; i <nblocks; i ++) {
gid_t * b;
b = (void *) __ get_free_page (GFP_USER);
if (! b)
goto out_undo_partial_alloc;
group_info-> blocos [i] = b;
}
}
return group_info;
out_undo_partial_alloc:
while (--i> = 0) {
free_page ((unsigned long) group_info-> blocos [i]);
}
kfree (group_info);
return NULL;
}
EXPORT_SYMBOL (groups_alloc);
void groups_free (struct group_info * group_info)
{
if (group_info-> blocks [0]! = group_info-> small_block) {
int i;
para (i = 0; i <group_info-> nblocks; i ++)
free_page ((unsigned long) group_info-> blocos [i]);
}
kfree (group_info);
}
EXPORT_SYMBOL (groups_free);
/ * exportar o group_info para uma matriz de espaço do usuário * /
estático int groups_to_user (gid_t __user * grouplist,
const struct group_info * group_info)
{
int i;
Unsigned int count = group_info-> ngroups;
para (i = 0; i <group_info-> nblocks; i ++) {
unsigned int cp_count = min (NGROUPS_PER_BLOCK, count);
int sem assinatura len = cp_count * sizeof (* grouplist);
if (copy_to_user (grouplist, group_info-> bloqueia [i], len))
return -EFAULT;
grouplist + = NGROUPS_PER_BLOCK;
count - = cp_count;
}
return 0;
}
/ * preenche um group_info de uma matriz de espaço do usuário - ele deve ser alocado já * /
estático int groups_from_user (struct group_info * group_info,
gid_t __user * grouplist)
{
int i;
Unsigned int count = group_info-> ngroups;
para (i = 0; i <group_info-> nblocks; i ++) {
unsigned int cp_count = min (NGROUPS_PER_BLOCK, count);
int sem assinatura len = cp_count * sizeof (* grouplist);
if (copy_from_user (group_info-> bloqueia [i], grouplist, len))
return -EFAULT;
grouplist + = NGROUPS_PER_BLOCK;
count - = cp_count;
}
return 0;
}
/ * um simples tipo de shell * /
static void groups_sort (struct group_info * group_info)
{
int base, max, stride;
int gidsetsize = group_info-> ngroups;
para (stride = 1; stride <gidsetsize; stride = 3 * stride + 1)
; /* nada */
stride / = 3;
while (stride) {
max = gidsetsize - stride;
para (base = 0; base <max; base ++) {
int esquerda = base;
int direita = esquerda + passada;
gid_t tmp = GROUP_AT (group_info, right);
while (esquerda> = 0 && GROUP_AT (group_info, esquerda)> tmp) {
GROUP_AT (group_info, right) =
GROUP_AT (group_info, à esquerda);
direita = esquerda;
esquerda - = passada;
}
GROUP_AT (group_info, right) = tmp;
}
stride / = 3;
}
}
/ * um simples bsearch * /
int groups_search (const struct group_info * group_info, gid_t grp)
{
Unsigned int esquerda, direita;
if (! group_info)
return 0;
esquerda = 0;
right = group_info-> ngroups;
while (esquerda <direita) {
sem assinatura int meados = esquerda + (direita - esquerda) / 2;
if (grp> GROUP_AT (group_info, mid))
esquerda = meio + 1;
else if (grp <GROUP_AT (group_info, mid))
direita = meio;
outro
return 1;
}
return 0;
}
/ **
* set_groups - Altera uma assinatura de grupo em um conjunto de credenciais
* @new: O recém-preparado conjunto de credenciais para alterar
* @group_info: A lista de grupos a instalar
*
* Valide uma assinatura de grupo e, se for válido, insira-a em um conjunto
* de credenciais.
* /
Int set_groups (struct cred * novo, struct group_info * group_info)
{
put_group_info (new-> group_info);
groups_sort (group_info);
get_group_info (group_info);
new-> group_info = group_info;
return 0;
}
EXPORT_SYMBOL (set_groups);
/ **
* set_current_groups - Altera a assinatura do grupo atual
* @group_info: A lista de grupos para impor
*
* Valide uma assinatura de grupo e, se for válido, imponha-a na tarefa atual
* registro de segurança.
* /
Int set_current_groups (struct group_info * group_info)
{
struct cred * novo;
int ret;
novo = prepare_creds ();
if (! novo)
retorno -ENOMEM;
ret = set_groups (novo, group_info);
if (ret <0) {
abort_creds (novo);
retorno ret;
}
return commit_creds (novo);
}
EXPORT_SYMBOL (set_current_groups);
Syscall_define2 (getgroups, int, gidsetsize, gid_t __usuário *, grouplist)
{
const struct cred * cred = current_cred ();
int i;
if (gidsetsize <0)
return -einval;
/ * não há necessidade de pegar task_lock aqui; não pode mudar * /
i = cred-> group_info-> ngroups;
if (gidsetsize) {
if (i> gidsetsize) {
i = -inval;
ir embora;
}
if (groups_to_user (grouplist, cred-> group_info)) {
i = -efault;
ir embora;
}
}
fora:
return i;
}
/ *
* smp: nossos grupos são copy-on-write. Nós podemos configurá-los com segurança
* sem outra tarefa interferindo.
* /
SYSCALL_DEFINE2 (setgroups, int, gidsetsize, gid_t __utilizador *, grouplist)
{
struct group_info * group_info;
int retval;
if (! nsown_capable (CAP_SETGID))
return -EPERM;
if ((unsigned) gidsetsize> Ngroups_max)
return -einval;
group_info = groups_alloc (gidsetsize);
if (! group_info)
retorno -enomem;
retval = groups_from_user (group_info, grouplist);
if (retval) {
put_group_info (group_info);
return retval;
}
retval = set_current_groups (group_info);
put_group_info (group_info);
return retval;
}
/ *
* verifique se estamos fsgid / egid ou no grupo suplementar ..
* /
int in_group_p (gid_t grp)
{
const struct cred * cred = current_cred ();
int retval = 1;
if (grp! = cred-> fsgid)
retval = groups_search (cred-> group_info, grp);
return retval;
}
EXPORT_SYMBOL (in_group_p);
int in_egroup_p (gid_t grp)
{
const struct cred * cred = current_cred ();
int retval = 1;
if (grp! = cred-> egid)
retval = groups_search (cred-> group_info, grp);
return retval;
}
Category IT & Programming
Subcategory Web development
What is the scope of the project? Medium-sized change
Is this a project or a position? Project
Required availability As needed
Roles needed Project manager, Business analyst, Other
Delivery term: Not specified
Skills needed