1 /*        $NetBSD: netgroup.c,v 1.3 2021/08/14 16:14:52 christos Exp $          */
2 
3 /* netgroup.c - netgroup lookup routines */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2008-2021 The OpenLDAP Foundation.
8  * Portions Copyright 2008 by Howard Chu, Symas Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted only as authorized by the OpenLDAP
13  * Public License.
14  *
15  * A copy of this license is available in the file LICENSE in the
16  * top-level directory of the distribution or, alternatively, at
17  * <http://www.OpenLDAP.org/license.html>.
18  */
19 /* ACKNOWLEDGEMENTS:
20  * This code references portions of the nss-ldapd package
21  * written by Arthur de Jong. The nss-ldapd code was forked
22  * from the nss-ldap library written by Luke Howard.
23  */
24 
25 #include "nssov.h"
26 #include <ac/ctype.h>
27 
28 /* ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
29  *   DESC 'Abstraction of a netgroup. May refer to other netgroups'
30  *   MUST cn
31  *   MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
32  */
33 
34 /* the basic search filter for searches */
35 static struct berval netgroup_filter = BER_BVC("(objectClass=nisNetgroup)");
36 
37 /* the attributes to request with searches */
38 static struct berval netgroup_keys[] = {
39           BER_BVC("cn"),
40           BER_BVC("nisNetgroupTriple"),
41           BER_BVC("memberNisNetgroup"),
42           BER_BVNULL
43 };
44 
45 NSSOV_INIT(netgroup)
46 
47 NSSOV_CBPRIV(netgroup,
48           char buf[256];
49           struct berval name;);
50 
write_string_stripspace_len(TFILE * fp,const char * str,int len)51 static int write_string_stripspace_len(TFILE *fp,const char *str,int len)
52 {
53           int32_t tmpint32;
54           int i,j;
55           DEBUG_PRINT("WRITE_STRING: var="__STRING(str)" string=\"%s\"",str);
56           if (str==NULL)
57           {
58                     WRITE_INT32(fp,0);
59           }
60           else
61           {
62                     /* skip leading spaces */
63                     for (i=0;(str[i]!='\0')&&(isspace(str[i]));i++)
64                               /* nothing else to do */ ;
65                     /* skip trailing spaces */
66                     for (j=len;(j>i)&&(isspace(str[j-1]));j--)
67                               /* nothing else to do */ ;
68                     /* write length of string */
69                     WRITE_INT32(fp,j-i);
70                     /* write string itself */
71                     if (j>i)
72                     {
73                               WRITE(fp,str+i,j-i);
74                     }
75           }
76           /* we're done */
77           return 0;
78 }
79 
80 #define WRITE_STRING_STRIPSPACE_LEN(fp,str,len) \
81           if (write_string_stripspace_len(fp,str,len)) \
82                     return -1;
83 
84 #define WRITE_STRING_STRIPSPACE(fp,str) \
85           WRITE_STRING_STRIPSPACE_LEN(fp,str,strlen(str))
86 
write_netgroup_triple(TFILE * fp,const char * triple)87 static int write_netgroup_triple(TFILE *fp,const char *triple)
88 {
89           int32_t tmpint32;
90           int i;
91           int hostb,hoste,userb,usere,domainb,domaine;
92           /* skip leading spaces */
93           for (i=0;(triple[i]!='\0')&&(isspace(triple[i]));i++)
94                     /* nothing else to do */ ;
95           /* we should have a bracket now */
96           if (triple[i]!='(')
97           {
98                     Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): entry does not begin with '(' (entry skipped)\n" );
99                     return 0;
100           }
101           i++;
102           hostb=i;
103           /* find comma (end of host string) */
104           for (;(triple[i]!='\0')&&(triple[i]!=',');i++)
105                     /* nothing else to do */ ;
106           if (triple[i]!=',')
107           {
108                     Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): missing ',' (entry skipped)\n" );
109                     return 0;
110           }
111           hoste=i;
112           i++;
113           userb=i;
114           /* find comma (end of user string) */
115           for (;(triple[i]!='\0')&&(triple[i]!=',');i++)
116                     /* nothing else to do */ ;
117           if (triple[i]!=',')
118           {
119                     Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): missing ',' (entry skipped)\n" );
120                     return 0;
121           }
122           usere=i;
123           i++;
124           domainb=i;
125           /* find closing bracket (end of domain string) */
126           for (;(triple[i]!='\0')&&(triple[i]!=')');i++)
127                     /* nothing else to do */ ;
128           if (triple[i]!=')')
129           {
130                     Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): missing ')' (entry skipped)\n" );
131                     return 0;
132           }
133           domaine=i;
134           i++;
135           /* skip trailing spaces */
136           for (;(triple[i]!='\0')&&(isspace(triple[i]));i++)
137                     /* nothing else to do */ ;
138           /* if anything is left in the string we have a problem */
139           if (triple[i]!='\0')
140           {
141                     Debug(LDAP_DEBUG_ANY,"write_netgroup_triple(): string contains trailing data (entry skipped)\n" );
142                     return 0;
143           }
144           /* write strings */
145           WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
146           WRITE_INT32(fp,NSLCD_NETGROUP_TYPE_TRIPLE);
147           WRITE_STRING_STRIPSPACE_LEN(fp,triple+hostb,hoste-hostb)
148           WRITE_STRING_STRIPSPACE_LEN(fp,triple+userb,usere-userb)
149           WRITE_STRING_STRIPSPACE_LEN(fp,triple+domainb,domaine-domainb)
150           /* we're done */
151           return 0;
152 }
153 
write_netgroup(nssov_netgroup_cbp * cbp,Entry * entry)154 static int write_netgroup(nssov_netgroup_cbp *cbp,Entry *entry)
155 {
156           int32_t tmpint32;
157           int i;
158           Attribute *a;
159 
160           /* get the netgroup triples and member */
161           a = attr_find(entry->e_attrs,cbp->mi->mi_attrs[1].an_desc);
162           if ( a ) {
163           /* write the netgroup triples */
164                     for (i=0;i<a->a_numvals;i++)
165                     {
166                               if (write_netgroup_triple(cbp->fp, a->a_vals[i].bv_val))
167                                         return -1;
168                     }
169           }
170           a = attr_find(entry->e_attrs,cbp->mi->mi_attrs[2].an_desc);
171           if ( a ) {
172           /* write netgroup members */
173                     for (i=0;i<a->a_numvals;i++)
174                     {
175                               /* write the result code */
176                               WRITE_INT32(cbp->fp,NSLCD_RESULT_BEGIN);
177                               /* write triple indicator */
178                               WRITE_INT32(cbp->fp,NSLCD_NETGROUP_TYPE_NETGROUP);
179                               /* write netgroup name */
180                               if (write_string_stripspace_len(cbp->fp,a->a_vals[i].bv_val,a->a_vals[i].bv_len))
181                                         return -1;
182                     }
183           }
184           /* we're done */
185           return 0;
186 }
187 
188 NSSOV_CB(netgroup)
189 
190 NSSOV_HANDLE(
191           netgroup,byname,
192           char fbuf[1024];
193           struct berval filter = {sizeof(fbuf)};
194           filter.bv_val = fbuf;
195           READ_STRING(fp,cbp.buf);,
196           cbp.name.bv_len = tmpint32;
197           cbp.name.bv_val = cbp.buf;
198           Debug(LDAP_DEBUG_TRACE,"nssov_netgroup_byname(%s)\n",cbp.name.bv_val);,
199           NSLCD_ACTION_NETGROUP_BYNAME,
200           nssov_filter_byname(cbp.mi,0,&cbp.name,&filter)
201 )
202