xref: /netbsd-src/external/bsd/openldap/dist/contrib/slapd-modules/nssov/nssov.h (revision fa28c6faa16e0b00edee7acdcaf4899797043def)
1 /*	$NetBSD: nssov.h,v 1.1.1.4 2014/05/28 09:58:28 tron Exp $	*/
2 
3 /* nssov.h - NSS overlay header file */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 2008-2014 The OpenLDAP Foundation.
8  * Portions Copyright 2008 Howard Chu.
9  * Portions Copyright 2013 Ted C. Cheng, Symas Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted only as authorized by the OpenLDAP
14  * Public License.
15  *
16  * A copy of this license is available in the file LICENSE in the
17  * top-level directory of the distribution or, alternatively, at
18  * <http://www.OpenLDAP.org/license.html>.
19  */
20 
21 #ifndef NSSOV_H
22 #define NSSOV_H
23 
24 #ifndef NSLCD_PATH
25 #define	NSLCD_PATH	"/var/run/nslcd"
26 #endif
27 
28 #ifndef NSLCD_SOCKET
29 #define NSLCD_SOCKET	NSLCD_PATH "/socket"
30 #endif
31 
32 #include <stdio.h>
33 
34 #include "nslcd.h"
35 #include "nslcd-prot.h"
36 #include "tio.h"
37 #include "attrs.h"
38 
39 #undef PACKAGE_BUGREPORT
40 #undef PACKAGE_NAME
41 #undef PACKAGE_STRING
42 #undef PACKAGE_TARNAME
43 #undef PACKAGE_VERSION
44 
45 #include "portable.h"
46 #include "slap.h"
47 #include <ac/string.h>
48 
49 /* selectors for different maps */
50 enum nssov_map_selector
51 {
52   NM_alias,
53   NM_ether,
54   NM_group,
55   NM_host,
56   NM_netgroup,
57   NM_network,
58   NM_passwd,
59   NM_protocol,
60   NM_rpc,
61   NM_service,
62   NM_shadow,
63   NM_NONE
64 };
65 
66 typedef struct nssov_mapinfo {
67 	struct berval mi_base;
68 	int mi_scope;
69 	struct berval mi_filter0;
70 	struct berval mi_filter;
71 	struct berval *mi_attrkeys;
72 	AttributeName *mi_attrs;
73 } nssov_mapinfo;
74 
75 typedef struct nssov_info
76 {
77 	/* search timelimit */
78 	int ni_timelimit;
79 	struct nssov_mapinfo ni_maps[NM_NONE];
80 	int ni_socket;
81 	Connection *ni_conn;
82 	BackendDB *ni_db;
83 
84 	/* PAM authz support... */
85 	slap_mask_t ni_pam_opts;
86 	struct berval ni_pam_group_dn;
87 	AttributeDescription *ni_pam_group_ad;
88 	int ni_pam_min_uid;
89 	int ni_pam_max_uid;
90 	AttributeDescription *ni_pam_template_ad;
91 	struct berval ni_pam_template;
92 	struct berval ni_pam_defhost;
93 	struct berval *ni_pam_sessions;
94 	struct berval ni_pam_password_prohibit_message;
95 	struct berval ni_pam_pwdmgr_dn;
96 	struct berval ni_pam_pwdmgr_pwd;
97 } nssov_info;
98 
99 #define NI_PAM_USERHOST		1	/* old style host checking */
100 #define NI_PAM_USERSVC		2	/* old style service checking */
101 #define NI_PAM_USERGRP		4	/* old style group checking */
102 #define NI_PAM_HOSTSVC		8	/* new style authz checking */
103 #define NI_PAM_SASL2DN		0x10	/* use sasl2dn */
104 #define NI_PAM_UID2DN		0x20	/* use uid2dn */
105 
106 #define	NI_PAM_OLD	(NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP)
107 #define	NI_PAM_NEW	NI_PAM_HOSTSVC
108 
109 extern AttributeDescription *nssov_pam_host_ad;
110 extern AttributeDescription *nssov_pam_svc_ad;
111 
112 /* Read the default configuration file. */
113 void nssov_cfg_init(nssov_info *ni,const char *fname);
114 
115 /* macros for basic read and write operations, the following
116    ERROR_OUT* marcos define the action taken on errors
117    the stream is not closed because the caller closes the
118    stream */
119 
120 #define ERROR_OUT_WRITEERROR(fp) \
121   Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \
122   return -1;
123 
124 #define ERROR_OUT_READERROR(fp) \
125   Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \
126   return -1;
127 
128 #define ERROR_OUT_BUFERROR(fp) \
129   Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \
130   return -1;
131 
132 #define WRITE_BERVAL(fp,bv) \
133   DEBUG_PRINT("WRITE_STRING: var="__STRING(bv)" string=\"%s\"",(bv)->bv_val); \
134   if ((bv)==NULL) \
135   { \
136     WRITE_INT32(fp,0); \
137   } \
138   else \
139   { \
140     WRITE_INT32(fp,(bv)->bv_len); \
141     if (tmpint32>0) \
142       { WRITE(fp,(bv)->bv_val,tmpint32); } \
143   }
144 
145 #define WRITE_BVARRAY(fp,arr) \
146   /* first determine length of array */ \
147   for (tmp3int32=0;(arr)[tmp3int32].bv_val!=NULL;tmp3int32++) \
148     /*nothing*/ ; \
149   /* write number of strings */ \
150   DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d",(int)tmp3int32); \
151   WRITE_TYPE(fp,tmp3int32,int32_t); \
152   /* write strings */ \
153   for (tmp2int32=0;tmp2int32<tmp3int32;tmp2int32++) \
154   { \
155     WRITE_BERVAL(fp,&(arr)[tmp2int32]); \
156   }
157 
158 /* This tries to get the user password attribute from the entry.
159    It will try to return an encrypted password as it is used in /etc/passwd,
160    /etc/group or /etc/shadow depending upon what is in the directory.
161    This function will return NULL if no passwd is found and will return the
162    literal value in the directory if conversion is not possible. */
163 void get_userpassword(struct berval *attr, struct berval *pw);
164 
165 /* write out an address, parsing the addr value */
166 int write_address(TFILE *fp,struct berval *addr);
167 
168 /* a helper macro to write out addresses and bail out on errors */
169 #define WRITE_ADDRESS(fp,addr) \
170   if (write_address(fp,addr)) \
171     return -1;
172 
173 /* read an address from the stream */
174 int read_address(TFILE *fp,char *addr,int *addrlen,int *af);
175 
176 /* helper macro to read an address from the stream */
177 #define READ_ADDRESS(fp,addr,len,af) \
178   len=(int)sizeof(addr); \
179   if (read_address(fp,addr,&(len),&(af))) \
180     return -1;
181 
182 /* checks to see if the specified string is a valid username */
183 int isvalidusername(struct berval *name);
184 
185 /* transforms the DN into a uid doing an LDAP lookup if needed */
186 int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid);
187 
188 /* transforms the uid into a DN by doing an LDAP lookup */
189 int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn);
190 int nssov_name2dn_cb(Operation *op, SlapReply *rs);
191 
192 /* Escapes characters in a string for use in a search filter. */
193 int nssov_escape(struct berval *src,struct berval *dst);
194 
195 int nssov_filter_byname(nssov_mapinfo *mi,int key,struct berval *name,struct berval *buf);
196 int nssov_filter_byid(nssov_mapinfo *mi,int key,struct berval *id,struct berval *buf);
197 
198 void nssov_alias_init(nssov_info *ni);
199 void nssov_ether_init(nssov_info *ni);
200 void nssov_group_init(nssov_info *ni);
201 void nssov_host_init(nssov_info *ni);
202 void nssov_netgroup_init(nssov_info *ni);
203 void nssov_network_init(nssov_info *ni);
204 void nssov_passwd_init(nssov_info *ni);
205 void nssov_protocol_init(nssov_info *ni);
206 void nssov_rpc_init(nssov_info *ni);
207 void nssov_service_init(nssov_info *ni);
208 void nssov_shadow_init(nssov_info *ni);
209 
210 int nssov_pam_init(void);
211 
212 /* these are the different functions that handle the database
213    specific actions, see nslcd.h for the action descriptions */
214 int nssov_alias_byname(nssov_info *ni,TFILE *fp,Operation *op);
215 int nssov_alias_all(nssov_info *ni,TFILE *fp,Operation *op);
216 int nssov_ether_byname(nssov_info *ni,TFILE *fp,Operation *op);
217 int nssov_ether_byether(nssov_info *ni,TFILE *fp,Operation *op);
218 int nssov_ether_all(nssov_info *ni,TFILE *fp,Operation *op);
219 int nssov_group_byname(nssov_info *ni,TFILE *fp,Operation *op);
220 int nssov_group_bygid(nssov_info *ni,TFILE *fp,Operation *op);
221 int nssov_group_bymember(nssov_info *ni,TFILE *fp,Operation *op);
222 int nssov_group_all(nssov_info *ni,TFILE *fp,Operation *op);
223 int nssov_host_byname(nssov_info *ni,TFILE *fp,Operation *op);
224 int nssov_host_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
225 int nssov_host_all(nssov_info *ni,TFILE *fp,Operation *op);
226 int nssov_netgroup_byname(nssov_info *ni,TFILE *fp,Operation *op);
227 int nssov_network_byname(nssov_info *ni,TFILE *fp,Operation *op);
228 int nssov_network_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
229 int nssov_network_all(nssov_info *ni,TFILE *fp,Operation *op);
230 int nssov_passwd_byname(nssov_info *ni,TFILE *fp,Operation *op);
231 int nssov_passwd_byuid(nssov_info *ni,TFILE *fp,Operation *op);
232 int nssov_passwd_all(nssov_info *ni,TFILE *fp,Operation *op);
233 int nssov_protocol_byname(nssov_info *ni,TFILE *fp,Operation *op);
234 int nssov_protocol_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
235 int nssov_protocol_all(nssov_info *ni,TFILE *fp,Operation *op);
236 int nssov_rpc_byname(nssov_info *ni,TFILE *fp,Operation *op);
237 int nssov_rpc_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
238 int nssov_rpc_all(nssov_info *ni,TFILE *fp,Operation *op);
239 int nssov_service_byname(nssov_info *ni,TFILE *fp,Operation *op);
240 int nssov_service_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
241 int nssov_service_all(nssov_info *ni,TFILE *fp,Operation *op);
242 int nssov_shadow_byname(nssov_info *ni,TFILE *fp,Operation *op);
243 int nssov_shadow_all(nssov_info *ni,TFILE *fp,Operation *op);
244 int pam_authc(nssov_info *ni,TFILE *fp,Operation *op);
245 int pam_authz(nssov_info *ni,TFILE *fp,Operation *op);
246 int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op);
247 int pam_sess_c(nssov_info *ni,TFILE *fp,Operation *op);
248 int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op);
249 
250 /* config initialization */
251 #define NSSOV_INIT(db) \
252  void nssov_##db##_init(nssov_info *ni) \
253  { \
254 	nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \
255 	int i; \
256 	for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \
257 	i++; \
258 	mi->mi_attrs = ch_malloc( i*sizeof(AttributeName)); \
259 	for (i=0;!BER_BVISNULL(&db##_keys[i]);i++) { \
260 		mi->mi_attrs[i].an_name = db##_keys[i]; \
261 		mi->mi_attrs[i].an_desc = NULL; \
262 	} \
263 	mi->mi_scope = LDAP_SCOPE_DEFAULT; \
264 	mi->mi_filter0 = db##_filter; \
265 	ber_dupbv( &mi->mi_filter, &mi->mi_filter0 ); \
266 	mi->mi_filter = db##_filter; \
267 	mi->mi_attrkeys = db##_keys; \
268 	BER_BVZERO(&mi->mi_base); \
269  }
270 
271 /* param structure for search callback */
272 #define NSSOV_CBPRIV(db,parms) \
273   typedef struct nssov_##db##_cbp { \
274   	nssov_mapinfo *mi; \
275 	TFILE *fp; \
276 	Operation *op; \
277 	parms \
278   } nssov_##db##_cbp
279 
280 /* callback for writing search results */
281 #define NSSOV_CB(db) \
282   static int nssov_##db##_cb(Operation *op, SlapReply *rs) \
283   { \
284     if ( rs->sr_type == REP_SEARCH ) { \
285     nssov_##db##_cbp *cbp = op->o_callback->sc_private; \
286   	if (write_##db(cbp,rs->sr_entry)) return LDAP_OTHER; \
287   } \
288   return LDAP_SUCCESS; \
289   } \
290 
291 /* macro for generating service handling code */
292 #define NSSOV_HANDLE(db,fn,readfn,logcall,action,mkfilter) \
293   int nssov_##db##_##fn(nssov_info *ni,TFILE *fp,Operation *op) \
294   { \
295     /* define common variables */ \
296     int32_t tmpint32; \
297     int rc; \
298 	nssov_##db##_cbp cbp; \
299 	slap_callback cb = {0}; \
300 	SlapReply rs = {REP_RESULT}; \
301 	cbp.mi = &ni->ni_maps[NM_##db]; \
302 	cbp.fp = fp; \
303 	cbp.op = op; \
304     /* read request parameters */ \
305     readfn; \
306     /* log call */ \
307     logcall; \
308     /* write the response header */ \
309     WRITE_INT32(fp,NSLCD_VERSION); \
310     WRITE_INT32(fp,action); \
311     /* prepare the search filter */ \
312     if (mkfilter) \
313     { \
314       Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \
315       return -1; \
316     } \
317 	cb.sc_private = &cbp; \
318 	op->o_callback = &cb; \
319 	cb.sc_response = nssov_##db##_cb; \
320 	slap_op_time( &op->o_time, &op->o_tincr ); \
321 	op->o_req_dn = cbp.mi->mi_base; \
322 	op->o_req_ndn = cbp.mi->mi_base; \
323 	op->ors_scope = cbp.mi->mi_scope; \
324 	op->ors_filterstr = filter; \
325 	op->ors_filter = str2filter_x( op, filter.bv_val ); \
326 	op->ors_attrs = cbp.mi->mi_attrs; \
327 	op->ors_tlimit = SLAP_NO_LIMIT; \
328 	op->ors_slimit = SLAP_NO_LIMIT; \
329     /* do the internal search */ \
330 	op->o_bd->be_search( op, &rs ); \
331 	filter_free_x( op, op->ors_filter, 1 ); \
332 	WRITE_INT32(fp,NSLCD_RESULT_END); \
333     return 0; \
334   }
335 
336 #endif /* NSSOV_H */
337