few edits
[Samba.git] / source / lib / util_getent.c
blob81b36effcb48143055308c7844e1d5cd7951d0b8
1 /*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 Samba utility functions
5 Copyright (C) Simo Sorce 2001
6 Copyright (C) Jeremy Allison 2001
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 #if 0
26 static void print_grent_list(struct sys_grent *glist)
28 DEBUG(100, ("print_grent_list: %x\n", glist ));
29 while (glist) {
30 DEBUG(100,("glist: %x ", glist));
31 if (glist->gr_name)
32 DEBUG(100,(": gr_name = (%x) %s ", glist->gr_name, glist->gr_name));
33 if (glist->gr_passwd)
34 DEBUG(100,(": gr_passwd = (%x) %s ", glist->gr_passwd, glist->gr_passwd));
35 if (glist->gr_mem) {
36 int i;
37 for (i = 0; glist->gr_mem[i]; i++)
38 DEBUG(100,(" : gr_mem[%d] = (%x) %s ", i, glist->gr_mem[i], glist->gr_mem[i]));
40 DEBUG(100,(": gr_next = %x\n", glist->next ));
41 glist = glist->next;
43 DEBUG(100,("FINISHED !\n\n"));
45 #endif
47 /****************************************************************
48 Returns a single linked list of group entries.
49 Use grent_free() to free it after use.
50 ****************************************************************/
52 struct sys_grent * getgrent_list(void)
54 struct sys_grent *glist;
55 struct sys_grent *gent;
56 struct group *grp;
58 gent = (struct sys_grent *) malloc(sizeof(struct sys_grent));
59 if (gent == NULL) {
60 DEBUG (0, ("Out of memory in getgrent_list!\n"));
61 return NULL;
63 memset(gent, '\0', sizeof(struct sys_grent));
64 glist = gent;
66 setgrent();
67 grp = getgrent();
68 if (grp == NULL) {
69 endgrent();
70 SAFE_FREE(glist);
71 return NULL;
74 while (grp != NULL) {
75 int i,num;
77 if (grp->gr_name) {
78 if ((gent->gr_name = strdup(grp->gr_name)) == NULL)
79 goto err;
81 if (grp->gr_passwd) {
82 if ((gent->gr_passwd = strdup(grp->gr_passwd)) == NULL)
83 goto err;
85 gent->gr_gid = grp->gr_gid;
87 /* number of strings in gr_mem */
88 for (num = 0; grp->gr_mem[num]; num++)
91 /* alloc space for gr_mem string pointers */
92 if ((gent->gr_mem = (char **) malloc((num+1) * sizeof(char *))) == NULL)
93 goto err;
95 memset(gent->gr_mem, '\0', (num+1) * sizeof(char *));
97 for (i=0; i < num; i++) {
98 if ((gent->gr_mem[i] = strdup(grp->gr_mem[i])) == NULL)
99 goto err;
101 gent->gr_mem[num] = NULL;
103 grp = getgrent();
104 if (grp) {
105 gent->next = (struct sys_grent *) malloc(sizeof(struct sys_grent));
106 if (gent->next == NULL)
107 goto err;
108 gent = gent->next;
109 memset(gent, '\0', sizeof(struct sys_grent));
113 endgrent();
114 return glist;
116 err:
118 endgrent();
119 DEBUG(0, ("Out of memory in getgrent_list!\n"));
120 grent_free(glist);
121 return NULL;
124 /****************************************************************
125 Free the single linked list of group entries made by
126 getgrent_list()
127 ****************************************************************/
129 void grent_free (struct sys_grent *glist)
131 while (glist) {
132 struct sys_grent *prev;
134 SAFE_FREE(glist->gr_name);
135 SAFE_FREE(glist->gr_passwd);
136 if (glist->gr_mem) {
137 int i;
138 for (i = 0; glist->gr_mem[i]; i++)
139 SAFE_FREE(glist->gr_mem[i]);
140 SAFE_FREE(glist->gr_mem);
142 prev = glist;
143 glist = glist->next;
144 SAFE_FREE(prev);
148 /****************************************************************
149 Returns a single linked list of passwd entries.
150 Use pwent_free() to free it after use.
151 ****************************************************************/
153 struct sys_pwent * getpwent_list(void)
155 struct sys_pwent *plist;
156 struct sys_pwent *pent;
157 struct passwd *pwd;
159 pent = (struct sys_pwent *) malloc(sizeof(struct sys_pwent));
160 if (pent == NULL) {
161 DEBUG (0, ("Out of memory in getpwent_list!\n"));
162 return NULL;
164 plist = pent;
166 setpwent();
167 pwd = getpwent();
168 while (pwd != NULL) {
169 memset(pent, '\0', sizeof(struct sys_pwent));
170 if (pwd->pw_name) {
171 if ((pent->pw_name = strdup(pwd->pw_name)) == NULL)
172 goto err;
174 if (pwd->pw_passwd) {
175 if ((pent->pw_passwd = strdup(pwd->pw_passwd)) == NULL)
176 goto err;
178 pent->pw_uid = pwd->pw_uid;
179 pent->pw_gid = pwd->pw_gid;
180 if (pwd->pw_gecos) {
181 if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL)
182 goto err;
184 if (pwd->pw_dir) {
185 if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL)
186 goto err;
188 if (pwd->pw_shell) {
189 if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL)
190 goto err;
193 pwd = getpwent();
194 if (pwd) {
195 pent->next = (struct sys_pwent *) malloc(sizeof(struct sys_pwent));
196 if (pent->next == NULL)
197 goto err;
198 pent = pent->next;
202 endpwent();
203 return plist;
205 err:
207 endpwent();
208 DEBUG(0, ("Out of memory in getpwent_list!\n"));
209 pwent_free(plist);
210 return NULL;
213 /****************************************************************
214 Free the single linked list of passwd entries made by
215 getpwent_list()
216 ****************************************************************/
218 void pwent_free (struct sys_pwent *plist)
220 while (plist) {
221 struct sys_pwent *prev;
223 SAFE_FREE(plist->pw_name);
224 SAFE_FREE(plist->pw_passwd);
225 SAFE_FREE(plist->pw_gecos);
226 SAFE_FREE(plist->pw_dir);
227 SAFE_FREE(plist->pw_shell);
229 prev = plist;
230 plist = plist->next;
231 SAFE_FREE(prev);
235 /****************************************************************
236 Add the individual group users onto the list.
237 ****************************************************************/
239 static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp)
241 size_t num_users, i;
243 /* Count the number of users. */
244 for (num_users = 0; grp->gr_mem[num_users]; num_users++)
247 for (i = 0; i < num_users; i++) {
248 struct sys_userlist *entry = (struct sys_userlist *)malloc(sizeof(*entry));
249 size_t len = strlen(grp->gr_mem[i])+1;
250 if (entry == NULL) {
251 free_userlist(list_head);
252 return NULL;
254 entry->unix_name = (char *)malloc(len);
255 if (entry->unix_name == NULL) {
256 SAFE_FREE(entry);
257 free_userlist(list_head);
258 return NULL;
260 safe_strcpy(entry->unix_name, grp->gr_mem[i],len);
261 DLIST_ADD(list_head, entry);
263 return list_head;
266 /****************************************************************
267 Get the list of UNIX users in a group.
268 We have to enumerate the /etc/group file as some UNIX getgrnam()
269 calls won't do that for us (notably Tru64 UNIX).
270 ****************************************************************/
272 struct sys_userlist *get_users_in_group(const char *gname)
274 struct sys_userlist *list_head = NULL;
275 struct group *gptr;
278 * If we're doing this via winbindd, don't do the
279 * entire group list enumeration as we know this is
280 * pointless (and slow).
283 if (strchr(gname,*lp_winbind_separator())) {
284 if ((gptr = (struct group *)getgrnam(gname)) == NULL)
285 return NULL;
286 return add_members_to_userlist(list_head, gptr);
289 setgrent();
290 while((gptr = getgrent()) != NULL) {
291 if (strequal(gname, gptr->gr_name)) {
292 list_head = add_members_to_userlist(list_head, gptr);
293 if (list_head == NULL)
294 return NULL;
297 endgrent();
298 return list_head;
301 /****************************************************************
302 Free list allocated above.
303 ****************************************************************/
305 void free_userlist(struct sys_userlist *list_head)
307 while (list_head) {
308 struct sys_userlist *old_head = list_head;
309 DLIST_REMOVE(list_head, list_head);
310 SAFE_FREE(old_head->unix_name);
311 SAFE_FREE(old_head);