Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/nss/netgroup.c
blob: d043fc194457006fc6a47e206b74a0ffeceadcd6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
   netgroup.c - NSS lookup functions for netgroup entries

   Copyright (C) 2006 West Consulting
   Copyright (C) 2006, 2007 Arthur de Jong

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301 USA
*/

#include "config.h"

#include <stdlib.h>
#include <string.h>
#include <nss.h>
#include <errno.h>

#include "prototypes.h"
#include "common.h"
#include "compat/attrs.h"

/* we redifine this here because we need to return NSS_STATUS_RETURN
   if we have sucessfully read some entries */
#undef ERROR_OUT_NOSUCCESS
#define ERROR_OUT_NOSUCCESS(fp,retv) \
  (void)tio_close(fp); \
  fp=NULL; \
  if (result->first) \
  { \
    *errnop=ENOENT; \
    return nslcd2nss(retv); \
  } \
  else \
    return NSS_STATUS_RETURN;

/* function for reading a single result entry */
static enum nss_status read_netgrent(
        TFILE *fp,struct __netgrent *result,
        char *buffer,size_t buflen,int *errnop)
{
  int32_t tmpint32;
  int type;
  size_t bufptr=0;
  /* read netgroup type */
  READ_INT32(fp,type);
  if (type==NETGROUP_TYPE_NETGROUP)
  {
    /* the response is a reference to another netgroup */
    result->type=group_val;
    READ_STRING_BUF(fp,result->val.group);
  }
  else if (type==NETGROUP_TYPE_TRIPLE)
  {
    /* the response is a host/user/domain triple */
    result->type=triple_val;
    /* read host and revert to NULL on empty string */
    READ_STRING_BUF(fp,result->val.triple.host);
    if (result->val.triple.host[0]=='\0')
    {
      result->val.triple.host=NULL;
      bufptr--; /* free unused space */
    }
    /* read user and revert to NULL on empty string */
    READ_STRING_BUF(fp,result->val.triple.user);
    if (result->val.triple.user[0]=='\0')
    {
      result->val.triple.user=NULL;
      bufptr--; /* free unused space */
    }
    /* read domain and revert to NULL on empty string */
    READ_STRING_BUF(fp,result->val.triple.domain);
    if (result->val.triple.domain[0]=='\0')
    {
      result->val.triple.domain=NULL;
      bufptr--; /* free unused space */
    }
  }
  else
    return NSS_STATUS_UNAVAIL;
  /* flag the fact that we have successfully returned an entry */
  result->first=0;
  /* we're done */
  return NSS_STATUS_SUCCESS;
}

/* thread-local file pointer to an ongoing request */
static __thread TFILE *netgrentfp;

enum nss_status _nss_ldap_setnetgrent(const char *group,struct __netgrent *result)
{
  /* we cannot use NSS_SETENT() here because we have a parameter */
  int32_t tmpint32;
  int errnocp;
  int *errnop;
  errnop=&errnocp;
  /* check parameter */
  if ((group==NULL)||(group[0]=='\0'))
    return NSS_STATUS_UNAVAIL;
  /* open a new stream and write the request */
  OPEN_SOCK(netgrentfp);
  WRITE_REQUEST(netgrentfp,NSLCD_ACTION_NETGROUP_BYNAME);
  WRITE_STRING(netgrentfp,group);
  WRITE_FLUSH(netgrentfp);
  /* read response header */
  READ_RESPONSEHEADER(netgrentfp,NSLCD_ACTION_NETGROUP_BYNAME);
  /* set the first flag, this is used to check if we should
     return NSS_STATUS_NOTFOUND (entry not found) or
     NSS_STATUS_RETURN (entry found but no more lines) */
  result->first=1;
  return NSS_STATUS_SUCCESS;
}

enum nss_status _nss_ldap_getnetgrent_r(struct __netgrent *result,char *buffer,size_t buflen,int *errnop)
{
  NSS_GETENT(netgrentfp,read_netgrent(netgrentfp,result,buffer,buflen,errnop));
}

enum nss_status _nss_ldap_endnetgrent(struct __netgrent UNUSED(* result))
{
  NSS_ENDENT(netgrentfp);
}