static enum nss_status internal_getgrent(struct group *gr, char *buffer, size_t buflen, int *errnop, void *cmpdata, int (*cmpFunc)(void *, void *)) { struct group *grpp; int r = 0; enum nss_status result = NSS_STATUS_SUCCESS; if ( (fgrent.stream == NULL) || (cmpdata != NULL) ) result = internal_setent(&fgrent); if (result != NSS_STATUS_SUCCESS) return result; while (!r) { r = fgetgrent_r(fgrent.stream, gr, buffer, buflen, &grpp); if ( (cmpFunc == NULL) || (cmpFunc(gr, cmpdata))) break; } if (r == ERANGE) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } if (r) return NSS_STATUS_NOTFOUND; return result; }
static enum nss_status _nss_map_getgrent_r_locked (struct group *g, char * buffer, size_t buflen, int * errnop) { enum nss_status ret = NSS_STATUS_NOTFOUND; fpos_t position; fgetpos(g_file, &position); if ( fgetgrent_r(g_file, g, buffer, buflen, &g) == 0) { DEBUG("%s:%d:getgrent_r: returning group %s (%d)\n", __FILE__, __LINE__, g->gr_name, g->gr_gid); ret = NSS_STATUS_SUCCESS; } else { switch(errno) { case ERANGE: /* Rewind back to where we were just before, otherwise * the data read into the buffer is probably going to be * lost because there's no guarantee that the caller is * going to have preserved the line we just read. Note * that glibc's nss/nss_files/files-XXX.c does something * similar in CONCAT(_nss_files_get,ENTNAME_r) (around * line 242 in glibc 2.4 sources). */ fsetpos(g_file, &position); *errnop = errno; ret = _nss_map_ent_bad_return_code(*errnop); break; case ENOENT: /* XXX */ return NSS_STATUS_NOTFOUND; break; } } return ret; }
static int findgroupbygid(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result) { int rc; # if defined(WITH_PAM_USER_LOOKUP) || \ ( defined(WITH_FILE_USER_LOOKUP) && \ !( defined(HAVE_FGETGRENT_R) && defined(HAVE_FGETPWENT_R) ) ) rc = pthread_mutex_lock( &pw_gr_serializer ); if( rc != 0 ) return ENOENT; # endif # if defined(WITH_PAM_USER_LOOKUP) setgrent(); # if defined(HAVE_GETGRGID_R) rc = getgrgid_r( gid, grp, buf, buflen, result ); # elif defined(HAVE_GETGRGID) # error non-reentrant function support using getgrgid() currently not implemented # else # error neither getgrgid_r() nor getgrgid() available # endif endgrent(); # elif defined(WITH_FILE_USER_LOOKUP) FILE *fp = fopen( "/etc/group", "r" ); if( 0 == fp ) { rc = errno; } else { # if defined(HAVE_FGETPWENT_R) while( 0 == ( rc = fgetgrent_r( fp, grp, buf, buflen, result ) ) ) { if( gid == grp->gr_gid ) break; } if( ( rc != 0 ) && ( result != 0 ) ) *result = 0; # elif defined(HAVE_FGETPWENT) # error non-reentrant function support using fgetgrent() currently not implemented # else # error neither fgetgrent_r() nor fgetgrent() available # endif fclose( fp ); } # endif # if defined(WITH_PAM_USER_LOOKUP) || \ ( defined(WITH_FILE_USER_LOOKUP) && \ !( defined(HAVE_FGETGRENT_R) && defined(HAVE_FGETPWENT_R) ) ) pthread_mutex_unlock( &pw_gr_serializer ); # endif return rc; }
int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result) { int res; FILE *file; if (0 != (res = open_db(GROUP_FILE, &file))) { return res; } while (0 == (res = fgetgrent_r(file, grp, buf, buflen, result))) { if ((*result)->gr_gid == gid) { break; } } fclose(file); if (0 != res) { result = NULL; return res == ENOENT ? 0 : -1; } return 0; }
int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result) { int res; FILE *file; if (0 != (res = open_db(GROUP_FILE, &file))) { return res; } while (0 == (res = fgetgrent_r(file, grp, buf, buflen, result))) { if (0 == strcmp((*result)->gr_name, name)) { break; } } fclose(file); if (0 != res) { result = NULL; return res == ENOENT ? 0 : -1; } return 0; }
static gboolean fgetgrent_callback (void (* callback) (struct group *, gpointer), gpointer user_data) { struct group grb; struct group *gr; gchar *buffer; gsize buflen; FILE *fp; int ret; fp = fopen (cockpit_bridge_path_group, "r"); if (fp == NULL) { g_message ("unable to open %s: %s", cockpit_bridge_path_group, g_strerror (errno)); return FALSE; } buflen = 16 * 1024; buffer = g_malloc (buflen); for (;;) { ret = fgetgrent_r (fp, &grb, buffer, buflen, &gr); if (ret == 0) { callback (gr, user_data); } else { g_free (buffer); fclose (fp); return (ret == ENOENT); } } }