int ipapwd_set_extradata(const char *dn, const char *principal, time_t unixtime) { Slapi_Mods *smods; Slapi_Value *va[2] = { NULL }; struct berval bv; char *xdata; int xd_len; int p_len; int ret; p_len = strlen(principal); xd_len = 2 + 4 + p_len + 1; xdata = malloc(xd_len); if (!xdata) { return LDAP_OPERATIONS_ERROR; } smods = slapi_mods_new(); /* data type id */ xdata[0] = 0x00; xdata[1] = 0x02; /* unix timestamp in Little Endian */ xdata[2] = unixtime & 0xff; xdata[3] = (unixtime & 0xff00) >> 8; xdata[4] = (unixtime & 0xff0000) >> 16; xdata[5] = (unixtime & 0xff000000) >> 24; /* append the principal name */ strncpy(&xdata[6], principal, p_len); xdata[xd_len -1] = 0; bv.bv_val = xdata; bv.bv_len = xd_len; va[0] = slapi_value_new_berval(&bv); slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE, "krbExtraData", va); ret = ipapwd_apply_mods(dn, smods); slapi_value_free(&va[0]); slapi_mods_free(&smods); return ret; }
/* * JCM SLOW FUNCTION * * WARNING: Use only if you absolutley need to... * This function mostly exists to map from the old slapi berval * based interface to the new Slapi_Value based interfaces. */ int valuearray_init_bervalarray(struct berval **bvals, Slapi_Value ***cvals) { int n; for(n=0; bvals != NULL && bvals[n] != NULL; n++); if(n==0) { *cvals = NULL; } else { int i; *cvals = (Slapi_Value **) slapi_ch_malloc((n + 1) * sizeof(Slapi_Value *)); for(i=0;i<n;i++) { (*cvals)[i] = slapi_value_new_berval(bvals[i]); } (*cvals)[i] = NULL; } return n; }
static void _usn_add_next_usn(Slapi_Entry *e, Slapi_Backend *be) { struct berval usn_berval = {0}; Slapi_Attr* attr = NULL; if (NULL == be->be_usn_counter) { /* USN plugin is not enabled */ return; } slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> _usn_add_next_usn\n"); /* add next USN to the entry; "be" contains the usn counter */ usn_berval.bv_val = slapi_ch_smprintf("%" NSPRIu64, slapi_counter_get_value(be->be_usn_counter)); usn_berval.bv_len = strlen(usn_berval.bv_val); slapi_entry_attr_find(e, SLAPI_ATTR_ENTRYUSN, &attr); if (NULL == attr) { /* ENTRYUSN does not exist; add it */ Slapi_Value *usn_value = slapi_value_new_berval(&usn_berval); slapi_entry_add_value(e, SLAPI_ATTR_ENTRYUSN, usn_value); slapi_value_free(&usn_value); } else { /* ENTRYUSN exists; replace it */ struct berval *new_bvals[2]; new_bvals[0] = &usn_berval; new_bvals[1] = NULL; slapi_entry_attr_replace(e, SLAPI_ATTR_ENTRYUSN, new_bvals); } slapi_ch_free_string(&usn_berval.bv_val); slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<-- _usn_add_next_usn\n"); return; }
int oath_preop_bind(Slapi_PBlock *pb) { char *dn; const char *creds; int creds_len, hotp_len = oath_preop_config.hotp_length, pin_len, method, rc = LDAP_SUCCESS, handled = 1; struct berval *credentials; Slapi_Value *sv_creds = NULL; Slapi_PBlock *upb, *tpb; // PBlocks for user and token searches Token token; slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind\n"); if (slapi_pblock_get(pb, SLAPI_BIND_METHOD, (void *) &method) != 0 || slapi_pblock_get(pb, SLAPI_BIND_TARGET, (void *) &dn) != 0 || slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, (void *) &credentials) != 0) { slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Could not get parameters for bind operation\n"); slapi_send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); return 1; } switch (method) { case LDAP_AUTH_SIMPLE: rc = LDAP_SUCCESS; sv_creds = slapi_value_new_berval(credentials); creds = slapi_value_get_string(sv_creds); creds_len = creds ? strlen(creds) : 0; Slapi_Entry **entries, *entry; int nentries = 0; upb = slapi_pblock_new(); slapi_search_internal_set_pb(upb, dn, LDAP_SCOPE_SUB, "(objectClass=*)", NULL, 0, NULL, NULL, oath_preop_plugin_id, 0); slapi_search_internal_pb(upb); slapi_pblock_get(upb, SLAPI_PLUGIN_INTOP_RESULT, &rc); slapi_pblock_get(upb, SLAPI_NENTRIES, &nentries); slapi_pblock_get(upb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); if (rc == LDAP_SUCCESS && nentries > 0 && entries != NULL && (entry = *entries) != NULL) { char filter[1024], *attrs[] = {"tokenSerial", "tokenSeed", "tokenCounter", "tokenPIN", NULL}; Slapi_Entry **tokens; int ntokens = 0; slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Authenticating DN: %s\n", dn); // search for tokens snprintf(filter, 1024, "(&(objectClass=oathToken)(tokenOwner=%s))", dn); tpb = slapi_pblock_new(); slapi_search_internal_set_pb(tpb, oath_preop_config.token_base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, oath_preop_plugin_id, 0); slapi_search_internal_pb(tpb); slapi_pblock_get(tpb, SLAPI_PLUGIN_INTOP_RESULT, &rc); slapi_pblock_get(tpb, SLAPI_NENTRIES, &ntokens); slapi_pblock_get(tpb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &tokens); if (rc == LDAP_SUCCESS && ntokens > 0 && tokens != NULL) { int t, w; unsigned char hotp[hotp_len + 1]; for (t = 0; t < ntokens; t++) { oath_token_from_entry(&token, tokens[t]); pin_len = token.pin ? strlen(token.pin) : 0; slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Found token: %s\n", token.serial); if (pin_len + hotp_len != creds_len) slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Credentials length did not match\n"); else if (token.pin && strncmp(creds, token.pin, pin_len)) slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: PIN did not match\n"); else for (w = 0; w < oath_preop_config.hotp_inner_window; w++) { if (oath_hotp(hotp, hotp_len, token.seed->bv_val, token.seed->bv_len, token.counter + w, oath_preop_config.hotp_trunc_offset, oath_preop_config.hotp_checksum)) { // slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: hotp(%d) = %s\n", token.counter + w, hotp); if (!strncmp(hotp, creds + pin_len, hotp_len)) { // success slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: hotp(%d) = %s\n", token.counter + w, hotp); if (oath_update_token(tokens[t], token.counter + w + 1) != 0) { slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Failed to update token entry\n"); rc = LDAP_OPERATIONS_ERROR; }; // OpenLDAP does not support setting SLAPI_CONN_DN and SLAPI_CONN_AUTHMETHOD /* if (slapi_pblock_set(pb, SLAPI_CONN_DN, slapi_ch_strdup(dn)) != 0 || slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, SLAPD_AUTH_SIMPLE) != 0) { slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Failed to set DN and auth method for connection\n", dn); rc = LDAP_OPERATIONS_ERROR; } */ goto free_tpb; } } else { // HOTP error slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: HOTP error for token %s\n", token.serial); break; } } slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: Token %s did not match\n", token.serial); oath_token_free(&token); } // No token matched handled = 0; goto free_tpb; } else { // no tokens associated slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: DN %s has got no token(s) associated, rc = %d\n", dn, rc); handled = 0; goto free_upb; } } else { // entry not found; don't fail because this can be root (directory manager) DN slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_preop_bind: DN %s not found\n", dn); if (rc == LDAP_SUCCESS) rc = LDAP_OPERATIONS_ERROR; else handled = 0; goto free_upb; } break; case LDAP_AUTH_NONE: case LDAP_AUTH_SASL: default: slapi_log_error(SLAPI_LOG_PLUGIN, "oath", "oath_bind_preop: Authentication type not supported: %d", method); return 0; } free_tpb: oath_token_free(&token); slapi_free_search_results_internal(tpb); slapi_pblock_destroy(tpb); free_upb: slapi_free_search_results_internal(upb); slapi_pblock_destroy(upb); slapi_value_free(&sv_creds); if (handled) { slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL); return 1; } else return 0; }
/* * Get an annotated value from the BerElement. Returns 0 on * success, -1 on failure. */ static int my_ber_scanf_value(BerElement *ber, Slapi_Value **value, PRBool *deleted) { struct berval *attrval = NULL; ber_len_t len = -1; ber_tag_t tag; CSN *csn = NULL; char csnstring[CSN_STRSIZE + 1]; CSNType csntype; char *lasti; PR_ASSERT(ber && value && deleted); if (NULL == ber && NULL == value) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 1\n"); goto loser; } *value = NULL; /* Each value is a sequence */ if (ber_scanf(ber, "{O", &attrval) == LBER_ERROR) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 2\n"); goto loser; } /* Allocate and fill in the attribute value */ if ((*value = slapi_value_new_berval(attrval)) == NULL) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 3\n"); goto loser; } /* check if this is a deleted value */ if (ber_peek_tag(ber, &len) == LBER_BOOLEAN) { if (ber_scanf(ber, "b", deleted) == LBER_ERROR) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 4\n"); goto loser; } } else /* default is present value */ { *deleted = PR_FALSE; } /* Read the sequence of CSNs */ for (tag = ber_first_element(ber, &len, &lasti); tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET; tag = ber_next_element(ber, &len, lasti)) { ber_int_t csntype_tmp; /* Each CSN is in a sequence that includes a csntype and CSN */ len = CSN_STRSIZE; if (ber_scanf(ber, "{es}", &csntype_tmp, csnstring, &len) == LBER_ERROR) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 7 - bval is %s\n", attrval->bv_val); goto loser; } switch (csntype_tmp) { case CSN_TYPE_VALUE_UPDATED_ON_WIRE: csntype = CSN_TYPE_VALUE_UPDATED; break; case CSN_TYPE_VALUE_DELETED_ON_WIRE: csntype = CSN_TYPE_VALUE_DELETED; break; case CSN_TYPE_VALUE_DISTINGUISHED_ON_WIRE: csntype = CSN_TYPE_VALUE_DISTINGUISHED; break; default: slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Error: preposterous CSN type " "%d received during total update.\n", csntype_tmp); goto loser; } csn = csn_new_by_string(csnstring); if (csn == NULL) { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 8\n"); goto loser; } value_add_csn(*value, csntype, csn); csn_free (&csn); } if (ber_scanf(ber, "}") == LBER_ERROR) /* End of annotated attribute value seq */ { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "my_ber_scanf_value BAD 10\n"); goto loser; } if (attrval) ber_bvfree(attrval); return 0; loser: /* Free any stuff we allocated */ if (csn) csn_free (&csn); if (attrval) ber_bvfree(attrval); if (value) { slapi_value_free (value); } return -1; }