Adicionar/remover usuários

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

[ Hits: 6.754 ]

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

Inversor de Links

Juntando tabelas em aquivo texto

Agenda PasPy

hicon - Criador de ícones desktop e aplicações do Gnome

ccl - cut and change lines


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts