00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "includes.h"
00028
00029 #ifndef HAVE_GETGROUPLIST
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups,
00042 int *grpcnt)
00043 {
00044 gid_t *gids_saved;
00045 int ret, ngrp_saved, num_gids;
00046
00047 if (non_root_mode()) {
00048 *grpcnt = 0;
00049 return 0;
00050 }
00051
00052
00053 ngrp_saved = getgroups(0, NULL);
00054 if (ngrp_saved == -1) {
00055
00056 return -1;
00057 }
00058
00059 gids_saved = SMB_MALLOC_ARRAY(gid_t, ngrp_saved+1);
00060 if (!gids_saved) {
00061 errno = ENOMEM;
00062 return -1;
00063 }
00064
00065 ngrp_saved = getgroups(ngrp_saved, gids_saved);
00066 if (ngrp_saved == -1) {
00067 SAFE_FREE(gids_saved);
00068
00069 return -1;
00070 }
00071
00072 if (initgroups(user, gid) != 0) {
00073 DEBUG(0, ("getgrouplist_internals: initgroups() failed!\n"));
00074 SAFE_FREE(gids_saved);
00075 return -1;
00076 }
00077
00078
00079
00080 save_re_gid();
00081 set_effective_gid(gid);
00082 setgid(gid);
00083
00084 num_gids = getgroups(0, NULL);
00085 if (num_gids == -1) {
00086 SAFE_FREE(gids_saved);
00087
00088 return -1;
00089 }
00090
00091 if (num_gids + 1 > *grpcnt) {
00092 *grpcnt = num_gids + 1;
00093 ret = -1;
00094 } else {
00095 ret = getgroups(*grpcnt - 1, &groups[1]);
00096 if (ret < 0) {
00097 SAFE_FREE(gids_saved);
00098
00099 return -1;
00100 }
00101 groups[0] = gid;
00102 *grpcnt = ret + 1;
00103 }
00104
00105 restore_re_gid();
00106
00107 if (sys_setgroups(ngrp_saved, gids_saved) != 0) {
00108
00109 DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n"));
00110 smb_panic("getgrouplist: failed to reset group list!\n");
00111 free(gids_saved);
00112 return -1;
00113 }
00114
00115 free(gids_saved);
00116 return ret;
00117 }
00118 #endif
00119
00120 static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
00121 {
00122 int retval;
00123 BOOL winbind_env;
00124
00125 DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
00126
00127
00128
00129
00130 winbind_env = winbind_env_set();
00131 winbind_off();
00132
00133 #ifdef HAVE_GETGROUPLIST
00134 retval = getgrouplist(user, gid, groups, grpcnt);
00135 #else
00136 become_root();
00137 retval = getgrouplist_internals(user, gid, groups, grpcnt);
00138 unbecome_root();
00139 #endif
00140
00141
00142 if (!winbind_env) {
00143 winbind_on();
00144 }
00145
00146 return retval;
00147 }
00148
00149 BOOL getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user,
00150 gid_t primary_gid,
00151 gid_t **ret_groups, size_t *p_ngroups)
00152 {
00153 size_t ngrp;
00154 int max_grp;
00155 gid_t *temp_groups;
00156 gid_t *groups;
00157 int i;
00158
00159 max_grp = groups_max();
00160 temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
00161 if (! temp_groups) {
00162 return False;
00163 }
00164
00165 if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
00166 temp_groups = SMB_REALLOC_ARRAY(temp_groups, gid_t, max_grp);
00167 if (!temp_groups) {
00168 return False;
00169 }
00170
00171 if (sys_getgrouplist(user, primary_gid,
00172 temp_groups, &max_grp) == -1) {
00173 DEBUG(0, ("get_user_groups: failed to get the unix "
00174 "group list\n"));
00175 SAFE_FREE(temp_groups);
00176 return False;
00177 }
00178 }
00179
00180 ngrp = 0;
00181 groups = NULL;
00182
00183
00184 if (!add_gid_to_array_unique(mem_ctx, primary_gid, &groups, &ngrp)) {
00185 SAFE_FREE(temp_groups);
00186 return False;
00187 }
00188
00189 for (i=0; i<max_grp; i++) {
00190 if (!add_gid_to_array_unique(mem_ctx, temp_groups[i],
00191 &groups, &ngrp)) {
00192 SAFE_FREE(temp_groups);
00193 return False;
00194 }
00195 }
00196
00197 *p_ngroups = ngrp;
00198 *ret_groups = groups;
00199 SAFE_FREE(temp_groups);
00200 return True;
00201 }