107
113
return NSS_STATUS_SUCCESS;
110
enum nss_status _nss_ldap_getnetgrent_r(struct __netgrent *result,char *buffer,size_t buflen,int *errnop)
116
/* get a single netgroup tuple from the stream */
117
nss_status_t _nss_ldap_getnetgrent_r(
118
struct __netgrent *result,
119
char *buffer,size_t buflen,int *errnop)
112
121
NSS_GETENT(netgrentfp,NSLCD_ACTION_NETGROUP_BYNAME,
113
122
read_netgrent(netgrentfp,result,buffer,buflen,errnop));
116
enum nss_status _nss_ldap_endnetgrent(struct __netgrent UNUSED(* result))
125
/* close the stream opened with setnetgrent() above */
126
nss_status_t _nss_ldap_endnetgrent(struct __netgrent UNUSED(*result))
118
128
NSS_ENDENT(netgrentfp);
131
#endif /* NSS_FLAVOUR_GLIBC */
133
#ifdef NSS_FLAVOUR_SOLARIS
135
/* this is the backend structure for the {set,get,end}ent() functions */
136
struct setnetgrent_backend
138
nss_backend_op_t *ops; /* function-pointer table */
139
int n_ops; /* number of function pointers */
140
TFILE *fp; /* the file pointer for {set,get,end}ent() functions */
141
SET *seen_groups; /* netgroups seen, for loop detection */
142
SET *unseen_groups; /* netgroups that need to be chased */
145
/* easy way to get sets from back-end */
146
#define NETGROUP_BE(be) ((struct setnetgrent_backend*)(be))
148
/* access arguments */
149
#define SETNETGRENT_ARGS(args) ((struct nss_setnetgrent_args *)(args))
150
#define GETNETGRENT_ARGS(args) ((struct nss_getnetgrent_args *)(args))
152
/* return a netgroup that has not been traversed */
153
static char *find_unseen_netgroup(nss_backend_t *be)
158
group=set_pop(NETGROUP_BE(be)->unseen_groups);
161
if (!set_contains(NETGROUP_BE(be)->seen_groups,group))
163
set_add(NETGROUP_BE(be)->seen_groups,group);
169
static nss_status_t netgroup_nslcd_setnetgrent(nss_backend_t *be,const char *group)
171
/* we cannot use NSS_SETENT() here because we have a parameter that is only
172
available in this function */
177
/* check parameter */
178
if ((group==NULL)||(group[0]=='\0'))
179
return NSS_STATUS_UNAVAIL;
180
/* open a new stream and write the request */
181
NSLCD_REQUEST(NETGROUP_BE(be)->fp,NSLCD_ACTION_NETGROUP_BYNAME,
182
WRITE_STRING(NETGROUP_BE(be)->fp,group));
183
return NSS_STATUS_SUCCESS;
186
static nss_status_t netgroup_nslcd_getnetgrent(nss_backend_t *be,struct __netgrent *result,char *buffer,size_t buflen,void *args)
188
NSS_GETENT(NETGROUP_BE(be)->fp,NSLCD_ACTION_NETGROUP_BYNAME,
189
read_netgrent(NETGROUP_BE(be)->fp,result,buffer,buflen,errnop));
192
static nss_status_t netgroup_setnetgrent_setnetgrent(nss_backend_t UNUSED(*be),void UNUSED(*args))
194
return NSS_STATUS_SUCCESS;
197
static nss_status_t netgroup_setnetgrent_getnetgrent(nss_backend_t *be,void *args)
199
struct __netgrent result;
202
nss_status_t status,rc;
203
GETNETGRENT_ARGS(args)->status=NSS_NETGR_NO;
206
status=netgroup_nslcd_getnetgrent(be,&result,GETNETGRENT_ARGS(args)->buffer,
207
GETNETGRENT_ARGS(args)->buflen,args);
208
if (status!=NSS_STATUS_SUCCESS)
212
/* done with the current netgroup */
213
/* explore nested netgroup,if any */
217
/* find a nested netgroup to pursue further */
218
group=find_unseen_netgroup(be);
221
/* no more netgroup */
227
rc=netgroup_nslcd_setnetgrent(be,group);
228
if (rc==NSS_STATUS_SUCCESS)
241
{ /* status==NSS_STATUS_SUCCESS */
242
if (result.type==group_val)
244
/* a netgroup nested within the current netgroup */
245
set_add(NETGROUP_BE(be)->unseen_groups,result.val.group);
247
else if (result.type==triple_val)
249
GETNETGRENT_ARGS(args)->retp[NSS_NETGR_MACHINE]=result.val.triple.host;
250
GETNETGRENT_ARGS(args)->retp[NSS_NETGR_USER]=result.val.triple.user;
251
GETNETGRENT_ARGS(args)->retp[NSS_NETGR_DOMAIN]=result.val.triple.domain;
252
GETNETGRENT_ARGS(args)->status=NSS_NETGR_FOUND;
257
/* NSS_STATUS_SUCCESS,but type is not group_val or triple_val */
258
/* should not be here,log a message */
259
status=NSS_STATUS_NOTFOUND;
267
static nss_status_t netgroup_setnetgrent_endnetgrent(nss_backend_t UNUSED(*be),void UNUSED(*args))
269
NSS_ENDENT(NETGROUP_BE(be)->fp);
272
static nss_status_t netgroup_setnetgrent_destructor(nss_backend_t *be,void *UNUSED(args))
274
struct setnetgrent_backend *ngbe=(struct setnetgrent_backend *)be;
276
(void)tio_close(ngbe->fp);
277
set_free(ngbe->seen_groups);
278
set_free(ngbe->unseen_groups);
280
return NSS_STATUS_SUCCESS;
283
static nss_backend_op_t netgroup_setnetgrent_ops[]={
284
netgroup_setnetgrent_destructor,
285
netgroup_setnetgrent_endnetgrent,
286
netgroup_setnetgrent_setnetgrent,
287
netgroup_setnetgrent_getnetgrent,
290
static nss_status_t netgroup_setnetgrent_constructor(nss_backend_t *be,void *args)
292
struct setnetgrent_backend *ngbe;
295
SETNETGRENT_ARGS(args)->iterator=NULL; /* initialize */
296
/* allocate a back-end specific to this request */
297
ngbe=(struct setnetgrent_backend *)malloc(sizeof(struct setnetgrent_backend));
299
return NSS_STATUS_UNAVAIL;
300
ngbe->ops=netgroup_setnetgrent_ops;
301
ngbe->n_ops=sizeof(netgroup_setnetgrent_ops)/sizeof(nss_backend_op_t);
303
ngbe->seen_groups=set_new();
304
ngbe->unseen_groups=set_new();
305
/* start the first search */
306
retv=netgroup_nslcd_setnetgrent(be,SETNETGRENT_ARGS(args)->netgroup);
307
if (retv!=NSS_STATUS_SUCCESS)
309
netgroup_setnetgrent_destructor(be,args);
312
/* return the new back-end */
313
SETNETGRENT_ARGS(args)->iterator=(nss_backend_t *)ngbe;
314
return NSS_STATUS_SUCCESS;
317
static nss_backend_op_t netgroup_ops[]={
322
NULL,/* TODO:_nss_ldap_netgr_in,*/
323
netgroup_setnetgrent_constructor
326
nss_backend_t *_nss_ldap_netgroup_constr(const char UNUSED(*db_name),
327
const char UNUSED(*src_name),const char UNUSED(*cfg_args))
329
return nss_ldap_constructor(netgroup_ops,sizeof(netgroup_ops));
332
#endif /* NSS_FLAVOUR_SOLARIS */