#include "portable.h"
#ifdef SLAPD_OVER_ODLOCALES
#include "overlayutils.h"
#include <arpa/inet.h>
#define ODLOCALES_BACK_CONFIG 1
#include <ac/string.h>
#include <ac/ctype.h>
#include "slap.h"
#include "ldif.h"
#include "config.h"
static slap_overinst odlocales;
typedef struct odlocales_info {
struct odlocales_info *ci_next;
struct berval ci_dn;
AttributeDescription *ci_ad;
} odlocales_info;
typedef struct odloc_res_s {
struct berval *ndn;
char *lname;
int count;
} odloc_res;
static int odloc_count_attr_cb(
Operation *op,
SlapReply *rs
)
{
odloc_res *uc;
int rc = 0;
if(!op || !rs) return(0);
if(rs->sr_type != REP_SEARCH) return(0);
uc = op->o_callback->sc_private;
dump_slap_attr(rs->sr_un.sru_search.r_entry->e_attrs);
Attribute *someVal = NULL;
AttributeDescription *ad = NULL;
const char *text = NULL;
rc = slap_str2ad( "apple-group-realname", &ad, &text );
someVal = attr_find(rs->sr_un.sru_search.r_entry->e_attrs, ad);
if (someVal != NULL) {
uc->lname = someVal->a_vals->bv_val;
uc->count++;
}
return(0);
}
static int odloc_cloud_attr_cb(
Operation *op,
SlapReply *rs
)
{
odloc_res *uc;
int rc = 0;
if(!op || !rs) return(0);
if(rs->sr_type != REP_SEARCH) return(0);
uc = op->o_callback->sc_private;
dump_slap_attr(rs->sr_un.sru_search.r_entry->e_attrs);
Attribute *someVal = NULL;
AttributeDescription *ad = NULL;
const char *text = NULL;
rc = slap_str2ad( "apple-dns-domain", &ad, &text );
someVal = attr_find(rs->sr_un.sru_search.r_entry->e_attrs, ad);
if (someVal != NULL) {
uc->lname = someVal->a_vals->bv_val;
uc->count++;
}
return(0);
}
static char* odlocale_record_search(
Operation *op,
Operation *nop,
char *key,
struct berval *searchbase
)
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
SlapReply nrs = { REP_RESULT };
slap_callback cb = { NULL, NULL, NULL, NULL };
odloc_res uq = { NULL, 0 };
int rc;
nop->ors_filter = str2filter(key);
ber_str2bv(key, 0, 0, &nop->ors_filterstr);
if (strstr(key, "(cn=locales)")){
cb.sc_response = (slap_response*)odloc_cloud_attr_cb;
}else{
cb.sc_response = (slap_response*)odloc_count_attr_cb;
}
cb.sc_private = &uq;
nop->o_callback = &cb;
nop->o_tag = LDAP_REQ_SEARCH;
nop->ors_scope = LDAP_SCOPE_SUBTREE;
nop->ors_deref = LDAP_DEREF_NEVER;
nop->ors_limit = NULL;
nop->ors_slimit = SLAP_NO_LIMIT;
nop->ors_tlimit = SLAP_NO_LIMIT;
nop->ors_attrs = slap_anlist_all_attributes;
nop->ors_attrsonly = 0;
uq.ndn = &op->o_req_ndn;
nop->o_req_dn = *searchbase;
nop->o_req_ndn = *searchbase;
nop->o_ndn = op->o_bd->be_rootndn;
nop->o_bd = on->on_info->oi_origdb;
rc = nop->o_bd->be_search(nop, &nrs);
if ((rc == LDAP_SUCCESS) && (uq.count !=0)){
return(uq.lname);
}else{
return NULL;
}
}
static char* get_locales(Operation *op,
Operation *nop,
char *myip,
struct berval *searchbase){
char *mySite = NULL;
in_addr_t y;
int c;
char ipOut[16];
char NetObj[100];
char *localeName = NULL;
in_addr_t x;
inet_aton(myip, &x);
for ( c=32; c > 0 && localeName == NULL; c--){
const char *attrs[2];
y = (ntohl(x) >> (32-c)) << (32-c);
unsigned int tempAddr = htonl( y );
unsigned char *X = (unsigned char *)&tempAddr;
snprintf( ipOut, sizeof(ipOut), "%i.%i.%i.%i", (int)X[0], (int)X[1], (int)X[2], (int)X[3]);
snprintf( NetObj, sizeof(NetObj), "(apple-locale-subnets=%s/%i)", ipOut, c );
localeName = odlocale_record_search(op,nop,NetObj,searchbase);
}
if (localeName != NULL) {
Debug( LDAP_DEBUG_TRACE, "found locale %s \n", localeName, 0, 0 );
return localeName;
} else {
return "DefaultLocale";
}
}
static int odlocales_response( Operation *op, SlapReply *rs )
{
if ((rs->sr_type != REP_SEARCH) || (op->oq_search.rs_attrs == NULL) ){
return SLAP_CB_CONTINUE;
}
if (strstr(op->oq_search.rs_attrs->an_name.bv_val, "netlogon") == NULL) {
return SLAP_CB_CONTINUE;
}
char *theLocale;
int rc = 0;
Debug( LDAP_DEBUG_TRACE, "OD Locale search called by client %s \n", op->o_hdr->oh_conn->c_peer_name.bv_val, 0, 0 );
Operation nop = *op;
struct berval searchbase;
Attribute *bDN = NULL;
AttributeDescription *ad = NULL;
const char *text = NULL;
rc = slap_str2ad( "namingContexts", &ad, &text );
bDN = attr_find(rs->sr_un.sru_search.r_entry->e_attrs, ad);
if(!bDN || !bDN->a_vals->bv_val)
return SLAP_CB_CONTINUE;
char *baseDN = bDN->a_vals->bv_val;
ber_str2bv( baseDN, 0, 0, &searchbase );
char *theCloud;
theCloud = odlocale_record_search(op,&nop,"(cn=locales)",&searchbase);
char *clientIP = strtok ( op->o_hdr->oh_conn->c_peer_name.bv_val, ":=" );
clientIP = strtok ( NULL,":=");
theLocale = get_locales(op,&nop,clientIP,&searchbase);
char test_entry[512];
rs->sr_err = LDAP_SUCCESS;
snprintf( test_entry, sizeof(test_entry), "dn: \nClientSiteName: %s\nDNSDomainName: %s\nDNSForestName: %s\n", theLocale, theCloud,theCloud);
Entry *new = str2entry2( test_entry, 0 );
rs->sr_un.sru_search.r_entry = new;
rs->sr_attrs = slap_anlist_all_attributes;
return SLAP_CB_CONTINUE;
}
static int
odlocales_db_config(
BackendDB *be,
const char *fname,
int lineno,
int argc,
char **argv )
{
if ( strcasecmp( argv[ 0 ], "odlocales-base" ) == 0 ) {
Debug( LDAP_DEBUG_TRACE, "OD Locale search base configured as: %s \n", argv[ 1 ], 0, 0 );
return 0;
}
}
static ConfigDriver odlocales_cf;
static ConfigTable localecfg[] = {
{ "odlocales", "enabled", 1, 1, 0,
ARG_MAGIC, odlocales_cf,
"( OLcfgOvAt:700.10 NAME 'olcLocalesEnabled' "
"DESC 'Enables LDAP Ping for OD Locales' "
"EQUALITY booleanMatch "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
};
static ConfigOCs localeocs[] = {
{ "( OLcfgOvOc:700.10 "
"NAME 'olcODLocale' "
"DESC 'OD Locale Overlay configuration' "
"SUP olcOverlayConfig "
"MAY (olcLocalesEnabled) )",
Cft_Overlay, localecfg, NULL, NULL },
{ NULL, 0, NULL }
};
static int odlocales_cf( ConfigArgs *c )
{
Debug( LDAP_DEBUG_TRACE, "OD Locales overlay odlocales_cf \n", 0, 0, 0 );
slap_overinst *on = (slap_overinst *)c->bi;
int rc = 1;
return rc;
}
int odlocales_initialize() {
int rc = 0;
Debug( LDAP_DEBUG_TRACE, "==> OD Locales overlay initialize called \n", 0, 0, 0 );
memset( &odlocales, 0, sizeof( slap_overinst ) );
odlocales.on_bi.bi_type = "odlocales";
odlocales.on_response = odlocales_response;
odlocales.on_bi.bi_cf_ocs = localeocs;
rc = config_register_schema( localecfg, localeocs );
if ( rc ) {
return rc;
}
return (overlay_register(&odlocales));
}
#if SLAPD_OVER_ODLOCALES == SLAPD_MOD_DYNAMIC
int
init_module( int argc, char *argv[] )
{
Debug( LDAP_DEBUG_TRACE, "OD Locales overlay init_module \n", 0, 0, 0 );
return odlocales_initialize();
}
#endif
#endif