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