Adicionar/remover usuários
Publicado por Italo Pessoa (última atualização em 14/03/2013)
[ Hits: 7.074 ]
Homepage: http://xconhecimento.blogspot.com.br
Script criado para adicionar e remover usuários do sistema GNU/Linux, sem utilizar comandos nativos.
Ainda possui alguns trechos que precisam ser otimizados, mas já funciona perfeitamente.
Vídeo com explicação: http://youtu.be/pU01Y60Cyj4
Um ponto que esqueci de informar no vídeo: o script só funciona para login via interface gráfica com o GDM, foi o único que testei. O LightDM apresenta um erro no momento do login, que ainda não consegui resolver.
#!/usr/bin/python
# -*- encoding: utf-8 -*-
# Funcao para adicinaor e remover usuario do sistema - UFC
# Italo Pessoa - italoneypessoa@gmail.com, 16 de Fevereiro de 2013
import getpass
import sys
import crypt
import os
import shutil
import copy
import time
import re
from datetime import datetime
new_password="" # senha do usuario
passwd_filename="root/etc/passwd"
shadow_filename="root/etc/shadow"
group_filename="root/etc/group"
gshadow_filename="root/etc/gshadow"
addUserErrorLog="add.log"
# funcao para criar id de usuario e/ou grupo
# a partir dos id's ja utilizados
# idsFile = arquivo onde se encontram as informacoes
# de usuario ou grupo
# exemplo: /etc/passwd, /etc/group
def getNewId(idsFile):
new_id=0
# variavel para armazenar arquivo
passwd = open(idsFile,'r')
# realizar leitura das linhas
# TODO pode ser utilizado diretamente
for linha in passwd.readlines():
# recuperar apenas o id
max_id=int(linha.strip('\n').split(':')[2])
# verificar se o id é maior que o atual
if max_id < 9999 and max_id > new_id:
new_id = max_id
new_id=new_id+1
# retornar o novo id
return new_id
# funcao para requisicao de senha do usuario
def getPassword():
# o operador global se faz necessario para modificar o valor da variavel global "new_password"
global new_password
# requisitar ao usuario que informa a senha
new_password = getpass.getpass("Digite a nova senha UNIX:")
# requisitar a confirmacao da senah
confirm_password = getpass.getpass("Redigite a nova senha UNIX:")
# caso a senha nao seha informada repetir o precesso anterior
while new_password == "":
# informar ao usuario que a senha noa foi digitada
print "Nenhuma senha informada"
new_password = getpass.getpass("Digite a nova senha UNIX:")
confirm_password = getpass.getpass("Redigite a nova senha UNIX:")
# verificar se a confirmacao da senha esta correta
if new_password != confirm_password:
# caso nao esteja informar o erro
print "Sorry, passwords do not match"
print "passwd: Erro na manipulação de token de autenticação"
print "passwd: Senha não alterada"
# perguntar ao usuario se deseja inserir a senha novamente
res=raw_input("Tentar de novo? [y/N]")
# caso afirmativo repetir o precesso de requisicao de senha
if re.match('[sSyY]',res):
getPassword()
# caso negativo salvar usuario sem senha '!'
else:
new_password="!"
# funcao para copiar arquivos
# src = diretorio origem dos arquivos
# dst = diretorio destino, onde os arquivos devem ser copiados
def copyFiles(src,dst):
for f in os.listdir(src):
shutil.copy(src+f,dst)
# funcao para remover o usuario
# username = nome do usuario a ser removido
def delUser(username):
# realizar a leitura de todos os arquivos e armazenados em listas
passwdLines = open(passwd_filename,'r').readlines()
shadowLines = open(shadow_filename,'r').readlines()
groupLines = open(group_filename,'r').readlines()
gshadowLines = open(gshadow_filename,'r').readlines()
# bkp das informacoes das listas
_bkp_PasswdLines = copy.copy(passwdLines)
_bkp_ShadowLines = copy.copy(shadowLines)
_bkp_GroupLines = copy.copy(groupLines)
_bkp_GshadowLines = copy.copy(gshadowLines)
# TODO realizar copia das listas atuais, no caso de erro
# restaurar os arquivos
# realizar a verificacao em todas as lista
# para encontrar informacoes referentes ao usuario informado
for u in passwdLines:
if u.split(':')[0] == username:
# caso encontre o usuario remover da lista
passwdLines.remove(u)
for s in shadowLines:
if s.split(':')[0] == username:
shadowLines.remove(s)
for g in groupLines:
if g.split(':')[0] == username:
groupLines.remove(g)
for gs in gshadowLines:
if gs.split(':')[0] == username:
gshadowLines.remove(gs)
# abrir arquivos para escrita
passwd = open(passwd_filename,'w')
shadow = open(shadow_filename,'w')
group = open(group_filename,'w')
gshadow = open(gshadow_filename,'w')
try:
# gravar nova lista nos arquivos especificos
print "Removendo o usuário `"+username+"' ..."
# PASSWD
passwd.writelines(passwdLines)
print "Aviso: o grupo `"+username+"' não possui mais membros."
# GROUP
group.writelines(groupLines)
# SHADOW
shadow.writelines(shadowLines)
# GSHADOW
gshadow.writelines(gshadowLines)
print "Concluído."
except Exception, e:
print 'Erro ao remover usuário '+ username +"."
# restaurar informacoes
# PASSWD
passwd.writelines(_bkp_PasswdLines)
# GROUP
group.writelines(_bkp_ShadowLines)
# SHADOW
shadow.writelines(_bkp_GroupLines)
# GSHADOW
gshadow.writelines(_bkp_GshadowLines)
errorLog(e.message)
finally:
# fechar os arquivos
passwd.close()
group.close()
shadow.close()
gshadow.close()
# funcao para adicionar novo usuario
# username = nome do usuario
# home = diretorio padrao do usuario
# senha = senha do usuario
def addUser(username,homeDir=None,user_pass=None):
# TODO
# verificar se o usuario ja existe
# verificar se o diretorio home ja existe
print "Adicionando o usuário `"+username+"' ..."
# recuperar id do novo usuario
uid=getNewId(passwd_filename)
# verificar se foi informado um caminho diferente
# do padrão para a home do usuario
if homeDir == None:
homeDir="/home/"+username
# criar grupo para o usuario e recuperar o id do grupo
gid=addGroup(username,uid)
print "Criando diretório pessoal `"+homeDir+"' ..."
# criar diretorio pessoal do usuario
os.mkdir(homeDir)
# modificar permissoes de acesso da pasta pessoal do usuario
os.chmod(homeDir,0755)
# modificar dono e grupo do diretorio pessoal
os.chown(homeDir,uid,gid)
print "Copiando arquivos de `/etc/skel' ..."
# copiar arquivos padrao para o diretorio pessoal do usuario
copyFiles('/etc/skel/',homeDir)
# criar senha do usuario se for utilizado o modo iterativo
if user_pass == None:
getPassword()
# adicionar ao shadow
# abrir arquivo shadow no modo append
shadow_file=open(shadow_filename,'a')
# o operador global se faz necessario para modificar o valor da variavel global "new_password"
global new_password
# se nao utilizar o modo iterativo
if user_pass != None and user_pass != "":
new_password=user_pass
# verificar se o usuario possui senha
if new_password != "!":
# data atual ##/##/#### ##:##:##
time=datetime.now()
aux1=str(time.year)[1:2] # 2 primeiros digitos do ano
aux2=str(time.year)[3:4] # 2 ultimos digitos do ano
# sal para gerar a senha, combinacao
# dia, mes, ano1,minuto,ano2,segundos,mes
salt=str(time.day)+str(time.hour)+aux1+str(time.minute)+aux2+str(time.second)+str(time.month)
salt="$6$"+salt+"$"
# criptografar senha
new_password=crypt.crypt(new_password,salt)
# salvar informacoes no shadow
shadow_file.write(username+":"+new_password+":15633:0:99999:7:::\n")
# fechar arquivo
shadow_file.close()
print "Modificando informações de usuário para "+username
# recuperar restante das informacoes do usuario se utilizar o modo iterativo
complete_name = ""
class_number=""
work_phone=""
home_phone=""
other=""
# se nao utilizar o modo iterativo
if user_pass != None:
complete_name = username.replace(username[0],username[0].upper())
else:
print "Informe o novo valor ou pressione ENTER para aceitar o valor padrão"
complete_name = raw_input("\tNome Completo []: ")
class_number=raw_input("\tNúmero da Sala []: ")
work_phone=raw_input("\tFone de Trabalho []: ")
home_phone=raw_input("\tFone Doméstico []: ")
other=raw_input("\tOutro []: ")
res=""
# se utilizar o modo iterativo
if user_pass == None:
res=raw_input("Esta informação está correta?[S/n]")
while not re.match('[sSyY]',res):
complete_name = raw_input("\tNome Completo []: ")
class_number=raw_input("\tNúmero da Sala []: ")
work_phone=raw_input("\tFone de Trabalho []: ")
home_phone=raw_input("\tFone Doméstico []: ")
other=raw_input("\tOutro []: ")
res=raw_input("Esta informação está correta?[S/n]")
# abrir passwd no modo apped
passwd_file=open(passwd_filename,'a')
numbers=str(class_number)+","+work_phone+","+home_phone
if(other != ""):
numbers=numbers+","+other
# salvar informacoes no passwd
passwd_file.write(username+":x:"+str(uid)+":"+str(gid)+":"+complete_name+","+numbers+":"+homeDir+":/bin/bash\n")
# fechar arquivo
passwd_file.close()
# funcao para adicinar grupo
# username = nome do usuario
# userid = id do usuario
def addGroup(username,userid):
# recuperar id do novo grupo
gid=getNewId(group_filename)
# variavel que contem as informacoes do grupo
group = username+":x:"+str(gid)
print "Adicionando novo grupo `"+username+"' ("+str(gid)+")..."
# adicionar ao gshadow
# abrir arquivo no modo append
gshadow_file=open(gshadow_filename,'a')
# salvar informacoes do grupo
gshadow_file.write(username+":!::\n")
# fechar arquivo
gshadow_file.close()
print "Adicionando novo usuário `"+username+"' ("+str(userid)+") ao grupo `"+username+"' ..."
# abrir arquivo no modo append
group_file=open(group_filename,'a')
# salvar informacoes do grupo
group_file.write(group+":\n")
# fechar arquivo
group_file.close()
# retornar o id do grupo salvo
return gid
# funcao para salvar mensagens de erro em arquivo de log
def errorLog(error):
logTime=time.strftime("%d/%m/%Y %H:%M:%S", time.localtime())
log=open(addUserErrorLog,'a')
log.write('[-] '+logTime+' - '+ error+'\n')
log.close()
# funcao para pesquisar usuario
# username = nome do usuario
# file = arquivo de usuarios
def findUser(username,file):
# ler todas as linhas do arquivo de usuarios
for u in open(file,'r').readlines():
# se o usuario existir retornar seu nome
if u.split(':')[0] == username:
return username
return None
# funcao para verificar se diretorio existe
# path = caminho completo do diretório
def findDir(path):
# guardar apenas o nome do diretorio
homeDir=path.split('/')[-1]
#remover diretorio do path
path=path.replace(homeDir,'')
# verificar todos os arquivos do path atual
for d in os.listdir(path):
# retornar o nome do diretorio caso ele exista
if os.path.isdir(path+homeDir) and d == homeDir:
return d
return None
def main():
# addUser add|del usuario home senha
if len(sys.argv) < 3:
print "Informe os parâmetros necessários\n[add|del] <username> [<homedir>] [<password>]"
else:
# se a funcao for adicionar
if sys.argv[1] == 'add':
# se utilzar o modo iterativo
if findUser(sys.argv[2],passwd_filename) != None:
print 'Usuário \''+sys.argv[2]+'\' já existe.'
errorLog('Usuário \''+sys.argv[2]+'\' já existe.')
exit(1) # usuario ja existe
elif findDir(sys.argv[3]) != None:
print 'Diretório \''+sys.argv[3]+'\' já existe.'
errorLog('Diretório \''+sys.argv[3]+'\' já existe.')
exit(2) # diretorio ja existe
if len(sys.argv) == 4:
# nao e informado a senha
addUser(username=sys.argv[2],homeDir=sys.argv[3])
elif len(sys.argv) == 5:
# nao utilizar o modo iterativo, informando a senha
addUser(username=sys.argv[2],homeDir=sys.argv[3],user_pass=sys.argv[4])
# se a funcao for remover usuario
elif sys.argv[1] == 'del':
delUser(username=sys.argv[2])
# funcao invalida
else:
print 'A opção \''+sys.argv[1]+'\' não existe.'
if __name__ == '__main__':
main()
Serialização em Python usando pickle
Dividir um grupo de arquivos em vários CDs Ou DVDs
Descobrir HOME do usuario e criar arquivo de configuração
Leitor de arquivo via linha de comandoEs
Nenhum comentário foi encontrado.
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Novos apps de produtividade, avanços em IA e distros em ebulição agitam o universo Linux
Como instalar o repositório do DBeaver no Ubuntu
Como instalar o Plex Media Server no Ubuntu
Digitando underscore com "shift" + "barra de espaços"
Como ativar a lixeira e recuperar aquivos deletados em um servidor Linux
Como mudar o nome de dispositivos Bluetooth via linha de comando
dpkg: erro: gatilho de arquivo duplicado chamado pelo arquivo de nome (6)
Instalação não está resolvendo as dependencias (2)
Captação de áudio no zorin linux começa a diminuir com o tempo (5)
Alternativas ao Multilogin para gerenciamento de múltiplas contas/prof... (0)









