Goto sanos source index
//
// user.c
//
// User management
//
// Copyright (C) 2002 Michael Ringgaard. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//
#include <os/krnl.h>
int getuid() {
return self()->ruid;
}
int setuid(uid_t uid) {
struct thread *thread = self();
if (thread->euid == 0) {
thread->ruid = thread->euid = uid;
} else if (uid == thread->ruid) {
thread->euid = uid;
} else {
return -EPERM;
}
return 0;
}
int getgid() {
return self()->rgid;
}
int setgid(gid_t gid) {
struct thread *thread = self();
if (thread->euid == 0) {
thread->rgid = thread->egid = gid;
} else if (gid == thread->rgid) {
thread->egid = gid;
} else {
return -EPERM;
}
return 0;
}
int geteuid() {
return self()->euid;
}
int seteuid(uid_t uid) {
struct thread *thread = self();
if (thread->euid == 0 || uid == thread->ruid) {
thread->euid = uid;
} else {
return -EPERM;
}
return 0;
}
int getegid() {
return self()->egid;
}
int setegid(gid_t gid) {
struct thread *thread = self();
if (thread->euid == 0 || gid == thread->rgid) {
thread->egid = gid;
} else {
return -EPERM;
}
return 0;
}
int getgroups(int size, gid_t *list) {
struct thread *thread = self();
if (!list || size < thread->ngroups) return -EINVAL;
memcpy(list, thread->groups, thread->ngroups * sizeof(gid_t));
return thread->ngroups;
}
int setgroups(int size, gid_t *list) {
struct thread *thread = self();
if (thread->euid != 0) return -EPERM;
if (!list || size < 0 || size > NGROUPS_MAX) return -EINVAL;
thread->ngroups = size;
memcpy(thread->groups, list, size * sizeof(gid_t));
return 0;
}
int check(int mode, uid_t uid, gid_t gid, int access) {
struct thread *thread = self();
if (thread->euid == 0) return 0;
if (thread->euid != uid) {
access >>= 3;
if (thread->egid != gid) access >>= 3;
}
if ((mode & access) == access) return 0;
return -EACCES;
}