nssov.h 13 KB
Newer Older
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
1
2
3
4
/* nssov.h - NSS overlay header file */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
5
 * Copyright 2008-2018 The OpenLDAP Foundation.
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
6
 * Portions Copyright 2008 Howard Chu.
7
 * Portions Copyright 2013 Ted C. Cheng, Symas Corp.
8
9
10
11
12
13
14
15
16
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
17
18
19
20
21
 */

#ifndef NSSOV_H
#define NSSOV_H

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
22
23
24
25
#ifndef NSLCD_PATH
#define	NSLCD_PATH	"/var/run/nslcd"
#endif

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
26
#ifndef NSLCD_SOCKET
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
27
#define NSLCD_SOCKET	NSLCD_PATH "/socket"
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
28
29
30
31
32
#endif

#include <stdio.h>

#include "nslcd.h"
33
34
35
#include "nslcd-prot.h"
#include "tio.h"
#include "attrs.h"
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION

#include "portable.h"
#include "slap.h"
#include <ac/string.h>

/* selectors for different maps */
enum nssov_map_selector
{
  NM_alias,
  NM_ether,
  NM_group,
  NM_host,
  NM_netgroup,
  NM_network,
  NM_passwd,
  NM_protocol,
  NM_rpc,
  NM_service,
  NM_shadow,
  NM_NONE
};

typedef struct nssov_mapinfo {
	struct berval mi_base;
	int mi_scope;
	struct berval mi_filter0;
	struct berval mi_filter;
	struct berval *mi_attrkeys;
	AttributeName *mi_attrs;
} nssov_mapinfo;

typedef struct nssov_info
{
	/* search timelimit */
	int ni_timelimit;
	struct nssov_mapinfo ni_maps[NM_NONE];
	int ni_socket;
	Connection *ni_conn;
	BackendDB *ni_db;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
81
82
83
84
85
86
87
88
89
90
91

	/* PAM authz support... */
	slap_mask_t ni_pam_opts;
	struct berval ni_pam_group_dn;
	AttributeDescription *ni_pam_group_ad;
	int ni_pam_min_uid;
	int ni_pam_max_uid;
	AttributeDescription *ni_pam_template_ad;
	struct berval ni_pam_template;
	struct berval ni_pam_defhost;
	struct berval *ni_pam_sessions;
92
93
94
	struct berval ni_pam_password_prohibit_message;
	struct berval ni_pam_pwdmgr_dn;
	struct berval ni_pam_pwdmgr_pwd;
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
95
96
} nssov_info;

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
97
98
99
100
101
102
103
104
105
106
107
108
109
#define NI_PAM_USERHOST		1	/* old style host checking */
#define NI_PAM_USERSVC		2	/* old style service checking */
#define NI_PAM_USERGRP		4	/* old style group checking */
#define NI_PAM_HOSTSVC		8	/* new style authz checking */
#define NI_PAM_SASL2DN		0x10	/* use sasl2dn */
#define NI_PAM_UID2DN		0x20	/* use uid2dn */

#define	NI_PAM_OLD	(NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP)
#define	NI_PAM_NEW	NI_PAM_HOSTSVC

extern AttributeDescription *nssov_pam_host_ad;
extern AttributeDescription *nssov_pam_svc_ad;

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* Read the default configuration file. */
void nssov_cfg_init(nssov_info *ni,const char *fname);

/* macros for basic read and write operations, the following
   ERROR_OUT* marcos define the action taken on errors
   the stream is not closed because the caller closes the
   stream */

#define ERROR_OUT_WRITEERROR(fp) \
  Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \
  return -1;

#define ERROR_OUT_READERROR(fp) \
  Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \
  return -1;

#define ERROR_OUT_BUFERROR(fp) \
  Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \
  return -1;

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#define WRITE_BERVAL(fp, bv)                                                   \
  DEBUG_PRINT("WRITE_BERVAL: var="__STRING(bv)" bv_val=\"%s\"", (bv)->bv_val); \
  if ((bv) == NULL)                                                            \
  {                                                                            \
    WRITE_INT32(fp, 0);                                                        \
  }                                                                            \
  else                                                                         \
  {                                                                            \
    WRITE_INT32(fp, (bv)->bv_len);                                             \
    tmpint32 = ntohl(tmpint32);                                                \
    if (tmpint32 > 0)                                                          \
    {                                                                          \
      WRITE(fp, (bv)->bv_val, tmpint32);                                       \
    }                                                                          \
  }                                                                            \

#define WRITE_BVARRAY(fp, arr)                                                 \
  if ((arr) == NULL)                                                           \
  {                                                                            \
    DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d", 0);               \
    WRITE_INT32(fp, 0);                                                        \
  }                                                                            \
  else                                                                         \
  {                                                                            \
    /* first determine length of array */                                      \
    for (tmp3int32 = 0; (arr)[tmp3int32].bv_val != NULL; tmp3int32++)          \
      /* nothing */ ;                                                          \
    /* write number of strings */                                              \
    DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d", (int)tmp3int32);  \
    WRITE_INT32(fp, tmp3int32);                                                \
    /* write strings */                                                        \
    for (tmp2int32 = 0; tmp2int32 < tmp3int32; tmp2int32++)                    \
    {                                                                          \
      WRITE_BERVAL(fp, &(arr)[tmp2int32]);                                     \
    }                                                                          \
  }                                                                            \
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
166

167
168
169
/* Find the given attribute's value in the RDN of the DN. */
void nssov_find_rdnval(struct berval *dn,AttributeDescription *ad,struct berval *value);

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* This tries to get the user password attribute from the entry.
   It will try to return an encrypted password as it is used in /etc/passwd,
   /etc/group or /etc/shadow depending upon what is in the directory.
   This function will return NULL if no passwd is found and will return the
   literal value in the directory if conversion is not possible. */
void get_userpassword(struct berval *attr, struct berval *pw);

/* write out an address, parsing the addr value */
int write_address(TFILE *fp,struct berval *addr);

/* a helper macro to write out addresses and bail out on errors */
#define WRITE_ADDRESS(fp,addr) \
  if (write_address(fp,addr)) \
    return -1;

/* read an address from the stream */
int read_address(TFILE *fp,char *addr,int *addrlen,int *af);

/* helper macro to read an address from the stream */
#define READ_ADDRESS(fp,addr,len,af) \
  len=(int)sizeof(addr); \
  if (read_address(fp,addr,&(len),&(af))) \
    return -1;

/* checks to see if the specified string is a valid username */
int isvalidusername(struct berval *name);

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
197
/* transforms the DN into a uid doing an LDAP lookup if needed */
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
198
199
200
201
int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid);

/* transforms the uid into a DN by doing an LDAP lookup */
int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn);
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
202
int nssov_name2dn_cb(Operation *op, SlapReply *rs);
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

/* Escapes characters in a string for use in a search filter. */
int nssov_escape(struct berval *src,struct berval *dst);

int nssov_filter_byname(nssov_mapinfo *mi,int key,struct berval *name,struct berval *buf);
int nssov_filter_byid(nssov_mapinfo *mi,int key,struct berval *id,struct berval *buf);

void nssov_alias_init(nssov_info *ni);
void nssov_ether_init(nssov_info *ni);
void nssov_group_init(nssov_info *ni);
void nssov_host_init(nssov_info *ni);
void nssov_netgroup_init(nssov_info *ni);
void nssov_network_init(nssov_info *ni);
void nssov_passwd_init(nssov_info *ni);
void nssov_protocol_init(nssov_info *ni);
void nssov_rpc_init(nssov_info *ni);
void nssov_service_init(nssov_info *ni);
void nssov_shadow_init(nssov_info *ni);

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
222
223
int nssov_pam_init(void);

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/* these are the different functions that handle the database
   specific actions, see nslcd.h for the action descriptions */
int nssov_alias_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_alias_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_ether_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_ether_byether(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_ether_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_group_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_group_bygid(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_group_bymember(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_group_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_host_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_host_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_host_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_netgroup_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_network_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_network_byaddr(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_network_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_passwd_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_passwd_byuid(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_passwd_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_protocol_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_protocol_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_protocol_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_rpc_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_rpc_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_rpc_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_service_byname(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_service_bynumber(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_service_all(nssov_info *ni,TFILE *fp,Operation *op);
int nssov_shadow_byname(nssov_info *ni,TFILE *fp,Operation *op);
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);
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
257
258
259
int pam_authz(nssov_info *ni,TFILE *fp,Operation *op);
int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op);
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);
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

/* config initialization */
#define NSSOV_INIT(db) \
 void nssov_##db##_init(nssov_info *ni) \
 { \
	nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \
	int i; \
	for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \
	i++; \
	mi->mi_attrs = ch_malloc( i*sizeof(AttributeName)); \
	for (i=0;!BER_BVISNULL(&db##_keys[i]);i++) { \
		mi->mi_attrs[i].an_name = db##_keys[i]; \
		mi->mi_attrs[i].an_desc = NULL; \
	} \
	mi->mi_scope = LDAP_SCOPE_DEFAULT; \
	mi->mi_filter0 = db##_filter; \
	ber_dupbv( &mi->mi_filter, &mi->mi_filter0 ); \
	mi->mi_filter = db##_filter; \
	mi->mi_attrkeys = db##_keys; \
	BER_BVZERO(&mi->mi_base); \
 }

/* param structure for search callback */
#define NSSOV_CBPRIV(db,parms) \
  typedef struct nssov_##db##_cbp { \
  	nssov_mapinfo *mi; \
	TFILE *fp; \
	Operation *op; \
	parms \
  } nssov_##db##_cbp

/* callback for writing search results */
#define NSSOV_CB(db) \
  static int nssov_##db##_cb(Operation *op, SlapReply *rs) \
  { \
    if ( rs->sr_type == REP_SEARCH ) { \
    nssov_##db##_cbp *cbp = op->o_callback->sc_private; \
  	if (write_##db(cbp,rs->sr_entry)) return LDAP_OTHER; \
  } \
  return LDAP_SUCCESS; \
  } \

/* macro for generating service handling code */
#define NSSOV_HANDLE(db,fn,readfn,logcall,action,mkfilter) \
  int nssov_##db##_##fn(nssov_info *ni,TFILE *fp,Operation *op) \
  { \
    /* define common variables */ \
    int32_t tmpint32; \
	nssov_##db##_cbp cbp; \
	slap_callback cb = {0}; \
	SlapReply rs = {REP_RESULT}; \
	cbp.mi = &ni->ni_maps[NM_##db]; \
	cbp.fp = fp; \
	cbp.op = op; \
    /* read request parameters */ \
    readfn; \
    /* log call */ \
    logcall; \
    /* write the response header */ \
    WRITE_INT32(fp,NSLCD_VERSION); \
    WRITE_INT32(fp,action); \
    /* prepare the search filter */ \
    if (mkfilter) \
    { \
      Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \
      return -1; \
    } \
	cb.sc_private = &cbp; \
	op->o_callback = &cb; \
	cb.sc_response = nssov_##db##_cb; \
	slap_op_time( &op->o_time, &op->o_tincr ); \
	op->o_req_dn = cbp.mi->mi_base; \
	op->o_req_ndn = cbp.mi->mi_base; \
	op->ors_scope = cbp.mi->mi_scope; \
	op->ors_filterstr = filter; \
	op->ors_filter = str2filter_x( op, filter.bv_val ); \
	op->ors_attrs = cbp.mi->mi_attrs; \
	op->ors_tlimit = SLAP_NO_LIMIT; \
	op->ors_slimit = SLAP_NO_LIMIT; \
    /* do the internal search */ \
	op->o_bd->be_search( op, &rs ); \
342
	filter_free_x( op, op->ors_filter, 1 ); \
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
343
	WRITE_INT32(fp,NSLCD_RESULT_END); \
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
344
345
346
347
    return 0; \
  }

#endif /* NSSOV_H */