1 /* nssov.h - NSS overlay header file */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2008-2009 The OpenLDAP Foundation.
6 * Portions Copyright 2008 Howard Chu.
13 #define NSLCD_SOCKET "/var/run/nslcd/socket"
19 #include "nslcd-common.h"
20 #include "common/tio.h"
21 #include "compat/attrs.h"
23 #undef PACKAGE_BUGREPORT
26 #undef PACKAGE_TARNAME
27 #undef PACKAGE_VERSION
31 #include <ac/string.h>
33 /* selectors for different maps */
34 enum nssov_map_selector
50 typedef struct nssov_mapinfo {
51 struct berval mi_base;
53 struct berval mi_filter0;
54 struct berval mi_filter;
55 struct berval *mi_attrkeys;
56 AttributeName *mi_attrs;
59 typedef struct nssov_info
61 /* search timelimit */
63 struct nssov_mapinfo ni_maps[NM_NONE];
68 /* PAM authz support... */
69 slap_mask_t ni_pam_opts;
70 struct berval ni_pam_group_dn;
71 AttributeDescription *ni_pam_group_ad;
74 AttributeDescription *ni_pam_template_ad;
75 struct berval ni_pam_template;
76 struct berval ni_pam_defhost;
77 AttributeDescription *ni_pam_host_ad;
78 AttributeDescription *ni_pam_svc_ad;
81 #define NI_PAM_USERHOST 1 /* old style host checking */
82 #define NI_PAM_USERSVC 2 /* old style service checking */
83 #define NI_PAM_USERGRP 4 /* old style group checking */
84 #define NI_PAM_HOSTSVC 8 /* new style authz checking */
85 #define NI_PAM_SASL2DN 0x10 /* use sasl2dn */
86 #define NI_PAM_UID2DN 0x20 /* use uid2dn */
88 #define NI_PAM_OLD (NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP)
89 #define NI_PAM_NEW NI_PAM_HOSTSVC
91 /* Read the default configuration file. */
92 void nssov_cfg_init(nssov_info *ni,const char *fname);
94 /* macros for basic read and write operations, the following
95 ERROR_OUT* marcos define the action taken on errors
96 the stream is not closed because the caller closes the
99 #define ERROR_OUT_WRITEERROR(fp) \
100 Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \
103 #define ERROR_OUT_READERROR(fp) \
104 Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \
107 #define ERROR_OUT_BUFERROR(fp) \
108 Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \
111 #define WRITE_BERVAL(fp,bv) \
112 DEBUG_PRINT("WRITE_STRING: var="__STRING(bv)" string=\"%s\"",(bv)->bv_val); \
119 WRITE_INT32(fp,(bv)->bv_len); \
121 { WRITE(fp,(bv)->bv_val,tmpint32); } \
124 #define WRITE_BVARRAY(fp,arr) \
125 /* first determine length of array */ \
126 for (tmp3int32=0;(arr)[tmp3int32].bv_val!=NULL;tmp3int32++) \
128 /* write number of strings */ \
129 DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d",(int)tmp3int32); \
130 WRITE_TYPE(fp,tmp3int32,int32_t); \
131 /* write strings */ \
132 for (tmp2int32=0;tmp2int32<tmp3int32;tmp2int32++) \
134 WRITE_BERVAL(fp,&(arr)[tmp2int32]); \
137 /* This tries to get the user password attribute from the entry.
138 It will try to return an encrypted password as it is used in /etc/passwd,
139 /etc/group or /etc/shadow depending upon what is in the directory.
140 This function will return NULL if no passwd is found and will return the
141 literal value in the directory if conversion is not possible. */
142 void get_userpassword(struct berval *attr, struct berval *pw);
144 /* write out an address, parsing the addr value */
145 int write_address(TFILE *fp,struct berval *addr);
147 /* a helper macro to write out addresses and bail out on errors */
148 #define WRITE_ADDRESS(fp,addr) \
149 if (write_address(fp,addr)) \
152 /* read an address from the stream */
153 int read_address(TFILE *fp,char *addr,int *addrlen,int *af);
155 /* helper macro to read an address from the stream */
156 #define READ_ADDRESS(fp,addr,len,af) \
157 len=(int)sizeof(addr); \
158 if (read_address(fp,addr,&(len),&(af))) \
161 /* checks to see if the specified string is a valid username */
162 int isvalidusername(struct berval *name);
164 /* transforms the DN into a uid doing an LDAP lookup if needed */
165 int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid);
167 /* transforms the uid into a DN by doing an LDAP lookup */
168 int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn);
169 int nssov_name2dn_cb(Operation *op, SlapReply *rs);
171 /* Escapes characters in a string for use in a search filter. */
172 int nssov_escape(struct berval *src,struct berval *dst);
174 int nssov_filter_byname(nssov_mapinfo *mi,int key,struct berval *name,struct berval *buf);
175 int nssov_filter_byid(nssov_mapinfo *mi,int key,struct berval *id,struct berval *buf);
177 void nssov_alias_init(nssov_info *ni);
178 void nssov_ether_init(nssov_info *ni);
179 void nssov_group_init(nssov_info *ni);
180 void nssov_host_init(nssov_info *ni);
181 void nssov_netgroup_init(nssov_info *ni);
182 void nssov_network_init(nssov_info *ni);
183 void nssov_passwd_init(nssov_info *ni);
184 void nssov_protocol_init(nssov_info *ni);
185 void nssov_rpc_init(nssov_info *ni);
186 void nssov_service_init(nssov_info *ni);
187 void nssov_shadow_init(nssov_info *ni);
189 /* these are the different functions that handle the database
190 specific actions, see nslcd.h for the action descriptions */
191 int nssov_alias_byname(nssov_info *ni,TFILE *fp,Operation *op);
192 int nssov_alias_all(nssov_info *ni,TFILE *fp,Operation *op);
193 int nssov_ether_byname(nssov_info *ni,TFILE *fp,Operation *op);
194 int nssov_ether_byether(nssov_info *ni,TFILE *fp,Operation *op);
195 int nssov_ether_all(nssov_info *ni,TFILE *fp,Operation *op);
196 int nssov_group_byname(nssov_info *ni,TFILE *fp,Operation *op);
197 int nssov_group_bygid(nssov_info *ni,TFILE *fp,Operation *op);
198 int nssov_group_bymember(nssov_info *ni,TFILE *fp,Operation *op);
199 int nssov_group_all(nssov_info *ni,TFILE *fp,Operation *op);
200 int nssov_host_byname(nssov_info *ni,TFILE *fp,Operation *op);
201 int nssov_host_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
202 int nssov_host_all(nssov_info *ni,TFILE *fp,Operation *op);
203 int nssov_netgroup_byname(nssov_info *ni,TFILE *fp,Operation *op);
204 int nssov_network_byname(nssov_info *ni,TFILE *fp,Operation *op);
205 int nssov_network_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
206 int nssov_network_all(nssov_info *ni,TFILE *fp,Operation *op);
207 int nssov_passwd_byname(nssov_info *ni,TFILE *fp,Operation *op);
208 int nssov_passwd_byuid(nssov_info *ni,TFILE *fp,Operation *op);
209 int nssov_passwd_all(nssov_info *ni,TFILE *fp,Operation *op);
210 int nssov_protocol_byname(nssov_info *ni,TFILE *fp,Operation *op);
211 int nssov_protocol_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
212 int nssov_protocol_all(nssov_info *ni,TFILE *fp,Operation *op);
213 int nssov_rpc_byname(nssov_info *ni,TFILE *fp,Operation *op);
214 int nssov_rpc_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
215 int nssov_rpc_all(nssov_info *ni,TFILE *fp,Operation *op);
216 int nssov_service_byname(nssov_info *ni,TFILE *fp,Operation *op);
217 int nssov_service_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
218 int nssov_service_all(nssov_info *ni,TFILE *fp,Operation *op);
219 int nssov_shadow_byname(nssov_info *ni,TFILE *fp,Operation *op);
220 int nssov_shadow_all(nssov_info *ni,TFILE *fp,Operation *op);
221 int pam_authc(nssov_info *ni,TFILE *fp,Operation *op);
222 int pam_authz(nssov_info *ni,TFILE *fp,Operation *op);
223 int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op);
224 int pam_sess_c(nssov_info *ni,TFILE *fp,Operation *op);
225 int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op);
227 /* config initialization */
228 #define NSSOV_INIT(db) \
229 void nssov_##db##_init(nssov_info *ni) \
231 nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \
233 for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \
235 mi->mi_attrs = ch_malloc( i*sizeof(AttributeName)); \
236 for (i=0;!BER_BVISNULL(&db##_keys[i]);i++) { \
237 mi->mi_attrs[i].an_name = db##_keys[i]; \
238 mi->mi_attrs[i].an_desc = NULL; \
240 mi->mi_scope = LDAP_SCOPE_DEFAULT; \
241 mi->mi_filter0 = db##_filter; \
242 ber_dupbv( &mi->mi_filter, &mi->mi_filter0 ); \
243 mi->mi_filter = db##_filter; \
244 mi->mi_attrkeys = db##_keys; \
245 BER_BVZERO(&mi->mi_base); \
248 /* param structure for search callback */
249 #define NSSOV_CBPRIV(db,parms) \
250 typedef struct nssov_##db##_cbp { \
257 /* callback for writing search results */
258 #define NSSOV_CB(db) \
259 static int nssov_##db##_cb(Operation *op, SlapReply *rs) \
261 if ( rs->sr_type == REP_SEARCH ) { \
262 nssov_##db##_cbp *cbp = op->o_callback->sc_private; \
263 if (write_##db(cbp,rs->sr_entry)) return LDAP_OTHER; \
265 return LDAP_SUCCESS; \
268 /* macro for generating service handling code */
269 #define NSSOV_HANDLE(db,fn,readfn,logcall,action,mkfilter) \
270 int nssov_##db##_##fn(nssov_info *ni,TFILE *fp,Operation *op) \
272 /* define common variables */ \
275 nssov_##db##_cbp cbp; \
276 slap_callback cb = {0}; \
277 SlapReply rs = {REP_RESULT}; \
278 cbp.mi = &ni->ni_maps[NM_##db]; \
281 /* read request parameters */ \
285 /* write the response header */ \
286 WRITE_INT32(fp,NSLCD_VERSION); \
287 WRITE_INT32(fp,action); \
288 /* prepare the search filter */ \
291 Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \
294 cb.sc_private = &cbp; \
295 op->o_callback = &cb; \
296 cb.sc_response = nssov_##db##_cb; \
297 slap_op_time( &op->o_time, &op->o_tincr ); \
298 op->o_req_dn = cbp.mi->mi_base; \
299 op->o_req_ndn = cbp.mi->mi_base; \
300 op->ors_scope = cbp.mi->mi_scope; \
301 op->ors_filterstr = filter; \
302 op->ors_filter = str2filter_x( op, filter.bv_val ); \
303 op->ors_attrs = cbp.mi->mi_attrs; \
304 op->ors_tlimit = SLAP_NO_LIMIT; \
305 op->ors_slimit = SLAP_NO_LIMIT; \
306 /* do the internal search */ \
307 op->o_bd->be_search( op, &rs ); \
308 filter_free_x( op, op->ors_filter, 1 ); \