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