mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-26 01:29:59 -05:00
Flesh out config options, implement authorization checks
This commit is contained in:
parent
615082b0d0
commit
8fd0d184a7
5 changed files with 288 additions and 24 deletions
|
|
@ -109,7 +109,7 @@ and checked to determine access. Also a check may be performed to see if
|
|||
the user is a member of a particular group. This method is pretty
|
||||
inflexible and doesn't scale well to large networks of users, hosts,
|
||||
and services.
|
||||
The second uses slapd's ACL engine to check if the user has "auth"
|
||||
The second uses slapd's ACL engine to check if the user has "compare"
|
||||
privilege on an ipHost object whose name matches the current hostname, and
|
||||
whose authorizedService attribute matches the current service name. This
|
||||
method is preferred, since it allows authorization to be centralized in
|
||||
|
|
|
|||
|
|
@ -407,9 +407,21 @@ static slap_verbmasks nss_svcs[] = {
|
|||
{ BER_BVNULL, 0 }
|
||||
};
|
||||
|
||||
static slap_verbmasks pam_opts[] = {
|
||||
{ BER_BVC("userhost"), NI_PAM_USERHOST },
|
||||
{ BER_BVC("userservice"), NI_PAM_USERSVC },
|
||||
{ BER_BVC("usergroup"), NI_PAM_USERGRP },
|
||||
{ BER_BVC("hostservice"), NI_PAM_HOSTSVC },
|
||||
{ BER_BVC("sasl2dn"), NI_PAM_SASL2DN },
|
||||
{ BER_BVC("uid2dn"), NI_PAM_UID2DN },
|
||||
{ BER_BVNULL, 0 }
|
||||
};
|
||||
|
||||
enum {
|
||||
NSS_SSD=1,
|
||||
NSS_MAP
|
||||
NSS_MAP,
|
||||
NSS_PAM,
|
||||
NSS_PAMGROUP,
|
||||
};
|
||||
|
||||
static ConfigDriver nss_cf_gen;
|
||||
|
|
@ -425,6 +437,52 @@ static ConfigTable nsscfg[] = {
|
|||
"DESC 'Map <service> lookups of <orig> attr to <new> attr' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
||||
{ "nssov-pam", "options", 2, 0, 0, ARG_MAGIC|NSS_PAM,
|
||||
nss_cf_gen, "(OLcfgCtAt:3.3 NAME 'olcNssPam' "
|
||||
"DESC 'PAM authentication and authorization options' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString )", NULL, NULL },
|
||||
{ "nssov-pam-defhost", "hostname", 2, 2, 0, ARG_OFFSET|ARG_BERVAL,
|
||||
(void *)offsetof(struct nssov_info, ni_pam_defhost),
|
||||
"(OLcfgCtAt:3.4 NAME 'olcNssPamDefHost' "
|
||||
"DESC 'Default hostname for service checks' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "nssov-pam-group-dn", "DN", 2, 2, 0, ARG_MAGIC|ARG_DN|NSS_PAMGROUP,
|
||||
nss_cf_gen, "(OLcfgCtAt:3.5 NAME 'olcNssPamGroupDN' "
|
||||
"DESC 'DN of group in which membership is required' "
|
||||
"EQUALITY distinguishedNameMatch "
|
||||
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
|
||||
{ "nssov-pam-group-ad", "options", 2, 2, 0, ARG_OFFSET|ARG_ATDESC,
|
||||
(void *)offsetof(struct nssov_info, ni_pam_group_ad),
|
||||
"(OLcfgCtAt:3.6 NAME 'olcNssPamGroupAD' "
|
||||
"DESC 'Member attribute to use for group check' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "nssov-pam-min-uid", "uid", 2, 2, 0, ARG_OFFSET|ARG_INT,
|
||||
(void *)offsetof(struct nssov_info, ni_pam_min_uid),
|
||||
"(OLcfgCtAt:3.7 NAME 'olcNssPamMinUid' "
|
||||
"DESC 'Minimum UID allowed to login' "
|
||||
"EQUALITY integerMatch "
|
||||
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
|
||||
{ "nssov-pam-max-uid", "uid", 2, 2, 0, ARG_OFFSET|ARG_INT,
|
||||
(void *)offsetof(struct nssov_info, ni_pam_max_uid),
|
||||
"(OLcfgCtAt:3.8 NAME 'olcNssPamMaxUid' "
|
||||
"DESC 'Maximum UID allowed to login' "
|
||||
"EQUALITY integerMatch "
|
||||
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
|
||||
{ "nssov-pam-template-ad", "attr", 2, 2, 0, ARG_OFFSET|ARG_ATDESC,
|
||||
(void *)offsetof(struct nssov_info, ni_pam_template_ad),
|
||||
"(OLcfgCtAt:3.9 NAME 'olcNssPamTemplateAD' "
|
||||
"DESC 'Attribute to use for template login name' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ "nssov-pam-template", "name", 2, 2, 0, ARG_OFFSET|ARG_BERVAL,
|
||||
(void *)offsetof(struct nssov_info, ni_pam_template),
|
||||
"(OLcfgCtAt:3.10 NAME 'olcNssPamTemplate' "
|
||||
"DESC 'Default template login name' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
|
||||
{ NULL, NULL, 0,0,0, ARG_IGNORED }
|
||||
};
|
||||
|
||||
|
|
@ -433,7 +491,10 @@ static ConfigOCs nssocs[] = {
|
|||
"NAME 'olcNssOvConfig' "
|
||||
"DESC 'NSS lookup configuration' "
|
||||
"SUP olcOverlayConfig "
|
||||
"MAY ( olcNssSsd $ olcNssMap ) )",
|
||||
"MAY ( olcNssSsd $ olcNssMap $ olcNssPam $ olcNssPamDefHost $ "
|
||||
"olcNssPamGroupDN $ olcNssPamGroupAD $ "
|
||||
"olcNssPamMinUid $ olcNssPamMaxUid $ "
|
||||
"olcNssPamTemplateAD $ olcNssPamTemplate ) )",
|
||||
Cft_Overlay, nsscfg },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
|
@ -445,6 +506,7 @@ nss_cf_gen(ConfigArgs *c)
|
|||
nssov_info *ni = on->on_bi.bi_private;
|
||||
nssov_mapinfo *mi;
|
||||
int i, j, rc = 0;
|
||||
slap_mask_t m;
|
||||
|
||||
if ( c->op == SLAP_CONFIG_EMIT ) {
|
||||
switch(c->type) {
|
||||
|
|
@ -500,9 +562,21 @@ nss_cf_gen(ConfigArgs *c)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case NSS_PAM:
|
||||
rc = mask_to_verbs( pam_opts, ni->ni_pam_opts, &c->rvalue_vals );
|
||||
break;
|
||||
case NSS_PAMGROUP:
|
||||
if (!BER_BVISEMPTY( &ni->ni_pam_group_dn )) {
|
||||
value_add_one( &c->rvalue_vals, &ni->ni_pam_group_dn );
|
||||
value_add_one( &c->rvalue_nvals, &ni->ni_pam_group_dn );
|
||||
} else {
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
} else if ( c->op == LDAP_MOD_DELETE ) {
|
||||
/* FIXME */
|
||||
return 1;
|
||||
}
|
||||
switch( c->type ) {
|
||||
|
|
@ -563,6 +637,19 @@ nss_cf_gen(ConfigArgs *c)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case NSS_PAM:
|
||||
m = ni->ni_pam_opts;
|
||||
i = verbs_to_mask(c->argc, c->argv, pam_opts, &m);
|
||||
if (i == 0) {
|
||||
ni->ni_pam_opts = m;
|
||||
} else {
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
case NSS_PAMGROUP:
|
||||
ni->ni_pam_group_dn = c->value_ndn;
|
||||
ch_free( c->value_dn.bv_val );
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,8 +64,30 @@ typedef struct nssov_info
|
|||
int ni_socket;
|
||||
Connection *ni_conn;
|
||||
BackendDB *ni_db;
|
||||
|
||||
/* 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;
|
||||
AttributeDescription *ni_pam_host_ad;
|
||||
AttributeDescription *ni_pam_svc_ad;
|
||||
} nssov_info;
|
||||
|
||||
#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
|
||||
|
||||
/* Read the default configuration file. */
|
||||
void nssov_cfg_init(nssov_info *ni,const char *fname);
|
||||
|
||||
|
|
@ -139,11 +161,12 @@ int read_address(TFILE *fp,char *addr,int *addrlen,int *af);
|
|||
/* checks to see if the specified string is a valid username */
|
||||
int isvalidusername(struct berval *name);
|
||||
|
||||
/* transforms the DN info a uid doing an LDAP lookup if needed */
|
||||
/* transforms the DN into a uid doing an LDAP lookup if needed */
|
||||
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);
|
||||
int nssov_name2dn_cb(Operation *op, SlapReply *rs);
|
||||
|
||||
/* Escapes characters in a string for use in a search filter. */
|
||||
int nssov_escape(struct berval *src,struct berval *dst);
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ int pam_authc(nssov_info *ni,TFILE *fp,Operation *op)
|
|||
char svcc[256];
|
||||
char pwdc[256];
|
||||
struct berval uid, svc, pwd, sdn, dn;
|
||||
int hlen;
|
||||
struct bindinfo bi;
|
||||
|
||||
bi.authz = PAM_SUCCESS;
|
||||
|
|
@ -129,28 +128,34 @@ int pam_authc(nssov_info *ni,TFILE *fp,Operation *op)
|
|||
goto finish;
|
||||
}
|
||||
|
||||
/* Why didn't we make this a berval? */
|
||||
hlen = strlen(global_host);
|
||||
|
||||
/* First try this form, to allow service-dependent mappings */
|
||||
/* cn=<service>+uid=<user>,cn=<host>,cn=pam,cn=auth */
|
||||
sdn.bv_len = uid.bv_len + svc.bv_len + hlen + STRLENOF( "cn=+uid=,cn=,cn=pam,cn=auth" );
|
||||
sdn.bv_val = op->o_tmpalloc( sdn.bv_len + 1, op->o_tmpmemctx );
|
||||
sprintf(sdn.bv_val, "cn=%s+uid=%s,cn=%s,cn=pam,cn=auth", svcc, uidc, global_host);
|
||||
BER_BVZERO(&dn);
|
||||
slap_sasl2dn(op, &sdn, &dn, 0);
|
||||
op->o_tmpfree( sdn.bv_val, op->o_tmpmemctx );
|
||||
|
||||
if (ni->ni_pam_opts & NI_PAM_SASL2DN) {
|
||||
int hlen = global_host_bv.bv_len;
|
||||
|
||||
/* cn=<service>+uid=<user>,cn=<host>,cn=pam,cn=auth */
|
||||
sdn.bv_len = uid.bv_len + svc.bv_len + hlen +
|
||||
STRLENOF( "cn=+uid=,cn=,cn=pam,cn=auth" );
|
||||
sdn.bv_val = op->o_tmpalloc( sdn.bv_len + 1, op->o_tmpmemctx );
|
||||
sprintf(sdn.bv_val, "cn=%s+uid=%s,cn=%s,cn=pam,cn=auth",
|
||||
svcc, uidc, global_host_bv.bv_val);
|
||||
slap_sasl2dn(op, &sdn, &dn, 0);
|
||||
op->o_tmpfree( sdn.bv_val, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
/* If no luck, do a basic uid search */
|
||||
if (BER_BVISEMPTY(&dn)) {
|
||||
if (!nssov_uid2dn(op, ni, &uid, &dn)) {
|
||||
rc = PAM_USER_UNKNOWN;
|
||||
goto finish;
|
||||
if (BER_BVISEMPTY(&dn) && (ni->ni_pam_opts & NI_PAM_UID2DN)) {
|
||||
nssov_uid2dn(op, ni, &uid, &dn);
|
||||
if (!BER_BVISEMPTY(&dn)) {
|
||||
sdn = dn;
|
||||
dnNormalize( 0, NULL, NULL, &sdn, &dn, op->o_tmpmemctx );
|
||||
}
|
||||
sdn = dn;
|
||||
dnNormalize( 0, NULL, NULL, &sdn, &dn, op->o_tmpmemctx );
|
||||
}
|
||||
BER_BVZERO(&sdn);
|
||||
if (BER_BVISEMPTY(&dn)) {
|
||||
rc = PAM_USER_UNKNOWN;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* Should only need to do this once at open time, but there's always
|
||||
* the possibility that ppolicy will get loaded later.
|
||||
|
|
@ -201,6 +206,18 @@ finish:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int pam_nullcb(Operation *op, SlapReply *rs)
|
||||
{
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static struct berval grpmsg =
|
||||
BER_BVC("Access denied by group check");
|
||||
static struct berval hostmsg =
|
||||
BER_BVC("Access denied for this host");
|
||||
static struct berval svcmsg =
|
||||
BER_BVC("Access denied for this service");
|
||||
|
||||
int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
|
||||
{
|
||||
struct berval dn, svc;
|
||||
|
|
@ -209,6 +226,11 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
|
|||
int32_t tmpint32;
|
||||
char dnc[1024];
|
||||
char svcc[256];
|
||||
int rc = PAM_SUCCESS;
|
||||
Entry *e = NULL;
|
||||
Attribute *a;
|
||||
SlapReply rs = {REP_RESULT};
|
||||
slap_callback cb = {0};
|
||||
|
||||
READ_STRING_BUF2(fp,dnc,sizeof(dnc));
|
||||
dn.bv_val = dnc;
|
||||
|
|
@ -219,12 +241,144 @@ int pam_authz(nssov_info *ni,TFILE *fp,Operation *op)
|
|||
|
||||
Debug(LDAP_DEBUG_TRACE,"nssov_pam_authz(%s)\n",dn.bv_val,0,0);
|
||||
|
||||
/* We don't do authorization if they weren't authenticated by us */
|
||||
if (BER_BVISEMPTY(&dn)) {
|
||||
rc = PAM_USER_UNKNOWN;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* See if they have access to the host and service */
|
||||
if (ni->ni_pam_opts & NI_PAM_HOSTSVC) {
|
||||
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
|
||||
struct berval hostdn = BER_BVNULL;
|
||||
{
|
||||
nssov_mapinfo *mi = &ni->ni_maps[NM_host];
|
||||
char fbuf[1024];
|
||||
struct berval filter = {sizeof(fbuf),fbuf};
|
||||
SlapReply rs2 = {REP_RESULT};
|
||||
|
||||
/* Lookup the host entry */
|
||||
nssov_filter_byname(mi,0,&global_host_bv,&filter);
|
||||
cb.sc_private = &hostdn;
|
||||
cb.sc_response = nssov_name2dn_cb;
|
||||
op->o_callback = &cb;
|
||||
op->o_req_dn = mi->mi_base;
|
||||
op->o_req_ndn = mi->mi_base;
|
||||
op->ors_scope = mi->mi_scope;
|
||||
op->ors_filterstr = filter;
|
||||
op->ors_filter = str2filter_x(op, filter.bv_val);
|
||||
op->ors_attrs = slap_anlist_no_attrs;
|
||||
op->ors_tlimit = SLAP_NO_LIMIT;
|
||||
op->ors_slimit = 2;
|
||||
rc = op->o_bd->be_search(op, &rs2);
|
||||
filter_free_x(op, op->ors_filter, 1);
|
||||
|
||||
if (BER_BVISEMPTY(&hostdn) &&
|
||||
!BER_BVISEMPTY(&ni->ni_pam_defhost)) {
|
||||
filter.bv_len = sizeof(fbuf);
|
||||
filter.bv_val = fbuf;
|
||||
memset(&rs2, 0, sizeof(rs2));
|
||||
rs2.sr_type = REP_RESULT;
|
||||
nssov_filter_byname(mi,0,&ni->ni_pam_defhost,&filter);
|
||||
op->ors_filterstr = filter;
|
||||
op->ors_filter = str2filter_x(op, filter.bv_val);
|
||||
rc = op->o_bd->be_search(op, &rs2);
|
||||
filter_free_x(op, op->ors_filter, 1);
|
||||
}
|
||||
|
||||
/* no host entry, no default host -> deny */
|
||||
if (BER_BVISEMPTY(&hostdn)) {
|
||||
rc = PAM_PERM_DENIED;
|
||||
authzmsg = hostmsg;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
cb.sc_response = pam_nullcb;
|
||||
cb.sc_private = NULL;
|
||||
op->o_tag = LDAP_REQ_COMPARE;
|
||||
op->o_req_dn = hostdn;
|
||||
op->o_req_ndn = hostdn;
|
||||
ava.aa_desc = ni->ni_pam_svc_ad;
|
||||
ava.aa_value = svc;
|
||||
op->orc_ava = &ava;
|
||||
rc = op->o_bd->be_compare( op, &rs );
|
||||
if ( rs.sr_err != LDAP_COMPARE_TRUE ) {
|
||||
authzmsg = svcmsg;
|
||||
rc = PAM_PERM_DENIED;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
/* See if they're a member of the group */
|
||||
if ((ni->ni_pam_opts & NI_PAM_USERGRP) &&
|
||||
!BER_BVISEMPTY(&ni->ni_pam_group_dn) &&
|
||||
ni->ni_pam_group_ad) {
|
||||
AttributeAssertion ava = ATTRIBUTEASSERTION_INIT;
|
||||
op->o_callback = &cb;
|
||||
cb.sc_response = pam_nullcb;
|
||||
op->o_tag = LDAP_REQ_COMPARE;
|
||||
op->o_req_dn = ni->ni_pam_group_dn;
|
||||
op->o_req_ndn = ni->ni_pam_group_dn;
|
||||
ava.aa_desc = ni->ni_pam_group_ad;
|
||||
ava.aa_value = dn;
|
||||
op->orc_ava = &ava;
|
||||
rc = op->o_bd->be_compare( op, &rs );
|
||||
if ( rs.sr_err != LDAP_COMPARE_TRUE ) {
|
||||
authzmsg = grpmsg;
|
||||
rc = PAM_PERM_DENIED;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to check the user's entry for these bits */
|
||||
if ((ni->ni_pam_opts & (NI_PAM_USERHOST|NI_PAM_USERSVC)) ||
|
||||
ni->ni_pam_template_ad ) {
|
||||
rc = be_entry_get_rw( op, &dn, NULL, NULL, 0, &e );
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
rc = PAM_USER_UNKNOWN;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if (ni->ni_pam_opts & NI_PAM_USERHOST) {
|
||||
a = attr_find(e->e_attrs, ni->ni_pam_host_ad);
|
||||
if (!a || value_find_ex( ni->ni_pam_host_ad,
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
|
||||
a->a_vals, &global_host_bv, op->o_tmpmemctx )) {
|
||||
rc = PAM_PERM_DENIED;
|
||||
authzmsg = hostmsg;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if (ni->ni_pam_opts & NI_PAM_USERSVC) {
|
||||
a = attr_find(e->e_attrs, ni->ni_pam_svc_ad);
|
||||
if (!a || value_find_ex( ni->ni_pam_svc_ad,
|
||||
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
|
||||
a->a_vals, &svc, op->o_tmpmemctx )) {
|
||||
rc = PAM_PERM_DENIED;
|
||||
authzmsg = svcmsg;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
if (ni->ni_pam_template_ad) {
|
||||
a = attr_find(e->e_attrs, ni->ni_pam_template_ad);
|
||||
if (a)
|
||||
tmpluser = a->a_vals[0];
|
||||
else if (!BER_BVISEMPTY(&ni->ni_pam_template))
|
||||
tmpluser = ni->ni_pam_template;
|
||||
}
|
||||
|
||||
finish:
|
||||
WRITE_INT32(fp,NSLCD_VERSION);
|
||||
WRITE_INT32(fp,NSLCD_ACTION_PAM_AUTHZ);
|
||||
WRITE_INT32(fp,NSLCD_RESULT_SUCCESS);
|
||||
WRITE_INT32(fp,PAM_SUCCESS);
|
||||
WRITE_INT32(fp,rc);
|
||||
WRITE_BERVAL(fp,&authzmsg);
|
||||
WRITE_BERVAL(fp,&tmpluser);
|
||||
if (e) {
|
||||
be_entry_release_r(op, e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *u
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int uid2dn_cb(Operation *op,SlapReply *rs)
|
||||
int nssov_name2dn_cb(Operation *op,SlapReply *rs)
|
||||
{
|
||||
if ( rs->sr_type == REP_SEARCH )
|
||||
{
|
||||
|
|
@ -175,7 +175,7 @@ int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *
|
|||
nssov_filter_byid(mi,UID_KEY,uid,&filter);
|
||||
BER_BVZERO(dn);
|
||||
cb.sc_private = dn;
|
||||
cb.sc_response = uid2dn_cb;
|
||||
cb.sc_response = nssov_name2dn_cb;
|
||||
op2 = *op;
|
||||
op2.o_callback = &cb;
|
||||
op2.o_req_dn = mi->mi_base;
|
||||
|
|
|
|||
Loading…
Reference in a new issue