ITEM: BL8384L
how to set real-uid to non-superuser and regain superuser later
Response:
ENV: AIX 4
DESC:
Need to change the effective and real user ids of a single process
during while the program is running. The sequence of user id changes
must be as follows.
1. real-uid = root , effective-uid = root, saved-uid = root
2. real-uid = non-root, effective-uid = non-root, saved-uid = root
3. real-uid = root, effective-uid = root, saved-uid = root.
ACTION:
Changes the user ids of a process in the above order requires
two different programs on AIX 4.2 and AIX 4.1. The primary reason
for the two different programs is that the setreuid() function
has been changed to support SPEC 1170 (VSU).
Included in this item are each procedure. Standard documented
system calls can be used on AIX 4.2 to accomplish the above
sequence of user ids. ON AIX 4.1 however, a number of
undocumented functions setgidx(), and setuidx must be used.
*********************** ON AIX 4.2 ******************************
The following program will produced the desired results
on AIX 4.2.
1. Make the executable owned by root with setuid bit set.
When it is invoked by a non-root user (e.g., 100), the
real user id will be non-root and the effective user id will be
root.
The commands that you can use (as the root user) to get the
proper initial setting of the executable file is:
chown root 'program'
chmod +s 'program'
chmod g-s 'program'
AIX 4.2 Sample code below:
\#include \
\#include \
\#include \
void printids()
{ printf("uid = %d\\teuid = %d\\n",
getuid(), geteuid());
}main ()
{ uid_t uid;
uid = 203;
printf(" 0. Starts with...\\n");
printids();
printf(" 1. seteuid (uid)\\n");
if (seteuid (uid) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 2. setreuid (uid, 0)\\n");
if (setreuid( uid, 0 ) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 3. setuid (0)\\n");
if (setuid (0) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 4. setreuid (uid, 0)\\n");
if (setreuid (uid,0) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 1. seteuid (uid)\\n");
if (seteuid (uid) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 2. setreuid (uid, 0)\\n");
if (setreuid( uid, 0 ) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 3. setuid (0)\\n");
if (setuid (0) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
printf(" 4. setreuid (uid, 0)\\n");
if (setreuid (uid,0) \< 0)
printf("failed. errno = %d '%s'\\n", errno, strerror (errno));
printids();
}
End AIX 4.2 sample code
*********************** ON AIX 4.1 ******************************
The following is a program (testcreds) that can be used on AIX 4.1
to change the real and effective user ids in the indicated
sequence above.
The setuidx() function is an internal routine that is visible
in .h files because they have to be. Documentation on this
unsupported function is not intended to be available.
$ ls -la testcreds
-rwsrwsr-x 1 root staff 14751 Sep 09 10:39 testcreds
$ id
uid=202(bartula) gid=1(staff)
AIX 4.1 Sample code begin:
\#include \
\#include \
\#include \
\#include \
\#define _LLPL_TYPES_ONLY
\#if 0
\#include \
\#include \
\#include \
\#include \
\#endif /* 0 */
/********************************/
/* external functions */
/********************************/
typedef unsigned long uid_t;
typedef unsigned long gid_t;
\#include \
\#include \
\#include \
\#include \ // Error checking
extern "C" int getpriv(int which, priv_t *privset, size_t privsiz);
extern "C" int setpriv(int which, priv_t *privset, size_t privsiz);
extern "C" void sigaddset (void *, int);
extern "C" int setresuid(uid_t ruid, uid_t euid, uid_t suid);
extern "C" int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
\#define seteuid(euid) setresuid( -1, (euid), -1)
\#define setegid(egid) setresgid( -1, (egid), -1)
extern "C" uid_t geteuid();
extern "C" gid_t getegid();
extern "C" int getgroups(int max_n_groups, gid_t *gidset);
extern "C" int setgroups(int n_groups, gid_t *gidset);
void setcreds(int an_id ,int a_gid );
void re_setcreds();
void printids();
int saved_privs[2];
main(int argc, char *argv[])
{ if (argc != 3) {
cerr \<\< "USAGE: testpriv uid gid";
exit(1);
}
int id = atoi(argv[1]);
int gid = atoi(argv[2]);
printids();
cout \<\< "setting credentials " \<\< endl;
setcreds(id,gid);
cout \<\< "re-setting credentials " \<\< endl;
re_setcreds();
cout \<\< "setting credentials " \<\< endl;
setcreds(id,gid);
cout \<\< "re-setting credentials " \<\< endl;
re_setcreds();
}void setcreds(int owner, int group)
{ priv_t ps;
ps.pv_priv[0] = 0;
ps.pv_priv[1] = 0;
/* we want no privileges except the ability to get back */
sigaddset ((void *)&ps, SET_PROC_DAC);
int r = setpriv (PRIV_SET | PRIV_EFFECTIVE, &ps, sizeof (ps));
if(r != 0) {
cerr \<\< "setpriv failed to reduce privs: " \<\< endl;
cerr \<\< "errno = " \<\< errno \<\< endl; // Error checking
}
r = setgidx (ID_SAVED | ID_REAL | ID_EFFECTIVE, group);
if(r != 0) {
cerr \<\< "setgidx failed to reduce privs: " \<\< endl;
cerr \<\< "errno = " \<\< errno \<\< endl; // Error checking
}
r = setuidx (ID_SAVED | ID_REAL | ID_EFFECTIVE, owner);
if(r != 0) {
cerr \<\< "setuidx failed to reduce privs: " \<\< endl;
cerr \<\< "errno = " \<\< errno \<\< endl; // Error checking
}
printids();
}
void re_setcreds()
{ int r = setuidx (ID_SAVED | ID_REAL | ID_EFFECTIVE, 0); // Set back to root.
if(r != 0) {
cerr \<\< "setpriv failed to reduce privs: " \<\< endl;
cerr \<\< "errno = " \<\< errno \<\< endl; // Error checking
}
printids();
}
void printids()
{ printf("uid = %d\\teuid = %d\\n",
getuid(), geteuid());
}
End of AIX 4.1 Sample Code
Support Line: how to set real-uid to non-superuser and regain superuser later ITEM: BL8384L
Dated: March 1997 Category: N/A
This HTML file was generated 99/06/24~13:30:21
Comments or suggestions?
Contact us