root/lib/util/util_getent.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getgrent_list
  2. grent_free
  3. getpwent_list
  4. pwent_free
  5. add_members_to_userlist
  6. get_users_in_group
  7. free_userlist

   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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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 }

/* [<][>][^][v][top][bottom][index][help] */