int nssov_uid2dn(Operation *op,nssov_info *ni,struct berval *uid,struct berval *dn) { nssov_mapinfo *mi = &ni->ni_maps[NM_passwd]; char fbuf[1024]; struct berval filter = {sizeof(fbuf),fbuf}; slap_callback cb = {0}; SlapReply rs = {REP_RESULT}; Operation op2; int rc; /* if it isn't a valid username, just bail out now */ if (!isvalidusername(uid)) return 0; /* we have to look up the entry */ nssov_filter_byid(mi,UID_KEY,uid,&filter); BER_BVZERO(dn); cb.sc_private = dn; cb.sc_response = nssov_name2dn_cb; op2 = *op; op2.o_callback = &cb; op2.o_req_dn = mi->mi_base; op2.o_req_ndn = mi->mi_base; op2.ors_scope = mi->mi_scope; op2.ors_filterstr = filter; op2.ors_filter = str2filter_x( op, filter.bv_val ); op2.ors_attrs = slap_anlist_no_attrs; op2.ors_tlimit = SLAP_NO_LIMIT; op2.ors_slimit = SLAP_NO_LIMIT; rc = op2.o_bd->be_search( &op2, &rs ); filter_free_x( op, op2.ors_filter, 1 ); return rc == LDAP_SUCCESS && !BER_BVISNULL(dn); }
/** create a username from an account name * * The requirements for username are not explained anywhere except * except in the source code at * https://hg.mozilla.org/mozilla-central/file/2cfff9240e9a/services/sync/modules/identity.js#l422 * */ static char *moz_sync_username_from_accountname(const char *accountname) { char *username; SHA_CTX context; uint8_t digest[20]; size_t bufflen = 80; if (isvalidusername(accountname)) { return strduptolower(accountname); } SHA1_Init(&context); SHA1_Update(&context, accountname, strlen(accountname)); SHA1_Final(digest, &context); username = calloc(1, bufflen); if (username != NULL) { base32_encode((uint8_t*)username, &bufflen, digest, sizeof(digest)); } return username; }
static int pam_uid2dn(nssov_info *ni, Operation *op, struct paminfo *pi) { struct berval sdn; BER_BVZERO(&pi->dn); if (!isvalidusername(&pi->uid)) { Debug(LDAP_DEBUG_ANY,"nssov_pam_uid2dn(%s): invalid user name\n", pi->uid.bv_val,0,0); return NSLCD_PAM_USER_UNKNOWN; } 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 = pi->uid.bv_len + pi->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", pi->svc.bv_val, pi->uid.bv_val, global_host_bv.bv_val); slap_sasl2dn(op, &sdn, &pi->dn, 0); op->o_tmpfree( sdn.bv_val, op->o_tmpmemctx ); } /* If no luck, do a basic uid search */ if (BER_BVISEMPTY(&pi->dn) && (ni->ni_pam_opts & NI_PAM_UID2DN)) { nssov_uid2dn(op, ni, &pi->uid, &pi->dn); if (!BER_BVISEMPTY(&pi->dn)) { sdn = pi->dn; dnNormalize( 0, NULL, NULL, &sdn, &pi->dn, op->o_tmpmemctx ); } } if (BER_BVISEMPTY(&pi->dn)) { return NSLCD_PAM_USER_UNKNOWN; } return 0; }
/* return 1 on success */ int nssov_dn2uid(Operation *op,nssov_info *ni,struct berval *dn,struct berval *uid) { nssov_mapinfo *mi = &ni->ni_maps[NM_passwd]; AttributeDescription *ad = mi->mi_attrs[UID_KEY].an_desc; Entry *e; /* check for empty string */ if (!dn->bv_len) return 0; /* try to look up uid within DN string */ if (!strncmp(dn->bv_val,ad->ad_cname.bv_val,ad->ad_cname.bv_len) && dn->bv_val[ad->ad_cname.bv_len] == '=') { struct berval bv, rdn; dnRdn(dn, &rdn); /* check if it is valid */ bv.bv_val = dn->bv_val + ad->ad_cname.bv_len + 1; bv.bv_len = rdn.bv_len - ad->ad_cname.bv_len - 1; if (!isvalidusername(&bv)) return 0; ber_dupbv_x( uid, &bv, op->o_tmpmemctx ); return 1; } /* look up the uid from the entry itself */ if (be_entry_get_rw( op, dn, NULL, ad, 0, &e) == LDAP_SUCCESS) { Attribute *a = attr_find(e->e_attrs, ad); if (a) { ber_dupbv_x(uid, &a->a_vals[0], op->o_tmpmemctx); } be_entry_release_r(op, e); if (a) return 1; } return 0; }