]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/nssov/nssov.h
Merge remote-tracking branch 'origin/mdb.RE/0.9'
[openldap] / contrib / slapd-modules / nssov / nssov.h
1 /* nssov.h - NSS overlay header file */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2008-2015 The OpenLDAP Foundation.
6  * Portions Copyright 2008 Howard Chu.
7  * Portions Copyright 2013 Ted C. Cheng, Symas Corp.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted only as authorized by the OpenLDAP
12  * Public License.
13  *
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>.
17  */
18
19 #ifndef NSSOV_H
20 #define NSSOV_H
21
22 #ifndef NSLCD_PATH
23 #define NSLCD_PATH      "/var/run/nslcd"
24 #endif
25
26 #ifndef NSLCD_SOCKET
27 #define NSLCD_SOCKET    NSLCD_PATH "/socket"
28 #endif
29
30 #include <stdio.h>
31
32 #include "nslcd.h"
33 #include "nslcd-prot.h"
34 #include "tio.h"
35 #include "attrs.h"
36
37 #undef PACKAGE_BUGREPORT
38 #undef PACKAGE_NAME
39 #undef PACKAGE_STRING
40 #undef PACKAGE_TARNAME
41 #undef PACKAGE_VERSION
42
43 #include "portable.h"
44 #include "slap.h"
45 #include <ac/string.h>
46
47 /* selectors for different maps */
48 enum nssov_map_selector
49 {
50   NM_alias,
51   NM_ether,
52   NM_group,
53   NM_host,
54   NM_netgroup,
55   NM_network,
56   NM_passwd,
57   NM_protocol,
58   NM_rpc,
59   NM_service,
60   NM_shadow,
61   NM_NONE
62 };
63
64 typedef struct nssov_mapinfo {
65         struct berval mi_base;
66         int mi_scope;
67         struct berval mi_filter0;
68         struct berval mi_filter;
69         struct berval *mi_attrkeys;
70         AttributeName *mi_attrs;
71 } nssov_mapinfo;
72
73 typedef struct nssov_info
74 {
75         /* search timelimit */
76         int ni_timelimit;
77         struct nssov_mapinfo ni_maps[NM_NONE];
78         int ni_socket;
79         Connection *ni_conn;
80         BackendDB *ni_db;
81
82         /* PAM authz support... */
83         slap_mask_t ni_pam_opts;
84         struct berval ni_pam_group_dn;
85         AttributeDescription *ni_pam_group_ad;
86         int ni_pam_min_uid;
87         int ni_pam_max_uid;
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;
95 } nssov_info;
96
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 */
103
104 #define NI_PAM_OLD      (NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP)
105 #define NI_PAM_NEW      NI_PAM_HOSTSVC
106
107 extern AttributeDescription *nssov_pam_host_ad;
108 extern AttributeDescription *nssov_pam_svc_ad;
109
110 /* Read the default configuration file. */
111 void nssov_cfg_init(nssov_info *ni,const char *fname);
112
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
116    stream */
117
118 #define ERROR_OUT_WRITEERROR(fp) \
119   Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \
120   return -1;
121
122 #define ERROR_OUT_READERROR(fp) \
123   Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \
124   return -1;
125
126 #define ERROR_OUT_BUFERROR(fp) \
127   Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \
128   return -1;
129
130 #define WRITE_BERVAL(fp, bv)                                                   \
131   DEBUG_PRINT("WRITE_BERVAL: var="__STRING(bv)" bv_val=\"%s\"", (bv)->bv_val); \
132   if ((bv) == NULL)                                                            \
133   {                                                                            \
134     WRITE_INT32(fp, 0);                                                        \
135   }                                                                            \
136   else                                                                         \
137   {                                                                            \
138     WRITE_INT32(fp, (bv)->bv_len);                                             \
139     tmpint32 = ntohl(tmpint32);                                                \
140     if (tmpint32 > 0)                                                          \
141     {                                                                          \
142       WRITE(fp, (bv)->bv_val, tmpint32);                                       \
143     }                                                                          \
144   }                                                                            \
145
146 #define WRITE_BVARRAY(fp, arr)                                                 \
147   if ((arr) == NULL)                                                           \
148   {                                                                            \
149     DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d", 0);               \
150     WRITE_INT32(fp, 0);                                                        \
151   }                                                                            \
152   else                                                                         \
153   {                                                                            \
154     /* first determine length of array */                                      \
155     for (tmp3int32 = 0; (arr)[tmp3int32].bv_val != NULL; tmp3int32++)          \
156       /* nothing */ ;                                                          \
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++)                    \
162     {                                                                          \
163       WRITE_BERVAL(fp, &(arr)[tmp2int32]);                                     \
164     }                                                                          \
165   }                                                                            \
166
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);
169
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);
176
177 /* write out an address, parsing the addr value */
178 int write_address(TFILE *fp,struct berval *addr);
179
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)) \
183     return -1;
184
185 /* read an address from the stream */
186 int read_address(TFILE *fp,char *addr,int *addrlen,int *af);
187
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))) \
192     return -1;
193
194 /* checks to see if the specified string is a valid username */
195 int isvalidusername(struct berval *name);
196
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);
199
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);
203
204 /* Escapes characters in a string for use in a search filter. */
205 int nssov_escape(struct berval *src,struct berval *dst);
206
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);
209
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);
221
222 int nssov_pam_init(void);
223
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);
261
262 /* config initialization */
263 #define NSSOV_INIT(db) \
264  void nssov_##db##_init(nssov_info *ni) \
265  { \
266         nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \
267         int i; \
268         for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \
269         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; \
274         } \
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); \
281  }
282
283 /* param structure for search callback */
284 #define NSSOV_CBPRIV(db,parms) \
285   typedef struct nssov_##db##_cbp { \
286         nssov_mapinfo *mi; \
287         TFILE *fp; \
288         Operation *op; \
289         parms \
290   } nssov_##db##_cbp
291
292 /* callback for writing search results */
293 #define NSSOV_CB(db) \
294   static int nssov_##db##_cb(Operation *op, SlapReply *rs) \
295   { \
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; \
299   } \
300   return LDAP_SUCCESS; \
301   } \
302
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) \
306   { \
307     /* define common variables */ \
308     int32_t tmpint32; \
309         nssov_##db##_cbp cbp; \
310         slap_callback cb = {0}; \
311         SlapReply rs = {REP_RESULT}; \
312         cbp.mi = &ni->ni_maps[NM_##db]; \
313         cbp.fp = fp; \
314         cbp.op = op; \
315     /* read request parameters */ \
316     readfn; \
317     /* log call */ \
318     logcall; \
319     /* write the response header */ \
320     WRITE_INT32(fp,NSLCD_VERSION); \
321     WRITE_INT32(fp,action); \
322     /* prepare the search filter */ \
323     if (mkfilter) \
324     { \
325       Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \
326       return -1; \
327     } \
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); \
344     return 0; \
345   }
346
347 #endif /* NSSOV_H */