]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/nssov/nssov.h
Flesh out config options, implement authorization checks
[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-2009 The OpenLDAP Foundation.
6  * Portions Copyright 2008 Howard Chu.
7  */
8
9 #ifndef NSSOV_H
10 #define NSSOV_H
11
12 #ifndef NSLCD_SOCKET
13 #define NSLCD_SOCKET    "/var/run/nslcd/socket"
14 #endif
15
16 #include <stdio.h>
17
18 #include "nslcd.h"
19 #include "nslcd-common.h"
20 #include "common/tio.h"
21 #include "compat/attrs.h"
22
23 #undef PACKAGE_BUGREPORT
24 #undef PACKAGE_NAME
25 #undef PACKAGE_STRING
26 #undef PACKAGE_TARNAME
27 #undef PACKAGE_VERSION
28
29 #include "portable.h"
30 #include "slap.h"
31 #include <ac/string.h>
32
33 /* selectors for different maps */
34 enum nssov_map_selector
35 {
36   NM_alias,
37   NM_ether,
38   NM_group,
39   NM_host,
40   NM_netgroup,
41   NM_network,
42   NM_passwd,
43   NM_protocol,
44   NM_rpc,
45   NM_service,
46   NM_shadow,
47   NM_NONE
48 };
49
50 typedef struct nssov_mapinfo {
51         struct berval mi_base;
52         int mi_scope;
53         struct berval mi_filter0;
54         struct berval mi_filter;
55         struct berval *mi_attrkeys;
56         AttributeName *mi_attrs;
57 } nssov_mapinfo;
58
59 typedef struct nssov_info
60 {
61         /* search timelimit */
62         int ni_timelimit;
63         struct nssov_mapinfo ni_maps[NM_NONE];
64         int ni_socket;
65         Connection *ni_conn;
66         BackendDB *ni_db;
67
68         /* PAM authz support... */
69         slap_mask_t ni_pam_opts;
70         struct berval ni_pam_group_dn;
71         AttributeDescription *ni_pam_group_ad;
72         int ni_pam_min_uid;
73         int ni_pam_max_uid;
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;
79 } nssov_info;
80
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 */
87
88 #define NI_PAM_OLD      (NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP)
89 #define NI_PAM_NEW      NI_PAM_HOSTSVC
90
91 /* Read the default configuration file. */
92 void nssov_cfg_init(nssov_info *ni,const char *fname);
93
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
97    stream */
98
99 #define ERROR_OUT_WRITEERROR(fp) \
100   Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \
101   return -1;
102
103 #define ERROR_OUT_READERROR(fp) \
104   Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \
105   return -1;
106
107 #define ERROR_OUT_BUFERROR(fp) \
108   Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \
109   return -1;
110
111 #define WRITE_BERVAL(fp,bv) \
112   DEBUG_PRINT("WRITE_STRING: var="__STRING(bv)" string=\"%s\"",(bv)->bv_val); \
113   if ((bv)==NULL) \
114   { \
115     WRITE_INT32(fp,0); \
116   } \
117   else \
118   { \
119     WRITE_INT32(fp,(bv)->bv_len); \
120     if (tmpint32>0) \
121       { WRITE(fp,(bv)->bv_val,tmpint32); } \
122   }
123
124 #define WRITE_BVARRAY(fp,arr) \
125   /* first determine length of array */ \
126   for (tmp3int32=0;(arr)[tmp3int32].bv_val!=NULL;tmp3int32++) \
127     /*nothing*/ ; \
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++) \
133   { \
134     WRITE_BERVAL(fp,&(arr)[tmp2int32]); \
135   }
136
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);
143
144 /* write out an address, parsing the addr value */
145 int write_address(TFILE *fp,struct berval *addr);
146
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)) \
150     return -1;
151
152 /* read an address from the stream */
153 int read_address(TFILE *fp,char *addr,int *addrlen,int *af);
154
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))) \
159     return -1;
160
161 /* checks to see if the specified string is a valid username */
162 int isvalidusername(struct berval *name);
163
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);
166
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);
170
171 /* Escapes characters in a string for use in a search filter. */
172 int nssov_escape(struct berval *src,struct berval *dst);
173
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);
176
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);
188
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);
226
227 /* config initialization */
228 #define NSSOV_INIT(db) \
229  void nssov_##db##_init(nssov_info *ni) \
230  { \
231         nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \
232         int i; \
233         for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \
234         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; \
239         } \
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); \
246  }
247
248 /* param structure for search callback */
249 #define NSSOV_CBPRIV(db,parms) \
250   typedef struct nssov_##db##_cbp { \
251         nssov_mapinfo *mi; \
252         TFILE *fp; \
253         Operation *op; \
254         parms \
255   } nssov_##db##_cbp
256
257 /* callback for writing search results */
258 #define NSSOV_CB(db) \
259   static int nssov_##db##_cb(Operation *op, SlapReply *rs) \
260   { \
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; \
264   } \
265   return LDAP_SUCCESS; \
266   } \
267
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) \
271   { \
272     /* define common variables */ \
273     int32_t tmpint32; \
274     int rc; \
275         nssov_##db##_cbp cbp; \
276         slap_callback cb = {0}; \
277         SlapReply rs = {REP_RESULT}; \
278         cbp.mi = &ni->ni_maps[NM_##db]; \
279         cbp.fp = fp; \
280         cbp.op = op; \
281     /* read request parameters */ \
282     readfn; \
283     /* log call */ \
284     logcall; \
285     /* write the response header */ \
286     WRITE_INT32(fp,NSLCD_VERSION); \
287     WRITE_INT32(fp,action); \
288     /* prepare the search filter */ \
289     if (mkfilter) \
290     { \
291       Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \
292       return -1; \
293     } \
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 ); \
309     return 0; \
310   }
311
312 #endif /* NSSOV_H */