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