Skip to content

Instantly share code, notes, and snippets.

@kadler
Last active November 27, 2019 22:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kadler/22c8fef08a9d45da189dc1c41ccc44de to your computer and use it in GitHub Desktop.
Save kadler/22c8fef08a9d45da189dc1c41ccc44de to your computer and use it in GitHub Desktop.
Basic sudo implementation on IBM i

Basic sudo implementation on IBM i

Uses standard Unix setuid to change the current process user id and executes the parameters passed. On other platforms, this usually requires root authority, but on IBM i we just need *USE authority to the user profile. :)

Build

gcc -o sudo sudo.c

Example

$ whoami
kadler

$ ./sudo whoami
qsecofr

$ ./sudo -u dummy
dummy

$ ./sudo -u 1234
otherdummy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include <pwd.h>
int debug(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
int rc = vprintf(fmt, args);
printf("\n");
return rc;
}
int fatal(const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
printf("\n");
exit(1);
}
int main(int argc, char** argv)
{
if(argc < 2 || strcmp(argv[1], "-h") == 0)
{
debug("usage: %s cmd [cmd args]\n", argv[0]);
return 1;
}
int rc;
uid_t uid = 0;
int argindex = 1;
if(argc > 1 && strcmp(argv[1], "-u") == 0)
{
if(argc > 2)
{
const char* username = argv[2];
argindex = 3;
if(*username >= '0' && *username <= '9') {
uid = (uid_t) atoi(username);
}
else {
putenv("PASE_USRGRP_LIMITED=N");
struct passwd* pwd = getpwnam(username);
if(!pwd) {
fatal("Couldn't get user");
}
uid = pwd->pw_uid;
}
}
}
setuid(uid);
execvp(argv[argindex], &argv[argindex]);
perror("Couldn't exec");
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment