Mimic the Linux adduser command in C


The add user command in Linux is used to add new user accounts on operating systems that resemble Unix. It is frequently used by system administrators to add new users with predetermined usernames, passwords, and other user-related information

System calls

Software can communicate with the kernel of the operating system, which manages system resources and provides services to user-level programs, through system calls. System calls are used in C programming to gain access to the features and services provided by the operating system, including file I/O, process management, network connectivity, and more.

To interact with the operating system, C programmers can utilize the following typical system calls −

open − This function returns a file descriptor that can be used for other file operations after the opening or creation of an existing file.

Example in c

int fd = open("filename.txt", O_RDWR); // open a file for reading and writing
if (fd == -1) {
   p error("open"); // handle error
}

Read: Gets data from the filename or file descriptor into a buffer.

Example in c

char buffer[1024];
int num_read = read(fd, buffer, sizeof(buffer)); // read data from file into buffer
if (num_read == -1) {
   p error("read"); // handle error 
}

write: Writing data from buffer to files or filename descriptors is accomplished by use of the Write command

Example in c

char buffer[1024];
int num_read = read(fd, buffer, sizeof(buffer)); // read data from file into buffer
if (num_read == -1) {
   p error("read"); // handle error
}

close − Ends the file descriptor's life

Example in c

close(fd); // close file descriptor

Fork − Creates a duplicate of the caller process in a new process, enabling the execution of many tasks simultaneously

Example in c

p id_t p id = fork(); // create a new process
if (pid == -1) {
   p error("fork"); // handle error
} else if (p id == 0) {
   // child process code
} else {
   // parent process code
}

exec − Allows the execution of an alternative programme by replacing the existing process image with a new one.

Example in c

execl("/bin/ls", "ls", "-l", NULL); // execute the "ls" command

wait − Puts the calling process on hold until one of its offspring finishes. Example in C −

Example in c

int status;
pid_t pid = wait(&status); // wait for child process to finish
if (pid == -1) {
   p error("wait"); // handle error
} else {
   // handle child process status
}

pipe − Establishes a single-direction channel (pipe) for communication between two processes.

Example in c

int fds[2];
if (pipe(fds) == -1) {
p error("pipe"); // handle error
} else {
   // use fds[0] for reading and fds[1] for writing
}

Kill − Sends a signal to a particular process called "kill" that enables it to be terminated or have its behavior changed.

Example in c

int fds[2];
if (pipe(fds) == -1) {
   p error("pipe"); // handle error
} else {
   // use fds[0] for reading and fds[1] for  writing
}

Socket − creates a network communication socket using the socket command

Example in c

int sockfd = socket(AF_INET, SOCK_STREAM, 0); // create a TCP socket
if (sockfd == -1) {
   perror("socket"); // handle error
}

Bind − Binds a socket to a particular address and port.

Example in c

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(8080);
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
   p error("bind"); // handle error
}

listen − Marks a socket as passive so it will be waiting for connections

Example in c

if (listen(sockfd, 5) == -1) { // set the    backlog to 5 connections
   perror("listen"); // handle error
}

accept − Establishes a new socket for communication with the client after accepting a connection on an existing socket.

Example in c

struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_sockfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len); // accept a new
connection
if (client_sockfd == -1) {
   p error("accept"); // handle error
}

connect − Creates a connection to a distant server at the given address and port.

Example in c

struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(8080);
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
   perror("connect"); // handle error
}

send − Transmits data across an established socket.

Example in c

char* data = "Hello, server!";
int num_sent = send(sockfd, data, strlen(data), 0); // send data to server

rec v − receives information from a connected socket.

Example in c

char buffer[1024];
int num_recv = recv(sockfd, buffer, sizeof(buffer), 0); // receive data from server into buffer
if (num_recv == -1) {
   perror("recv"); // handle error
}

Steps of Linux add user command in C

To imitate the "add user" command in Linux, you need a C program to perform similar operations as those performed when adding new user accounts into your Linux system. The breakdown of the procedures at this point is as follows:

Accept user input − Use C's input/output functions (scanf() or fgets()) to accept user input for the new user's details, including username, password, and any other required information

Example in c

char username[50];
char password[50];
printf("Enter username: ");
scanf("%s", username);
printf("Enter password: ");
scanf("%s", password);

Validate input − Use input validation to make sure that the entered data is accurate and complies with any specifications. For instance, you might need to make sure the password satisfies specified complexity requirements or that the username doesn't contain any prohibited characters.

Example in c

if(strlen(password) < 8){
   printf("Password should be at least 8 characters long.");
   exit(1);
}

Create user account − Use system calls or functions like fork(), exec(), system(), or libraries like libuser to create the new user account. This can involve executing Linux commands like useradd, or directly manipulating system files like /etc/passwd, /etc/shadow, and /etc/group to add the new user. Be sure to handle any errors or exceptions that may occur during this process.

Example in c

char command[100];
//execute useradd command
sprintf(command, "useradd %s -p %s", username, password);
int status = system(command);
if(status == -1){
   printf("Error creating user account.");
   exit(1);
}

Establish user permissions − To establish the proper permissions for the user's home directory and other pertinent files, use system calls or functions like chown() and chmod(). Setting the files' owner, group, and read, write, and execute rights can be a part of this

Example in c

//change owner of the user's home directory to the newly created user
chown("/home/username", uid, gid);
//set read, write, execute permissions for user, group and others on user's home directory
chmod("/home/username", 0700);

Add other configurations − If necessary, you may also need to define more options, such as the user's default shell, password expiration guidelines, or membership in particular groups. Utilizing the proper system calls or functions, or changing system files, may be required.

Example in c

char command[100];
//add user to the sudo group
sprintf(command, "usermod -aG sudo %s", username);
system(command);

Display output − Give the user suitable feedback about whether the user creation process was successful or unsuccessful and display any pertinent data, such as the newly formed username and home directory path.

Example in c

printf("User %s created successfully.
", username);

Portability

To make a C program portable, use standard C libraries and avoid platform-specific code. Be aware of the system's endianness for binary data and handle errors carefully. Avoid hard coding file paths and use configuration files or environment variables to select directories dynamically

Conclusion

System functions and libraries included in the C language can be used to mimic the "add user" command in Linux using the C programming language. You may simulate the functionality of the "add user" command in Linux by writing a C program that makes use of the proper system calls and functions to establish user accounts, set passwords, and manage user information.

Updated on: 25-Jul-2023

99 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements