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