Adicionar/remover usuários

Publicado por Italo Pessoa (última atualização em 14/03/2013)

[ Hits: 4.543 ]

Homepage: http://xconhecimento.blogspot.com.br

Download addUser.py




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.

  



Esconder código-fonte

#!/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()

Scripts recomendados

Criando um rootfs para sistemas embarcados a partir de cópia de um sistema já operando

ccl - cut and change lines

Expressão regular com input STDIN

Agenda de cadastros com tratamento de erros

Dividir um grupo de arquivos em vários CDs Ou DVDs


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts