static int get_ldap_seq(const char *server, int port, uint32 *seq) { int ret = -1; struct timeval to; char *attrs[] = {"highestCommittedUSN", NULL}; LDAPMessage *res = NULL; char **values = NULL; LDAP *ldp = NULL; *seq = DOM_SEQUENCE_NONE; /* * Parameterised (5) second timeout on open. This is needed as the search timeout * doesn't seem to apply to doing an open as well. JRA. */ if ((ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout())) == NULL) return -1; /* Timeout if no response within 20 seconds. */ to.tv_sec = 10; to.tv_usec = 0; if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res)) goto done; if (ldap_count_entries(ldp, res) != 1) goto done; values = ldap_get_values(ldp, res, "highestCommittedUSN"); if (!values || !values[0]) goto done; *seq = atoi(values[0]); ret = 0; done: if (values) ldap_value_free(values); if (res) ldap_msgfree(res); if (ldp) ldap_unbind(ldp); return ret; }
/* receive a cldap netlogon reply */ static int recv_cldap_netlogon(TALLOC_CTX *mem_ctx, int sock, uint32_t *nt_version, union nbt_cldap_netlogon **reply) { int ret; ASN1_DATA data; DATA_BLOB blob = data_blob_null; DATA_BLOB os1 = data_blob_null; DATA_BLOB os2 = data_blob_null; DATA_BLOB os3 = data_blob_null; int i1; /* half the time of a regular ldap timeout, not less than 3 seconds. */ unsigned int al_secs = MAX(3,lp_ldap_timeout()/2); union nbt_cldap_netlogon *r = NULL; blob = data_blob(NULL, 8192); if (blob.data == NULL) { DEBUG(1, ("data_blob failed\n")); errno = ENOMEM; return -1; } /* Setup timeout */ gotalarm = 0; CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); alarm(al_secs); /* End setup timeout. */ ret = read(sock, blob.data, blob.length); /* Teardown timeout. */ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); alarm(0); if (ret <= 0) { DEBUG(1,("no reply received to cldap netlogon\n")); data_blob_free(&blob); return -1; } blob.length = ret; asn1_load(&data, blob); asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_read_Integer(&data, &i1); asn1_start_tag(&data, ASN1_APPLICATION(4)); asn1_read_OctetString(&data, &os1); asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_read_OctetString(&data, &os2); asn1_start_tag(&data, ASN1_SET); asn1_read_OctetString(&data, &os3); asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); if (data.has_error) { data_blob_free(&blob); data_blob_free(&os1); data_blob_free(&os2); data_blob_free(&os3); asn1_free(&data); DEBUG(1,("Failed to parse cldap reply\n")); return -1; } r = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon); if (!r) { errno = ENOMEM; data_blob_free(&os1); data_blob_free(&os2); data_blob_free(&os3); data_blob_free(&blob); return -1; } if (!pull_mailslot_cldap_reply(mem_ctx, &os3, r, nt_version)) { data_blob_free(&os1); data_blob_free(&os2); data_blob_free(&os3); data_blob_free(&blob); TALLOC_FREE(r); return -1; } data_blob_free(&os1); data_blob_free(&os2); data_blob_free(&os3); data_blob_free(&blob); asn1_free(&data); if (reply) { *reply = r; } else { TALLOC_FREE(r); } return 0; }