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-2011 The OpenLDAP Foundation. 6 * Portions Copyright 2008 Howard Chu. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17 18#ifndef NSSOV_H 19#define NSSOV_H 20 21#ifndef NSLCD_PATH 22#define NSLCD_PATH "/var/run/nslcd" 23#endif 24 25#ifndef NSLCD_SOCKET 26#define NSLCD_SOCKET NSLCD_PATH "/socket" 27#endif 28 29#include <stdio.h> 30 31#include "nslcd.h" 32#include "nslcd-prot.h" 33#include "tio.h" 34#include "attrs.h" 35 36#undef PACKAGE_BUGREPORT 37#undef PACKAGE_NAME 38#undef PACKAGE_STRING 39#undef PACKAGE_TARNAME 40#undef PACKAGE_VERSION 41 42#include "portable.h" 43#include "slap.h" 44#include <ac/string.h> 45 46/* selectors for different maps */ 47enum nssov_map_selector 48{ 49 NM_alias, 50 NM_ether, 51 NM_group, 52 NM_host, 53 NM_netgroup, 54 NM_network, 55 NM_passwd, 56 NM_protocol, 57 NM_rpc, 58 NM_service, 59 NM_shadow, 60 NM_NONE 61}; 62 63typedef struct nssov_mapinfo { 64 struct berval mi_base; 65 int mi_scope; 66 struct berval mi_filter0; 67 struct berval mi_filter; 68 struct berval *mi_attrkeys; 69 AttributeName *mi_attrs; 70} nssov_mapinfo; 71 72typedef struct nssov_info 73{ 74 /* search timelimit */ 75 int ni_timelimit; 76 struct nssov_mapinfo ni_maps[NM_NONE]; 77 int ni_socket; 78 Connection *ni_conn; 79 BackendDB *ni_db; 80 81 /* PAM authz support... */ 82 slap_mask_t ni_pam_opts; 83 struct berval ni_pam_group_dn; 84 AttributeDescription *ni_pam_group_ad; 85 int ni_pam_min_uid; 86 int ni_pam_max_uid; 87 AttributeDescription *ni_pam_template_ad; 88 struct berval ni_pam_template; 89 struct berval ni_pam_defhost; 90 struct berval *ni_pam_sessions; 91} nssov_info; 92 93#define NI_PAM_USERHOST 1 /* old style host checking */ 94#define NI_PAM_USERSVC 2 /* old style service checking */ 95#define NI_PAM_USERGRP 4 /* old style group checking */ 96#define NI_PAM_HOSTSVC 8 /* new style authz checking */ 97#define NI_PAM_SASL2DN 0x10 /* use sasl2dn */ 98#define NI_PAM_UID2DN 0x20 /* use uid2dn */ 99 100#define NI_PAM_OLD (NI_PAM_USERHOST|NI_PAM_USERSVC|NI_PAM_USERGRP) 101#define NI_PAM_NEW NI_PAM_HOSTSVC 102 103extern AttributeDescription *nssov_pam_host_ad; 104extern AttributeDescription *nssov_pam_svc_ad; 105 106/* Read the default configuration file. */ 107void nssov_cfg_init(nssov_info *ni,const char *fname); 108 109/* macros for basic read and write operations, the following 110 ERROR_OUT* marcos define the action taken on errors 111 the stream is not closed because the caller closes the 112 stream */ 113 114#define ERROR_OUT_WRITEERROR(fp) \ 115 Debug(LDAP_DEBUG_ANY,"nssov: error writing to client\n",0,0,0); \ 116 return -1; 117 118#define ERROR_OUT_READERROR(fp) \ 119 Debug(LDAP_DEBUG_ANY,"nssov: error reading from client\n",0,0,0); \ 120 return -1; 121 122#define ERROR_OUT_BUFERROR(fp) \ 123 Debug(LDAP_DEBUG_ANY,"nssov: client supplied argument too large\n",0,0,0); \ 124 return -1; 125 126#define WRITE_BERVAL(fp,bv) \ 127 DEBUG_PRINT("WRITE_STRING: var="__STRING(bv)" string=\"%s\"",(bv)->bv_val); \ 128 if ((bv)==NULL) \ 129 { \ 130 WRITE_INT32(fp,0); \ 131 } \ 132 else \ 133 { \ 134 WRITE_INT32(fp,(bv)->bv_len); \ 135 if (tmpint32>0) \ 136 { WRITE(fp,(bv)->bv_val,tmpint32); } \ 137 } 138 139#define WRITE_BVARRAY(fp,arr) \ 140 /* first determine length of array */ \ 141 for (tmp3int32=0;(arr)[tmp3int32].bv_val!=NULL;tmp3int32++) \ 142 /*nothing*/ ; \ 143 /* write number of strings */ \ 144 DEBUG_PRINT("WRITE_BVARRAY: var="__STRING(arr)" num=%d",(int)tmp3int32); \ 145 WRITE_TYPE(fp,tmp3int32,int32_t); \ 146 /* write strings */ \ 147 for (tmp2int32=0;tmp2int32<tmp3int32;tmp2int32++) \ 148 { \ 149 WRITE_BERVAL(fp,&(arr)[tmp2int32]); \ 150 } 151 152/* This tries to get the user password attribute from the entry. 153 It will try to return an encrypted password as it is used in /etc/passwd, 154 /etc/group or /etc/shadow depending upon what is in the directory. 155 This function will return NULL if no passwd is found and will return the 156 literal value in the directory if conversion is not possible. */ 157void get_userpassword(struct berval *attr, struct berval *pw); 158 159/* write out an address, parsing the addr value */ 160int write_address(TFILE *fp,struct berval *addr); 161 162/* a helper macro to write out addresses and bail out on errors */ 163#define WRITE_ADDRESS(fp,addr) \ 164 if (write_address(fp,addr)) \ 165 return -1; 166 167/* read an address from the stream */ 168int read_address(TFILE *fp,char *addr,int *addrlen,int *af); 169 170/* helper macro to read an address from the stream */ 171#define READ_ADDRESS(fp,addr,len,af) \ 172 len=(int)sizeof(addr); \ 173 if (read_address(fp,addr,&(len),&(af))) \ 174 return -1; 175 176/* checks to see if the specified string is a valid username */ 177int isvalidusername(struct berval *name); 178 179/* transforms the DN into a uid doing an LDAP lookup if needed */ 180int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid); 181 182/* transforms the uid into a DN by doing an LDAP lookup */ 183int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn); 184int nssov_name2dn_cb(Operation *op, SlapReply *rs); 185 186/* Escapes characters in a string for use in a search filter. */ 187int nssov_escape(struct berval *src,struct berval *dst); 188 189int nssov_filter_byname(nssov_mapinfo *mi,int key,struct berval *name,struct berval *buf); 190int nssov_filter_byid(nssov_mapinfo *mi,int key,struct berval *id,struct berval *buf); 191 192void nssov_alias_init(nssov_info *ni); 193void nssov_ether_init(nssov_info *ni); 194void nssov_group_init(nssov_info *ni); 195void nssov_host_init(nssov_info *ni); 196void nssov_netgroup_init(nssov_info *ni); 197void nssov_network_init(nssov_info *ni); 198void nssov_passwd_init(nssov_info *ni); 199void nssov_protocol_init(nssov_info *ni); 200void nssov_rpc_init(nssov_info *ni); 201void nssov_service_init(nssov_info *ni); 202void nssov_shadow_init(nssov_info *ni); 203 204int nssov_pam_init(void); 205 206/* these are the different functions that handle the database 207 specific actions, see nslcd.h for the action descriptions */ 208int nssov_alias_byname(nssov_info *ni,TFILE *fp,Operation *op); 209int nssov_alias_all(nssov_info *ni,TFILE *fp,Operation *op); 210int nssov_ether_byname(nssov_info *ni,TFILE *fp,Operation *op); 211int nssov_ether_byether(nssov_info *ni,TFILE *fp,Operation *op); 212int nssov_ether_all(nssov_info *ni,TFILE *fp,Operation *op); 213int nssov_group_byname(nssov_info *ni,TFILE *fp,Operation *op); 214int nssov_group_bygid(nssov_info *ni,TFILE *fp,Operation *op); 215int nssov_group_bymember(nssov_info *ni,TFILE *fp,Operation *op); 216int nssov_group_all(nssov_info *ni,TFILE *fp,Operation *op); 217int nssov_host_byname(nssov_info *ni,TFILE *fp,Operation *op); 218int nssov_host_byaddr(nssov_info *ni,TFILE *fp,Operation *op); 219int nssov_host_all(nssov_info *ni,TFILE *fp,Operation *op); 220int nssov_netgroup_byname(nssov_info *ni,TFILE *fp,Operation *op); 221int nssov_network_byname(nssov_info *ni,TFILE *fp,Operation *op); 222int nssov_network_byaddr(nssov_info *ni,TFILE *fp,Operation *op); 223int nssov_network_all(nssov_info *ni,TFILE *fp,Operation *op); 224int nssov_passwd_byname(nssov_info *ni,TFILE *fp,Operation *op); 225int nssov_passwd_byuid(nssov_info *ni,TFILE *fp,Operation *op); 226int nssov_passwd_all(nssov_info *ni,TFILE *fp,Operation *op); 227int nssov_protocol_byname(nssov_info *ni,TFILE *fp,Operation *op); 228int nssov_protocol_bynumber(nssov_info *ni,TFILE *fp,Operation *op); 229int nssov_protocol_all(nssov_info *ni,TFILE *fp,Operation *op); 230int nssov_rpc_byname(nssov_info *ni,TFILE *fp,Operation *op); 231int nssov_rpc_bynumber(nssov_info *ni,TFILE *fp,Operation *op); 232int nssov_rpc_all(nssov_info *ni,TFILE *fp,Operation *op); 233int nssov_service_byname(nssov_info *ni,TFILE *fp,Operation *op); 234int nssov_service_bynumber(nssov_info *ni,TFILE *fp,Operation *op); 235int nssov_service_all(nssov_info *ni,TFILE *fp,Operation *op); 236int nssov_shadow_byname(nssov_info *ni,TFILE *fp,Operation *op); 237int nssov_shadow_all(nssov_info *ni,TFILE *fp,Operation *op); 238int pam_authc(nssov_info *ni,TFILE *fp,Operation *op); 239int pam_authz(nssov_info *ni,TFILE *fp,Operation *op); 240int pam_sess_o(nssov_info *ni,TFILE *fp,Operation *op); 241int pam_sess_c(nssov_info *ni,TFILE *fp,Operation *op); 242int pam_pwmod(nssov_info *ni,TFILE *fp,Operation *op); 243 244/* config initialization */ 245#define NSSOV_INIT(db) \ 246 void nssov_##db##_init(nssov_info *ni) \ 247 { \ 248 nssov_mapinfo *mi = &ni->ni_maps[NM_##db]; \ 249 int i; \ 250 for (i=0;!BER_BVISNULL(&db##_keys[i]);i++); \ 251 i++; \ 252 mi->mi_attrs = ch_malloc( i*sizeof(AttributeName)); \ 253 for (i=0;!BER_BVISNULL(&db##_keys[i]);i++) { \ 254 mi->mi_attrs[i].an_name = db##_keys[i]; \ 255 mi->mi_attrs[i].an_desc = NULL; \ 256 } \ 257 mi->mi_scope = LDAP_SCOPE_DEFAULT; \ 258 mi->mi_filter0 = db##_filter; \ 259 ber_dupbv( &mi->mi_filter, &mi->mi_filter0 ); \ 260 mi->mi_filter = db##_filter; \ 261 mi->mi_attrkeys = db##_keys; \ 262 BER_BVZERO(&mi->mi_base); \ 263 } 264 265/* param structure for search callback */ 266#define NSSOV_CBPRIV(db,parms) \ 267 typedef struct nssov_##db##_cbp { \ 268 nssov_mapinfo *mi; \ 269 TFILE *fp; \ 270 Operation *op; \ 271 parms \ 272 } nssov_##db##_cbp 273 274/* callback for writing search results */ 275#define NSSOV_CB(db) \ 276 static int nssov_##db##_cb(Operation *op, SlapReply *rs) \ 277 { \ 278 if ( rs->sr_type == REP_SEARCH ) { \ 279 nssov_##db##_cbp *cbp = op->o_callback->sc_private; \ 280 if (write_##db(cbp,rs->sr_entry)) return LDAP_OTHER; \ 281 } \ 282 return LDAP_SUCCESS; \ 283 } \ 284 285/* macro for generating service handling code */ 286#define NSSOV_HANDLE(db,fn,readfn,logcall,action,mkfilter) \ 287 int nssov_##db##_##fn(nssov_info *ni,TFILE *fp,Operation *op) \ 288 { \ 289 /* define common variables */ \ 290 int32_t tmpint32; \ 291 int rc; \ 292 nssov_##db##_cbp cbp; \ 293 slap_callback cb = {0}; \ 294 SlapReply rs = {REP_RESULT}; \ 295 cbp.mi = &ni->ni_maps[NM_##db]; \ 296 cbp.fp = fp; \ 297 cbp.op = op; \ 298 /* read request parameters */ \ 299 readfn; \ 300 /* log call */ \ 301 logcall; \ 302 /* write the response header */ \ 303 WRITE_INT32(fp,NSLCD_VERSION); \ 304 WRITE_INT32(fp,action); \ 305 /* prepare the search filter */ \ 306 if (mkfilter) \ 307 { \ 308 Debug(LDAP_DEBUG_ANY,"nssov_" __STRING(db) "_" __STRING(fn) "(): filter buffer too small",0,0,0); \ 309 return -1; \ 310 } \ 311 cb.sc_private = &cbp; \ 312 op->o_callback = &cb; \ 313 cb.sc_response = nssov_##db##_cb; \ 314 slap_op_time( &op->o_time, &op->o_tincr ); \ 315 op->o_req_dn = cbp.mi->mi_base; \ 316 op->o_req_ndn = cbp.mi->mi_base; \ 317 op->ors_scope = cbp.mi->mi_scope; \ 318 op->ors_filterstr = filter; \ 319 op->ors_filter = str2filter_x( op, filter.bv_val ); \ 320 op->ors_attrs = cbp.mi->mi_attrs; \ 321 op->ors_tlimit = SLAP_NO_LIMIT; \ 322 op->ors_slimit = SLAP_NO_LIMIT; \ 323 /* do the internal search */ \ 324 op->o_bd->be_search( op, &rs ); \ 325 filter_free_x( op, op->ors_filter, 1 ); \ 326 WRITE_INT32(fp,NSLCD_RESULT_END); \ 327 return 0; \ 328 } 329 330#endif /* NSSOV_H */ 331