1/* 2 Copyright (C) Andrew Tridgell 2009 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#define UID_WRAPPER_NOT_REPLACE 19#include "includes.h" 20#include "system/passwd.h" 21#include "system/filesys.h" 22 23#ifndef _PUBLIC_ 24#define _PUBLIC_ 25#endif 26 27/* 28 we keep the virtualised euid/egid/groups information here 29 */ 30static struct { 31 bool initialised; 32 bool enabled; 33 uid_t euid; 34 gid_t egid; 35 unsigned ngroups; 36 gid_t *groups; 37} uwrap; 38 39static void uwrap_init(void) 40{ 41 if (uwrap.initialised) return; 42 uwrap.initialised = true; 43 if (getenv("UID_WRAPPER")) { 44 uwrap.enabled = true; 45 /* put us in one group */ 46 uwrap.ngroups = 1; 47 uwrap.groups = talloc_array(talloc_autofree_context(), gid_t, 1); 48 uwrap.groups[0] = 0; 49 } 50} 51 52#undef uwrap_enabled 53_PUBLIC_ int uwrap_enabled(void) 54{ 55 uwrap_init(); 56 return uwrap.enabled?1:0; 57} 58 59_PUBLIC_ int uwrap_seteuid(uid_t euid) 60{ 61 uwrap_init(); 62 if (!uwrap.enabled) { 63 return seteuid(euid); 64 } 65 /* assume for now that the ruid stays as root */ 66 uwrap.euid = euid; 67 return 0; 68} 69 70_PUBLIC_ uid_t uwrap_geteuid(void) 71{ 72 uwrap_init(); 73 if (!uwrap.enabled) { 74 return geteuid(); 75 } 76 return uwrap.euid; 77} 78 79_PUBLIC_ int uwrap_setegid(gid_t egid) 80{ 81 uwrap_init(); 82 if (!uwrap.enabled) { 83 return setegid(egid); 84 } 85 /* assume for now that the ruid stays as root */ 86 uwrap.egid = egid; 87 return 0; 88} 89 90_PUBLIC_ uid_t uwrap_getegid(void) 91{ 92 uwrap_init(); 93 if (!uwrap.enabled) { 94 return getegid(); 95 } 96 return uwrap.egid; 97} 98 99_PUBLIC_ int uwrap_setgroups(size_t size, const gid_t *list) 100{ 101 uwrap_init(); 102 if (!uwrap.enabled) { 103 return setgroups(size, list); 104 } 105 106 talloc_free(uwrap.groups); 107 uwrap.ngroups = 0; 108 uwrap.groups = NULL; 109 110 if (size != 0) { 111 uwrap.groups = talloc_array(talloc_autofree_context(), gid_t, size); 112 if (uwrap.groups == NULL) { 113 errno = ENOMEM; 114 return -1; 115 } 116 memcpy(uwrap.groups, list, size*sizeof(gid_t)); 117 uwrap.ngroups = size; 118 } 119 return 0; 120} 121 122_PUBLIC_ int uwrap_getgroups(int size, gid_t *list) 123{ 124 uwrap_init(); 125 if (!uwrap.enabled) { 126 return getgroups(size, list); 127 } 128 129 if (size > uwrap.ngroups) { 130 size = uwrap.ngroups; 131 } 132 if (size == 0) { 133 return uwrap.ngroups; 134 } 135 if (size < uwrap.ngroups) { 136 errno = EINVAL; 137 return -1; 138 } 139 memcpy(list, uwrap.groups, size*sizeof(gid_t)); 140 return uwrap.ngroups; 141} 142 143_PUBLIC_ uid_t uwrap_getuid(void) 144{ 145 uwrap_init(); 146 if (!uwrap.enabled) { 147 return getuid(); 148 } 149 /* we don't simulate ruid changing */ 150 return 0; 151} 152 153_PUBLIC_ gid_t uwrap_getgid(void) 154{ 155 uwrap_init(); 156 if (!uwrap.enabled) { 157 return getgid(); 158 } 159 /* we don't simulate rgid changing */ 160 return 0; 161} 162