Administração de usuários no Ubuntu 12.04

Nesse artigo vou escrever sobre a administração de usuários no GNU/Linux. Estou usando o Ubuntu 12.04 para realizar os testes, mas tudo deve ocorrer normalmente em outras distribuições.

No GNU/Linux existem 4 arquivos que são usados para administrar usuários, são eles:

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /etc/gshadow

Observaçãp: Você pode consultar o manual desses arquivos com o seguinte comando: man 5 nome_arquivo.

O arquivo /etc/passwd é responsável por armazenar informações da conta de cada usuário. Ele segue a seguinte estrutura:


usuario : x : id_usuario : id_grupo_primario : infos( gecos ) : caminho_home : caminho_shell

Para ver o conteúdo desse arquivo execute o seguinte comando no terminal:


getent /etc/passwd

O arquivo /etc/shadow armazena as senhas dos usuários ( na verdade um hash delas ) e infomações relacionadas ao tempo de validade das senhas.

Antigamente o arquivo passwd guardava a senha do usuário, mas por segurança essa informação foi migrada para o shadow. Assim, a senha no arquivo passwd foi substituida por um x, indicando dessa forma que o sistema faz uso do arquivo shadow.

Para visualizar o conteúdo do arquivo /etc/shadow você também pode usar o comando getent, mas é necessário utilizar o usuário root( sudo ) ou um usuário que esteja no grupo shadow.

O arquivo /etc/group armazena informações sobre os grupos do sistema. Ele segue a seguinte estrutura:


grupo : x : id_grupo : usuarios_dentro_do_grupo

Da mesma forma que os arquivos anteriores, é possível usar o comando getent para visualizar o conteúdo desse arquivo.

O arquivo /etc/gshadow é responsável por armazenar as senhas dos grupos.

Conhecendo as estruturas desses arquivos e tendo as permissões necessárias é possível fazer qualquer tipo de admnistração de usuários no GNU/Linux. Porém, não é recomendado alterar esses arquivos manualmente, o ideal é utilizar os seguintes comandos:

  • chage
  • passwd
  • usermod
  • groupmod
  • useradd
  • userdel
  • groupadd
  • groupdel

O comando chage serve para alterar caracteristicas da senha do usuário.

Veja a saida do comando ‘chage -l paulo’ no meu sistema:



Última mudança de senha : Out 28, 2014
Senha expira : nunca
Senha inativa : nunca
Conta expira : nunca
Número mínimo de dias entre troca de senhas : 0
Número máximo de dias entre troca de senhas : 99999
Número de dias de avisos antes da expiração da senha : 7

Essas informações também podem ser alteradas com o comando chage, por exemplo, com o comando a baixo altera a data de expiração da conta:


sudo chage -E 11/09/2020 paulo # a data está no padrão mm/dd/aaaa

Para saber mais utilize o comando man chage.

No GNU/Linux além de um arquivo passwd, também existe um comando com esse mesmo nome. O comando passwd serve para alterar a senha de um usuário. ( evidente que é necessário permissões de administrador para trocar a senha de outro usuário ). O seguinte comando altera a senha do usuário ‘paulo’:


passwd paulo

Tendo as devidas permissões também é possível bloquear a conta de um usuário com o comando passwd. Veja:


sudo passwd -l paulo #bloqueia
sudo passwd -u paulo #desbloqueia

Através do comado usermod também é possível alterar várias informações da conta de um usuário. Entre outras, é possível alterar os grupos, o diretório home e o shell do usuário:


sudo usermod -G adm,cdrom,sudo paulo # altera os grupos
sudo usermod -d /home/paulo2 paulo # altera o home
sudo usermod -s /bin/csh paulo # altera o shell

Veja mais com o comando man usermod.

Assim como o usermod serve para fazer alterações nos usuários o comando groupmod faz alterações nos grupos:


groupmod -n novo antigo

Esse comando altera o nome do grupo ‘antigo’ para ‘novo’.

O comando useradd é utilizado para inserir um novo usuário no sistema. Veja:


sudo useradd -m -s /bin/bash paulo

Nesse exemplo o -m é para criar o diretório home e o -s é para especificar o shell do novo usuário. Depois de criar o usuário ainda é necessário utilizar o comando passwd para especificar uma senha, somente depois disso o usuário poderá ser usado.

Para remover um usuário no sistema é utilizado o comando userdel assim:


sudo userdel -r paulo

É importante utilizar o -r para garantir que o diretório home do usuário será removido.

O comando groupadd serve para adicionar um grupo no sistema, veja o exemplo:


sudo groupadd grupo

E para remover um grupo é usado o comando groupdel:


sudo groupdel grupo

Para remover um grupo que seja primário de algum usuário é necessário primeiro excluir o usuário com o comando userdel.

Feito, por hoje é isso! Existem vários outros comandos que são utéis para admnistração de usuários no GNU/Linux, segue mais alguns comandos para quem quiser saber mais: id, finger, chfn, adduser( debian-like ), who, users, fuser …

T+

Sistema de arquivos

O sistema de arquivos do GNU/Linux pode ser representado como uma árvore de cabeça para baixo… No topo dessa arvore fica o diretório raiz( / ).  Dentro do diretório raiz encontramos os seguinte diretórios:

bin Arquivos executáveis
boot Arquivos essências para a carga do sistema. É aqui que fica a imagem do kernel
dev Arquivos que representam dispositivos do sistema
etc Arquivos de configuração do sistema
home Diretórios dos usuários
lib Bibliotecas do sistemas. Usadas pelos programas e módulos do kernel
mnt Diretório para montagem de dispositivos ( Em alguns casos existe o diretório media com a mesma utilidade )
proc Informações do sistema e dos processos atuais
opt Programas que não fazem parte da distribuição
root Diretório do super usuário ( root )
sbin Programas do super usuário ( programas/comandos de administração )
tmp Arquivos temporários. O conteúdo desse diretório é apagado a cada reboot
usr Programas usados pelos usuários
var Arquivos variáveis. Logs e arquivos de email

Essa estrutura foi definida por um padrão de mercado criado pelo comunidade em 1994, chamado Filesystem Hierarchy Standard ( FHS ). As distribuições não precisam seguir esse padrão, mas existe uma grande conscientização sobre a importância desse padrão.

GNU/Linux – Trabalhando com textos

Oi pessoal, tudo bem? Hoje vou mostrar alguns comandos do GNU/Linux para trabalhar com arquivos de texto. O GNU/Linux possui uma grande quantidade de comandos para trabalhar com arquivos de textos, mas nesse artigo vou escrever apenas sobre os seguintes comandos:

 

    • cat
    • tac
    • cut
    • head
    • tail
    • join
    • nl
    • tr

 

Apesar de não aparecerem nessa lista, existem 2 comandos( linguagens ) que precisam ser lembrados… O primeiro deles é o awk, já escrevi sobre ele aqui, e o outro é o sed, que vou dedicar um artigo exclusivo futuramente.

Bem, feito a declaração inicial, vejamos os comandos desse aritgo.

cat

O comando cat serve para visualizar, concatenar e criar arquivos.

Para visualizar um arquivo utilize o comando cat da seguinte forma:

cat caminho_para_o_arquivo

Veja:

 


cat /etc/passwd

Para concatenar arquivos utilize o comando cat assim:

cat arquivo1 arquivo2 arquivo3 >> arquivo123.

Veja:


cat /etc/environment /etc/profile >> arquivo_final

Para criar arquivos utilize o comando cat da seguinte maneira:

cat > arquivo.

Veja:


cat > arquivo

O prompt vai ser aberto para digitação, para encerrar a escrita utilize ‘ctrl + d’

tac

O comando tac funciona da mesma forma que o comando cat, porém coloca as linhas na ordem contrária.

cut

O comando cut serve para cortar partes de um arquivo de texto. Esse comando geralmente é usado com arquivos do tipo CSV.

Veja:


cut -d : -f 1 /etc/passwd

Dessa forma o comando cut vai mostrar apenas a primeira coluna (primeiro campo de cada linha).

-d Delimitador
-f O campo que vai ser exibido

head

O comando head serve para visualizar um arquivo a partir do inicio( cabeça ). É possível limitar a quantidade de linhas que serão exibidas da seguinte maneira:


head -n 10 /etc/passwd

Nesse exemplo a saída vai ser as 10 primeiras linhas do arquivo /etc/passwd

tail

O comando tail serve para visualizar um arquivo a partir do final( cauda ). Da mesma forma que o head é possível limitar a quantidade de linhas que serão exibidas da seguinte maneira:


tail -n 10 /etc/passwd

Nesse exemplo a saída vai ser as 10 últimas linhas do arquivo /etc/passwd

join

O comando join faz a junção de arquivos que tenham um campo com índice comum.

Veja:

arquivo1

1 paulo
2 andre
3 junior

arquivo2

1 10
2 9
3 10

 


join -j 1 arquivo1 arquivo2

A saída vai ser:

1 paulo 10
2 andre 9
3 junior 10

nl

O comando nl serve para numerar as linhas de um arquivo, veja:


nl /etc/passwd

tr

O comando tr é um tradutor… Com ele é possível substituir um caracterer por outro…

veja:


cat /etc/passwd | tr a-z A-Z

Esse comando vai alterar as letras minúsculas do arquivo /etc/passwd para maiúsculas.

Outra possibilidade desse comando é retirar caracteres repetidos, por exemplo:


echo "paaaaaaulo" | tr -s a

E também é possível apagar caracteres de um arquivo, assim:


echo "paulo" | tr -d a

Chegamos ao fim de mais um artigo… Claro que existem várias outras possibilidades para esses comandos, para saber mais, utilize o comando man.

Assim:

man nome_comando

Segue alguns links:

http://www.prminformatica.com.br/2014/01/awk.html
http://thobias.org/doc/inc_sed.html

Como montar um servidor LTSP no Ubuntu

O que é LTSP?

Nessa semana eu tive que instalar um servidor LTSP em uma escola aqui da minha cidade. Utilizei o sistema Ubuntu e o processo de instalação e configuração foi extremamente simples. Segue algumas imagens de como ficou o laboratório:

Observação: Algumas máquinas nas imagens não estão utilizando o servidor LTSP

Nesse artigo vou mostrar os passos que usei para ter o servidor e todos as máquinas clientes funcionando. No meu caso, a maioria dos clientes são equipamentos especializados chamados thin client, mas também é possível utilizar computadores comuns, desde que eles tenham suporte ao boot pela rede (sendo necessário apenas um mínimo de memória ram e não sendo necessário ter um HD na máquina ). Para o servidor é necessário ter duas placas de rede, um bom processador e quanto mais memória ram melhor. Para calcular a quantidade mínima de memória do servidor utilizei a seguinte fórmula: 2GB + (numeroClientes * 512MB).

Os passos necessários são:

1 – Instalar o Ubuntu com a seguinte tabela de partições: *valores aproximados

100MB /dev/sda1 /boot
16GB /dev/sda2 swap
250GB /dev/sda3 /
250GB /dev/sda4 /home

Observação: Você pode alterar as partições conforme a sua necessidade.

2 – Configurar a rede através do arquivo /etc/network/interfaces:

 
auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
address 192.168.0.1
netmask 255.255.255.0

Observação: A interface de rede eth0 fica conectada na internet e a eth1 nos clientes.

3 – Instalar os serviços:

 
sudo apt-get install ltsp-server-standalone openssh-server

4 – Configurar os arquivos /etc/ltsp/dhcpd.conf e /etc/default/isc-dhcp-server

O arquivo /etc/ltsp/dhcpd.conf já estava preenchido, foi necessário apenas adaptar as configurações de rede. Esse arquivo têm essa aparência:


authoritative;

subnet 192.168.0.0 netmask 255.255.255.0 {
    range 192.168.0.20 192.168.0.250;
    option domain-name "example.com";
    option domain-name-servers 192.168.0.1;
    option broadcast-address 192.168.0.255;
    option routers 192.168.0.1;
#    next-server 192.168.0.1;
#    get-lease-hostnames true;
    option subnet-mask 255.255.255.0;
    option root-path "/opt/ltsp/i386";
    if substring( option vendor-class-identifier, 0, 9 ) = "PXEClient" {
        filename "/ltsp/i386/pxelinux.0";
    } else {
        filename "/ltsp/i386/nbi.img";
    }
}

No arquivo /etc/default/isc-dhcp-server foi necessário apenas configurar a interface de rede que se conecta nos clientes:

 
INTERFACES=”eth1″

5 – Criar os usuários para os clientes.

 
sudo adduser

6 – Criar e atualizar a imagem do sistema para os clientes:

 
sudo ltsp-build-client --arch i386 #esse cria a imagem dos clientes, vai demorar :)

sudo ltsp-update-sshkeys 

sudo ltsp-update-image

Observação: No primeiro comando, também é possível usar o parâmetro –dist para especificar um versão diferente do ubuntu. Exemplo: lucid ou precise.

7 – Reiniciar o servidor

 
sudo reboot

8 – Configurar os clientes para dar boot pela rede

Observação: Isso pode ser feito de várias maneiras diferentes dependendo da bios dos clientes. Procure onde é configurada a ordem de boot e altere para LAN, network ou PXE.

Pronto, se você seguiu os passos de forma correta, o seu servidor LTSP já está funcionando.

Segue alguns links para ajudar e complementar esse artigo:

http://www.hardware.com.br/termos/pxe
https://www.youtube.com/watch?v=LJt9VIqWfDY
https://fedorahosted.org/k12linux/wiki/InstallGuide

Precisa trabalhar com arquivos de texto ? AWK!

Eae pessoal, nos últimos meses eu tive que usar bastante a linguagem C para manipular arquivos de texto (txt). Apesar de ser uma linguagem poderosa, trabalhar com esses arquivos em C pode ser bem complicado. Pensando nisso, quero mostrar nesse artigo uma linguagem mais especialiazada em manipulação de arquivos de texto ( lembre-se, para quem só sabe usar martelo, tudo é prego ).

Essa linguagem é a AWK, ela foi criada em 1977 pelos cientistas Alfred Aho, Peter J. Weinberger e Brian Kernighan no laboratório Bell Labs.

Para criar os exemplos vou utilizar o arquivo “/etc/passwd”, e para que tudo ocorra de forma segura fiz uma copia desse arquivo para pasta home do meu usuário. Faça você também:



cp /etc/passwd $HOME

O meu arquivo passwd têm essa aparência:


saned:x:110:120::/home/saned:/bin/false
ntp:x:111:121::/home/ntp:/bin/false
rtkit:x:114:123:RealtimeKit,,,:/proc:/bin/false
mdm:x:108:112:Gnome Display Manager:/var/lib/mdm:/bin/false
paulo:x:1000:1000:paulo:/home/paulo:/bin/bash

Perceba que é um arquivo CSV separado por ‘:’ . Cada linha desse arquivo representa um usuário do sistema, sendo que os campos estão organizados assim:

login: senha : Id do usuario : Id do grupo : extras : pasta home : shell

Para iniciar, vou apenas usar o AWK para imprimir o arquivo no terminal, para isso digite o seguinte comando ( no terminal ) :



awk '{ print }' $HOME/passwd

O AWK fez a leitura de cada linha (uma por uma) do arquivo passwd e imprimiu na saida padrão( monitor ). Isso não é muito util, afinal, o comando cat também pode fazer isso e com uma sintaxe mais simples ( cat $HOME/passwd ). Agora vou tentar algo um pouco mais elaborado, vou imprimir o arquivo novamente, mas apenas o primeiro campo (login).



awk -F: '{ print $1 }' $HOME/passwd

Dessa vez eu utilizei o parametro -F, que especifica o separador de campos utilizado no arquivo ( nesse caso :, sem isso, o separador padrão é o TAB ou ” ” ) e passei a variável $1 ( que representa o primeiro campo ) para o print. Para cada campo da linha que esta sendo processada existe uma variável $n, onde n é a posicao do campo apartir do 1, A variavel $0 contém a linha inteira.

Para o próximo exemplo quero imprimir apenas quem utiliza o shell Bash:



awk -F: '{ if( $7 == "/bin/bash" ) print $1 }' $HOME/passwd

Obs. AWK utiliza os mesmos operadores condicionais e lógicos do C

Funcionou, mas ainda é possível melhorar a aparência dessa saída:



awk -F: ' { if( $7 == "/bin/bash" ) printf "%s usa o shell %s n", $1, $7 }' $HOME/passwd

Obs. Perceba que o printf do AWK é quase igual ao do C, ele aceita vários formatos, por exemplo: %d, %i, %f, %s e outros.

Assim fica melhor, né? No próximo exemplo quero finalizar a saída com a quantidade de campos encontrados:



awk -F: '{ if( $7 == "/bin/bash" ) { printf "%s usa o shell %s n", $1, $7; total++ } } END { printf "Total de registros %d n", total }' $HOME/passwd

Nesse exemplo utilizei o bloco END, esse bloco é executado depois que o AWK processou todo conteúdo do arquivo. Diferente do C em AWK não é necessário instanciar uma variavel. Na primeira vez que uma variável é mencionada o AWK automaticamente cria uma instância e atribui um valor inicial, para números esse valor é 0 e para strings é “”.

Caso seja necessário também é possível especificar um bloco BEGIN que é executado antes do AWK processe o conteúdo do arquivo.

O exemplo anterior ficou um pouco grande para ser executado direto no terminal, para facilitar a escrita, é possivel utilizar a AWK em forma de script, para isso basta criar um arquivo que inicie com a linha “#!/usr/bin/awk -f” e escrever os comandos nas linhas seguintes. Vai ser necessário fazer algumas adaptações, exemplo anterior em forma de script fica assim:


#!/usr/bin/awk -f

BEGIN {
FS=":";
}

{
if( $7 == "/bin/bash") {

printf "%s usa o shell %s n", $1, $7;
total++;
}
}

END {
printf "Total de registros %d n", total
}

A principal diferença é que no lugar de especificar o separador através do parametro -F, utilizo a variavel padrão FS, dentro do bloco BEGIN.

Salvei o script no arquivo teste.awk, depois dei permissão de execução para ele através do comando “chmod +x teste.awk” e para executar basta escrever no terminal “./teste.awk $HOME/passwd” . Assim fica parecido com shell script, né? ( não sabe o que é shell script? clique aqui )

Continuando, agora eu quero mostrar apenas as linhas onde o login tenha menos de 4 letras:


#!/usr/bin/awk -f

BEGIN {
FS=":";
}

{
if( length( $1 ) < 4) {

printf "%s n", $1;
total++;
}
}

END {
printf "Total de registros %d n", total
}

Nesse exemplo utilizei a função length que retorna o tamanho de uma string. Algumas das funções do AWK para trabalhar com strings são:

index( s1, s2 ) retorna a posição da string s1 na string s2
gsub( sO, sS, s ) substitui a string original sO pela a string substituta sS na sting s
length( s ) retorna o tamanho da string s
split( s, v, d ) quebra a string s usando o delimitador d e coloca no vetor v
substr( s, i, f ) retorna a parte da string s que inicia na posição i e termina na posição f

AWK também têm funções para trabalhar com números, alguma delas são:

sqrt( n ) raiz quadrada
sen( n ) seno
cos( n ) cosseno
int( n ) a parte inteira de n

No próximo exemplo vou redirecionar a saída para um arquivo e vou alterar o shell de todos os usuários que usam o “/bin/sh” para o “/bin/bash”:


#!/usr/bin/awk -f

BEGIN {
FS=":";
}

{
if( $7 == "/bin/sh") $7 = "/bin/bash";

for( i = 1; i < 8; i++ ) printf "%s:", $i >> "bkp";

print "" >> "bkp"; #pra quebrar a linha
}

Obs1. A AWK também possui uma instrução while, que assim como o for tem uma sintaxe idêntica a do C
Obs2. Os comentários em AWK são feitos com #

O exemplo anterior foi escrito ao estilo C propositalmente, eu queria mostrar como é a instrução for, o jeito AWK de fazer isso é utilizando a função gsub, assim:



#!/usr/bin/awk -f
{
gsub( "/bin/sh", "/bin/bash", $0 )

print $0 > "bkp"
}

Pessoal por hoje é isso, tem muito mais para mostrar sobre o AWK, mas fica para um próximo artigo. Para quem quiser continuar estudando o AWK, aqui fica alguns links…

http://www.inf.pucrs.br/~manssour/AWK/
http://pt.wikipedia.org/wiki/AWK
http://br-linux.org/artigos/awk_intro.htm

Bitwise. Escovar Bits

Oi, tudo bem? Depois de um tempo parado com as postagens do blog, hoje vou mostrar como trabalhar com operadores de bits em C. Essa técnica é conhecida como bitwise (e também como “escovar bits”), trata-se basicamente de usar alguns operadores para alterar a sequência de bits de uma variável.

Em C, cada variável têm um tipo, e cada um desses tipos têm um tamanho diferente( quantidade de bits ). Por exemplo, uma variável do tipo char têm o tamanho de 8 bits ( o que equivale a 1 byte ) e uma variável do tipo int geralmente têm 32 bits ( 4 bytes ).

Os principais operadores bitwise são:

  • Operador & ( and )
  • Operador | ( or )
  • Operador ^ ( xor )
  • Operador ~ ( not )
  • Operador >> ( right shift )
  • Operador << ( left shift )

Esses operadores funcionam da seguinte maneira:

& (and)

O operador & compara os bits de cada variável um por um, quando os dois bits (um da variável ‘a’ e outro da variável ‘b’) são iguais a 1 (bit ligado) o retorno é 1, caso contrário o retorno é 0.



char a = 1; // 0000 0001
char b = 5; // 0000 0101

char c = a & b; // 0000 0001

| (or)

O operador | também compara os bits de cada variável um por um, quando pelo menos um dos bits é igual a 1 o retorno é 1, caso contrário o retorno é 0.



char a = 1; // 0000 0001
char b = 5; // 0000 0101

char c = a | b; // 0000 0101

^ (xor)

O operador ^ compara os bits de forma que se os 2 bits( um da variável ‘a’ e outro da variável ‘b’ ) forem iguais ele retorna 0, caso contrario ele retorna 1.



char a = 1; // 0000 0001
char b = 5; // 0000 0101

char c = a ^ b; // 0000 0100

~ (not)

O operador ~ inverte os bits de uma variável, onde era 1 fica 0 e onde era 0 fica 1.



char a = 1; // 0000 0001

char b = ~a; // 1111 1110

<< (left shift) e >> (right shift)

Os operadores << e >> fazem o deslocamentos dos bits para direita e para a esquerda. Preenchendo o restante com 0.



char a = 1; // 0000 0001
char b = a << 2; // 0000 0100

char c = b >> 2; // 0000 0001

Nesses exemplos, utilizei os valores em base 10, mas em C, também é possível especificar valores em binario e hexadecimal. Para isso basta usar a seguinte sintaxe:



char a = 0b101; // binario
char b = 0xff; // hexa

Para tentar apresentar melhor esses operadores vou usar como exemplo um controle de quartos de um hotel. Nesse controle só é necessário saber se o quarto está livre ou se está ocupado. O hotel vai ter 8 quartos e vou armazenar as informações em uma única variável do tipo char, ou seja, cada bit vai representar um quarto. Esse não é um exemplo realista, mas com ele é possível ter uma idéia de como trabalhar com operadores de bits.

O programa inicia assim:



int main(int argc, char **argv)
{
char hotel;

hotel = 0b101; //temos 2 quartos ocupados ( 0000 0101 )

return 0;
}

O primeiro passo é desenvolver uma função para verificar se um determinado quarto está ocupado:



// o quarto é um valor entre 0 e 7 inclusive,
// seria importante testar esse valor
int estaOcupado( char hotel, int quarto )
{
char teste = 1; // 0000 0001

// rotaciona para que o bit ligado fique no quarto desejado
teste = teste << quarto;

// se o retorno for diferente de 0 o quarto esta ocupado
return hotel & teste;
}

int main(int argc, char **argv)
{
char hotel;

hotel = 0b101;

if( estaOcupado( hotel, 0 ) )
printf(" O quarto 0 esta ocupado n" );

return 0;
}

Agora vou desenvolver uma função para ocupar um quarto



void ocuparQuarto( char* hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

// o bit ligado do teste garante que o quarto vai ficar ocupado,
// os outros bits do teste estão desligados e não vão alterar o hotel
*hotel = *hotel | teste;
}

int estaOcupado( char hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

return hotel & teste;
}

int main(int argc, char **argv)
{
char hotel;

hotel = 0b101;

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

ocuparQuarto( &hotel, 1 );

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

return 0;
}

Por último tenho uma função para liberar um quarto:



void liberarQuarto( char* hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

// inverte o teste, 0000 0001 fica 1111 1110
teste = ~teste;

// o bit desligado do teste garante que o quarto vai ser liberado,
// os bits ligados do teste não alteram o hotel.
*hotel = *hotel & teste;
}

void ocuparQuarto( char* hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

*hotel = *hotel | teste;
}

int estaOcupado( char hotel, int quarto )
{
char teste = 1; // 0000 0001

teste = teste << quarto;

return hotel & teste;
}

int main(int argc, char **argv)
{
char hotel;

hotel = 0b101;

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

ocuparQuarto( &hotel, 1 );

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

liberarQuarto( &hotel, 1 );

if( estaOcupado( hotel, 1 ) )
printf(" O quarto 1 esta ocupado n" );
else
printf(" O quarto 1 nao esta ocupado n" );

return 0;
}

Bom pessoal é isso, sei que o exemplo não é muito real, mas vou deixar alguns links para quem quiser saber mais sobre a arte de escovar bits. Até a próxima postagem 🙂

http://www.diogomatheus.com.br/blog/php/operadores-bitwise-bit-a-bit/
http://samuca.wordpress.com/2007/03/26/operadores-bitwise/
http://blog.bsoares.com.br/aspnet/operacoes-binarias

Permissões especiais: SUID, SGID e STICKY

Hoje quero mostrar as permissões especiais do linux: SUID, SGID e STICKY. Esses bits podem ser aplicados em determinadas situações para se conseguir um comportamento bem especifico.

Esses bits têm as seguintes características:

SUID

Esse bit só pode ser aplicado em arquivos executáveis. Basicamente, quando esse bit está ativado o arquivo é executado com as permissões do dono dele e não com as permissões de quem executou. Por exemplo, um arquivo executável onde o dono é o root e o bit SUID está ativado, sempre roda com as permissões do root, ou seja, qualquer usuário pode executa-lo com privilégios de administrador.

SGID

O bit SGID quando é aplicado em um arquivo executável, funciona de forma parecida com o SUID, mas é usada a permissão do grupo do arquivo e não do dono. Além disso, esse bit pode ser aplicado em diretórios, quando isso acontece, tudo que for criado dentro desse diretório terá o grupo dele, ou seja, se o diretório pai tem o bit SGID ativado, tudo que for criado dentro dele terá o seu grupo e não o do usuário que criou.

STICKY

O bit STICKY geralmente é utilizado em diretórios públicos (777) onde todos os usuários podem gravar e apagar arquivos. Esse bit altera a capacidade dos usuários apagarem arquivos/diretórios dos quais não sejam donos, ou seja, o bit STICKY interfere na permissão de apagar arquivos/diretórios, permitindo apenas que o usuário apague os seus arquivos/diretorios (onde ele é dono), mesmo que ele tenha a permissão necessária para apagar arquivos de outros usuários. (o root obviamente não sofre esse bloqueio )

Como aplicar essas permissões

Para ativar esses bits você pode usar o comando chmod de forma octal colocando um digito a mais no inicio da sequencia de dono, grupo e outros.( X777 )

Para ativar o SUID : chmod 4777

Para ativar o SGID : chmod 2777

Para ativar o STICKY : chmod 1777

OBS: não precisa ser sempre X777, as 3 últimas você define como quiser, dependendo das permissões que for aplicar para o dono, grupo e outros

Exemplos

SUID

Perceba que tem ‘s’ no lugar do ‘x’ na sequencia de permissões do dono. Ele representa SUID ativado

SGID

Perceba que tem ‘s’ no lugar do ‘x’ na sequencia de permissões do grupo. Ele representa SGID ativado

STICKY

Perceba que tem ‘t’ no lugar do ‘x’ na sequencia de permissões do outros. Ele representa STICKY ativado

Saib mais…
http://www.vivaolinux.com.br/artigo/Entendendo-as-permissoes-no-Linux
http://pt.wikipedia.org/wiki/Sistema_octal

Configuração básica do Squid no Fedora

Eae pessoal, dessa vez quero mostrar como configurar rapidamente um servidor de proxy Squid. Vou mostrar o básico para o Squid funcionar, no final deixo alguns links para quem quiser se aprofundar no assunto, beleza? Dessa vez vou utilizar o Fedora.

Um servidor de proxy tem basicamente duas funções: Agilizar o processo de entrega de requisições web e filtrar o conteúdo que os usuários tem acesso. Existem duas maneiras de configurar o servidor Squid, manualmente e transparente.

Quando você usa configuração manual é necessário especificar para todos os clientes(geralmente navegadores) que eles devem fazer uso do proxy. Já quando você faz a configuração de forma transparente não existe a necessidade de especificar que os clientes utilizem o proxy. Na verdade, os clientes não sabem da existência dele.

Em um proxy configurado de forma manual e tendo como cliente um navegador o processo de requisição seria (+ ou -) assim:

NAVEGADOR > SERVIDOR_PROXY > SITE V

NAVEGADOR < SERVIDOR_PROXY < SITE

Ou seja, o navegador faz a requisição da página para o servidor proxy, esse realiza a filtragem e se for o caso( se for aprovado ) requisita a página para o site e devolve para o navegador.

E se proxy for transparente o processo de requisição de uma página é o seguinte:

NAVEGADOR > FIREWALL > SERVIDOR_PROXY > SITE V

NAVEGADOR < SERVIDOR_PROXY < SITE

Nesse caso o navegador não sabe da existência do proxy, então faz a requisição normalmente para o roteador padrão( por isso não é necessário configurar o navegador), o firewall da rede então identifica essa operação e desvia o fluxo para o proxy para que ele faça a filtragem e se for o caso a requisição para o site.

Nesse tutorial vou mostrar como fazer a configuração manual. O ideal é que você instale e configure o servidor em uma máquina e use outra como cliente, se você não tiver outra máquina disponível utilize o virtualbox para criar uma máquina virtual. (Nunca usou o virtual box? aqui têm um tutorial).

Na máquina que vai ser o servidor use o seguinte comando para instalar o Squid: ( O servidor deve ser Fedora, o cliente pode se qualquer sistema, ok?)

 
sudo yum install squid -y

Com o Squid instalado no servidor abra com um editor de texto o arquivo “/etc/squid/squid.conf” :

 
sudo nano /etc/squid/squid.conf

Veja que já existe bastante conteúdo nesse arquivo, mas não se preocupe a maior parte dele não será alterada. A idéia é ser simples e rápido, então não vou fazer muitas configurações, vou mudar somente o necessário. A configuração completa para colocar o proxy em ‘produção’ fica para um próximo artigo.

Vou iniciar configurando o cache, para isso altere a seguinte linha no arquivo squid.conf:

 
#cache_dir ufs /var/spool/squid 100 16 256

Essa linha faz o ajuste do cache em disco: O 100 especifca o tamanho do cache em MB, o 16 a quantidade de diretórios e o 256 a quantidade de subdiretórios que o Squid pode criar. Você pode alterar os valores conforme achar necessário, apenas se certifique de tirar o ‘#’ do inicio da linha. Este ‘#’ comenta a linha, com ele essa instrução não é avaliada pelo Squid.

Em seguida coloque essa linha abaixo da anterior( em baixo da cache_dir…):

 
visible_hostname nome_do_seu_servidor_aqui

Essa linha especifica o hostname do Squid e também vai aparecer nas páginas de informação.

Pronto, salve o arquivo e você já têm o cache do seu Squid configurado. O próximo passo é configurar as regras de filtragem. Essas regras são definidas através dos comandos ‘acl’ e ‘http_access’. Veja a documentação para encontrar todas as ‘acls’ possíveis. http://www.squid-cache.org/

As ‘acls’ são escritas da seguinte forma:

 
acl < nome_da_acl > < tipo_acl > < parâmetro >

Veja alguns exemplos de ‘acls’:

 

# acl de origem, representa o ip do cliente que acessa o proxy
acl rede_local src 192.168.0.0/24

# acl de destino, representa o destino da requisição
acl meu_blog dstdomain .prmjuniorblog.blogspot.com.br

# acl de expressão regular, verifica se a palavra jogo esta na url
acl words url_regex jogo

Para iniciar a configuração da filtragem coloque um ‘#’ (comentar) as seguintes linhas: (Elas estão permitindo acesso total para a rede local e para o próprio servidor, vamos tirar esse acesso.)

 
#No seu elas devem estar sem o '#' na frente, coloque.
#http_access allow localnet
#http_access allow localhost

Agora é possível criar regras personalizadas. A configuração que vou utilizar vai estabelecer algumas palavras proibidas e se o Squid encontrar alguma delas o acesso será negado, para isso procure no arquivo “/etc/squid/squid.conf” a seguinte linha:

 
http_access deny all

Digite os comando abaixo antes dela:

 

# a sua rede, -ALTERE- para a faixa de IP que você usa. Use o comando ifconfig para ter essa informação
acl rede_local src 192.168.0.0/24
#as palavras proibidas
acl proibidas url_regex -i "/etc/squid/proibidas"

Criei duas ‘acls’, a primeira representa o IP da sua rede local, ou seja a faixa de ip dos computadores clientes e a segunda representa as palavras proibidas. O “-i” garante que a busca pelas palavras não vai considerar diferença entre maiusculas e minusculas, e o endereço “/etc/squid/proibidas” é o arquivo onde as palavras serão armazenadas( uma por linha ). Para testar crie o arquivo “/etc/squid/proibidas” e coloque a palavra baixaki dentro dele. Salve as modificações no “/etc/squid/squid.conf”, abra um terminal e execute o comando abaixo:

 

sudo echo "baixaki" > /etc/squid/proibidas

Depois de executar esse comando o arquivo das palavras proibidas já estará criado e contendo a palavra baixaki. Volte a abrir o arquivo “squid.conf” e digite o seguinte logo abaixo das linhas anteriores:

 

#nega que a rede acesse requisições que tenham as palavras proibidas em qualquer lugar da url
http_access deny rede proibidas
#permite que a rede acesse o restante
http_access allow rede

OBS: Se uma regra bloquear o acesso, esse vai ficar bloqueado, mesmo que uma regra abaixo libere

Com isso a filtragem está pronta, use o seguinte comando para verificar erros de digitação na configuração:



squid -k parse

Se for mostrado algum erro tente corrigi-lo( se não souber arrumar deixe um comentário 🙂 .Quando a configuração estiver ok, inicie o Squid com o comando:

 

sudo service squid start

OBS: para que o Squid inicie sempre com o Fedora, use o comando “sudo chkconfig squid on”

Agora é necessário configurar o navegador do cliente para usar o proxy. Aqui têm tutorial explicando como fazer isso em vários navegadores. Você vai precisar do ip do servidor, se não souber, use o comando ifconfig.

Segue uma imagem de como ficou no meu Firefox

Feito, tente navegar… o Baixaki deve ser o único site bloqueado. Se quiser fazer outros bloqueios não é necessário alterar o “/etc/squid/squid.conf”, basta alterar o arquivo das palavras proibidas.

Se você preferir ter um arquivo com palavras liberadas, ou seja, acessa somente os sites que tiverem uma das palavras na url, crie o arquivo liberadas e altere as seguintes linhas no “/etc/squid/squid.conf”:

 
# cria a acl
acl liberadas url_regex -i "/etc/squid/liberadas"
#nega acesso a qualquer url que não tenha uma das palavras liberadas
http_access deny rede !liberadas

Saiba mais…
http://pt.wikipedia.org/wiki/Proxy
http://www.sourcebrasil.org/tutoriais/visualizar/instalacao-e-configuracao-do-servidor-proxy-squid.html
http://www.youtube.com/watch?v=fgOw-3PV_sQ

Quota de disco no Linux (Fedora 19)

Hoje vou escrever sobre como aplicar um sistema de quota de disco no GNU/Linux. Dessa vez estou utilizando o Fedora 19, mas tudo deve funcionar perfeitamente em outras distribuições.

A ideia ao se criar um sistema de quota é dividir o disco de forma justa ou da melhor maneira possível.

Por exemplo, imagine que em um sistema a partição /home têm 1GB, e que determinado usuário resolve fazer o download de uma .iso de 700MB… Os demais usuários terão que dividir os 300MB restantes.  Nesse caso, temos um usuário usando a maior parte do disco sozinho, para evitar essa situação, é possível usar o sistema de quota.

Para configurar o sistema de quotas, é necessário  instalar o pacote quota com o seguinte comando:

sudo yum install quota 

Depois de instalar o pacote, é necessário alterar o arquivo /etc/fstab de forma que a partição /home tenha as seguintes opções: usrquota e grpquota.

Exemplo:

/dev/mapper/fedora-home /home ext4 defaults,usrquota,grpquota 1 2

Para ativar a configuração é possível reiniciar o sistema ou remontar a partição com o seguinte comando: 

sudo mount -o remount /home

Agora que o sistema de quota já esta instalado, é possível fazer a configuração das quotas por usuário ou por grupo.

Execute o seguinte comando para criar os arquivos de configuração:

sudo quotacheck -cugfm /home

Após esse comando, a  pasta /home deve possuir os arquivos aquota.group e aquota.user.  É importante que esses arquivos possam ser alterados apenas pelo root .

Ative a quota de disco com:

sudo quotaon /home

Feito isso, a configuração de um usuário pode ser feita com o comando:

sudo edquota -u usuario

O seguinte arquivo será aberto para edição no vi:

Filesystem blocks soft hard inodes soft hard
/dev/mapper/fedora-home 32 2000 3000 14 10 15

Nesse arquivo, apenas as colunas soft e hard devem ser alteradas. O primeiro conjunto de colunas soft e hard especifica a quota de disco por espaço ocupado e o segundo conjunto especifica a quota por inode.

Você pode considerar um inode como um ponteiro para um arquivo, a quantidade desses inodes é limitada, por isso, pode ser útil fazer um sistema de quota para eles também… Para saber mais sobre inode, clique aqui.

A coluna soft especifica a quota do usuário, ou seja, acima disso o usuário estourou sua quota. E a coluna hard, especifica um tamanho máximo após estourar a quota( um extra ).

Simplificando,  soft é a quota do usuário e hard é um extra para armazenar mais alguns arquivos enquanto o usuário resolve o problema.

O tempo que o usuário têm para usar o espaço extra é chamado de grace period e serve para que seja possível fazer backup ou excluir algum arquivo que não seja mais necessário. Esse tempo pode ser especificado com o comando:

sudo edquota -t

Para consultar a situação das quotas é utilizado o comando:

sudo repquota -va

Uma vez que um usuário possui quota definida, é possível replicar a quota dele em outro usuário através do seguinte comando:

sudo edquota -up usuario paulo

Dessa forma, o usuário paulo terá a mesma configuração de quota do usuário usuario

As quotas por grupo podem ser configurada de forma semelhante… Por exemplo, para configurar a quota de um grupo é possível usar o comando:

sudo edquota -g grupo

E para listar as quotas:

sudo repquota -vag

Por hoje é isso, qualquer dúvida deixe um comentário.

A leitura dos seguintes links pode ser interessante.

Comandos básicos do vi
Add usuário pela linha de comando
O comando mount

Gerenciando processos no Ubuntu 12.04

Nesse artigo vou mostrar como usar alguns comandos para gerenciar processos no GNU/Linux. Mais uma vez estou usando o ubuntu 12.04 , mas tudo deve funcionar normalmente em outras distribuições .

O primeiro comando que vou mostrar é o ps:

 
ps aux | more
 

Na saida desse comando é possível encontrar as colunas:

USER é o nome do usuário que iniciou o processo;
PID é o id do processo;
% CPU é a porcentagem de uso do processador;
% MEM é a porcentagem de uso da memória;
VSZ é o tamanho virtual do processo ;
RSS é a quantidade de memória usada em KB;
TTY é o terminal do processo;
STAT é o estado atual do processo;
START é hora em que o processo foi iniciado;
COMMAND é comando que executa o processo;

O STAT pode ter os valores:

D um processo morto;
R um processo em execução;
S um processo parado(dormindo);
T um processo parado, por um sinal de controle;
Z um processo terminado, mas removido por seu processo pai;

E esses valores podem também ser combinados com os seguintes caracteres:

> o processo têm prioridade maior que o normal, a alteração foi feita pelo kernel;
< o processo têm prioridade menor do que o normal, a alteração foi feita pelo kernel;
+ o processo é pai 🙂 possui processos filhos;
s o processo possui processos que dependem dele;
l o processo possui múltiplas threads;
L o processo possui páginas travadas na memória;
N o processo têm prioridade diferente do normal, a alteração foi feita por um usuário;

O comando ps é como um ‘print screen’ dos processos, ou seja, ele mostra como os processos estavam em um determinado momento, mas em algumas situações pode ser melhor ver a ‘movimentação’ dos processos em ‘tempo real’. Para isso, é possível usar o comando top. Existe também o comando htop que é uma versão mais amigável do top.

Para instalar o htop no Ubuntu digite no terminal:

 
sudo apt-get install htop
 

Depois de visualizar os processos você pode enviar sinais para mudar o comportamento deles. Veja mais sobre os sinais aqui

Alguns dos sinais possíveis são:

9 (SIGKILL) para matar o processo ( quase sempre uso esse :);
15 (SIGTERM) para terminar o processo;
18 (SIGCONT) para continuar um processo parado;
19 (SIGSTOP) para parar um processo;

É possível enviar esses sinais direto da interface do comando top ou utilizar alguns comandos externos. Em alguns deles é usado o nome do programa e em outros o PID.

Por exemplo, nos comandos abaixo é usado o nome do programa para matar os processos:

 
pkill -9 firefox
killall -s 9 firefox

E no próximo é usado o PID de um processo para matá-lo;

kill -9 1889

Com o comando kill é necessário saber o PID do processo para enviar um sinal para ele. Você pode usar os comandos ps e top para encontrar esse número, mas existem comandos que facilitam essa busca, por exemplo:

pidof firefox
pgrep firefox

Para terminar, vou mostrar dois comandos para alterar a prioridade de um processo.

Para executar um processo com prioridade diferente do normal use o comando:

nice -n 19 firefox

E para alterar a prioridade de um processo use:

renice -20 1889

Bom, espero que esse artigo seja útil para alguém… Se quiser ver outra forma de gerenciar processos( gráfica ), veja esse artigo do terminal de informação.