Adicionar/remover usuários
Publicado por Italo Pessoa (última atualização em 14/03/2013)
[ Hits: 6.885 ]
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
subwrite - um simples editor de texto em Python
hicon - Criador de ícones desktop e aplicações do Gnome
Nenhum comentário foi encontrado.
Enviar mensagem ao usuário trabalhando com as opções do php.ini
Meu Fork do Plugin de Integração do CVS para o KDevelop
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Compartilhamento de Rede com samba em modo Público/Anônimo de forma simples, rápido e fácil
Cups: Mapear/listar todas as impressoras de outro Servidor CUPS de forma rápida e fácil
Criando uma VPC na AWS via CLI
Tem como instalar o gerenciador AMD Adrenalin no Ubuntu 24.04? (16)
Arch Linux - Guia para Iniciantes (2)
Problemas ao instalar o PHP (11)
Tenho dois Link's ( IP VÁLIDOS ), estou tentando fazer o failover... (0)