2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Simo Sorce 2001
5 Copyright (C) Jeremy Allison 2001
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 2 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 /****************************************************************
26 Returns a single linked list of group entries.
27 Use grent_free() to free it after use.
28 ****************************************************************/
30 struct sys_grent
* getgrent_list(void)
32 struct sys_grent
*glist
;
33 struct sys_grent
*gent
;
36 gent
= SMB_MALLOC_P(struct sys_grent
);
38 DEBUG (0, ("Out of memory in getgrent_list!\n"));
41 memset(gent
, '\0', sizeof(struct sys_grent
));
56 if ((gent
->gr_name
= SMB_STRDUP(grp
->gr_name
)) == NULL
)
60 if ((gent
->gr_passwd
= SMB_STRDUP(grp
->gr_passwd
)) == NULL
)
63 gent
->gr_gid
= grp
->gr_gid
;
65 /* number of strings in gr_mem */
66 for (num
= 0; grp
->gr_mem
[num
]; num
++)
69 /* alloc space for gr_mem string pointers */
70 if ((gent
->gr_mem
= SMB_MALLOC_ARRAY(char *, num
+1)) == NULL
)
73 memset(gent
->gr_mem
, '\0', (num
+1) * sizeof(char *));
75 for (i
=0; i
< num
; i
++) {
76 if ((gent
->gr_mem
[i
] = SMB_STRDUP(grp
->gr_mem
[i
])) == NULL
)
79 gent
->gr_mem
[num
] = NULL
;
83 gent
->next
= SMB_MALLOC_P(struct sys_grent
);
84 if (gent
->next
== NULL
)
87 memset(gent
, '\0', sizeof(struct sys_grent
));
97 DEBUG(0, ("Out of memory in getgrent_list!\n"));
102 /****************************************************************
103 Free the single linked list of group entries made by
105 ****************************************************************/
107 void grent_free (struct sys_grent
*glist
)
110 struct sys_grent
*prev
;
112 SAFE_FREE(glist
->gr_name
);
113 SAFE_FREE(glist
->gr_passwd
);
116 for (i
= 0; glist
->gr_mem
[i
]; i
++)
117 SAFE_FREE(glist
->gr_mem
[i
]);
118 SAFE_FREE(glist
->gr_mem
);
126 /****************************************************************
127 Returns a single linked list of passwd entries.
128 Use pwent_free() to free it after use.
129 ****************************************************************/
131 struct sys_pwent
* getpwent_list(void)
133 struct sys_pwent
*plist
;
134 struct sys_pwent
*pent
;
137 pent
= SMB_MALLOC_P(struct sys_pwent
);
139 DEBUG (0, ("Out of memory in getpwent_list!\n"));
146 while (pwd
!= NULL
) {
147 memset(pent
, '\0', sizeof(struct sys_pwent
));
149 if ((pent
->pw_name
= SMB_STRDUP(pwd
->pw_name
)) == NULL
)
152 if (pwd
->pw_passwd
) {
153 if ((pent
->pw_passwd
= SMB_STRDUP(pwd
->pw_passwd
)) == NULL
)
156 pent
->pw_uid
= pwd
->pw_uid
;
157 pent
->pw_gid
= pwd
->pw_gid
;
159 if ((pent
->pw_gecos
= SMB_STRDUP(pwd
->pw_gecos
)) == NULL
)
163 if ((pent
->pw_dir
= SMB_STRDUP(pwd
->pw_dir
)) == NULL
)
167 if ((pent
->pw_shell
= SMB_STRDUP(pwd
->pw_shell
)) == NULL
)
173 pent
->next
= SMB_MALLOC_P(struct sys_pwent
);
174 if (pent
->next
== NULL
)
186 DEBUG(0, ("Out of memory in getpwent_list!\n"));
191 /****************************************************************
192 Free the single linked list of passwd entries made by
194 ****************************************************************/
196 void pwent_free (struct sys_pwent
*plist
)
199 struct sys_pwent
*prev
;
201 SAFE_FREE(plist
->pw_name
);
202 SAFE_FREE(plist
->pw_passwd
);
203 SAFE_FREE(plist
->pw_gecos
);
204 SAFE_FREE(plist
->pw_dir
);
205 SAFE_FREE(plist
->pw_shell
);
213 /****************************************************************
214 Add the individual group users onto the list.
215 ****************************************************************/
217 static struct sys_userlist
*add_members_to_userlist(struct sys_userlist
*list_head
, const struct group
*grp
)
221 /* Count the number of users. */
222 for (num_users
= 0; grp
->gr_mem
[num_users
]; num_users
++)
225 for (i
= 0; i
< num_users
; i
++) {
226 struct sys_userlist
*entry
= SMB_MALLOC_P(struct sys_userlist
);
228 free_userlist(list_head
);
231 entry
->unix_name
= (char *)SMB_STRDUP(grp
->gr_mem
[i
]);
232 if (entry
->unix_name
== NULL
) {
234 free_userlist(list_head
);
237 DLIST_ADD(list_head
, entry
);
242 /****************************************************************
243 Get the list of UNIX users in a group.
244 We have to enumerate the /etc/group file as some UNIX getgrnam()
245 calls won't do that for us (notably Tru64 UNIX).
246 ****************************************************************/
248 struct sys_userlist
*get_users_in_group(const char *gname
)
250 struct sys_userlist
*list_head
= NULL
;
255 enum SID_NAME_USE name_type
;
257 /* No point using winbind if we can't split it in the
259 if (split_domain_and_name(gname
, domain
, groupname
)) {
262 * If we're doing this via winbindd, don't do the
263 * entire group list enumeration as we know this is
264 * pointless (and slow).
267 if (winbind_lookup_name(domain
, groupname
, &sid
, &name_type
)
268 && name_type
== SID_NAME_DOM_GRP
) {
269 if ((gptr
= (struct group
*)getgrnam(gname
)) == NULL
)
271 return add_members_to_userlist(list_head
, gptr
);
275 #if !defined(BROKEN_GETGRNAM)
276 if ((gptr
= (struct group
*)getgrnam(gname
)) == NULL
)
278 return add_members_to_userlist(list_head
, gptr
);
280 /* BROKEN_GETGRNAM - True64 */
282 while((gptr
= getgrent()) != NULL
) {
283 if (strequal(gname
, gptr
->gr_name
)) {
284 list_head
= add_members_to_userlist(list_head
, gptr
);
285 if (list_head
== NULL
)
294 /****************************************************************
295 Free list allocated above.
296 ****************************************************************/
298 void free_userlist(struct sys_userlist
*list_head
)
301 struct sys_userlist
*old_head
= list_head
;
302 DLIST_REMOVE(list_head
, list_head
);
303 SAFE_FREE(old_head
->unix_name
);
308 /****************************************************************
309 ****************************************************************/
311 static int int_compare( int *a
, int *b
)
321 void remove_duplicate_gids( int *num_groups
, gid_t
*groups
)
324 int count
= *num_groups
;
326 if ( *num_groups
<= 0 || !groups
)
330 DEBUG(8,("remove_duplicate_gids: Enter %d gids\n", *num_groups
));
332 qsort( groups
, *num_groups
, sizeof(gid_t
), QSORT_CAST int_compare
);
334 for ( i
=1; i
<count
; ) {
335 if ( groups
[i
-1] == groups
[i
] ) {
336 memmove( &groups
[i
-1], &groups
[i
], (count
- i
+ 1)*sizeof(gid_t
) );
338 /* decrement the total number of groups and do not increment
348 DEBUG(8,("remove_duplicate_gids: Exit %d gids\n", *num_groups
));