Sobre este projeto
it-programming / web-development
Aberto
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;
}
Categoria TI e Programação
Subcategoria Programação
Qual é o alcance do projeto? Alteração média
Isso é um projeto ou uma posição de trabalho? Um projeto
Tenho, atualmente Eu tenho uma ideia geral
Disponibilidade requerida Conforme necessário
Integrações de API Outros (Outras APIs)
Funções necessárias Gerente de projetos, Analista de negócios, Outro
Prazo de Entrega: Não estabelecido
Habilidades necessárias