~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to lib/util/util_getent.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/CIFS implementation.
 
3
   Samba utility functions
 
4
   Copyright (C) Simo Sorce 2001
 
5
   Copyright (C) Jeremy Allison 2001
 
6
 
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
 
11
   
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
   
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
*/
 
20
 
 
21
#include "includes.h"
 
22
 
 
23
 
 
24
/****************************************************************
 
25
 Returns a single linked list of group entries.
 
26
 Use grent_free() to free it after use.
 
27
****************************************************************/
 
28
 
 
29
struct sys_grent * getgrent_list(void)
 
30
{
 
31
        struct sys_grent *glist;
 
32
        struct sys_grent *gent;
 
33
        struct group *grp;
 
34
        
 
35
        gent = malloc_p(struct sys_grent);
 
36
        if (gent == NULL) {
 
37
                DEBUG (0, ("Out of memory in getgrent_list!\n"));
 
38
                return NULL;
 
39
        }
 
40
        memset(gent, '\0', sizeof(struct sys_grent));
 
41
        glist = gent;
 
42
        
 
43
        setgrent();
 
44
        grp = getgrent();
 
45
        if (grp == NULL) {
 
46
                endgrent();
 
47
                SAFE_FREE(glist);
 
48
                return NULL;
 
49
        }
 
50
 
 
51
        while (grp != NULL) {
 
52
                int i,num;
 
53
                
 
54
                if (grp->gr_name) {
 
55
                        if ((gent->gr_name = strdup(grp->gr_name)) == NULL)
 
56
                                goto err;
 
57
                }
 
58
                if (grp->gr_passwd) {
 
59
                        if ((gent->gr_passwd = strdup(grp->gr_passwd)) == NULL)
 
60
                                goto err;
 
61
                }
 
62
                gent->gr_gid = grp->gr_gid;
 
63
                
 
64
                /* number of strings in gr_mem */
 
65
                for (num = 0; grp->gr_mem[num]; num++)
 
66
                        ;
 
67
                
 
68
                /* alloc space for gr_mem string pointers */
 
69
                if ((gent->gr_mem = malloc_array_p(char *, num+1)) == NULL)
 
70
                        goto err;
 
71
 
 
72
                memset(gent->gr_mem, '\0', (num+1) * sizeof(char *));
 
73
 
 
74
                for (i=0; i < num; i++) {
 
75
                        if ((gent->gr_mem[i] = strdup(grp->gr_mem[i])) == NULL)
 
76
                                goto err;
 
77
                }
 
78
                gent->gr_mem[num] = NULL;
 
79
                
 
80
                grp = getgrent();
 
81
                if (grp) {
 
82
                        gent->next = malloc_p(struct sys_grent);
 
83
                        if (gent->next == NULL)
 
84
                                goto err;
 
85
                        gent = gent->next;
 
86
                        memset(gent, '\0', sizeof(struct sys_grent));
 
87
                }
 
88
        }
 
89
        
 
90
        endgrent();
 
91
        return glist;
 
92
 
 
93
  err:
 
94
 
 
95
        endgrent();
 
96
        DEBUG(0, ("Out of memory in getgrent_list!\n"));
 
97
        grent_free(glist);
 
98
        return NULL;
 
99
}
 
100
 
 
101
/****************************************************************
 
102
 Free the single linked list of group entries made by
 
103
 getgrent_list()
 
104
****************************************************************/
 
105
 
 
106
void grent_free (struct sys_grent *glist)
 
107
{
 
108
        while (glist) {
 
109
                struct sys_grent *prev;
 
110
                
 
111
                SAFE_FREE(glist->gr_name);
 
112
                SAFE_FREE(glist->gr_passwd);
 
113
                if (glist->gr_mem) {
 
114
                        int i;
 
115
                        for (i = 0; glist->gr_mem[i]; i++)
 
116
                                SAFE_FREE(glist->gr_mem[i]);
 
117
                        SAFE_FREE(glist->gr_mem);
 
118
                }
 
119
                prev = glist;
 
120
                glist = glist->next;
 
121
                SAFE_FREE(prev);
 
122
        }
 
123
}
 
124
 
 
125
/****************************************************************
 
126
 Returns a single linked list of passwd entries.
 
127
 Use pwent_free() to free it after use.
 
128
****************************************************************/
 
129
 
 
130
struct sys_pwent * getpwent_list(void)
 
131
{
 
132
        struct sys_pwent *plist;
 
133
        struct sys_pwent *pent;
 
134
        struct passwd *pwd;
 
135
        
 
136
        pent = malloc_p(struct sys_pwent);
 
137
        if (pent == NULL) {
 
138
                DEBUG (0, ("Out of memory in getpwent_list!\n"));
 
139
                return NULL;
 
140
        }
 
141
        plist = pent;
 
142
        
 
143
        setpwent();
 
144
        pwd = getpwent();
 
145
        while (pwd != NULL) {
 
146
                memset(pent, '\0', sizeof(struct sys_pwent));
 
147
                if (pwd->pw_name) {
 
148
                        if ((pent->pw_name = strdup(pwd->pw_name)) == NULL)
 
149
                                goto err;
 
150
                }
 
151
                if (pwd->pw_passwd) {
 
152
                        if ((pent->pw_passwd = strdup(pwd->pw_passwd)) == NULL)
 
153
                                goto err;
 
154
                }
 
155
                pent->pw_uid = pwd->pw_uid;
 
156
                pent->pw_gid = pwd->pw_gid;
 
157
                if (pwd->pw_gecos) {
 
158
                        if ((pent->pw_name = strdup(pwd->pw_gecos)) == NULL)
 
159
                                goto err;
 
160
                }
 
161
                if (pwd->pw_dir) {
 
162
                        if ((pent->pw_name = strdup(pwd->pw_dir)) == NULL)
 
163
                                goto err;
 
164
                }
 
165
                if (pwd->pw_shell) {
 
166
                        if ((pent->pw_name = strdup(pwd->pw_shell)) == NULL)
 
167
                                goto err;
 
168
                }
 
169
 
 
170
                pwd = getpwent();
 
171
                if (pwd) {
 
172
                        pent->next = malloc_p(struct sys_pwent);
 
173
                        if (pent->next == NULL)
 
174
                                goto err;
 
175
                        pent = pent->next;
 
176
                }
 
177
        }
 
178
        
 
179
        endpwent();
 
180
        return plist;
 
181
 
 
182
  err:
 
183
 
 
184
        endpwent();
 
185
        DEBUG(0, ("Out of memory in getpwent_list!\n"));
 
186
        pwent_free(plist);
 
187
        return NULL;
 
188
}
 
189
 
 
190
/****************************************************************
 
191
 Free the single linked list of passwd entries made by
 
192
 getpwent_list()
 
193
****************************************************************/
 
194
 
 
195
void pwent_free (struct sys_pwent *plist)
 
196
{
 
197
        while (plist) {
 
198
                struct sys_pwent *prev;
 
199
                
 
200
                SAFE_FREE(plist->pw_name);
 
201
                SAFE_FREE(plist->pw_passwd);
 
202
                SAFE_FREE(plist->pw_gecos);
 
203
                SAFE_FREE(plist->pw_dir);
 
204
                SAFE_FREE(plist->pw_shell);
 
205
 
 
206
                prev = plist;
 
207
                plist = plist->next;
 
208
                SAFE_FREE(prev);
 
209
        }
 
210
}
 
211
 
 
212
/****************************************************************
 
213
 Add the individual group users onto the list.
 
214
****************************************************************/
 
215
 
 
216
static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_head, const struct group *grp)
 
217
{
 
218
        size_t num_users, i;
 
219
 
 
220
        /* Count the number of users. */
 
221
        for (num_users = 0; grp->gr_mem[num_users]; num_users++)
 
222
                ;
 
223
 
 
224
        for (i = 0; i < num_users; i++) {
 
225
                struct sys_userlist *entry = malloc_p(struct sys_userlist);
 
226
                if (entry == NULL) {
 
227
                        free_userlist(list_head);
 
228
                        return NULL;
 
229
                }
 
230
                entry->unix_name = (char *)strdup(grp->gr_mem[i]);
 
231
                if (entry->unix_name == NULL) {
 
232
                        SAFE_FREE(entry);
 
233
                        free_userlist(list_head);
 
234
                        return NULL;
 
235
                }
 
236
                DLIST_ADD(list_head, entry);
 
237
        }
 
238
        return list_head;
 
239
}
 
240
 
 
241
/****************************************************************
 
242
 Get the list of UNIX users in a group.
 
243
 We have to enumerate the /etc/group file as some UNIX getgrnam()
 
244
 calls won't do that for us (notably Tru64 UNIX).
 
245
****************************************************************/
 
246
 
 
247
struct sys_userlist *get_users_in_group(const char *gname)
 
248
{
 
249
        struct sys_userlist *list_head = NULL;
 
250
        struct group *gptr;
 
251
 
 
252
#if !defined(BROKEN_GETGRNAM)
 
253
        if ((gptr = (struct group *)getgrnam(gname)) == NULL)
 
254
                return NULL;
 
255
        return add_members_to_userlist(list_head, gptr);
 
256
#else
 
257
        /* BROKEN_GETGRNAM - True64 */
 
258
        setgrent();
 
259
        while((gptr = getgrent()) != NULL) {
 
260
                if (strequal(gname, gptr->gr_name)) {
 
261
                        list_head = add_members_to_userlist(list_head, gptr);
 
262
                        if (list_head == NULL)
 
263
                                return NULL;
 
264
                }
 
265
        }
 
266
        endgrent();
 
267
        return list_head;
 
268
#endif
 
269
}
 
270
 
 
271
/****************************************************************
 
272
 Free list allocated above.
 
273
****************************************************************/
 
274
 
 
275
void free_userlist(struct sys_userlist *list_head)
 
276
{
 
277
        while (list_head) {
 
278
                struct sys_userlist *old_head = list_head;
 
279
                DLIST_REMOVE(list_head, list_head);
 
280
                SAFE_FREE(old_head->unix_name);
 
281
                SAFE_FREE(old_head);
 
282
        }
 
283
}