#ifndef _SYS_PERSONA_H_
#define _SYS_PERSONA_H_
#ifdef PRIVATE
#include <sys/param.h>
enum {
PERSONA_INVALID = 0,
PERSONA_GUEST = 1,
PERSONA_MANAGED = 2,
PERSONA_PRIV = 3,
PERSONA_SYSTEM = 4,
PERSONA_TYPE_MAX = PERSONA_SYSTEM,
};
#define PERSONA_ID_NONE ((uid_t)-1)
struct kpersona_info {
uint32_t persona_info_version;
uid_t persona_id;
int persona_type;
gid_t persona_gid;
uint32_t persona_ngroups;
gid_t persona_groups[NGROUPS];
uid_t persona_gmuid;
char persona_name[MAXLOGNAME+1];
};
#define PERSONA_INFO_V1 1
#define PERSONA_INFO_V1_SIZE (sizeof(struct kpersona_info))
#define PERSONA_OP_ALLOC 1
#define PERSONA_OP_DEALLOC 2
#define PERSONA_OP_GET 3
#define PERSONA_OP_INFO 4
#define PERSONA_OP_PIDINFO 5
#define PERSONA_OP_FIND 6
#ifndef KERNEL
int kpersona_alloc(struct kpersona_info *info, uid_t *id);
int kpersona_dealloc(uid_t id);
int kpersona_get(uid_t *id);
int kpersona_info(uid_t id, struct kpersona_info *info);
int kpersona_pidinfo(pid_t pid, struct kpersona_info *info);
int kpersona_find(const char *name, uid_t uid, uid_t *id, size_t *idlen);
#endif
#ifdef KERNEL_PRIVATE
#include <sys/cdefs.h>
#include <sys/kauth.h>
#include <libkern/libkern.h>
#ifdef PERSONA_DEBUG
#define persona_dbg(fmt, ...) \
printf("[%4d] %s: " fmt "\n", \
current_proc() ? current_proc()->p_pid : -1, \
__func__, ## __VA_ARGS__)
#else
#define persona_dbg(fmt, ...) do { } while (0)
#endif
#ifdef XNU_KERNEL_PRIVATE
struct persona {
int32_t pna_refcount;
int32_t pna_valid;
uid_t pna_id;
int pna_type;
char pna_login[MAXLOGNAME+1];
kauth_cred_t pna_cred;
uid_t pna_pgid;
int pna_cred_locked;
LIST_ENTRY(persona) pna_list;
LIST_HEAD(, proc) pna_members;
lck_mtx_t pna_lock;
#ifdef PERSONA_DEBUG
char pna_desc[128];
#endif
};
#define persona_lock(persona) lck_mtx_lock(&(persona)->pna_lock)
#define persona_unlock(persona) lck_mtx_unlock(&(persona)->pna_lock)
#define persona_try_lock(persona) lck_mtx_try_lock(&(persona)->pna_lock)
#define persona_lock_assert_held(persona) \
lck_mtx_assert(&(persona)->pna_lock, LCK_MTX_ASSERT_OWNED)
#ifdef PERSONA_DEBUG
static inline const char *persona_desc(struct persona *persona, int locked)
{
if (!persona)
return "<none>";
if (persona->pna_desc[0] != 0)
return persona->pna_desc;
if (!locked)
persona_lock(persona);
if (persona->pna_desc[0] != 0)
goto out_unlock;
char *p = &persona->pna_desc[0];
char *end = p + sizeof(persona->pna_desc) - 1;
*end = 0;
p += snprintf(p, end - p, "%s/%d:%d",
persona->pna_login,
kauth_cred_getuid(persona->pna_cred),
kauth_cred_getgid(persona->pna_cred));
if (p <= end)
*p = 0;
out_unlock:
if (!locked)
persona_unlock(persona);
return persona->pna_desc;
}
#else
static inline const char *persona_desc(struct persona *persona, int locked)
{
(void)persona;
(void)locked;
return "<persona>";
}
#endif
#else
struct persona;
#endif
__BEGIN_DECLS
#ifndef _KAUTH_CRED_T
#define _KAUTH_CRED_T
typedef struct ucred *kauth_cred_t;
#endif
uid_t persona_get_id(struct persona *persona);
int persona_get_type(struct persona *persona);
kauth_cred_t persona_get_cred(struct persona *persona);
struct persona *persona_lookup(uid_t id);
int persona_find(const char *login, uid_t uid,
struct persona **persona, size_t *plen);
struct persona *current_persona_get(void);
struct persona *persona_get(struct persona *persona);
void persona_put(struct persona *persona);
#ifdef XNU_KERNEL_PRIVATE
#if CONFIG_PERSONAS
#include <sys/proc_internal.h>
extern uint32_t g_max_personas;
extern struct persona *g_system_persona;
void personas_bootstrap(void);
struct persona *persona_alloc(uid_t id, const char *login,
int type, int *error);
int persona_invalidate(struct persona *persona);
static inline int proc_has_persona(proc_t p)
{
if (p && p->p_persona)
return 1;
return 0;
}
static inline uid_t persona_id_from_proc(proc_t p)
{
if (p && p->p_persona)
return p->p_persona->pna_id;
return PERSONA_ID_NONE;
}
int persona_proc_inherit(proc_t child, proc_t parent);
int persona_proc_adopt_id(proc_t p, uid_t id,
kauth_cred_t auth_override);
int persona_proc_adopt(proc_t p, struct persona *persona,
kauth_cred_t auth_override);
int persona_proc_drop(proc_t p);
int persona_set_cred(struct persona *persona, kauth_cred_t cred);
int persona_set_cred_from_proc(struct persona *persona, proc_t proc);
uid_t persona_get_uid(struct persona *persona);
int persona_set_gid(struct persona *persona, gid_t gid);
gid_t persona_get_gid(struct persona *persona);
int persona_set_groups(struct persona *persona, gid_t *groups, int ngroups, uid_t gmuid);
int persona_get_groups(struct persona *persona, int *ngroups, gid_t *groups, int groups_sz);
uid_t persona_get_gmuid(struct persona *persona);
int persona_get_login(struct persona *persona, char login[MAXLOGNAME+1]);
struct persona *persona_proc_get(pid_t pid);
#else
static inline int proc_has_persona(__unused proc_t p)
{
return 0;
}
static inline uid_t persona_id_from_proc(__unused proc_t p)
{
return PERSONA_ID_NONE;
}
#endif
#endif
__END_DECLS
#endif
#endif
#endif