1 /* nssov.h - NSS overlay header file */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2008-2015 The OpenLDAP Foundation.
6 * Portions Copyright 2008 Howard Chu.
7 * Portions Copyright 2013 Ted C. Cheng, Symas Corp.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
23 #define NSLCD_PATH "/var/run/nslcd"
27 #define NSLCD_SOCKET NSLCD_PATH "/socket"
33 #include "nslcd-prot.h"
37 #undef PACKAGE_BUGREPORT
40 #undef PACKAGE_TARNAME
41 #undef PACKAGE_VERSION
45 #include <ac/string.h>
47 /* selectors for different maps */
48 enum nssov_map_selector
64 typedef struct nssov_mapinfo {
65 struct berval mi_base;
67 struct berval mi_filter0;
68 struct berval mi_filter;
69 struct berval *mi_attrkeys;
70 AttributeName *mi_attrs;
73 typedef struct nssov_info
75 /* search timelimit */
77 struct nssov_mapinfo ni_maps[NM_NONE];
82 /* PAM authz support... */
83 slap_mask_t ni_pam_opts;
84 struct berval ni_pam_group_dn;
85 AttributeDescription *ni_pam_group_ad;
88 AttributeDescription *ni_pam_template_ad;
89 struct berval ni_pam_template;
90 struct berval ni_pam_defhost;
91 struct berval *ni_pam_sessions;
92 struct berval ni_pam_password_prohibit_message;
93 struct berval ni_pam_pwdmgr_dn;
94 struct berval ni_pam_pwdmgr_pwd;
97 #define NI_PAM_USERHOST 1 /* old style host checking */
98 #define NI_PAM_USERSVC 2 /* old style service checking */
99 #define NI_PAM_USERGRP 4 /* old style group checking */
100 #define NI_PAM_HOSTSVC 8 /* new style authz checking */
101 #define NI_PAM_SASL2DN 0x10 /* use sasl2dn */
102 #define NI_PAM_UID2DN 0x20 /* use uid2dn */
104 #define NI_PAM_OLD (NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP)
105 #define NI_PAM_NEW NI_PAM_HOSTSVC
107 extern AttributeDescription *nssov_pam_host_ad;
108 extern AttributeDescription *nssov_pam_svc_ad;
110 /* Read the default configuration file. */
111 void nssov_cfg_init(nssov_info *ni,const char *fname);
113 /* macros for basic read and write operations, the following
114 ERROR_OUT* marcos define the action taken on errors
115 the stream is not closed because the caller closes the
118 #define ERROR_OUT_WRITEERROR(fp) \
119 Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \
122 #define ERROR_OUT_READERROR(fp) \
123 Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \
126 #define ERROR_OUT_BUFERROR(fp) \
127 Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \
130 #define WRITE_BERVAL(fp, bv) \
131 DEBUG_PRINT("WRITE_BERVAL: var="__STRING(bv)" bv_val=\"%s\"", (bv)->bv_val); \
134 WRITE_INT32(fp, 0); \
138 WRITE_INT32(fp, (bv)->bv_len); \
139 tmpint32 = ntohl(tmpint32); \
142 WRITE(fp, (bv)->bv_val, tmpint32); \
146 #define WRITE_BVARRAY(fp, arr) \
149 DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d", 0); \
150 WRITE_INT32(fp, 0); \
154 /* first determine length of array */ \
155 for (tmp3int32 = 0; (arr)[tmp3int32].bv_val != NULL; tmp3int32++) \
157 /* write number of strings */ \
158 DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d", (int)tmp3int32); \
159 WRITE_INT32(fp, tmp3int32); \
160 /* write strings */ \
161 for (tmp2int32 = 0; tmp2int32 < tmp3int32; tmp2int32++) \
163 WRITE_BERVAL(fp, &(arr)[tmp2int32]); \
167 /* Find the given attribute's value in the RDN of the DN. */
168 void nssov_find_rdnval(struct berval *dn,AttributeDescription *ad,struct berval *value);
170 /* This tries to get the user password attribute from the entry.
171 It will try to return an encrypted password as it is used in /etc/passwd,
172 /etc/group or /etc/shadow depending upon what is in the directory.
173 This function will return NULL if no passwd is found and will return the
174 literal value in the directory if conversion is not possible. */
175 void get_userpassword(struct berval *attr, struct berval *pw);
177 /* write out an address, parsing the addr value */
178 int write_address(TFILE *fp,struct berval *addr);
180 /* a helper macro to write out addresses and bail out on errors */
181 #define WRITE_ADDRESS(fp,addr) \
182 if (write_address(fp,addr)) \
185 /* read an address from the stream */
186 int read_address(TFILE *fp,char *addr,int *addrlen,int *af);
188 /* helper macro to read an address from the stream */
189 #define READ_ADDRESS(fp,addr,len,af) \
190 len=(int)sizeof(addr); \
191 if (read_address(fp,addr,&(len),&(af))) \
194 /* checks to see if the specified string is a valid username */
195 int isvalidusername(struct berval *name);
197 /* transforms the DN into a uid doing an LDAP lookup if needed */
198 int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid);
200 /* transforms the uid into a DN by doing an LDAP lookup */
201 int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn);
202 int nssov_name2dn_cb(Operation *op, SlapReply *rs);
204 /* Escapes characters in a string for use in a search filter. */
205 int nssov_escape(struct berval *src,struct berval *dst);
207 int nssov_filter_byname(nssov_mapinfo *mi,int key,struct berval *name,struct berval *buf);
208 int nssov_filter_byid(nssov_mapinfo *mi,int key,struct berval *id,struct berval *buf);
210 void nssov_alias_init(nssov_info *ni);
211 void nssov_ether_init(nssov_info *ni);
212 void nssov_group_init(nssov_info *ni);
213 void nssov_host_init(nssov_info *ni);
214 void nssov_netgroup_init(nssov_info *ni);
215 void nssov_network_init(nssov_info *ni);
216 void nssov_passwd_init(nssov_info *ni);
217 void nssov_protocol_init(nssov_info *ni);
218 void nssov_rpc_init(nssov_info *ni);
219 void nssov_service_init(nssov_info *ni);
220 void nssov_shadow_init(nssov_info *ni);
222 int nssov_pam_init(void);
224 /* these are the different functions that handle the database
225 specific actions, see nslcd.h for the action descriptions */
226 int nssov_alias_byname(nssov_info *ni,TFILE *fp,Operation *op);
227 int nssov_alias_all(nssov_info *ni,TFILE *fp,Operation *op);
228 int nssov_ether_byname(nssov_info *ni,TFILE *fp,Operation *op);
229 int nssov_ether_byether(nssov_info *ni,TFILE *fp,Operation *op);
230 int nssov_ether_all(nssov_info *ni,TFILE *fp,Operation *op);
231 int nssov_group_byname(nssov_info *ni,TFILE *fp,Operation *op);
232 int nssov_group_bygid(nssov_info *ni,TFILE *fp,Operation *op);
233 int nssov_group_bymember(nssov_info *ni,TFILE *fp,Operation *op);
234 int nssov_group_all(nssov_info *ni,TFILE *fp,Operation *op);
235 int nssov_host_byname(nssov_info *ni,TFILE *fp,Operation *op);
236 int nssov_host_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
237 int nssov_host_all(nssov_info *ni,TFILE *fp,Operation *op);
238 int nssov_netgroup_byname(nssov_info *ni,TFILE *fp,Operation *op);
239 int nssov_network_byname(nssov_info *ni,TFILE *fp,Operation *op);
240 int nssov_network_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
241 int nssov_network_all(nssov_info *ni,TFILE *fp,Operation *op);
242 int nssov_passwd_byname(nssov_info *ni,TFILE *fp,Operation *op);
243 int nssov_passwd_byuid(nssov_info *ni,TFILE *fp,Operation *op);
244 int nssov_passwd_all(nssov_info *ni,TFILE *fp,Operation *op);
245 int nssov_protocol_byname(nssov_info *ni,TFILE *fp,Operation *op);
246 int nssov_protocol_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
247 int nssov_protocol_all(nssov_info *ni,TFILE *fp,Operation *op);
248 int nssov_rpc_byname(nssov_info *ni,TFILE *fp,Operation *op);
249 int nssov_rpc_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
250 int nssov_rpc_all(nssov_info *ni,TFILE *fp,Operation *op);
251 int nssov_service_byname(nssov_info *ni,TFILE *fp,Operation *op);
252 int nssov_service_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
253 int nssov_service_all(nssov_info *ni,TFILE *fp,Operation *op);
254 int nssov_shadow_byname(nssov_info *ni,TFILE *fp,Operation *op);
255 int nssov_shadow_all(nssov_info *ni,TFILE *fp,Operation *op);
256 int pam_authc(nssov_info *ni,TFILE *fp,Operation *op,uid_t calleruid);
257 int pam_authz(nssov_info *ni,TFILE *fp,Operation *op);
258 int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op);
259 int pam_sess_c(nssov_info *ni,TFILE *fp,Operation *op);
260 int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op,uid_t calleruid);
262 /* config initialization */
263 #define NSSOV_INIT(db) \
264 void nssov_##db##_init(nssov_info *ni) \
266 nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \
268 for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \
270 mi->mi_attrs = ch_malloc( i*sizeof(AttributeName)); \
271 for (i=0;!BER_BVISNULL(&db##_keys[i]);i++) { \
272 mi->mi_attrs[i].an_name = db##_keys[i]; \
273 mi->mi_attrs[i].an_desc = NULL; \
275 mi->mi_scope = LDAP_SCOPE_DEFAULT; \
276 mi->mi_filter0 = db##_filter; \
277 ber_dupbv( &mi->mi_filter, &mi->mi_filter0 ); \
278 mi->mi_filter = db##_filter; \
279 mi->mi_attrkeys = db##_keys; \
280 BER_BVZERO(&mi->mi_base); \
283 /* param structure for search callback */
284 #define NSSOV_CBPRIV(db,parms) \
285 typedef struct nssov_##db##_cbp { \
292 /* callback for writing search results */
293 #define NSSOV_CB(db) \
294 static int nssov_##db##_cb(Operation *op, SlapReply *rs) \
296 if ( rs->sr_type == REP_SEARCH ) { \
297 nssov_##db##_cbp *cbp = op->o_callback->sc_private; \
298 if (write_##db(cbp,rs->sr_entry)) return LDAP_OTHER; \
300 return LDAP_SUCCESS; \
303 /* macro for generating service handling code */
304 #define NSSOV_HANDLE(db,fn,readfn,logcall,action,mkfilter) \
305 int nssov_##db##_##fn(nssov_info *ni,TFILE *fp,Operation *op) \
307 /* define common variables */ \
309 nssov_##db##_cbp cbp; \
310 slap_callback cb = {0}; \
311 SlapReply rs = {REP_RESULT}; \
312 cbp.mi = &ni->ni_maps[NM_##db]; \
315 /* read request parameters */ \
319 /* write the response header */ \
320 WRITE_INT32(fp,NSLCD_VERSION); \
321 WRITE_INT32(fp,action); \
322 /* prepare the search filter */ \
325 Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \
328 cb.sc_private = &cbp; \
329 op->o_callback = &cb; \
330 cb.sc_response = nssov_##db##_cb; \
331 slap_op_time( &op->o_time, &op->o_tincr ); \
332 op->o_req_dn = cbp.mi->mi_base; \
333 op->o_req_ndn = cbp.mi->mi_base; \
334 op->ors_scope = cbp.mi->mi_scope; \
335 op->ors_filterstr = filter; \
336 op->ors_filter = str2filter_x( op, filter.bv_val ); \
337 op->ors_attrs = cbp.mi->mi_attrs; \
338 op->ors_tlimit = SLAP_NO_LIMIT; \
339 op->ors_slimit = SLAP_NO_LIMIT; \
340 /* do the internal search */ \
341 op->o_bd->be_search( op, &rs ); \
342 filter_free_x( op, op->ors_filter, 1 ); \
343 WRITE_INT32(fp,NSLCD_RESULT_END); \