Skip to content
Snippets Groups Projects
Select Git revision
  • main default protected
  • refactor/folder-structure
2 results

useradm

  • Clone with SSH
  • Clone with HTTPS
  • user avatar
    yago yudi authored
    e9f362fe
    History

    Useradm

    This command is a CLI for managing users and groups in a LDAP/KRB environment.

    Installation

    To install, just clone the repo:

    git clone https://gitlab.c3sl.ufpr.br/tss24/useradm.git

    and build the binary:

    cd useradm && go build -o useradm

    if you want, add it the go path use:

    go install

    Usage

    For each command given we want to know what we will interact with (user/group), as well as the action (create/remove/etc). The CLI will ask for confirmation in commands where some change is made so you can preview and denyif something is not as you wanted.

    Note 1: order of flags does not matter

    Note 2: most commands have the -y flag to skip the confirmation if you want

    Show

    To show a user's info you can use:

    useradm user show [options]

    the command needs identifiers to make the search, such as:

    useradm user show -n pedro -r 2024 -g bcc -i 

    here it is searching for a user with name with pedro, grr with 2024, is part of the group 'bcc' and -i is to make the search case insensitive.

    Create

    To create a user you can use:

    useradm user create [options]

    the command needs some basic info to create a user. The baseline is this:

    useradm user create -n "<User Full Name>" -g <User group>

    but if we run something like

    useradm user create -n "Joao da Silva" -g bcc

    we will get an error. That is because the login generation needs the user GRR for the default 'ini' login type. So this is now correct:

    useradm user create -n "Joao da Silva" -g bcc -t last

    the auto generation will be explained in the section "Implementation"

    Remove

    To remove a user, since the login name is guaranteed to be unique, you can use:

    useradm user remove [username]

    then the users info will be displayed for confirmation and their account will be removed from LDAP and Kerberos, their directories will end up at:

    home: /home/contas_removidas/<Year of removal>/
    webdir: /home/contas_removidas/html/<Year of removal>/
    webdir: /nobackup/contas_removidas/<Year of removal>/

    You can modify these paths in /cmd/user/create.go

    Modify

    To modify a user you can do:

    useradm user mod [username]

    after pressing return a temp file with the user config will be opened in an editor (based on your terminal varible $EDITOR).

    After editing you can save and exit the file and the modifications will be read, shown for confirmation and applied.

    Reset

    The most often used modification gets it's own command.

    To reset a user's password you can do:

    useradm user reset [flag]

    with no flag a password will be auto-generated. Passing the flag -p you can specify the new password. Passwords need to be good lol.

    Bulk

    TODO :))))))

    Migrate

    TODO :<<<<<

    Evolve(?)

    TODO :&&&&&&&

    Implementation

    To make this binary I used Go's cobra CLI module since it is common and I wanted to learn Go lol. It makes it easy to show help and parsing args/flags :D

    This command is the evolution of useradm.py and was heavily based on it. It had no documentation besides the actual code with no comments. So for anyone that is going to change this in the future I will now explain how things work. I will now explain some not so obvious parts.

    LDAP

    Since we use LDAP to store data about users I used the LDAP module to make and send requests. A good example is user show to use that command we first get all users and store them in a array of User models (structs). Then we filter based on the user input.

    To connect to LDAP we need to connect to the socket, and bind it using some credentials. From the time of writting this (26/02/2025) there is a password file that is used for that in urquell lol.

    Then we generate the request that will give us all the users, get the response, and store the result in structs.

    Many other requests are made in the code and you can learn the syntax by reading it or via the docs of the module. One thing I want to add it that in LDAP, group assingments need to be done by setting the user object to be member of the group and set the group object to have the user as a member. Interesting...

    Kerberos

    You may have realized that we do not store user passords in LDAP. We store them in Kerberos. After you created the LDAP entry you can create a KerberosPrincipal for the user that will take care of authentication and tokens. When you create a principal you need to set a password via the kadmin.local command, which is cursed :p the command even returns 0 (success) even when the password change was not accepted so the function for it is a little different (PS: don't judge me)

    Validation

    The old command useradm.py didn't really validate the entries given and had no confirmation. Because of that and some intelligence misfortunes there were/are some users with messed up names, gecos, etc. So I made an effort on making a CLI that minimizes those misfortunes.

    Login generation

    useradm.py had 3 functions to generate names that used a very wierd algorithm. At first I just copied them, then I thought it was too long and repetitive so I merged them into one (See commit e49eca75). It was VERY ugly, so Fernando K. helped and rewrote/improved the algorithm to a more mantainable state, thanks :) (See commit e9762f8b)

    There are 3 types of login generation: ini, first, last. Instead of explaining how the algorithm works, I believe it is best to just show examples. So for the user with name Fabiano Antunes Pereira de Souza, with GRR 20241982:

    'ini' would create the following (based on variance variable):

    faps24
    faaps24
    faanps24
    faanpes24
    faanpeso24
    fabanpeso24

    and so on. 'first' would create something like this:

    fabiano
    fabianoa
    fabianoap
    fabianoaps
    fabianoanps
    fabianoanpes
    fabianoanpeso

    and so on. 'last' would generate:

    fapsouza
    faapsouza
    faanpsouza
    faanpesouza
    fabanpesouza
    fabantpesouza

    and so on...

    You may use /cmd/user/create_test.go if you want a test for the algorithm.

    Essentially we add one letter to each name part for each variance added. We also remove any connectives (do, da, de, dos, von...) from the name. If there comes a time a person appears with a new connective, update the formatName() function currently at /cmd/user/create.go to account for that :)

    TODO: finish...